fix(#2825): gsd-code-fixer honors workflow.use_worktrees; never rm -rf a reparse point (#2905)

* fix(#2825): gsd-code-fixer honors workflow.use_worktrees; never rm -rf a reparse point

gsd-code-fixer was the only writer that hand-rolled a git worktree inside the
agent prompt and the only one that never read workflow.use_worktrees. With the
setting explicitly false, --fix still created worktrees; the fresh worktree had
no node_modules, so runs improvised a teardown whose `rm -rf` followed a Windows
junction into the REAL node_modules (silent data loss, 3x observed).

Defect 1: gate setup_worktree + its cleanup tail on workflow.use_worktrees
(same gsd_run query config-get read the four sibling workflows use). When false:
edit/commit in the main checkout (wt='.', no temp branch, no sentinel, no cleanup).

Defect 2: forbid rm -rf on a possible reparse point in the spec — never fall
through to a destructive remove; on failure, stop and surface the error.

Defect 3: REVIEW-FIX records where verification ran (main checkout vs worktree).

The transactional worktree path (#2839/#2990/#2686) is unchanged when worktrees
are enabled. Docs-parity guards in tests/code-review.test.cjs bind the spec to
the fix.

* chore(#2825): backfill changeset PR 2905

* fix(#2825): drop stale agents/gsd-code-fixer.toml ack + spent entries (emitted-attribution)

gsd-test failed: agents/gsd-code-fixer.toml is a STALE ack here — that TOML was
changed by #2834 (now in next), not this PR. The 4 base-carried acks
(autonomous/discuss-phase-assumptions/next/plan-phase) are spent/inert.

---------

Co-authored-by: Test <test@example.com>
(cherry picked from commit 5d0fd4dc53)
This commit is contained in:
Tom Boucher
2026-07-31 01:57:50 -04:00
committed by sim
parent dc73680532
commit 3aabb0f441
4 changed files with 175 additions and 144 deletions

View File

@@ -260,6 +260,39 @@ describe('CR-AGENT: code review agent frontmatter', () => {
assert.ok(content.includes('files_reviewed_list'),
'gsd-code-reviewer REVIEW.md frontmatter spec must include files_reviewed_list for --auto scope persistence');
});
// #2825: gsd-code-fixer is the only writer that hand-rolls a git worktree; it
// must honor workflow.use_worktrees (the documented opt-out) like its four
// sibling writer workflows, and never rm -rf a possible Windows reparse point.
test('#2825 gsd-code-fixer.md reads workflow.use_worktrees and gates git worktree add on it', () => {
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-code-fixer.md'), 'utf-8');
assert.ok(
content.includes('workflow.use_worktrees'),
'gsd-code-fixer setup_worktree must read the workflow.use_worktrees config flag (#2825)',
);
// The git worktree add must be CONDITIONAL on the flag, not unconditional.
// Locate the worktree-add line and confirm a USE_WORKTREES gate precedes it.
assert.ok(
/USE_WORKTREES=.false./.test(content) || content.includes('if [ "$USE_WORKTREES" = "false" ]'),
'gsd-code-fixer must gate worktree creation on USE_WORKTREES=false (skip when opted out) (#2825)',
);
});
test('#2825 gsd-code-fixer.md forbids rm -rf on a possible reparse point (Windows junction safety)', () => {
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-code-fixer.md'), 'utf-8');
assert.ok(
/rm -rf.*reparse point|reparse point.*rm -rf|NEVER .rm -rf.|never use .rm -rf/i.test(content),
'gsd-code-fixer must forbid rm -rf on a possible reparse point/junction (#2825) — on Windows that is the delete-the-target path',
);
});
test('#2825 gsd-code-fixer.md records where verification ran (main checkout vs worktree)', () => {
const content = fs.readFileSync(path.join(AGENTS_DIR, 'gsd-code-fixer.md'), 'utf-8');
assert.ok(
/verification[\s\S]*(main checkout|worktree)|(main checkout|worktree)[\s\S]*verification/i.test(content),
'gsd-code-fixer REVIEW-FIX.md must record where verification ran (main checkout vs worktree) so a reader knows if the numbers are reproducible (#2825)',
);
});
});
// --- CR-CMD: code review command structure ---

View File

@@ -1,119 +1,39 @@
{
"version": 1,
"paths": {
"plan-phase.md": {
"reason": "#2770: decision-coverage gate recomputes CONTEXT_PATH in-block + guards the empty-glob case (handler now fails closed on empty arg). Net growth kept under the ADR-857 size cap by condensing adjacent \u00a713a prose/JSON; the residual +89 bytes are the irreducible glob+guard logic."
},
"discuss-phase-assumptions.md": {
"reason": "#2772: re-synced <answer_validation> to the parent canonical block (had drifted \u2014 lost the 'Other' empty-text branch) + fixed the auto_advance\u2192confirm_creation circularity (end the workflow). discuss-phase.md is net -11 (condensed); auto.md shrank -4650 (removed a dead MAX_PASSES resolver shim)."
},
"autonomous.md": {
"reason": "#2800 \u2014 the hand-enumerated reviewer-flag list is replaced by a loop over `gsd_run review-lane flags`, and the whole CONVERGENCE_ARGS construction is relocated below the runtime-launcher preamble because it now calls gsd_run and each bash fence is its own shell. Growth is the explanatory comments carrying that constraint plus the loop body, against nine deleted flag literals. Deliberate: the byte delta is the cost of the flags no longer being hand-maintained in three places that had drifted apart."
},
"next.md": {
"reason": "#2800 \u2014 same derived-flag-loop change as autonomous.md. next.md needed no relocation (its launcher preamble already precedes the loop), so the growth here is only the loop plus the comment recording that --all and --text stay literal because they are convergence controls, not reviewer lanes."
},
"agents/gsd-advisor-researcher.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-ai-researcher.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-assumptions-analyzer.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-code-fixer.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-code-reviewer.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-codebase-mapper.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-debug-session-manager.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-debugger.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-doc-classifier.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-doc-synthesizer.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-doc-verifier.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-doc-writer.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-domain-researcher.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-eval-auditor.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-eval-planner.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-executor.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-framework-selector.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-integration-checker.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-intel-updater.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-mempalace-curator.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-nyquist-auditor.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-pattern-mapper.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-phase-researcher.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-plan-checker.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-planner.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-project-researcher.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-research-synthesizer.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-roadmapper.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-security-auditor.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-ui-auditor.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-ui-checker.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-ui-researcher.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-user-profiler.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
},
"agents/gsd-verifier.toml": {
"reason": "#2834: Codex agent TOML now carries model-routing fields on first install."
}
"agents/gsd-advisor-researcher.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-ai-researcher.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-assumptions-analyzer.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-code-reviewer.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-codebase-mapper.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-debug-session-manager.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-debugger.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-doc-classifier.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-doc-synthesizer.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-doc-verifier.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-doc-writer.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-domain-researcher.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-eval-auditor.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-eval-planner.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-executor.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-framework-selector.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-integration-checker.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-intel-updater.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-mempalace-curator.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-nyquist-auditor.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-pattern-mapper.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-phase-researcher.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-plan-checker.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-planner.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-project-researcher.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-research-synthesizer.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-roadmapper.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-security-auditor.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-ui-auditor.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-ui-checker.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-ui-researcher.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-user-profiler.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"agents/gsd-verifier.toml": "#2834: Codex agent TOML now carries model-routing fields on first install.",
"gsd-code-fixer.md": "#2825: setup_worktree now reads workflow.use_worktrees and gates git worktree add on it (skipping worktree creation when the user opted out), the cleanup tail is gated to a no-op in that mode, and the spec adds three safety guardrails — honor the opt-out, never rm -rf a possible Windows reparse point/junction (the delete-the-target path that wiped real node_modules), and record where verification ran. Growth is the gated bash branch + the three guardrail paragraphs."
}
}
}