From e2792536d99709310c740d14a554d71c101c8c04 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 1 May 2026 09:32:21 -0400 Subject: [PATCH] feat(workflows): atomic Write+commit ordering for SUMMARY.md (#2806) (#2939) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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) --- get-shit-done/workflows/execute-phase.md | 2 ++ get-shit-done/workflows/execute-plan.md | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md index c12af3298..737f8f8d0 100644 --- a/get-shit-done/workflows/execute-phase.md +++ b/get-shit-done/workflows/execute-phase.md @@ -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). @@ -602,6 +603,7 @@ increases monotonically across waves. `{status}` is `complete` (success), 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). ``` diff --git a/get-shit-done/workflows/execute-plan.md b/get-shit-done/workflows/execute-plan.md index 5696c5c1e..4a39dc457 100644 --- a/get-shit-done/workflows/execute-plan.md +++ b/get-shit-done/workflows/execute-plan.md @@ -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 `` from every task — if any fail, fix before finalizing SUMMARY - Re-run the plan-level `` 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 +**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- +**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