fix: anchor rootDir at the git toplevel so subdir runs don't skip tests (#1785)

greptile: my earlier existence-check anchor was necessary but insufficient.
`rootDir` (= process.cwd() when FUSION_PROJECT_DIR is unset) drives ALL workspace
discovery (readWorkspacePatterns / listWorkspacePackageInfos /
packageHasVitestConfig). Launched from a package subdir, cwd-based discovery
found no packages, so decideExecutionPlan saw "no affected package", ran only the
gate, and exited successfully WITHOUT running the live changed package tests.

Fix the root cause: resolveRepoRoot() resolves the git toplevel as the fallback
(FUSION_PROJECT_DIR still the explicit override; cwd only when git can't report a
toplevel). This is correct from any cwd inside the repo, including a git worktree
(how the engine runs per-task verification). repoRootForExistence is now
redundant and removed; the existence check defaults back to rootDir.

Demonstrated: resolveRepoRoot() from packages/core (no FUSION_PROJECT_DIR) now
resolves the repo root and finds the workspace. +1 regression test. 121/121.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-06-25 22:56:10 -07:00
parent e29954e50d
commit 1699c60033
2 changed files with 53 additions and 21 deletions

View File

@@ -46,6 +46,7 @@ import {
isTestFilePath,
changedSourceFilesAffectingPackage,
existingChangedTestFilesInPackage,
resolveRepoRoot,
GATE_COVERED_MEMORY_ENVELOPE_PACKAGES,
SCOPED_AFFECTED_MEMORY_ENVELOPES,
CORE_SCOPED_AFFECTED_PACKAGE,
@@ -2032,6 +2033,26 @@ test("existingChangedTestFilesInPackage: default existence root anchors at the g
assert.deepEqual(existingChangedTestFilesInPackage([selfRel], "scripts"), [selfRel]);
});
// FNXC:TestInfrastructure 2026-06-26-14:40: regression for the "subdirectory runs
// skip" bug — rootDir (which drives ALL workspace discovery) must resolve to the
// git toplevel, not process.cwd(), so a run launched from a package subdir without
// FUSION_PROJECT_DIR still finds the workspace instead of exiting through the gate.
test("resolveRepoRoot: honors FUSION_PROJECT_DIR else resolves the git toplevel (cwd-independent)", () => {
const saved = process.env.FUSION_PROJECT_DIR;
try {
process.env.FUSION_PROJECT_DIR = path.join(path.sep, "explicit", "root");
assert.equal(resolveRepoRoot(), path.resolve(path.join(path.sep, "explicit", "root")));
delete process.env.FUSION_PROJECT_DIR;
const top = resolveRepoRoot();
assert.ok(path.isAbsolute(top), "toplevel must be absolute");
// The resolved root must contain this workspace (cwd-independent), not a subdir.
assert.ok(existsSync(path.join(top, "scripts/test-changed.mjs")), "resolved root must be the repo root");
} finally {
if (saved === undefined) delete process.env.FUSION_PROJECT_DIR;
else process.env.FUSION_PROJECT_DIR = saved;
}
});
// FNXC:TestInfrastructure 2026-06-26-09:15: the merge gate re-covers a delegated
// engine lane (curated engine-core subset) but runs NO dashboard tests. Lock that
// asymmetry so the delegation messaging never overclaims dashboard gate coverage.

View File

@@ -96,9 +96,31 @@ function parseWorkspacePackagesFromYaml(rawYaml) {
return packages;
}
const rootDir = process.env.FUSION_PROJECT_DIR
? path.resolve(process.env.FUSION_PROJECT_DIR)
: process.cwd();
/*
FNXC:TestInfrastructure 2026-06-26-14:40:
This is a workspace-wide test runner: it MUST anchor at the repo root, not the
cwd. If launched from a package subdirectory without FUSION_PROJECT_DIR, a bare
`process.cwd()` root made workspace discovery (readWorkspacePatterns /
listWorkspacePackageInfos / packageHasVitestConfig) find no packages, so
decideExecutionPlan saw "no affected package", ran only the gate, and exited
SUCCESSFULLY without running the live changed package tests (greptile). Resolve
the git toplevel as the fallback so every cwd inside the repo (including a git
worktree, which is how the engine runs per-task verification) resolves to the
correct root. FUSION_PROJECT_DIR remains the explicit override; fall back to cwd
only when git can't report a toplevel (e.g. not a repo).
*/
export function resolveRepoRoot() {
if (process.env.FUSION_PROJECT_DIR) return path.resolve(process.env.FUSION_PROJECT_DIR);
try {
const r = spawnSync("git", ["rev-parse", "--show-toplevel"], { encoding: "utf8" });
const top = r.status === 0 ? (r.stdout ?? "").trim() : "";
if (top) return top;
} catch {
// git unavailable / not a repo — fall through to cwd
}
return process.cwd();
}
const rootDir = resolveRepoRoot();
/** @type {string} Cache format version — bump when the shape or hash inputs change. */
const CACHE_FORMAT_VERSION = 1;
@@ -1480,25 +1502,14 @@ handing Vitest an empty/garbage positional set.
* @returns {string[]}
*/
/*
FNXC:TestInfrastructure 2026-06-26-13:40:
Existence checks for changed test files must anchor at the GIT REPO ROOT, not
`rootDir` (which falls back to `process.cwd()`). `git diff --name-only` returns
repo-root-relative paths regardless of the cwd it runs from, so joining them
against a `rootDir` that is a package SUBDIR (script run from a package without
FUSION_PROJECT_DIR) would form a doubled path (packages/x/packages/x/...), make
`existsSync` false, and silently DROP live changed tests into the delegate path.
Resolve the toplevel once via git so the check is correct from any cwd inside the
repo; fall back to rootDir if git can't report a toplevel.
FNXC:TestInfrastructure 2026-06-26-14:40:
Existence checks for changed test files join repo-root-relative `git diff` paths
against `projectRoot` (default `rootDir`). `rootDir` is now resolved to the git
toplevel (see resolveRepoRoot above), so this is correct from any cwd inside the
repo — no doubled path, no silently-dropped live test. Deleted/renamed-away test
paths correctly fail existsSync and fall into the delegate-to-gate path.
*/
let _repoToplevelCache;
function repoRootForExistence() {
if (_repoToplevelCache !== undefined) return _repoToplevelCache;
const top = gitOutput(["rev-parse", "--show-toplevel"]);
_repoToplevelCache = top && top.trim() ? top.trim() : rootDir;
return _repoToplevelCache;
}
export function existingChangedTestFilesInPackage(changedFiles, pkgDir, { projectRoot = repoRootForExistence() } = {}) {
export function existingChangedTestFilesInPackage(changedFiles, pkgDir, { projectRoot = rootDir } = {}) {
return (changedFiles ?? []).filter(
(file) =>
isTestFilePath(file) &&