Repository navigation
fix(workflow): atomic task-call contract in Plan Activate Step 2c (#1678) - #1687
Conversation
) Root cause: watchdog timeout triggered ~20s after epic creation when all task bodies were composed before the first create-issue call — the agent had already exceeded the post-result idle window before making any task API calls. Mitigation: add an explicit ATOMIC CONTRACT to Step 2c requiring each task body to be composed, called, and verified before the next — eliminating the gap between epic completion and first task API call. Changes: - workflows/squad.md: ATOMIC CONTRACT note in 2c; compact body spec (one sentence + 1-2 ACs + one context line); explicit no-batch rule; 2d incomplete fallback now calls report_incomplete with counts, never noops, and states idempotent re-run via title match - test/gh-aw-quality.test.ts: 7 new focused tests locking atomic contract, compact body, no-batch rule, report_incomplete fallback Evidence: live failed canary run 31555893180 — watchdog fired after epics, before task creation. Prompt bytes (squad.md + imports): 59,846 / ~80,000 ceiling → 20 KB headroom. Existing 37 tests remain green; total 44 passed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🟡 Impact Analysis — PR #1687Risk tier: 🟡 MEDIUM 📊 Summary
🎯 Risk Factors
📦 Modules Affectedroot (1 file)
tests (1 file)
This report is generated automatically for every PR. See #733 for details. |
🛫 PR Readiness Check
PR Scope: 🔧 Infrastructure
|
| Status | Check | Details |
|---|---|---|
| ✅ | Single commit | 1 commit — clean history |
| ✅ | 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 | 1 unresolved Copilot thread(s) — fix and resolve before merging |
| ✅ | CI passing | All checks passing |
Files Changed (2 files, +45 −2)
| File | +/− |
|---|---|
test/gh-aw-quality.test.ts |
+38 −0 |
workflows/squad.md |
+7 −2 |
Total: +45 −2
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
bradygaster
left a comment
There was a problem hiding this comment.
FIDO Quality Review — PR #1687 e372c14d
✅ APPROVE (via comment — same-author restriction)
Checklist Results
| Check | Result |
|---|---|
Based on latest dev (includes #1685/#1686 via dbb878da) |
✅ |
Changed files: workflows/squad.md + test/gh-aw-quality.test.ts only |
✅ |
No changeset; skip-changelog label present |
✅ |
| All 7 new tests pass; total 44 green | ✅ |
| All 37 prior tests remain green | ✅ |
| CI: all checks pass (test: pending at review time; others all pass) | ✅ |
Atomic Contract Wording (Step 2c)
For each task: compose ONLY that task's body → call
create-issueimmediately → verify the returned issue number → then move to the next task.
DO NOT compose or buffer multiple task bodies before making calls. One compose → one call → one verify, repeated per task.
Assessment: Unambiguous and minimal. The sequential constraint is stated twice (positive and negative form), removing any inference gap about batching. Minimizes post-result idle latency because the first API call happens immediately after the first body is composed.
report_incomplete Fallback (Step 2d)
If created count is below expected: call
report_incompleteimmediately withcreated={N},expected={M}, and the last verified issue number — never noop.
Assessment: Correctly configured. No contradictory summary behavior (no language suggesting partial success or silent continuation). Idempotent re-run via title match is explicit.
Prompt Byte Budget — KEY FINDING
The commit message states: 59,846 / ~80,000 ceiling → 20 KB headroom
The ~80,000 figure is a safety budget, not the hard production ceiling.
Live measurement at e372c14d:
workflows/squad.md: 34,017 bytesworkflows/shared/squad.md: 6,690 bytesworkflows/shared/planning-ontology.md: 15,231 bytesworkflows/shared/planning-policy.md: 3,910 bytes- Combined total: 59,848 bytes (58.4 KB)
The test suite correctly uses the hard production ceiling of 102,400 bytes (100 KB), enforced at GH_AW_PROMPT_CEILING_BYTES = 100 * 1024. The ~80,000 in the commit message is an informal safety budget (~78% of ceiling), not a ceiling. Tests enforce the correct value.
Headroom vs hard ceiling: 42,552 bytes (41.6 KB) — well above the 5 KB regression guard.
The commit message should ideally read "59,846 / ~80,000 (safety budget) vs 102,400 hard ceiling" but this is documentation-level only; the test assertion is correct.
No-Batch Prohibition & Compact Body Bounds
- Explicit
DO NOT compose or buffer multiple task bodiesprohibition present ✅ - Body spec: "one sentence describing scope; 1-2 acceptance criteria; one compact context line" — sufficient semantic preservation for issue triage without verbosity that triggers batching temptation ✅
Prior Hardening Integrity
All pre-existing tests (safe-output config, mode dispatch, shared imports, planning state machine, frontmatter schema, hardening behaviors) pass without regression. No imports removed.
Brittle Assertion Risk
The 7 new tests are regex-based against prose in squad.md. They will break if the exact phrases "ATOMIC CONTRACT", "never noop", "idempotent via title match", or "1-2 acceptance criteria" are paraphrased. This is intentional lock behavior — acceptable and desirable for a behavioral contract. Not brittle in a bad sense.
Verdict
APPROVE. All blockers resolved. Exact byte evidence: 59,848 / 102,400 bytes, 41.6 KB headroom. 44/44 tests pass. No regressions. The ~80,000 figure in the commit message is a safety budget annotation, not an error in the ceiling enforced by tests.
There was a problem hiding this comment.
Pull request overview
Hardens the Plan Activate portion of the Squad agentic workflow to prevent watchdog timeouts between epic creation and task issue creation by enforcing an atomic “compose → call → verify” loop and adding an explicit incomplete-activation fallback.
Changes:
- Adds an explicit ATOMIC CONTRACT to Step 2c to prevent batching task bodies before
create-issuecalls. - Compacts the task issue body requirements to reduce token/output overhead during activation.
- Adds/updates quality tests to enforce the new Step 2c/2d requirements in
workflows/squad.md.
Show a summary per file
| File | Description |
|---|---|
| workflows/squad.md | Adds atomic one-task-at-a-time contract for task creation and strengthens self-validation/fallback guidance. |
| test/gh-aw-quality.test.ts | Adds regression tests asserting the atomic contract language and the incomplete-activation fallback requirements are present. |
Review details
Tip
Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
| - Size: Project field if available, else body line | ||
|
|
||
| **2d. Self-Validation:** Compare created counts vs expected. If mismatch: report partial activation with counts, note idempotent re-run. | ||
| **2d. Self-Validation:** Compare created/recognized task count vs expected. If created count is below expected: call `report_incomplete` immediately with `created={N}`, `expected={M}`, and the last verified issue number — never noop. Re-runs are idempotent via title match. |
Root Cause
The watchdog fires ~20 s after the last visible model output. In the live failed canary run 31555893180, the agent composed all task bodies in one reasoning burst after epic creation completed — then the post-result idle window expired before the first
create-issuetask call was ever made.Exact Mitigation
Added an ATOMIC CONTRACT to Step 2c that mandates: compose one task body → call
create-issueimmediately → verify returned issue number → repeat. This breaks the silent inter-call gap that triggered the watchdog.Also:
report_incompletewithcreated={N},expected={M}, and last verified issue number — never noop; re-runs are idempotent via title matchEvidence — Run 31555893180
Watchdog fired after epic creation; zero task issues created. This patch eliminates the reasoning burst that caused the gap.
Prompt Bytes
Ceiling: ~80,000 B — ~20 KB headroom.
Tests
7 new focused tests added to
test/gh-aw-quality.test.ts:report_incompletecalled with created/expected countsAll 44 tests pass (37 pre-existing + 7 new).
Compile Status
gh aw compilenot available in this environment; workflow markdown is valid..lock.ymlnot regenerated (prompt-body-only change).Live Rerun
A live rerun on a fresh plan is still required to confirm end-to-end task creation completes before watchdog fires.
Files Changed (2)
workflows/squad.mdtest/gh-aw-quality.test.tsNotes
skip-changeloglabel applied