From f57e4dc765e85b47f39e5271fd7712cbea572b32 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 21 Jul 2026 01:27:47 -0700 Subject: [PATCH 1/2] ci(build): catch stale committed miner/mcp compiled output before merge packages/loopover-miner and packages/loopover-mcp compile real TypeScript in place and commit the emitted .js/.d.ts (both ship as installable CLIs, so a runnable .js has to exist without a build step). Nothing enforced that the committed output actually matched a fresh build: root-level tests import the emitted .js by its literal specifier, and the job that builds these packages runs as a separate GitHub Actions job from the one that tests them, so a contributor who edited .ts without rebuilding got tests silently running old behavior with zero CI signal -- the same drift class the Selfhost/Miner env-reference checks were previously added to close. Adds scripts/check-build-drift.mjs (git-status-based, so a compiled file that was never committed at all is caught too, not just a stale one), wires it into ci.yml right after each package's real build step, and into package.json's local test:ci for pre-push parity. Also fixes three comments left stale by the #7290/#7291 TypeScript migrations completing, and adds loopover-mcp's missing migration-complete guard test (mirroring loopover-miner's existing one). --- .../skills/contributing-to-loopover/SKILL.md | 6 +- .github/workflows/ci.yml | 30 ++++- .github/workflows/publish-miner.yml | 10 +- package.json | 4 +- packages/loopover-mcp/tsconfig.json | 6 +- scripts/check-build-drift.d.mts | 8 ++ scripts/check-build-drift.mjs | 62 +++++++++ test/unit/check-build-drift-script.test.ts | 120 ++++++++++++++++++ .../mcp-typescript-migration-complete.test.ts | 43 +++++++ 9 files changed, 275 insertions(+), 14 deletions(-) create mode 100644 scripts/check-build-drift.d.mts create mode 100644 scripts/check-build-drift.mjs create mode 100644 test/unit/check-build-drift-script.test.ts create mode 100644 test/unit/mcp-typescript-migration-complete.test.ts diff --git a/.claude/skills/contributing-to-loopover/SKILL.md b/.claude/skills/contributing-to-loopover/SKILL.md index 3d3674704b..7a81638fd6 100644 --- a/.claude/skills/contributing-to-loopover/SKILL.md +++ b/.claude/skills/contributing-to-loopover/SKILL.md @@ -221,9 +221,9 @@ npm audit --audit-level=moderate # the dependency-review job's local eq `npm run test:ci` runs, and must pass, **all of**: `actionlint`, `db:migrations:check`, `db:schema-drift:check`, `selfhost:env-reference:check`, `selfhost:validate-observability`, -`cf-typegen:check`, `typecheck`, `test:coverage`, `test:engine-parity`, `test:live-gate-parity`, `test:driver-parity`, the -`@loopover/engine` workspace's own test run, `test:workers`, `build:mcp`, `test:mcp-pack`, -`build:miner`, `test:miner-pack`, `rees:test`, `ui:openapi:check`, `ui:openapi:settings-parity`, +`cf-typegen:check`, `build:mcp:check`, `build:miner:check`, `typecheck`, `test:coverage`, `test:engine-parity`, `test:live-gate-parity`, `test:driver-parity`, the +`@loopover/engine` workspace's own test run, `test:workers`, `test:mcp-pack`, +`test:miner-pack`, `rees:test`, `ui:openapi:check`, `ui:openapi:settings-parity`, `ui:version-audit`, `docs:drift-check`, `manifest:drift-check`, `engine-parity:drift-check`, `command-reference:check`, `ui:lint`, `ui:typecheck`, `ui:test`, `ui:build`. If any step fails, fix it and re-run — do not push a red tree. (Full per-check table in `reference.md`; check `package.json`'s diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee8856f07a..79ff4be51e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -470,13 +470,29 @@ jobs: - name: Build MCP if: ${{ github.event_name == 'push' || needs.changes.outputs.mcp == 'true' || needs.changes.outputs.engine == 'true' }} run: npx turbo run build --filter=@loopover/mcp + # packages/loopover-mcp/{bin,lib} compile real TypeScript in place (tsc's outDir === rootDir, so + # e.g. lib/foo.ts emits lib/foo.js right next to it) and commit that emitted output -- the package + # ships as an installable CLI (npm install -g), so a runnable .js has to exist in the published + # tarball, and test/**/*.test.ts imports the emitted .js by its literal specifier, not the .ts + # source. "Build MCP" above (this job) and the "Test with coverage" job below run as separate GitHub + # Actions jobs with independent checkouts, so nothing in this job's build step can ever self-heal a + # stale commit before the coverage job's tests run against it -- a contributor who edits .ts and + # forgets to rebuild+commit the .js gets tests silently exercising old behavior with no CI signal, + # same drift-class gap the Selfhost/Miner env-reference checks above were added to close. This + # fails loudly instead: the build one step up already regenerated bin/lib in place, so any git + # status output here means the committed .js/.d.ts didn't match what that build just produced. + - name: MCP build drift check + if: ${{ github.event_name == 'push' || needs.changes.outputs.mcp == 'true' || needs.changes.outputs.engine == 'true' }} + run: node scripts/check-build-drift.mjs mcp - name: MCP package check if: ${{ github.event_name == 'push' || needs.changes.outputs.mcp == 'true' || needs.changes.outputs.engine == 'true' }} run: npm run test:mcp-pack - # Invokes turbo.json's @loopover/miner#build:tsc (cache: false, since its committed lib/**/*.js - # output can't be safely restored without risking a stomp of hand-written files) and - # @loopover/miner#build:verify (real caching win: skips re-`node --check`-ing all 121 bin/lib files - # when neither changed) DIRECTLY as their own task names, deliberately NOT via the aggregate + # Invokes turbo.json's @loopover/miner#build:tsc (cache: false -- historically to avoid a cache + # restore stomping this package's hand-written .js files while the #7290 migration was still + # in-flight; now that #7317 closed it out, every bin/lib file is compiler-owned and that original + # risk no longer applies, but re-enabling caching here is a separate change this PR doesn't make) + # and @loopover/miner#build:verify (real caching win: skips re-`node --check`-ing all 121 bin/lib + # files when neither changed) DIRECTLY as their own task names, deliberately NOT via the aggregate # `@loopover/miner#build` task (which exists for standalone/local `npm run build` callers) -- that # aggregate's own script is `npm run build:tsc && npm run build:verify`, i.e. it re-invokes both of # these exact scripts a second time even when turbo already ran them as cached prerequisite tasks @@ -488,6 +504,12 @@ jobs: - name: Build miner CLI if: ${{ github.event_name == 'push' || needs.changes.outputs.miner == 'true' || needs.changes.outputs.engine == 'true' }} run: npx turbo run build:tsc build:verify --filter=@loopover/miner + # Same "separate job, no self-heal" drift-class gap as MCP's own build drift check above, and the + # ORIGINAL motivating case for it: packages/loopover-miner/lib/cross-repo-evaluation.{ts,js,d.ts} + # are real files a contributor edits directly, not obscure internals. + - name: Miner build drift check + if: ${{ github.event_name == 'push' || needs.changes.outputs.miner == 'true' || needs.changes.outputs.engine == 'true' }} + run: node scripts/check-build-drift.mjs miner # loopover-miner depends on @loopover/engine for real too (same relationship as loopover-mcp above # -- packages/loopover-miner/package.json lists it as a dependency), so this and "Build miner CLI" # above now also trigger on an engine-only PR, matching "Build MCP"/"MCP package check"'s existing diff --git a/.github/workflows/publish-miner.yml b/.github/workflows/publish-miner.yml index 3f97b3c74f..7b9742b169 100644 --- a/.github/workflows/publish-miner.yml +++ b/.github/workflows/publish-miner.yml @@ -89,9 +89,13 @@ jobs: - name: Install dependencies run: npm ci - # Miner ships hand-written, checked-in JS (no tsc build) -- "build" here is node --check syntax - # validation over every bin/lib file, the same script test:ci already runs on every PR. - - name: Miner syntax validation + # Real tsc build (in-place emit -- see packages/loopover-miner/tsconfig.json), same as ci.yml's own + # "Build miner CLI" step, followed by node --check syntax validation over every bin/lib file (the + # same two-part script test:ci already runs on every PR). Re-running the compile here means this + # job always packs from a freshly-built tree even if the tagged commit's committed .js/.d.ts had + # somehow drifted from its .ts source (ci.yml's build-drift check on every PR is what keeps that + # from happening in the first place). + - name: Miner build + syntax validation run: npm run build --workspace @loopover/miner # Reuses the exact allowlist/required-files/forbidden-content check test:ci already runs on diff --git a/package.json b/package.json index 310762f59b..3e613fad64 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,9 @@ "db:migrate:remote": "wrangler d1 migrations apply loopover --remote", "drizzle:generate": "drizzle-kit generate", "build:mcp": "npm --workspace @loopover/mcp run build", + "build:mcp:check": "npm run build:mcp && node scripts/check-build-drift.mjs mcp", "build:miner": "turbo run build --filter=@loopover/engine && npm --workspace @loopover/miner run build", + "build:miner:check": "npm run build:miner && node scripts/check-build-drift.mjs miner", "test:mcp-pack": "node scripts/check-mcp-package.mjs", "test:miner-pack": "node scripts/check-miner-package.mjs", "test:miner-deployment-docs-audit": "node scripts/check-miner-deployment-docs.mjs", @@ -109,7 +111,7 @@ "test:smoke:browser:install": "playwright install chromium", "test:smoke:browser": "node scripts/smoke-ui-browser.mjs", "pretest:ci": "npm run check-node-version", - "test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run test --workspace @loopover/engine && npm run test:workers && npm run build:mcp && npm run test:mcp-pack && npm run build:miner && npm run test:miner-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run ui:openapi:settings-parity && npm run ui:version-audit && npm run docs:drift-check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run command-reference:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build", + "test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build:mcp:check && npm run build:miner:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:miner-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run ui:openapi:settings-parity && npm run ui:version-audit && npm run docs:drift-check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run command-reference:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build", "test:release": "npm run test:ci && npm run changelog:check", "test:release:mcp": "npm run test:ci", "test:watch": "vitest", diff --git a/packages/loopover-mcp/tsconfig.json b/packages/loopover-mcp/tsconfig.json index 3345a971fd..63895b7219 100644 --- a/packages/loopover-mcp/tsconfig.json +++ b/packages/loopover-mcp/tsconfig.json @@ -24,9 +24,9 @@ // repo root and corrupt each other's incremental state. "tsBuildInfoFile": "./.tsbuildinfo" }, - // Only files already converted to real TypeScript are included -- everything else in bin/lib stays - // plain, hand-maintained .js until its own migration phase lands (#7291). No edits needed here as - // later phases convert more files: the glob picks them up automatically. + // Every bin/lib runtime module is real TypeScript (#7291, phased across #7328/#7329/#7330): tsc owns + // the in-place .js emit. The glob stays the include surface; test/unit/mcp-typescript-migration-complete.test.ts + // fails closed if a hand-maintained .js orphan ever reappears. "include": ["bin/**/*.ts", "lib/**/*.ts"], // Without this, tsc's default exclude list (which always adds outDir) resolves to "." -- the whole // package root -- and silently excludes every include match, since outDir is "." for in-place emit. diff --git a/scripts/check-build-drift.d.mts b/scripts/check-build-drift.d.mts new file mode 100644 index 0000000000..a04bbb4384 --- /dev/null +++ b/scripts/check-build-drift.d.mts @@ -0,0 +1,8 @@ +export function pathsForPackage(name: string): string[]; + +export function checkBuildDrift( + paths: string[], + options?: { cwd?: string; run?: (paths: string[], cwd: string) => string }, +): string; + +export function main(argv: string[]): void; diff --git a/scripts/check-build-drift.mjs b/scripts/check-build-drift.mjs new file mode 100644 index 0000000000..cdee307a32 --- /dev/null +++ b/scripts/check-build-drift.mjs @@ -0,0 +1,62 @@ +#!/usr/bin/env node +// packages/loopover-{miner,mcp} both compile real TypeScript in place (tsc's outDir === rootDir, so +// e.g. lib/foo.ts emits lib/foo.js + lib/foo.d.ts right next to it) and commit that emitted output -- +// both packages ship as installable CLIs (npm install -g), so a runnable .js has to exist in the +// published tarball, and root-level tests import the emitted .js by its literal specifier (NodeNext +// resolution), not the .ts source, so a stale commit makes test:coverage silently exercise old +// behavior instead of loudly failing. package.json composes this AFTER the package's real build +// (`npm run build:{miner,mcp} && node scripts/check-build-drift.mjs {miner,mcp}`) -- this script's own +// job is just: did that build change anything relative to what's committed. Mirrors cf-typegen:check's +// "regenerate for real, then diff" shape for a package whose generated output is emitted in place +// across a whole directory rather than to one named file. +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const PACKAGE_PATHS = { + miner: ["packages/loopover-miner/bin", "packages/loopover-miner/lib"], + mcp: ["packages/loopover-mcp/bin", "packages/loopover-mcp/lib"], +}; + +/** The bin/lib directories a package name checks. Exported (rather than inlined into main()) so a test + * can validate the real PACKAGE_PATHS table itself -- e.g. that "miner" resolves to real repo paths -- + * not just a fake stand-in for it. Throws on an unknown name instead of silently checking nothing. */ +export function pathsForPackage(name) { + const paths = PACKAGE_PATHS[name]; + if (!paths) { + throw new Error(`check-build-drift: unknown package "${name}" (expected one of: ${Object.keys(PACKAGE_PATHS).join(", ")})`); + } + return paths; +} + +function defaultGitStatus(paths, cwd) { + return execFileSync("git", ["status", "--porcelain", "--", ...paths], { cwd, encoding: "utf8" }); +} + +/** Trimmed `git status --porcelain` text for `paths` under `cwd` (a real git worktree) -- "" when + * clean. Porcelain (not plain `git diff --exit-code`) deliberately: a .ts file whose emitted .js/.d.ts + * was never committed at all shows up as an untracked file, which `git diff` alone never reports. + * `run` is injectable so tests can fake the git call entirely; the default shells out for real. */ +export function checkBuildDrift(paths, { cwd = process.cwd(), run = defaultGitStatus } = {}) { + return run(paths, cwd).trim(); +} + +export function main(argv) { + try { + const name = argv[0]; + const paths = pathsForPackage(name); + const drift = checkBuildDrift(paths); + if (drift.length > 0) { + process.stderr.write( + `check-build-drift: packages/loopover-${name}'s committed .js/.d.ts is stale relative to its .ts source -- run \`npm run build:${name}\` and commit the result:\n${drift}\n`, + ); + process.exit(1); + return; + } + process.stdout.write(`check-build-drift: packages/loopover-${name}'s committed .js/.d.ts matches its .ts source.\n`); + } catch (err) { + process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`); + process.exit(1); + } +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(2)); diff --git a/test/unit/check-build-drift-script.test.ts b/test/unit/check-build-drift-script.test.ts new file mode 100644 index 0000000000..e7ca0df9aa --- /dev/null +++ b/test/unit/check-build-drift-script.test.ts @@ -0,0 +1,120 @@ +import { execFileSync } from "node:child_process"; +import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { afterEach, describe, expect, it } from "vitest"; +import { checkBuildDrift, pathsForPackage } from "../../scripts/check-build-drift.mjs"; + +const tmpDirs: string[] = []; +afterEach(() => { + for (const dir of tmpDirs.splice(0)) rmSync(dir, { recursive: true, force: true }); +}); + +function initScratchGitRepo(): string { + const dir = mkdtempSync(join(tmpdir(), "gtbuild-drift-")); + tmpDirs.push(dir); + const git = (...args: string[]) => execFileSync("git", args, { cwd: dir, encoding: "utf8" }); + git("init", "--quiet"); + git("-c", "user.email=test@example.com", "-c", "user.name=test", "-c", "commit.gpgsign=false", "commit", "--allow-empty", "-m", "init", "--quiet"); + return dir; +} + +describe("check-build-drift script", () => { + describe("pathsForPackage", () => { + it("resolves the real loopover-miner bin/lib paths", () => { + expect(pathsForPackage("miner")).toEqual(["packages/loopover-miner/bin", "packages/loopover-miner/lib"]); + }); + + it("resolves the real loopover-mcp bin/lib paths", () => { + expect(pathsForPackage("mcp")).toEqual(["packages/loopover-mcp/bin", "packages/loopover-mcp/lib"]); + }); + + it("throws a clear error for an unknown package name", () => { + expect(() => pathsForPackage("engine")).toThrow(/unknown package "engine".*miner.*mcp/s); + }); + }); + + describe("checkBuildDrift (injected run)", () => { + it("returns empty when the injected git status reports nothing", () => { + const drift = checkBuildDrift(["packages/loopover-miner/lib"], { run: () => "" }); + expect(drift).toBe(""); + }); + + it("trims and returns whatever the injected git status reports", () => { + const drift = checkBuildDrift(["packages/loopover-miner/lib"], { + run: () => "\n M packages/loopover-miner/lib/foo.js\n?? packages/loopover-miner/lib/foo.d.ts\n\n", + }); + expect(drift).toBe("M packages/loopover-miner/lib/foo.js\n?? packages/loopover-miner/lib/foo.d.ts"); + }); + + it("passes the paths and cwd it was given through to run", () => { + const calls: Array<{ paths: string[]; cwd: string }> = []; + checkBuildDrift(["bin", "lib"], { + cwd: "/fake/repo", + run: (paths, cwd) => { + calls.push({ paths, cwd }); + return ""; + }, + }); + expect(calls).toEqual([{ paths: ["bin", "lib"], cwd: "/fake/repo" }]); + }); + }); + + describe("checkBuildDrift (real git, scratch repo)", () => { + it("reports clean when nothing has changed since the last commit", () => { + const dir = initScratchGitRepo(); + expect(checkBuildDrift(["lib"], { cwd: dir })).toBe(""); + }); + + it("reports a modified tracked file (the 'stale committed .js' case)", () => { + const dir = initScratchGitRepo(); + const git = (...args: string[]) => execFileSync("git", args, { cwd: dir, encoding: "utf8" }); + writeFileSync(join(dir, "foo.js"), "export const x = 1;\n"); + git("add", "foo.js"); + git("-c", "user.email=test@example.com", "-c", "user.name=test", "-c", "commit.gpgsign=false", "commit", "-m", "add foo.js", "--quiet"); + + writeFileSync(join(dir, "foo.js"), "export const x = 2;\n"); + + expect(checkBuildDrift(["foo.js"], { cwd: dir })).toContain("foo.js"); + }); + + it("reports a brand new untracked file (the 'compiled output never committed' case)", () => { + // git diff --exit-code alone would miss this -- untracked files are invisible to `git diff`, + // which is exactly why this script uses `git status --porcelain` instead. + const dir = initScratchGitRepo(); + writeFileSync(join(dir, "bar.d.ts"), "export {};\n"); + + const drift = checkBuildDrift(["bar.d.ts"], { cwd: dir }); + + expect(drift).toContain("bar.d.ts"); + expect(drift.startsWith("??")).toBe(true); + }); + }); + + describe("CLI (real subprocess)", () => { + // Most important regression test in this file: proves the REAL currently-committed miner/mcp + // .js/.d.ts are not already stale relative to their .ts source -- if they were, this check would + // fail on `main` from the moment it merges. (Doesn't run the build itself -- npm run build:{miner,mcp} + // already ran as part of getting a green `npm run test:ci` locally before this change was committed.) + it("reports the real repo's loopover-miner output as clean", () => { + const output = execFileSync(process.execPath, ["scripts/check-build-drift.mjs", "miner"], { encoding: "utf8" }); + expect(output).toContain("packages/loopover-miner's committed .js/.d.ts matches its .ts source."); + }); + + it("reports the real repo's loopover-mcp output as clean", () => { + const output = execFileSync(process.execPath, ["scripts/check-build-drift.mjs", "mcp"], { encoding: "utf8" }); + expect(output).toContain("packages/loopover-mcp's committed .js/.d.ts matches its .ts source."); + }); + + it("exits non-zero with a clear message for an unknown package name", () => { + try { + execFileSync(process.execPath, ["scripts/check-build-drift.mjs", "engine"], { encoding: "utf8" }); + expect.unreachable("expected the CLI to exit non-zero for an unknown package name"); + } catch (err) { + const e = err as { status?: number; stdout?: string; stderr?: string }; + expect(e.status).toBe(1); + expect(`${e.stdout ?? ""}${e.stderr ?? ""}`).toContain('unknown package "engine"'); + } + }); + }); +}); diff --git a/test/unit/mcp-typescript-migration-complete.test.ts b/test/unit/mcp-typescript-migration-complete.test.ts new file mode 100644 index 0000000000..df77f896d6 --- /dev/null +++ b/test/unit/mcp-typescript-migration-complete.test.ts @@ -0,0 +1,43 @@ +import { readdirSync } from "node:fs"; +import { join } from "node:path"; +import { describe, expect, it } from "vitest"; + +const mcpRoot = join(process.cwd(), "packages/loopover-mcp"); +const dirs = ["bin", "lib"] as const; + +function listBasenames(dir: string, predicate: (name: string) => boolean): string[] { + return readdirSync(join(mcpRoot, dir)) + .filter(predicate) + .map((name) => name.replace(/\.(?:d\.ts|ts|js)$/, "")) + .sort(); +} + +/** + * #7291 closing guard for the phased #7328/#7329/#7330 mcp TypeScript migration -- the loopover-mcp + * twin of loopover-miner's own #7290/#7317 guard in test/unit/miner-typescript-migration-complete.test.ts. + * Every runtime file under packages/loopover-mcp/{bin,lib} must be compiler-owned (.ts source -> emitted + * .js). A lone hand-maintained .js is the drift gap the migration was filed to close. + */ +describe("loopover-mcp TypeScript migration complete (#7291)", () => { + it("has zero hand-maintained .js orphans — every basename has a real .ts source", () => { + for (const dir of dirs) { + const sources = new Set(listBasenames(dir, (name) => name.endsWith(".ts") && !name.endsWith(".d.ts"))); + const scripts = listBasenames(dir, (name) => name.endsWith(".js")); + + const jsWithoutTs = scripts.filter((base) => !sources.has(base)); + + expect(jsWithoutTs, `${dir}/ .js without sibling .ts`).toEqual([]); + expect(scripts).toEqual([...sources].sort()); + } + }); + + // Unlike loopover-miner, packages/loopover-mcp/tsconfig.json sets declaration: false (no pre-existing + // hand-written .d.ts files to replace when the mcp migration started) -- so a .d.ts appearing here at + // all, not just an orphaned one, means either that tsconfig setting or this guard has drifted. + it("emits no .d.ts (declaration: false in packages/loopover-mcp/tsconfig.json)", () => { + for (const dir of dirs) { + const declarations = readdirSync(join(mcpRoot, dir)).filter((name) => name.endsWith(".d.ts")); + expect(declarations, `${dir}/ unexpected .d.ts`).toEqual([]); + } + }); +}); From d8998e76d227064ab53d16ebdd8d64111b8d7278 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 21 Jul 2026 01:28:00 -0700 Subject: [PATCH 2/2] fix(miner): canonicalize the cross-repo-evaluation scratch workspace path defaultPrepareExecutionWorkspace built its scratch directory straight from mkdtempSync, but coding-task-spec.ts's writeAcceptanceCriteriaFile separately realpath's the working directory before writing into it (a deliberate containment-check canonicalization, not something to remove). On macOS, os.tmpdir() resolves under a symlink (/var/folders/... -> /private/var/folders/...), so the two disagreed on which string names the same directory: a plain acceptanceCriteriaPath.startsWith(workingDirectory) check failed even though the file genuinely was inside the working directory. Resolving once at the source, right after mkdtempSync, keeps every downstream path in the same canonical form with no other changes needed, and is a no-op on Linux CI runners where /tmp isn't itself a symlink. Discovered while validating the build-drift check against #7668's own newly-merged full-execution mode. --- .../lib/cross-repo-evaluation.d.ts | 10 +++++++++- .../loopover-miner/lib/cross-repo-evaluation.js | 16 ++++++++++++---- .../loopover-miner/lib/cross-repo-evaluation.ts | 14 +++++++++++--- test/unit/miner-cross-repo-evaluation.test.ts | 15 ++++++++++++++- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.d.ts b/packages/loopover-miner/lib/cross-repo-evaluation.d.ts index 7e843e635a..a074033adf 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.d.ts +++ b/packages/loopover-miner/lib/cross-repo-evaluation.d.ts @@ -161,7 +161,15 @@ export type EvaluateRepoExecutionOptions = EvaluateRepoReadinessOptions & { commandTimeoutMs?: number; }; /** Copy the benchmark clone into a discardable temp tree — the agent and the repo's test suite only ever touch - * the copy, so the clone stays pristine and cleanup is a single recursive remove. */ + * the copy, so the clone stays pristine and cleanup is a single recursive remove. realpathSync's the fresh + * mkdtemp directory immediately: on macOS, os.tmpdir() resolves under a symlink (/var/folders/... -> + * /private/var/folders/...), so without this, the raw mkdtempSync path and coding-task-spec.ts's own + * realpathSync(workingDirectory) (a deliberate containment-check canonicalization in writeAcceptanceCriteriaFile, + * not something to remove) disagree on which string names the same directory -- acceptanceCriteriaPath then + * fails a plain acceptanceCriteriaPath.startsWith(workingDirectory) check even though the file genuinely is + * inside the working directory. Resolving once here, at the source, keeps every downstream path (workspace.path, + * task.workingDirectory, the acceptance-criteria path) in the same canonical form with no further changes + * needed. A no-op on Linux CI runners, where /tmp is not itself a symlink. */ export declare function defaultPrepareExecutionWorkspace(repoPath: string): CrossRepoExecutionWorkspace; /** Command runner for the stack's inferred build/test commands. detectRepoStack only ever emits simple * `tool subcommand` forms ("npm test", "cargo build", "npm run build"), so the command is tokenized on diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.js b/packages/loopover-miner/lib/cross-repo-evaluation.js index 0327062a89..b7acd4bb75 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.js +++ b/packages/loopover-miner/lib/cross-repo-evaluation.js @@ -4,7 +4,7 @@ // resolveMinerGoalSpec, buildCodingTaskSpec) and failures are categorized as stack-detection gaps, execution // readiness gaps, leaked loopover assumptions in agent instructions, clone/setup problems, or other. import { spawn as nodeSpawn } from "node:child_process"; -import { cpSync, existsSync, mkdtempSync, rmSync } from "node:fs"; +import { cpSync, existsSync, mkdtempSync, realpathSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; // Already a transitive dependency via coding-task-spec.js's own engine imports -- this adds no load weight. @@ -377,9 +377,17 @@ export const DEFAULT_CROSS_REPO_EXECUTION_MAX_TURNS = 24; * benchmark repos, small enough that a hung suite cannot wedge the whole run. */ export const DEFAULT_CROSS_REPO_EXECUTION_COMMAND_TIMEOUT_MS = 600_000; /** Copy the benchmark clone into a discardable temp tree — the agent and the repo's test suite only ever touch - * the copy, so the clone stays pristine and cleanup is a single recursive remove. */ + * the copy, so the clone stays pristine and cleanup is a single recursive remove. realpathSync's the fresh + * mkdtemp directory immediately: on macOS, os.tmpdir() resolves under a symlink (/var/folders/... -> + * /private/var/folders/...), so without this, the raw mkdtempSync path and coding-task-spec.ts's own + * realpathSync(workingDirectory) (a deliberate containment-check canonicalization in writeAcceptanceCriteriaFile, + * not something to remove) disagree on which string names the same directory -- acceptanceCriteriaPath then + * fails a plain acceptanceCriteriaPath.startsWith(workingDirectory) check even though the file genuinely is + * inside the working directory. Resolving once here, at the source, keeps every downstream path (workspace.path, + * task.workingDirectory, the acceptance-criteria path) in the same canonical form with no further changes + * needed. A no-op on Linux CI runners, where /tmp is not itself a symlink. */ export function defaultPrepareExecutionWorkspace(repoPath) { - const scratchRoot = mkdtempSync(join(tmpdir(), "loopover-cross-repo-exec-")); + const scratchRoot = realpathSync(mkdtempSync(join(tmpdir(), "loopover-cross-repo-exec-"))); const path = join(scratchRoot, "repo"); cpSync(repoPath, path, { recursive: true }); return { @@ -558,4 +566,4 @@ export async function runCrossRepoFullExecution(parsed, options = {}) { } return results; } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlIQUFpSDtBQUNqSCw4R0FBOEc7QUFDOUcsMkdBQTJHO0FBQzNHLDZHQUE2RztBQUM3RyxxR0FBcUc7QUFFckcsT0FBTyxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDakMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNqQyw0R0FBNEc7QUFDNUcsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBR3ZELDZEQUE2RDtBQUM3RCxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FNbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNqQixlQUFlLEVBQUUscUJBQXFCO0lBQ3RDLFNBQVMsRUFBRSxlQUFlO0lBQzFCLG9CQUFvQixFQUFFLHFCQUFxQjtJQUMzQyxXQUFXLEVBQUUsYUFBYTtJQUMxQixLQUFLLEVBQUUsT0FBTztDQUNmLENBQUMsQ0FBQztBQUVIO21HQUNtRztBQUNuRyxNQUFNLENBQUMsTUFBTSxvQ0FBb0MsR0FBbUQsTUFBTSxDQUFDLE1BQU0sQ0FB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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlIQUFpSDtBQUNqSCw4R0FBOEc7QUFDOUcsMkdBQTJHO0FBQzNHLDZHQUE2RztBQUM3RyxxR0FBcUc7QUFFckcsT0FBTyxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNoRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2pDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDakMsNEdBQTRHO0FBQzVHLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzVELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUd2RCw2REFBNkQ7QUFDN0QsTUFBTSxDQUFDLE1BQU0sMkJBQTJCLEdBTW5DLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDakIsZUFBZSxFQUFFLHFCQUFxQjtJQUN0QyxTQUFTLEVBQUUsZUFBZTtJQUMxQixvQkFBb0IsRUFBRSxxQkFBcUI7SUFDM0MsV0FBVyxFQUFFLGFBQWE7SUFDMUIsS0FBSyxFQUFFLE9BQU87Q0FDZixDQUFDLENBQUM7QUFFSDttR0FDbUc7QUFDbkcsTUFBTSxDQUFDLE1BQU0sb0NBQW9DLEdBQW1ELE1BQU0sQ0FB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 \ No newline at end of file diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.ts b/packages/loopover-miner/lib/cross-repo-evaluation.ts index 61fdf68c6d..2e4512c915 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.ts +++ b/packages/loopover-miner/lib/cross-repo-evaluation.ts @@ -5,7 +5,7 @@ // readiness gaps, leaked loopover assumptions in agent instructions, clone/setup problems, or other. import { spawn as nodeSpawn } from "node:child_process"; -import { cpSync, existsSync, mkdtempSync, rmSync } from "node:fs"; +import { cpSync, existsSync, mkdtempSync, realpathSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; // Already a transitive dependency via coding-task-spec.js's own engine imports -- this adds no load weight. @@ -553,9 +553,17 @@ export type EvaluateRepoExecutionOptions = EvaluateRepoReadinessOptions & { }; /** Copy the benchmark clone into a discardable temp tree — the agent and the repo's test suite only ever touch - * the copy, so the clone stays pristine and cleanup is a single recursive remove. */ + * the copy, so the clone stays pristine and cleanup is a single recursive remove. realpathSync's the fresh + * mkdtemp directory immediately: on macOS, os.tmpdir() resolves under a symlink (/var/folders/... -> + * /private/var/folders/...), so without this, the raw mkdtempSync path and coding-task-spec.ts's own + * realpathSync(workingDirectory) (a deliberate containment-check canonicalization in writeAcceptanceCriteriaFile, + * not something to remove) disagree on which string names the same directory -- acceptanceCriteriaPath then + * fails a plain acceptanceCriteriaPath.startsWith(workingDirectory) check even though the file genuinely is + * inside the working directory. Resolving once here, at the source, keeps every downstream path (workspace.path, + * task.workingDirectory, the acceptance-criteria path) in the same canonical form with no further changes + * needed. A no-op on Linux CI runners, where /tmp is not itself a symlink. */ export function defaultPrepareExecutionWorkspace(repoPath: string): CrossRepoExecutionWorkspace { - const scratchRoot = mkdtempSync(join(tmpdir(), "loopover-cross-repo-exec-")); + const scratchRoot = realpathSync(mkdtempSync(join(tmpdir(), "loopover-cross-repo-exec-"))); const path = join(scratchRoot, "repo"); cpSync(repoPath, path, { recursive: true }); return { diff --git a/test/unit/miner-cross-repo-evaluation.test.ts b/test/unit/miner-cross-repo-evaluation.test.ts index 91f1ab8825..e177c70ef6 100644 --- a/test/unit/miner-cross-repo-evaluation.test.ts +++ b/test/unit/miner-cross-repo-evaluation.test.ts @@ -1,4 +1,4 @@ -import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { existsSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, describe, expect, it, vi } from "vitest"; @@ -916,6 +916,19 @@ describe("cross-repo evaluation harness (#4788)", () => { expect(existsSync(workspace.path)).toBe(false); }); + // REGRESSION: on macOS, os.tmpdir() resolves under a symlink (/var/folders/... -> /private/var/folders/...), + // so a raw mkdtempSync path and coding-task-spec.ts's own realpathSync(workingDirectory) (a deliberate + // containment-check canonicalization in writeAcceptanceCriteriaFile) used to disagree on which string names + // the same directory. That made a plain acceptanceCriteriaPath.startsWith(workingDirectory) check fail even + // though the file genuinely was inside the working directory ("hands the agent a task rooted in a REAL + // discardable scratch copy" below). Asserted directly here, independent of that whole orchestration, so a + // regression is attributable to defaultPrepareExecutionWorkspace itself rather than rediscovered downstream. + it("REGRESSION: workspace.path is already realpath-canonical — no symlink hop for a downstream caller to trip on", () => { + const workspace = defaultPrepareExecutionWorkspace(nodeFixture()); + expect(workspace.path).toBe(realpathSync(workspace.path)); + workspace.cleanup(); + }); + it("createDefaultCrossRepoExecutionRunCommand reports exit codes, output, timeouts, and spawn errors", async () => { // The runner tokenizes on whitespace and execs directly (no shell), so every command here is a plain // `tool arg...` form — the only shape detectRepoStack ever emits.