fix(#4734): degrade worktree isolation when the root has no git repository (#4843)

* test(#4734): non-git root must degrade worktree isolation (failing first)

* fix(#4734): degrade worktree isolation when the root has no git repository

* fix(#4734): review fold-ins — 3972 ladder fixture, parity fixture, docs row, message wording

* chore(#4734): backfill changeset PR number (4843)

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-09-18 03:16:25 -04:00
committed by GitHub
parent 8d0b6868ae
commit c5629bbe74
8 changed files with 290 additions and 83 deletions

View File

@@ -337,6 +337,30 @@ function resolveRegistryIsolation(cwd, configPath) {
if (!useWorktrees) isolation = 'none';
}
// #4734: a harness worktree can never be created in a directory that is not
// a git repository (or a repository with no commits) — git's definitive
// exit-128 answer on `rev-parse HEAD`. Demanding the isolation flag there
// blocked every flag-less dispatch the moment the sentinel went stale, on a
// root where no worktree can exist. Degrade to 'none' exactly like the
// use_worktrees opt-out above; the classification is owned by
// `classifyGitHead` (worktree-base-ref.cjs) — the same single owner the
// base-check's degrade decision uses — and ambiguous or failed resolutions
// keep the conservative (enforce) default, matching that check's own
// fail-closed treatment of the same classes.
if (isolation === 'harness-worktree') {
try {
ensureRuntimeBuild();
const { classifyGitHead } = require('../gsd-core/bin/lib/worktree-base-ref.cjs');
if (classifyGitHead({ cwd }).status === 'definitive-absence') {
isolation = 'none';
}
} catch {
// Unbuilt or unreadable runtime library — keep the conservative
// (enforce) default rather than silently disabling the guard, same
// posture as the ladder fallback above.
}
}
return { isolation, harnessFlag };
}