From 3bfc0f68455c9043cecd7db855542b898f478c2f Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Mon, 16 Mar 2026 20:31:45 -0400 Subject: [PATCH] fix: add --no-verify support for parallel executor commits (#1116) Parallel executor agents trigger pre-commit hooks on every commit, causing build lock contention (e.g., cargo lock fights in Rust projects) and 40+ minute delays from cascading retries. Changes: - Add --no-verify flag to gsd-tools commit command (commands.cjs) - Wire --no-verify through gsd-tools.cjs CLI parser - Update execute-phase.md to instruct parallel agents to use --no-verify - Add post-wave hook validation step so orchestrator runs hooks once - Update execute-plan.md pre-commit handling: parallel agents skip hooks, sequential agents still handle hooks normally - Add parallel agent note to git-integration.md reference Fixes #1116 --- get-shit-done/bin/gsd-tools.cjs | 5 +++-- get-shit-done/bin/lib/commands.cjs | 5 +++-- get-shit-done/references/git-integration.md | 4 ++++ get-shit-done/workflows/execute-phase.md | 20 +++++++++++++++++++- get-shit-done/workflows/execute-plan.md | 8 +++++--- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/get-shit-done/bin/gsd-tools.cjs b/get-shit-done/bin/gsd-tools.cjs index cdee42566..02915d58b 100755 --- a/get-shit-done/bin/gsd-tools.cjs +++ b/get-shit-done/bin/gsd-tools.cjs @@ -19,7 +19,7 @@ * state signal-resume Remove WAITING.json signal * resolve-model Get model for agent based on profile * find-phase Find phase directory by number - * commit [--files f1 f2] Commit planning docs + * commit [--files f1 f2] [--no-verify] Commit planning docs * verify-summary Verify a SUMMARY.md file * generate-slug Convert text to URL-safe slug * current-timestamp [format] Get timestamp (full|date|filename) @@ -290,6 +290,7 @@ async function main() { case 'commit': { const amend = args.includes('--amend'); + const noVerify = args.includes('--no-verify'); const filesIndex = args.indexOf('--files'); // Collect all positional args between command name and first flag, // then join them — handles both quoted ("multi word msg") and @@ -298,7 +299,7 @@ async function main() { const messageArgs = args.slice(1, endIndex).filter(a => !a.startsWith('--')); const message = messageArgs.join(' ') || undefined; const files = filesIndex !== -1 ? args.slice(filesIndex + 1).filter(a => !a.startsWith('--')) : []; - commands.cmdCommit(cwd, message, files, raw, amend); + commands.cmdCommit(cwd, message, files, raw, amend, noVerify); break; } diff --git a/get-shit-done/bin/lib/commands.cjs b/get-shit-done/bin/lib/commands.cjs index d7109df19..b7416a1b3 100644 --- a/get-shit-done/bin/lib/commands.cjs +++ b/get-shit-done/bin/lib/commands.cjs @@ -214,7 +214,7 @@ function cmdResolveModel(cwd, agentType, raw) { output(result, raw, model); } -function cmdCommit(cwd, message, files, raw, amend) { +function cmdCommit(cwd, message, files, raw, amend, noVerify) { if (!message && !amend) { error('commit message required'); } @@ -241,8 +241,9 @@ function cmdCommit(cwd, message, files, raw, amend) { execGit(cwd, ['add', file]); } - // Commit + // Commit (--no-verify skips pre-commit hooks, used by parallel executor agents) const commitArgs = amend ? ['commit', '--amend', '--no-edit'] : ['commit', '-m', message]; + if (noVerify) commitArgs.push('--no-verify'); const commitResult = execGit(cwd, commitArgs); if (commitResult.exitCode !== 0) { if (commitResult.stdout.includes('nothing to commit') || commitResult.stderr.includes('nothing to commit')) { diff --git a/get-shit-done/references/git-integration.md b/get-shit-done/references/git-integration.md index 1e0a9d1b4..d9bbecac2 100644 --- a/get-shit-done/references/git-integration.md +++ b/get-shit-done/references/git-integration.md @@ -61,6 +61,10 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs: initialize [p Each task gets its own commit immediately after completion. +> **Parallel agents:** When running as a parallel executor (spawned by execute-phase), +> use `--no-verify` on all commits to avoid pre-commit hook lock contention. +> The orchestrator validates hooks once after all agents complete. + ``` {type}({phase}-{plan}): {task-name} diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md index e5c6afe4d..e6e855398 100644 --- a/get-shit-done/workflows/execute-phase.md +++ b/get-shit-done/workflows/execute-phase.md @@ -204,6 +204,14 @@ Execute each wave in sequence. Within a wave: parallel if `PARALLELIZATION=true` Commit each task atomically. Create SUMMARY.md. Update STATE.md and ROADMAP.md. + + You are running as a PARALLEL executor agent. Use --no-verify on all git + commits to avoid pre-commit hook contention with other agents. The + orchestrator validates hooks once after all agents complete. + For gsd-tools commits: add --no-verify flag. + For direct git commits: use git commit --no-verify -m "..." + + @~/.claude/get-shit-done/workflows/execute-plan.md @~/.claude/get-shit-done/templates/summary.md @@ -240,7 +248,17 @@ Execute each wave in sequence. Within a wave: parallel if `PARALLELIZATION=true` 3. **Wait for all agents in wave to complete.** -4. **Report completion — spot-check claims first:** +4. **Post-wave hook validation (parallel mode only):** + + When agents committed with `--no-verify`, run pre-commit hooks once after the wave: + ```bash + # Run project's pre-commit hooks on the current state + git diff --cached --quiet || git stash # stash any unstaged changes + git hook run pre-commit 2>&1 || echo "⚠ Pre-commit hooks failed — review before continuing" + ``` + If hooks fail: report the failure and ask "Fix hook issues now?" or "Continue to next wave?" + +5. **Report completion — spot-check claims first:** For each SUMMARY.md: - Verify first 2 files from `key-files.created` exist on disk diff --git a/get-shit-done/workflows/execute-plan.md b/get-shit-done/workflows/execute-plan.md index e64dec825..0e5d8e8a5 100644 --- a/get-shit-done/workflows/execute-plan.md +++ b/get-shit-done/workflows/execute-plan.md @@ -234,6 +234,10 @@ See `~/.claude/get-shit-done/references/tdd.md` for structure. Your commits may trigger pre-commit hooks. Auto-fix hooks handle themselves transparently — files get fixed and re-staged automatically. +**If running as a parallel executor agent (spawned by execute-phase):** +Use `--no-verify` on all commits. Pre-commit hooks cause build lock contention when multiple agents commit simultaneously (e.g., cargo lock fights in Rust projects). The orchestrator validates once after all agents complete. + +**If running as the sole executor (sequential mode):** If a commit is BLOCKED by a hook: 1. The `git commit` command fails with hook error output @@ -241,9 +245,7 @@ If a commit is BLOCKED by a hook: 3. Fix the issue (type error, lint violation, secret leak, etc.) 4. `git add` the fixed files 5. Retry the commit -6. Do NOT use `--no-verify` - -This is normal and expected. Budget 1-2 retry cycles per commit. +6. Budget 1-2 retry cycles per commit