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
This commit is contained in:
Tom Boucher
2026-03-16 20:31:45 -04:00
parent a9be67f504
commit 3bfc0f6845
5 changed files with 34 additions and 8 deletions

View File

@@ -19,7 +19,7 @@
* state signal-resume Remove WAITING.json signal
* resolve-model <agent-type> Get model for agent based on profile
* find-phase <phase> Find phase directory by number
* commit <message> [--files f1 f2] Commit planning docs
* commit <message> [--files f1 f2] [--no-verify] Commit planning docs
* verify-summary <path> Verify a SUMMARY.md file
* generate-slug <text> 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;
}

View File

@@ -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')) {

View File

@@ -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}

View File

@@ -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.
</objective>
<parallel_execution>
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 "..."
</parallel_execution>
<execution_context>
@~/.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

View File

@@ -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
</precommit_failure_handling>
<task_commit>