Two windows-only failure clusters surfaced when the chunking fix in
52f23ac0 made Windows tests actually run:
1) Cleanup EBUSY race. On Windows, fs.rmSync without {maxRetries,retryDelay}
races against AV scanners / file-indexers / just-exited child processes
that still hold handles when teardown fires. Surfaces as
EBUSY: resource busy or locked, rmdir 'C:\Users\...\AppData\Local\Temp\gsd-...'
in bug-1736, bug-2248, bug-2698, bug-2838, and every test routing through
the shared tests/helpers.cjs cleanup() (≈170 consumers — bug-2774 et al).
Fix: add {maxRetries: 10, retryDelay: 100} to the shared helper plus the
four inline cleanup sites. On POSIX the retry loop is dead code (first
try succeeds), so no impact on ubuntu/macos.
2) bug-2839 had a local parseFrontmatter that anchored on /^---\n/ — on a
Windows checkout with autocrlf=true the file content is CRLF, the regex
never matches, the function returns null, and the before() hook asserts
"agent must have YAML frontmatter" → entire suite cancels. The shared
tests/helpers.cjs parseFrontmatter is already CRLF-aware (split /\r?\n/);
switch to it.
Validated: plex2 (ubuntu docker) 11224/0 pass post-patch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(#2839): make /gsd-code-review-fix cleanup transactional
Cleanup tail in agents/gsd-code-fixer.md previously did 'git worktree
remove' without any recovery marker. If the process was killed between
fix commits and worktree removal, the orphan worktree + branch survived
with no resume path — the next run had no way to discover or finish
the cleanup.
Introduce a recovery sentinel at ${phase_dir}/.review-fix-recovery-pending.json
with strict ordering:
- Sentinel written AFTER 'git worktree add' succeeds (never points at a
worktree that does not exist).
- Sentinel removed ONLY AFTER 'git worktree remove' returns successfully
(interruption between commits and removal leaves a sentinel behind).
- New runs detect a pre-existing sentinel, force-remove the recorded
orphan worktree, then drop the stale sentinel before continuing —
making the agent self-healing after a crash.
Closes#2839
* fix(#2839): harden sentinel JSON parse and scope ordering assertion
Address CodeRabbit review feedback on PR #2846:
- agents/gsd-code-fixer.md: Guard the recovery-sentinel JSON parse with
try/catch so a corrupted/truncated sentinel (a realistic crash artifact)
emits a warning and yields an empty prior_wt instead of aborting setup.
This preserves the self-healing recovery path even when the sentinel
itself is the casualty of the original crash.
- tests/bug-2839-review-fix-transactional-cleanup.test.cjs: Scope the
cleanup-ordering assertion to the cleanup-tail section of the
setup_worktree step rather than first global occurrences. Previously
the assertion could pass on pre-recovery references even if cleanup-tail
ordering regressed. The regex also now accepts the shell-variable form
(\`rm -f \"\$sentinel\"\`) used in the cleanup tail.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>