fix(#3309): W020 fires on any degraded worktree scan, not just real failures

gsd-test found buildWorktreeHealthField collapsed every
inspectWorktreeHealth failure reason (git_timed_out, git_list_failed,
not_a_git_repo) into one UNREADABLE scope, discarding which one. The
migrated checkW020 then warned unconditionally on any UNREADABLE
scope — but the original (verify.cts:2202-2217) only warned on
git_timed_out/git_list_failed, staying silent on not_a_git_repo (a
.planning/-only fixture with no git repo at all is not a degraded
scan, just the absence of one). This spuriously degraded every test
fixture that isn't a real git repo.

planning-snapshot.cts's worktreeHealth field now carries `reason`
through instead of discarding it; checkW020 branches on it exactly
like the pre-migration code did.
This commit is contained in:
sim
2026-08-13 04:30:57 -04:00
parent 96c7ea9b35
commit eae2b52e4a
2 changed files with 47 additions and 36 deletions

View File

@@ -4526,13 +4526,15 @@ describe('bug #3384: adjacent worktree data-loss guards', () => {
});
test('validate health warns when worktree inventory cannot be listed', () => {
const source = read('gsd-core/bin/lib/verify.cjs');
// Accept both hand-written dot access and the tsc-compiled bracket form
// (ADR-457: verify.cjs is now emitted from src/verify.cts):
// hand-written: worktreeHealth.reason === 'git_list_failed'
// tsc-compiled: worktreeHealth['reason'] === 'git_list_failed'
const failureBranch = source.search(/worktreeHealth(?:\.reason|\['reason'\]) === 'git_list_failed'/);
const warning = source.indexOf("addIssue('warning', 'W020'", failureBranch);
// Phase 11 (#3309, ADR-3180): this branch moved out of verify.cts into
// the W020 rule (src/health-diagnostic-rules/worktree-health.cts),
// compiled to gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs.
// Accept both hand-written dot access and the tsc-compiled bracket form:
// hand-written: reason === 'git_list_failed'
// tsc-compiled: reason === 'git_list_failed' (unchanged shape either way)
const source = read('gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs');
const failureBranch = source.search(/reason === 'git_list_failed'/);
const warning = source.indexOf("code: 'W020'", failureBranch);
assert.ok(failureBranch > 0, 'verify health should branch on git_list_failed');
assert.ok(warning > failureBranch, 'git_list_failed should emit W020 degraded-health warning');