Repository navigation
Description
Blocks the last unproven hop of epic continuation. Everything before it now works; this is the final gap.
Live repro
Fixture repo bradygaster/aspiregregator-squad-e2e, worker run 32324473906.
The worker agent emitted two safe-output calls. From agent/safeoutputs.jsonl:
{"type":"dispatch_workflow"}
{"type":"dispatch_workflow","inputs":{"command":"implement","issue_number":"5"},"workflow_name":"squad"}The first is an empty schema-discovery probe — the agent calling the tool with no arguments to learn its shape. The second is the fully correct payload.
gh-aw's safe-output collection is configured max: 1, and it keeps the first matching item, discarding the rest. So safe-outputs-items/safe-output-items.jsonl contained only:
{"type":"dispatch_workflow","timestamp":"2026-08-20T02:28:13.892Z"}The real payload was thrown away. The router then received a dispatch with no command input and filed issue #12 "Squad workflow dispatch missing command" — which is #1752's safety net working exactly as designed, failing loudly instead of silently defaulting to cast.
What is NOT broken
- The payload construction from Fix Squad continuation dispatch inputs #1752 is correct
- The safety net is correct
- Do not revert or weaken either
The only defect is that the agent probes before committing.
The fix
gh-aw already defends against this pattern elsewhere. Its add_comment tool description opens with language to the effect of:
WRITE-ONCE: do NOT call this tool with empty or placeholder arguments to probe or discover its schema — if you are not ready to post a real comment, call
noopinstead.
dispatch_workflow carries no such warning.
Per the standing directive that all work stays in this repo, the deliverable is a workaround in our own prompt, not a change request elsewhere.
Target: workflows/squad-implement-worker.md, the ## Continue Parent Epic After Merge section (~L216–248, payload ~L232).
Add explicit WRITE-ONCE / never-probe language telling the agent to:
- Call
dispatch_workflowexactly once, only with a complete payload - Never call it with empty, partial, or placeholder arguments to probe the schema
- Understand the schema is already in the prompt — there is nothing to discover
- Call
noopinstead when there is no next wave to dispatch - Know the first call wins and later calls are silently discarded, so a probe destroys the real dispatch
Contract assertion
Add a test in test/gh-aw-quality.test.ts — there's an existing merge continuation dispatch contract describe block and an extractWorkflowDispatchInputs() helper to follow.
Make it contract-based, not a change-detector: assert the semantic guarantee (dispatch section warns against empty/probe calls and names noop as the alternative), not an exact sentence. A prior version of this file was criticized for being a change-detector that defended two bugs.
Verification
Re-run /squad implement on epic #5 in the fixture repo. Children #8 and #9 are still open and blocked, so a successful run should dispatch #8.
⚠️ Gotchas
- Never put a
##heading inside a## skill:block inworkflows/squad.md— it closes implicitly at the next H2 and everything up to the next skill marker is silently discarded (~29 KB lost once, still compiled clean). Skills use#####. - Injection safety: the interpolation CI gate covers
inputs.*only.comment.body/issue.bodymust stay un-interpolated — they're attacker-controlled and sanitized separately. Do not "fix" them. - ~16 local Vitest failures on Windows are a known baseline; CI is the arbiter.
Activity