feat(workflows): atomic Write+commit ordering for SUMMARY.md (#2806) (#2939)

* feat(workflows): add atomic Write+commit ordering directive for SUMMARY.md

Adds explicit prompt-ordering language to executor spawn prompts and
plan-execution steps so agents commit SUMMARY.md before emitting any
concluding narrative. Mitigates the truncation-between-Write-and-commit
failure mode that has made the #2070 rescue net load-bearing.

Refs #2806

* fix(workflows): condense REQUIRED ORDER blocks to fit XL budget

The two REQUIRED ORDER directives added in bd1956df pushed
execute-phase.md to 1712 lines, exceeding the 1700-line XL budget.

Collapse each 6-line block into a single line that preserves the
semantic intent (Write SUMMARY.md → commit → narration; no text
between Write and commit; #2070 rescue is not primary defense).

File is now exactly 1700 lines; workflow-size-budget test passes.

* fix(execute-plan): move self-check before commit to preserve atomic Write+commit (#2939)
This commit is contained in:
Tom Boucher
2026-05-01 09:32:21 -04:00
committed by GitHub
parent 7cc6358f91
commit e2792536d9
2 changed files with 19 additions and 1 deletions

View File

@@ -548,6 +548,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
only (STATE.md and ROADMAP.md are excluded automatically). Do NOT skip or defer
this commit — the orchestrator force-removes the worktree after you return, and
any uncommitted SUMMARY.md will be permanently lost (#2070).
REQUIRED ORDER: Write SUMMARY.md → commit → only then any narration. No text between Write and commit (truncation risk; #2070 rescue is not primary defense).
</parallel_execution>
<execution_context>
@@ -602,6 +603,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
<sequential_execution>
You are running as a SEQUENTIAL executor agent on the main working tree.
Use normal git commits (with hooks). Do NOT use --no-verify.
REQUIRED ORDER: Write SUMMARY.md → commit → only then any narration. No text between Write and commit (truncation risk; #2070 rescue is not primary defense).
</sequential_execution>
```

View File

@@ -116,12 +116,18 @@ Pattern B only (verify-only checkpoints). Skip for A/C.
2. Per segment:
- Subagent route: spawn gsd-executor for assigned tasks only. Prompt: task range, plan path, read full plan for context, execute assigned tasks, track deviations, NO SUMMARY/commit. Track via agent protocol.
- Main route: execute tasks using standard flow (step name="execute")
3. After ALL segments: aggregate files/deviations/decisions → create SUMMARY.md → commit → self-check:
3. **Critical ordering — write and commit SUMMARY.md as one atomic block.** Do NOT
emit narrative output between the Write tool call and the commit tool call.
Truncation at this boundary is a known failure mode (see #2070 rescue logic in
execute-phase.md step 5.5).
After ALL segments: aggregate files/deviations/decisions → create SUMMARY.md → self-check:
- Verify key-files.created exist on disk with `[ -f ]`
- Check `git log --oneline --all --grep="{phase}-{plan}"` returns ≥1 commit
- Re-run ALL `<acceptance_criteria>` from every task — if any fail, fix before finalizing SUMMARY
- Re-run the plan-level `<verification>` commands — log results in SUMMARY
- Append `## Self-Check: PASSED` or `## Self-Check: FAILED` to SUMMARY
Then commit (no narrative between Write and commit).
**Known Claude Code bug (classifyHandoffIfNeeded):** If any segment agent reports "failed" with `classifyHandoffIfNeeded is not defined`, this is a Claude Code runtime bug — not a real failure. Run spot-checks; if they pass, treat as successful.
@@ -336,6 +342,11 @@ If user_setup exists: create `{phase}-USER-SETUP.md` using template `~/.claude/g
</step>
<step name="create_summary">
**Critical ordering — write and commit SUMMARY.md as one atomic block.** Do NOT
emit narrative output between the Write tool call and the commit tool call.
Truncation at this boundary is a known failure mode (see #2070 rescue logic in
execute-phase.md step 5.5).
Create `{phase}-{plan}-SUMMARY.md` at `.planning/phases/XX-name/`. Use `~/.claude/get-shit-done/templates/summary.md`.
**Frontmatter:** phase, plan, subsystem, tags | requires/provides/affects | tech-stack.added/patterns | key-files.created/modified | key-decisions | requirements-completed (**MUST** copy `requirements` array from PLAN.md frontmatter verbatim) | duration ($DURATION), completed ($PLAN_END_TIME date).
@@ -437,6 +448,11 @@ Extract requirement IDs from the plan's frontmatter (e.g., `requirements: [AUTH-
</step>
<step name="git_commit_metadata">
**Critical ordering — write and commit SUMMARY.md as one atomic block.** Do NOT
emit narrative output between the Write tool call and the commit tool call.
Truncation at this boundary is a known failure mode (see #2070 rescue logic in
execute-phase.md step 5.5).
Task code already committed per-task. Commit plan metadata:
```bash