Repository navigation
Description
Summary
The first full end-to-end E4 run against the new fixture (octodemo/aspiregregator-squad-e2e) surfaced five procedures in the E2E runbooks that are stale or incorrect. Two of them are silent-failure traps of exactly the class test/e2e-runbook-hygiene.test.ts was created to prevent — they don't error, they just produce a wrong answer confidently.
Filing so the corrections land as one reviewable change while the measurements are fresh.
1. E4 Phase 2 "short path" is stale — it cannot reach its own verification targets
.squad/e2e/E4-agent-binding-verification.md:601-613 prescribes five commands and says in bold:
Do not continue to
plan validate/plan accept …/implement. Those add ~27 min and verify nothing additional for E4.
Measured false. /squad plan activate (run 32772695400) completed with all six jobs success and did nothing:
🤖 Squad — Plan Activate blocked
Result: No issues/milestones were created. Activation requires an `impl-accepted`
artifact (or a fully accepted `impl-phases-accepted` state), which doesn't exist yet.
A second halt then appeared at accept implementation, which requires accept scope first. The real path is eight commands:
/squad research
/squad triage
/squad plan program
/squad plan implementation ← #1784 leak site (3a)
/squad plan validate ← NEWLY REQUIRED
/squad plan accept scope ← NEWLY REQUIRED
/squad plan accept implementation ← NEWLY REQUIRED
/squad plan activate ← #1812 provenance site (3b/3c/3e); STOP
Both halts are correct Squad behaviour — clean lifecycle tables, precise remediation, no partial writes. The runbook is what's wrong. As written, plan activate never does anything, so Phases 3b, 3c, and 3e are unscoreable and only 3a survives.
L615-619 already anticipated this ("refuses to run without plan accept in later revisions"). That future has arrived; the prescription above it hasn't caught up.
2. E4 Phase 0b reports STALE forever on a correctly-provisioned fixture
E4-agent-binding-verification.md:432-466 compares raw .size from the contents API. But gh aw add injects a provenance line into the top-level workflow only:
source: bradygaster/squad/workflows/squad.md@dev
Measured on a freshly provisioned fixture: src=69913 fixture=69961 (+48 bytes) with identical line counts (1391 each). Compare-Object shows that single line as the only difference. The three shared/* files match exactly — only the entry workflow is affected.
So any fixture provisioned the documented way reports STALE permanently, and the 0c refresh loop can never reach its required post-condition of "all four MATCH". An operator following the runbook literally would loop forever or override the gate.
Fix: compare content modulo the injected source: line rather than byte size.
3. E4 §3b contamination table is stale from the deleted fixture
E4-agent-binding-verification.md:677-684 carries a 🛑 warning:
DO NOT check repo-global label existence. It is a guaranteed false FAIL.
squad:lead,squad:devrel, andsquad:revieweralready exist in the fixture — minted by E1 on 2026-08-19 and E3 on 2026-08-21.
And L736-742 tabulates contamination on issues #6-9 and #17-20.
All of that describes the old fixture, which was deleted. In octodemo/aspiregregator-squad-e2e those issue numbers don't exist and no squad:* label was pre-present — the repo had exactly 12 labels, none of them squad:*.
The guidance is therefore inverted: on a fresh fixture, repo-global absence is meaningful evidence, not a guaranteed false FAIL. L702's inline reference to "#6-9, #17-20 as of 2026-08-21" needs the same treatment.
This was missed when #1856 repointed the runbooks at the new fixture.
4. E4 §3a should warn against substituting Out-File for Set-Content
E4-agent-binding-verification.md:653-655 correctly uses Set-Content. Out-File wraps at console width, splitting long markdown table rows mid-cell.
Hit this directly: the roster name Keaton split across two lines as Ke / aton, which silently corrupted a roster-membership check. The failure is invisible — you get a plausible-looking name list with one entry quietly truncated. Re-extracting with [IO.File]::WriteAllText produced clean output.
Worth an explicit inline warning, since the natural PowerShell instinct is to reach for Out-File.
5. E1 "Autonomy Blockers" describes the wrong mechanism
.squad/e2e/E1-merge-continuation-relay.md:57-70 states that worker-opened PRs are parked by GitHub in action_required pending manual approval, and offers:
gh api -X POST "repos/<owner>/<repo>/actions/runs/<RUN_ID>/approve"Observed on fixture PR #4: pull_request workflows never triggered at all. GitHub suppresses workflow triggers entirely for PRs created with GITHUB_TOKEN. The check rollup showed only dynamic-event checks (CodeQL, dependency submission) — no parked runs.
Same practical consequence (the loop can't close unattended), different cause. The documented override cannot apply to a run that does not exist, so an operator following it will search for a run ID that was never created.
The recommendation in L65 — use a PAT or GitHub App token — remains correct.
Scope
Docs only: .squad/e2e/E4-agent-binding-verification.md and .squad/e2e/E1-merge-continuation-relay.md. No product code, no changeset required. Must continue to satisfy test/e2e-runbook-hygiene.test.ts.
Separately worth filing: README.md:541-543's install line omits four paths gh aw add writes (.github/aw/, .github/skills/, .github/workflows/agentics-maintenance.yml, .vscode/). Not included here to keep this change scoped to the runbooks.
Activity
docs(e2e): correct five stale procedures found by the first full E4 r…