feat(gh-aw): auto-cast and guide resumable work from one issue - #1690
Conversation
…1689) - Add Team Guard section: bash TEAM_PRESENT/TEAM_ABSENT check applied before all work modes (Research, Triage, Plan, etc.); exempt Cast/Connect/Adopt/Status/Implement - Auto-Cast Pivot: when TEAM_ABSENT, write-once squad-pending-intent-v1 comment (records original issue + command), deduplicate open Cast PR via gh pr list, run Cast on first run, post squad-cast-opened-v1 without fabricating PR number - Cast PR body includes squad-cast-pr-v1 origin reference marker - Plan Activate 2d: clarify N/M copy uses plan declared total not safe-output cap; never surface safe-output caps as reason for partial run - Register squad-pending-intent-v1, squad-cast-opened-v1, squad-cast-pr-v1 in planning-ontology.md marker registry - Add 18 structural tests in gh-aw-quality.test.ts covering all contract points (team guard, bash check, write-once semantics, dedup, no fabricated PR number, no /squad cast recovery copy, cast-pr-v1 origin, N/M copy, cap non-conflation) Closes #1689 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32ea40b4-299f-49f4-9561-243ad1f277c7
…1689) - Team Guard TG-1: replace shallow `test -s` with awk roster-row detection; missing file, empty file, header-only scaffold, and zero-member table all yield TEAM_ABSENT; only a real data row inside ## Members yields TEAM_PRESENT (HIGH finding 1) - Team Guard TG-3: replace `gh pr list --head "squad/cast-"` with `--jq '[.[] | select(.headRefName | startswith("squad/cast-"))]` so cast-{repo} branches are found; --head exact-matching was truncating the branch name and never returning results (HIGH finding 2) - Marker security: remove raw {original_command} from HTML marker attributes and user-facing retry copy; use {canonical_mode} and {canonical_command} derived from the allowlisted Parse Command output only; marker fields now contain only issue integer, mode enum, optional numeric phase, ISO timestamp (security finding 3) - Tests: update 2 existing tests (remove test -s assertion, require awk/## Members; replace permissive --head regex with headRefName + startsWith + forbidden --head check); add 9 new tests including fixture-based roster-row execution (missing/empty/scaffold/one-member) and canonical marker field assertions; all 71 tests pass Closes #1689 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 32ea40b4-299f-49f4-9561-243ad1f277c7
- TG-1: add sub(/\r$/,"") to awk roster-row check so CRLF-formatted
team.md is parsed correctly; CRLF scaffold-only correctly yields
TEAM_ABSENT instead of the previous false TEAM_PRESENT
- TG-3: narrow Cast PR dedup filter to exclude squad/cast-member-*
branches; previously startswith("squad/cast-") would match
squad/cast-member-dev and prevent legitimate Cast dedup; new filter:
startswith("squad/cast-") AND NOT startswith("squad/cast-member-")
- Tests: add 2 CRLF fixture tests (scaffold-crlf → TEAM_ABSENT,
one-member-crlf → TEAM_PRESENT); update runRosterCheck snippet to
match new CRLF-safe awk; update structural PR dedup test to require
cast-member exclusion; add 4-test behavioral jq suite that extracts
the exact --jq filter from squad.md and runs it against test JSON
confirming Cast branch matches and Cast Member branch is excluded
Closes #1689
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 32ea40b4-299f-49f4-9561-243ad1f277c7
🛫 PR Readiness Check
PR Scope: 🔧 Infrastructure
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 5 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 | 0 active Copilot thread(s) resolved (1 outdated skipped) |
| ✅ | CI passing | All checks passing |
Files Changed (19 files, +983 −299)
| File | +/− |
|---|---|
.github/agents.md |
+38 −41 |
docs/demo-agentic-sdlc-walkthrough.md |
+4 −10 |
test-fixtures/planning/aspiregregator/README.md |
+11 −11 |
test-fixtures/planning/aspiregregator/acceptance-outputs.md |
+30 −3 |
test-fixtures/planning/aspiregregator/assertions.md |
+21 −21 |
test-fixtures/planning/aspiregregator/implementation-plan-output.md |
+10 −1 |
test-fixtures/planning/aspiregregator/lifecycle-state.md |
+10 −1 |
test-fixtures/planning/aspiregregator/program-plan-output.md |
+10 −1 |
test-fixtures/planning/aspiregregator/research-output.md |
+10 −1 |
test-fixtures/planning/aspiregregator/triage-output.md |
+10 −1 |
test-fixtures/planning/aspiregregator/validation-output.md |
+10 −1 |
test/fixtures/team-guard/empty.md |
+0 −0 |
test/fixtures/team-guard/one-member-crlf.md |
+6 −0 |
test/fixtures/team-guard/one-member.md |
+6 −0 |
test/fixtures/team-guard/scaffold-crlf.md |
+5 −0 |
test/fixtures/team-guard/scaffold.md |
+5 −0 |
test/gh-aw-quality.test.ts |
+538 −83 |
workflows/shared/planning-ontology.md |
+86 −73 |
workflows/squad.md |
+173 −51 |
Total: +983 −299
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
🟡 Impact Analysis — PR #1690Risk tier: 🟡 MEDIUM 📊 Summary
🎯 Risk Factors
📦 Modules Affectedci-workflows (1 file)
docs (1 file)
root (11 files)
tests (6 files)
This report is generated automatically for every PR. See #733 for details. |
There was a problem hiding this comment.
Pull request overview
Extends the gh aw Squad workflow spec to support a one-issue “auto-cast then resume” journey when a guarded command is issued on an issue in a repo without a populated .squad/team.md, and hardens partial-activation messaging to use plan totals (not safe-output caps).
Changes:
- Add a “Team Guard” section to
workflows/squad.mddescribing roster-row detection and an Auto-Cast pivot flow (pending-intent marker, Cast PR dedup, and rerun guidance). - Register the new Auto-Cast markers in the planning ontology marker registry.
- Add structural/behavioral tests plus fixtures to validate the Team Guard awk snippet (including CRLF handling) and Cast PR dedup jq filter behavior.
Show a summary per file
| File | Description |
|---|---|
| workflows/squad.md | Documents Team Guard (TG-1..TG-3) auto-cast pivot flow and clarifies partial activation N/M copy vs plan totals. |
| workflows/shared/planning-ontology.md | Registers new Auto-Cast-related comment/PR markers in the marker registry. |
| test/gh-aw-quality.test.ts | Adds structural tests for Team Guard/Auto-Cast pivot, roster detection fixtures, canonical marker constraints, and PR dedup jq filter behavior. |
| test/fixtures/team-guard/empty.md | Empty fixture for roster-row detection (should yield TEAM_ABSENT). |
| test/fixtures/team-guard/scaffold.md | Header-only fixture for roster-row detection (should yield TEAM_ABSENT). |
| test/fixtures/team-guard/scaffold-crlf.md | CRLF header-only fixture to validate CRLF normalization (should yield TEAM_ABSENT). |
| test/fixtures/team-guard/one-member.md | One-member fixture for roster-row detection (should yield TEAM_PRESENT). |
| test/fixtures/team-guard/one-member-crlf.md | CRLF one-member fixture to validate CRLF normalization (should yield TEAM_PRESENT). |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 7/8 changed files
- Comments generated: 1
- Review effort level: Lite
| | `<!-- squad-pending-intent-v1 -->` | Auto-Cast: original issue + command | 1 per issue | Immutable once written; never written a second time | | ||
| | `<!-- squad-cast-opened-v1 -->` | Auto-Cast: Cast was initiated | 1 per issue | Immutable once written | | ||
| | `<!-- squad-cast-pr-v1 -->` | Cast PR body: origin issue + command reference | 1 per Cast PR | Immutable (in PR body, not issue comment) | |
) The E2E failure (run 31628021029) showed that when the activation pre-step runs `squad init --preset default`, a local .squad/team.md scaffold is created before the agent job. The previous Team Guard (TG-1) read the local filesystem and returned TEAM_PRESENT for that scaffold, causing /squad research to skip Auto-Cast and post research instead of assembling a team. Changes: - TG-1 command changed from: awk '...' .squad/team.md 2>/dev/null | grep -q . && ... to: git show HEAD:.squad/team.md 2>/dev/null | awk '...' | grep -q . && ... Only committed blobs are visible to the guard; activation-restored local files are intentionally invisible. - Description paragraph added explaining the committed-HEAD vs local-activation distinction so future authors understand why. - Replaced fixture-based roster tests with 8 executable tests against real temporary git repos covering all required cases: working-tree-only scaffold → ABSENT; committed empty → ABSENT; committed header-only → ABSENT; committed real → PRESENT; working-tree real over absent committed → ABSENT; committed real + dirty working tree → PRESENT; CRLF scaffold → ABSENT; CRLF real → PRESENT. - Added two structural tests enforcing `git show HEAD:.squad/team.md` presence and forbidding direct local file path in TG-1. - All 81 tests pass; lint and build clean. Closes #1689 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace unsupported Squad HTML state markers with schema-validated gh-aw data, preserve additive Cast retries, and keep originating issues open. Closes #1689 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Closes #1689
Summary
Extends the Squad workflow so a user issuing any guarded command (Research, Triage, Plan, etc.) on an issue that has no team yet is automatically handled in a single, resumable journey — no separate
/squad castrequired.One-issue auto-Cast journey
Without this change: issuing
/squad researchon an issue with no.squad/team.mdproduced an unhelpful error. The user had to discover and separately run/squad cast, wait for the PR to merge, then re-issue the original command.With this change: the workflow detects team absence via the new Team Guard and auto-pivots:
<!-- squad-pending-intent-v1 issue={N} mode={canonical_mode} -->— never duplicated across reruns.gh pr list --json headRefNameandstartswith("squad/cast-")(excludingsquad/cast-member-*). If a Cast PR is already open, it posts the PR link and stops — no duplicate.<!-- squad-cast-pr-v1 origin-issue={N} origin-mode={canonical_mode} -->for traceability./squad {canonical_mode}— always using the parsed canonical command, never raw user input.Same-run PR ID limitation
The Cast PR number is not available in the same run that opens it (a workflow constraint). The
squad-cast-opened-v1comment honestly tells users to find it in the Pull Requests tab. This is the correct behavior; fabricating a number is explicitly forbidden.Roster detection (Team Guard TG-1)
test -s .squad/team.mdwas replaced with a portable awk roster-row check:TEAM_ABSENTTEAM_PRESENTsub(/\r$/,"")normalizes CRLF line endings (Windows-formatted files no longer falsely reportTEAM_PRESENT)Canonical commands (security hardening)
{original_command}(raw user input from the issue comment) is never embedded in HTML marker attributes. All marker fields contain only parsed, allowlisted values: issue integer, mode enum, optional numeric phase. User-facing retry copy uses{canonical_command}assembled from the parsed mode.N/M partial activation
Step 2d clarifies that the
N of M issues createdcopy uses the plan's declared total — never the safe-output cap (75). Users are told to rerun the identical command to continue; the cap is never surfaced as a reason for stopping.Validation
npm run buildnpm run lint(tsc --noEmit)gh aw compile --dir workflows/Review history
An initial revision was reviewed and one round of targeted structural findings were addressed (Team Guard roster semantics, PR dedup regex, marker injection hardening, CRLF safety, Cast-Member branch exclusion). All findings were resolved and re-reviewed before this PR was opened.