* test: red — bounded git subprocess + structured worktree warnings (#3281)
Regression tests for #3281: worktree-related git subprocess calls have no
timeout bound, and timeout/error outcomes are not surfaced as structured signals.
Failing assertions:
- planWorktreePrune / listLinkedWorktreePaths / snapshotWorktreeInventory must
return reason=git_timed_out (not generic git_list_failed) when execGit returns
timedOut:true — enables callers to distinguish timeout from auth failure
- executeWorktreePrunePlan must include timedOut:true in result when the git
prune call itself times out
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(worktree): bounded git subprocess + structured warning surfacing (#3281)
Root cause (PRED.k014): execGit / execGitDefault called spawnSync with no
timeout, so `git worktree list --porcelain` against a hung/locked repo
blocked the parent process indefinitely. Downstream callers in core.cjs
and verify.cjs then swallowed any resulting failure silently via
catch { /* intentionally empty */ } (PRED.k302).
Fix:
- worktree-safety.cjs: execGitDefault now passes timeout:10000 to spawnSync.
Detects SIGTERM+ETIMEDOUT and returns { timedOut:true } in the result shape.
readWorktreeList maps timedOut:true -> reason:'git_timed_out' (distinct from
generic git_list_failed) so callers can emit a structured warning.
executeWorktreePrunePlan propagates timedOut:true as a first-class result field.
- core.cjs: execGit receives the same timeout+timedOut treatment (PRED.k014
uniform-fix discipline). pruneOrphanedWorktrees now emits a [gsd-tools]
WARNING to stderr when the git prune call times out instead of silent-catch.
- verify.cjs: Check 11 branches on worktreeHealth.ok to surface W018 warning
when the worktree list times out, instead of silent-catch on ok:false.
Backward-compatible: exitCode/stdout/stderr continue to work for all existing
callers; timedOut and error are additive new fields.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* changeset: pr=3283 for #3281
* fix(verify): rename W020 for worktree-timeout warning to avoid W018 collision
W018 is already used for milestone archive drift (Check 12). The new
worktree-health-degraded timeout warning was assigned W018, causing
warning-code ambiguity in triage. Rename to W020 (next available code).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>