Skip to content

fix(ci): unblock gh-aw generated workflows in lint + agents guard - #1596

Merged
bradygaster merged 2 commits into
devfrom
squad/fix-ghaw-ci-gates
Aug 5, 2026
Merged

bradygaster merged 2 commits into
devfrom
squad/fix-ghaw-ci-gates

Conversation

@bradygaster

Copy link
Copy Markdown
Collaborator

Summary

This PR fixes two CI gates that are blocking PRs #1587 and #1592 (the Squad × gh-aw integration). It does not close, merge, or rebase those PRs — they remain on their SHIP-HOLD.

Background

Brady is landing a Squad × GitHub Agentic Workflows (gh-aw) integration. Two PRs are open against dev:

Both are currently RED in CI on two gates.


Fix 1 — Lint workflows and templates gate

File: .github/workflows/squad-workflow-lint.yml

Root cause: actionlint v1.7.12 — which is already the newest release; upgrading cannot fix this — lags GitHub's evolving feature set on two constructs used by gh-aw's generated files:

  • copilot-requests: write — a real, current GitHub Actions permission scope used by GitHub's own gh-aw toolchain in production.
  • concurrency.queue: max — a real, current Actions concurrency feature.

The files triggering these errors are DO-NOT-EDIT compiler output from gh-aw's gh aw compile toolchain (*.lock.yml) and gh-aw's own code generators (e.g. agentics-maintenance.yml). Their first few lines carry a header like:

# This file was automatically generated by gh-aw (v0.81.6). DO NOT EDIT.

Editing these files is not acceptable — they are clobbered on each compile/generate cycle and validated upstream by gh-aw's own toolchain.

Fix: Detect generated files by their header (automatically generated / DO NOT EDIT within the first 5 lines) and skip them. Header-based detection automatically covers future gh-aw generated files without manual maintenance. Hand-authored workflows are always linted. Skipped files are echoed in CI logs for debuggability.

Sabotage test: I intentionally introduced a bad options: [''] step into a hand-authored workflow and confirmed the gate still failed with a [syntax-check] error. I then reverted the sabotage. The gate still catches real errors in hand-written workflows.


Fix 2 — test gate (PR #1592 only)

File: test/template-sync.test.ts

Root cause: test/template-sync.test.ts:183 had a strict whole-directory equality assertion:

expect(files).toEqual([AGENT_MD_FILE]);

This over-reaches. .github/agents/ is legitimately shared between Squad and gh-aw. gh aw init installs its own dispatcher agent at .github/agents/agentic-workflows.md. Squad's sync never created this file — it belongs to gh-aw.

The test's actual intent (per its name and section comment) is to catch the template sync accidentally spraying extra files into .github/agents/.

Fix: Narrowed the guard to its actual intent. Now asserts:

  1. squad.agent.md is present.
  2. No file appears that is neither squad.agent.md nor a known non-Squad agent.

An explicit allowlist (agentic-workflows.md) with a comment explaining ownership. A truly random stray file still fails the test — verified by touch .github/agents/rogue-agent.md which produced:

AssertionError: unexpected file(s) in .github/agents/ that are neither squad.agent.md
nor a known third-party agent: rogue-agent.md

Validation Evidence

  1. npx vitest run test/template-sync.test.ts — ✅ 252 tests pass (on dev, which does not have agentic-workflows.md present)
  2. Stray file guard — ✅ still fails when rogue-agent.md is present
  3. Generated file detection — ✅ both agentics-maintenance.yml (PR chore(gh-aw): add gh aw init tooling (skills, MCP, setup + maintenance workflows) #1592) and squad-backlog-triage.lock.yml (PR feat(gh-aw): add Squad shared component for GitHub Agentic Workflows #1587) would be skipped by the header-based detection
  4. Sabotage test — ✅ deliberately broken hand-authored workflow still caught by actionlint
  5. npx vitest run full suite — 5 failed | 262 passed | 1 skipped (268) — the 5 failing test files are pre-existing failures on dev (externalized state [External State] squad export does not resolve externalized state #1396-[External State] squad cast does not follow externalized state for agent discovery #1399, ralph-instructions.md) and are not caused by this PR

git diff --cached --stat before commit:

 .github/workflows/squad-workflow-lint.yml | 45 +++++++++++++++++++++++++++++--
 test/template-sync.test.ts                | 19 ++++++++++++-
 2 files changed, 61 insertions(+), 3 deletions(-)

Scope

  • Touches only .github/workflows/squad-workflow-lint.yml and test/template-sync.test.ts
  • No product source changes (packages/*/src/ untouched)
  • No changeset required

References PRs #1587 and #1592 (does NOT close them).

…ents guard

actionlint v1.7.12 is the current latest release — upgrading cannot fix
this. The tool lags GitHub's evolving feature set on two specific
constructs:

  • 'copilot-requests: write' — a real current Actions permission scope
    used by GitHub's own gh-aw toolchain.
  • 'concurrency.queue: max' — a newer Actions concurrency feature.

The files triggering these errors are DO-NOT-EDIT compiler output from
gh-aw's 'gh aw compile' toolchain (*.lock.yml) and gh-aw's code
generators (e.g. agentics-maintenance.yml). Editing them is not
acceptable — they are clobbered on each compile/generate cycle and are
validated upstream by gh-aw's own toolchain.

Fix 1 (.github/workflows/squad-workflow-lint.yml):
  Detect generated files by their header ('automatically generated' /
  'DO NOT EDIT' within the first 5 lines) and skip them. Header-based
  detection automatically covers future gh-aw generated files without
  manual maintenance. Hand-authored workflows are always linted. Verified
  with a sabotage test: intentionally broken hand-authored workflow still
  fails the gate. Skipped files are echoed in CI logs for debuggability.

Fix 2 (test/template-sync.test.ts):
  The '.github/agents/ negative guard' asserted strict directory equality,
  which over-reaches. 'gh aw init' legitimately installs its own
  agentic-workflows.md in that directory. Narrowed the guard to its actual
  intent: squad.agent.md must be present, no *unexpected* files allowed,
  with an explicit allowlist of known non-Squad agents. A truly random
  stray file still fails the test.

Unblocks PRs #1587 and #1592 (does NOT close them).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 4, 2026 18:02
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🟡 Impact Analysis — PR #1596

Risk tier: 🟡 MEDIUM

📊 Summary

Metric Count
Files changed 2
Files added 0
Files modified 2
Files deleted 0
Modules touched 2

🎯 Risk Factors

  • 2 files changed (≤5 → LOW)
  • 2 modules touched (2-4 → MEDIUM)

📦 Modules Affected

ci-workflows (1 file)
  • .github/workflows/squad-workflow-lint.yml
tests (1 file)
  • test/template-sync.test.ts

This report is generated automatically for every PR. See #733 for details.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🏗️ Architectural Review

⚠️ Architectural review: 1 info.

Severity Category Finding Files
ℹ️ info template-sync Template files changed in .github/workflows/ but not in other template locations. If these templates should stay in sync, consider updating the others too. Changed: .github/workflows/, Unchanged: templates/, .squad-templates/, packages/squad-cli/templates/

Automated architectural review — informational only.

@github-actions

github-actions Bot commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit 7055f5e

PR Scope: 🔧 Infrastructure

⚠️ 3 item(s) to address before review

Status Check Details
❌ Single commit 2 commits — consider squashing before review
✅ Not in draft Ready for review
✅ Branch up to date Up to date with dev
❌ Copilot review No Copilot review yet — it may still be processing
✅ Changeset present No source files changed — changeset not required
✅ Scope clean No .squad/ or docs/proposals/ files
✅ No merge conflicts No merge conflicts
❌ Copilot threads resolved 2 unresolved Copilot thread(s) — fix and resolve before merging
✅ CI passing All checks passing

Files Changed (2 files, +76 −3)

File +/−
.github/workflows/squad-workflow-lint.yml +43 −2
test/template-sync.test.ts +33 −1

Total: +76 −3


This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR unblocks CI for the ongoing Squad × GitHub Agentic Workflows (gh-aw) integration by (1) skipping actionlint on machine-generated workflows that actionlint can’t currently parse, and (2) relaxing an over-strict template sync test that assumed .github/agents/ could only contain squad.agent.md.

Changes:

  • Update the workflow lint job to detect gh-aw generated workflows via header text and exclude them from actionlint runs while still linting hand-authored workflows.
  • Update test/template-sync.test.ts to allowlist a known third-party agent file in .github/agents/ while still failing on unexpected files.
Show a summary per file
File Description
.github/workflows/squad-workflow-lint.yml Skips actionlint for DO-NOT-EDIT generated workflows based on header detection, keeping lint coverage for hand-authored workflows.
test/template-sync.test.ts Narrows .github/agents/ directory assertions to allow known non-Squad agent files while still guarding against stray files.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment on lines +196 to +199
expect(
unexpected,
`unexpected file(s) in .github/agents/ that are neither squad.agent.md nor a known third-party agent: ${unexpected.join(', ')}`,
).toEqual([]);
Comment on lines 66 to +70
- name: Lint .github/workflows/*.yml
run: |
echo "--- Linting .github/workflows/ ---"
actionlint .github/workflows/*.yml
# Why we skip machine-generated files:
#
# actionlint v1.7.12 is the current latest release and CANNOT be upgraded to fix

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bradygaster see the copilot comment

…ding race

test/init-scaffolding.test.ts runs runInit() from a subdirectory of the repo
root.  In monorepo mode the init command detects the git root and places
squad.agent.md at .github/agents/ in the REAL repo root, then calls
stampVersion() to rewrite that file in place.  This runs concurrently with
template-sync.test.ts in a different Vitest worker.

The file-level beforeAll sync in template-sync.test.ts is correct but leaves
a race window: if init-scaffolding's stampVersion write lands between the
file-level sync and section 1's readFileBytes calls, the byte comparison sees
the stamped file (which differs from the canonical) and fails.

Fix: add a describe-scoped beforeAll inside section 1 that re-runs the sync
immediately before the byte comparisons start.  This collapses the race
window from 'entire beforeAll + test-collection time' to near-zero.

The byte-for-byte assertion itself is unchanged; this only makes the setup
more resilient.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bradygaster
bradygaster merged commit 86f1514 into dev Aug 5, 2026
16 checks passed
@bradygaster
bradygaster deleted the squad/fix-ghaw-ci-gates branch August 5, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants