Repository navigation
Description
Found during the E4 staged walk, gate 8 (plan activate), run 32471509974 on fixture bradygaster/aspiregregator-squad-e2e.
This changes the root cause of #1784. #1784 is not retired — it is re-diagnosed.
Measured
The activation summary on fixture issue #22 states:
Roster set read from
.squad/team.md(## Members→Namecolumn):lead,reviewer,devrel,security,docs
The fixture's actual .squad/team.md roster:
| Name | Role |
|---|---|
| Keaton | Lead / Architect |
| McManus | Backend Engineer (Orleans) |
| Fenster | Frontend Engineer (Blazor) |
| Hockney | Test Engineer |
| Kint | DevOps / Platform Engineer |
None of lead, reviewer, devrel, security, docs appears anywhere in team.md. The claim of provenance is false — the roster was not read from that file.
Reproduce:
gh api repos/bradygaster/aspiregregator-squad-e2e/contents/.squad/team.md \
-H "Accept: application/vnd.github.raw"Corroboration
The fixture's existing squad:* labels:
squad
squad:lead
squad:devrel
squad:reviewer
lead, devrel, reviewer are a strict subset of the falsely-reported roster, and are exactly the three labels E3's plan activate minted (squad:lead ×3, squad:devrel ×1). They are not a subset of the real roster.
Consequence — why #1784's diagnosis was wrong
The original framing was "activate derives owner tokens from roles instead of using roster names," addressed as prompt token-salience in #1789.
The measurement says otherwise:
- E3 — activate applied
squad:lead/squad:devrelbecause those are members of the hardcoded list it actually uses. It was not leaking role tokens; it was correctly labelling against the wrong roster. - E4 — the implementation planner read
team.mdcorrectly and producedKeaton/McManus/Fenster/Hockney. Activate compared them against the hardcoded list, found no match, and refused to apply anysquad:{agent}label.
So #1789 fixed a real thing in the planner and did not touch this. The planner's roster read is correct — verified at gate 4, Condition 1, 11/11 verbatim. The defect is downstream, in activate's roster source.
Impact on the E4 gate result
E4 passes 4/4 conditions as written, but Condition 2's pass is non-informative and must not be quoted as evidence that #1784 is fixed.
Condition 2 asserts no squad:lead/squad:devrel/squad:reviewer in timeline labeled events after $E4_START. It passed — 15 labeled events, all squad, zero role tokens. But it passed because activate applied no role labels at all, having refused on a roster mismatch. The absence is evidence of a refusal, not of correct binding.
This is the vacuous-pass pattern the condition was written to avoid, arriving through a path the condition could not distinguish: "correct owner labels minted" and "all owner labels refused" both yield an empty role-token set.
Two defects, separable
- Wrong source. Activate uses a hardcoded default roster (
lead, reviewer, devrel, security, docs) rather than parsing.squad/team.md. Any repo whose roster is cast-named — i.e. any repo that ransquad initwith a themed or custom universe — will never match, and will silently get zero owner labels. - False provenance. The summary asserts "Roster set read from
.squad/team.md" when it was not. This is worse than the wrong roster: it defeats the obvious diagnostic. A reader checking the summary againstteam.mdwould conclude the file was malformed rather than unread.
Defect 2 is the reason this survived E3. The E3 analysis accepted the summary's account of its own inputs.
What is NOT claimed
- No fix proposed. Not diagnosed further at 03:25.
- Whether the hardcoded list lives in the workflow, the ontology, or the compiled lock is unmeasured.
- Whether the planner and activate share a roster-reading code path is unmeasured.
- The
create-label+issues: writeprerequisite gap is real and separate — activate reported it correctly. That remains its own item.
Suggested condition change for the next E-series run
Condition 2 needs a both-terminals companion, or its green stays ambiguous:
2a. At least one
squad:{name}label was applied, and every appliedsquad:{name}matches aNamein.squad/team.md.
Without 2a, "refused everything" and "bound everything correctly" are indistinguishable — which is precisely what happened here.
/cc @bradygaster — relevant to the 2026-08-21 E2E series. Does not block it; the walk completed 8/8.
Activity
bradygaster commentedon Aug 21, 2026
Measurement — mechanism resolved, and it changes the remediation
Follow-up to the report above. Two measurements against E3 (fixture issue #16), which refute one inference and add a second defect site.
1.
activateapplies the plan's Agent value; it does not synthesize role tokensE3's implementation-plan Agent column, verbatim:
leadleaddevrelPlus epic #17 →
lead. That is exactly the label set E3 minted:squad:leadx3,squad:devrelx1.So
activateapplied what the plan gave it, filtered through its (wrong) roster. It did not derive owner tokens independently.Consequence: the earlier inference that "with
create-labelenabled, this run would plausibly have mintedsquad:leadandsquad:devrelagain" does not hold. E4's plan column containsMcManus/Keaton/Fenster/Hockneyand no role tokens anywhere — there is noleadvalue foractivateto apply. Enablingcreate-labelwould not reproduce the leak;activatewould still refuse, on roster-mismatch grounds, whichcreate-labeldoes not affect.create-labelis required for the correct behavior (mintingsquad:mcmanusand friends). It is not what is currently suppressing the defect.2. Second defect site —
plan validateconsults the same wrong roster, and passed on itFrom E3's validation gate, verbatim:
plan validatedeclaredlead, lead, devrelto be cast Names and returned PASS. The same wrong roster set is consulted at validate as at activate.That is why E3 reached
activatewith role tokens at all — the gate designed to catch exactly this condition was checking against the same incorrect roster, so it could not fail.Revised shape of the defect
One wrong roster set, consulted at at least two points in the lifecycle:
plan validatelead, lead, devrel— false acceptplan activatesquad:leadx3 +squad:devrel#1789 changed the planner's output from role tokens to real cast names. The wrong roster did not change; its failure mode inverted from false accept to false reject.
Impact on the E-series
plan validatecannot currently be relied on to catch agent-binding errors — it passedlead, lead, devrelas valid cast Names. Any future condition that treats a greenvalidateas evidence of correct binding inherits this.Still unmeasured
validateandactivateshare one roster-reading code path or duplicate it.bradygaster commentedon Aug 21, 2026
The claim "
plan validateconsults the same wrong roster" is wrong. Measured by Sims against E4's ownplan validateoutput, 23 minutes beforeactivatein the same walk:Same file, same section, same column, same run session — read correctly at
validate, incorrectly atactivate.Revised shape — the defect is stage-local to
activateNot one wrong roster with two consult sites.
validatereadsteam.mdcorrectly and echoes it. Onlyactivatedoes not.And E3's
validatefailed differently than described. Grepping E3's validate comment (fixture issue #16, 23,655 chars) forRoster set/Non-roster/Check 10returns one hit total:No roster enumerated. No Check 10 row. E3's
validatewas not consulting a wrong roster — it was consulting none, and asserting the conclusion anyway. False accept by omission, not by wrong reference.plan validate(lead, lead, devrel)— no roster, no Check 10; false accept by omissionplan activatesquad:leadx3 +squad:devrelConsequences
fix(squad.md): stop seeding Owner/Agent binding with the tokens it forbids #1789 did not invert a failure mode. It fixed two things — the implementation-plan Agent column and the
validategate's roster echo + Check 10 — and leftactivateuntouched. Theactivatebehavior is a separate, pre-existing defect, not a mutation of the one fix(squad.md): stop seeding Owner/Agent binding with the tokens it forbids #1789 addressed.The fix is cheaper than stated. There is a working reference implementation one stage earlier in the same lifecycle. The remediation is "make
activatedo whatvalidatealready does" — enumerate the roster from.squad/team.md, echo it, then verify verbatim. Not a research problem.Finding A is hardened.
validateemits the same citation format with accurate contents. The format is demonstrably achievable, which means theactivateinstance fabricated its roster rather than misparsing the file.The earlier framing "a validation gate returning ✅ while measuring against the wrong reference" is also wrong, and the truth is more mundane: a validation gate returning ✅ while measuring against no reference, with the failing values printed in the same cell as the pass. A claim rendered beside its own counter-evidence. That instance is caught by requiring the gate to show its reference set — which is exactly what fix(squad.md): stop seeding Owner/Agent binding with the tokens it forbids #1789 made it do.
Provenance of the error
The refuted claim was inferred from a single artifact (E3's validate output) without reading the adjacent one (E4's validate), which was one API call away and decisive. Two explanations fit the E3 data equally — wrong roster and no roster — and the more elegant one was chosen without measurement.
Recording this because the same failure mode is the subject of the issue.
docs(e2e): amend E4 for #1811/#1812, formalize E1 Rule D gate, add fo…
bradygaster commentedon Aug 23, 2026
1. Owner & rationale
Owner:
squad:procedures.plan activateis implemented in the gh-aw Squad workflow prompt, and the defect is a prompt-stage roster source/provenance failure.Labels reconciled as:
gh-aw,type:bug,priority:p0,wave:1-next,squad:procedures,triaged,go:spec-ready. I removed the legacybuglabel because this issue now uses thetype:*taxonomy.2. Files in scope
Verified existing paths:
workflows/squad.mdworkflows/shared/squad-planning-ontology.mdtest/gh-aw-plan-lifecycle.test.tstest/gh-aw-quality.test.ts.squad/e2e/E4-agent-binding-verification.md3. Reproduction / measurement
These commands were execution-tested and use no output suppression:
They show the fixture roster names (
Keaton,McManus,Fenster,Hockney,Kint) and the activation summary claiming.squad/team.mdyieldedlead,reviewer,devrel,security,docs.4. Verification bar
Activation must quote the actual
Namecolumn values from the target repo's.squad/team.md, and everysquad:{agent}label decision must be derived from that quoted set. The check must fail if the summary says it read.squad/team.mdbut emits any value absent from that file, or if all owner labels are refused while the plan contains valid roster names.5. Traps
Cross-cutting call: keep #1812 and #1801 independent. #1801 is the validation/template false-green; #1812 is a stage-local activation provenance/source defect. E4 already shows
plan validatecan read the roster correctly whileplan activatereads a false default roster, so neither issue is a safe dependency for the other.Do not treat
create-labelpermission gaps as the root cause. Missing label creation is separate; this issue is about choosing and reporting the roster source.6. Out of scope
Do not recast the fixture, change the roster names, add write permissions, or rewrite the activation lifecycle. Fix only the roster source/provenance and the fail-closed checks around it.
7. Session-stall guard
Align Step 3 validator with TG-2 certified set (#1812)
Certify roster set via emitting Team Guard Step TG-2 (Closes github#1812
chore(squad): gh-aw wave-1 session records + repair 3 lost history ar…