* fix(3678): executor must respect commit_docs:false; teach SDK skip envelope Closes #3678 When `commit_docs: false` in `.planning/config.json`, the SDK's `cmdCommit` correctly short-circuits and returns `{committed: false, hash: null, reason: 'skipped_commit_docs_false'}` without staging or committing anything. The agent prompt at `agents/gsd-executor.md:710-720` (final_commit block) tells the executor to call `gsd-sdk query commit "docs(...)" --files .planning/...` but says NOTHING about how to interpret a skipped return. With no explicit instruction, the LLM improvises raw `git add` / `git add -f` / `git commit` to "fulfill" the per-plan commit step it was told to make, which leaks gitignored `.planning/` artifacts into the user's git history (exactly what the reporter observed). Three coordinated fixes: 1. **agents/gsd-executor.md final_commit block** — adds explicit handling text for all three SDK return envelopes (`committed:true`, `skipped:true commit_docs`, `skipped:true gitignored`, `committed:false other reasons`). States plainly: "Do not fall back to raw `git add` / `git commit` / `git add -f` when the SDK returns `skipped: true`." 2. **get-shit-done/bin/lib/commands.cjs cmdCommit** — adds `skipped: true` to both skip-path envelopes so agents see "skipped" as a first-class success signal rather than inferring "no commit happened, I must improvise" from absent `hash` / `committed:false`. Backward-compatible: existing callers reading `committed` / `hash` / `reason` are unaffected. 3. **tests/bug-3678-executor-commit-docs-respect.test.cjs** — 7-test regression covering: - A1/A2: agent prompt mentions the skip envelope AND explicitly forbids raw-git fallback (`source-text-is-the-product` exception) - B1: SDK envelope carries `committed:false`, `skipped:true`, canonical `reason: 'skipped_commit_docs_false'` (frozen enum) - B2: git index empty after commit_docs:false skip (no `.planning/` staged) - B3: HEAD unchanged after commit_docs:false skip - C1/C2: structural ban on `git add -f` / `git add --force` in any agent or workflow body (prohibition-sentence exception preserves audit prose) Verification: - node --test tests/bug-3678-*: 7/7 pass - Targeted regression (10 commit/executor-adjacent files): 135/135 pass - Full docker suite (gsd-test-summary): 11751/11740 pass / 0 fail (the 11 added are this test plus a few collateral pickups) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(changeset): add fragment for #3678 fix (Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>) * chore(changeset): set PR number 3679 (Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>) * fix(3678): preserve skip-aware carve-out in executor completion checklist The new `final_commit` prose at lines 717-741 teaches the executor to treat `skipped:true` as success and forbids raw-git fallback, but the downstream completion checklist still contained an unconditional "Final metadata commit made" checkbox. An LLM executor reading an unchecked mandatory box may attempt to satisfy it via raw `git add`, re-introducing the exact regression this PR is meant to prevent. Update the checklist line to carve out the intentional-skip case and add a regression test asserting the carve-out remains present. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
11 KiB
11 KiB