Merge pull request #1505 from Tibsfox/fix/quick-plan-uncommitted-1503

fix(quick): enforce commit boundary between executor and orchestrator
This commit is contained in:
Tom Boucher
2026-04-01 17:32:05 -04:00
committed by GitHub
2 changed files with 59 additions and 2 deletions

View File

@@ -568,8 +568,9 @@ ${AGENT_SKILLS_EXECUTOR}
<constraints>
- Execute all tasks in the plan
- Commit each task atomically
- Commit each task atomically (code changes only)
- Create summary at: ${QUICK_DIR}/${quick_id}-SUMMARY.md
- Do NOT commit docs artifacts (SUMMARY.md, STATE.md, PLAN.md) — the orchestrator handles the docs commit in Step 8
- Do NOT update ROADMAP.md (quick tasks are separate from planned phases)
</constraints>
",
@@ -711,7 +712,7 @@ Use Edit tool to make these changes atomically
**Step 8: Final commit and completion**
Stage and commit quick task artifacts:
Stage and commit quick task artifacts. This step MUST always run — even if the executor already committed some files (e.g. when running without worktree isolation). The `gsd-tools commit` command handles already-committed files gracefully.
Build file list:
- `${QUICK_DIR}/${quick_id}-PLAN.md`
@@ -722,6 +723,9 @@ Build file list:
- If `$VALIDATE_MODE` and verification file exists: `${QUICK_DIR}/${quick_id}-VERIFICATION.md`
```bash
# Explicitly stage all artifacts before commit — PLAN.md may be untracked
# if the executor ran without worktree isolation and committed docs early
git add ${file_list} 2>/dev/null
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs(quick-${quick_id}): ${DESCRIPTION}" --files ${file_list}
```

View File

@@ -0,0 +1,53 @@
/**
* GSD Quick Workflow — Commit Boundary Tests (#1503)
*
* Validates that the quick workflow correctly separates executor
* responsibilities (code commits) from orchestrator responsibilities
* (docs artifact commit), preventing PLAN.md from being left untracked
* when the executor runs without worktree isolation.
*/
const { test, describe } = require('node:test');
const assert = require('node:assert');
const fs = require('fs');
const path = require('path');
const WORKFLOWS_DIR = path.join(__dirname, '..', 'get-shit-done', 'workflows');
describe('quick workflow commit boundary (#1503)', () => {
const quickPath = path.join(WORKFLOWS_DIR, 'quick.md');
let content;
test('quick.md exists', () => {
assert.ok(fs.existsSync(quickPath), 'workflows/quick.md should exist');
content = fs.readFileSync(quickPath, 'utf-8');
});
test('executor constraints prohibit committing docs artifacts', () => {
assert.ok(
content.includes('Do NOT commit docs artifacts'),
'executor constraints should prohibit committing SUMMARY.md, STATE.md, PLAN.md'
);
});
test('Step 8 explicitly stages artifacts with git add before commit', () => {
assert.ok(
content.includes('git add ${file_list}'),
'Step 8 should explicitly git add the file list before gsd-tools commit'
);
});
test('Step 8 includes PLAN.md in file list', () => {
assert.ok(
content.includes('${QUICK_DIR}/${quick_id}-PLAN.md'),
'Step 8 file list must include PLAN.md'
);
});
test('Step 8 runs unconditionally', () => {
assert.ok(
content.includes('MUST always run'),
'Step 8 should state it must always run regardless of executor commits'
);
});
});