From 7d13f880ba959d39389dee7c15a136ae83cb3e2c Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 26 Jun 2026 06:47:27 -0700 Subject: [PATCH] FN-7059: pin merge gate composition Add CI-shape coverage that guards the trusted merge gate composition.\n\n- Load root and engine package scripts plus the engine vitest config in the CI workflow test.\n- Assert test:gate includes the audited guard scripts, engine core suite, and CLI CI-shape suite.\n- Assert engine test:core continues targeting the engine-core vitest project.\n\nFiles changed:\n packages/cli/src/__tests__/ci-workflow.test.ts | 26 ++++++++++++++++++++++++++\n 1 file changed, 26 insertions(+) Fusion-Task-Id: FN-7059 Fusion-Task-Lineage: 47af7fdd-a812-4d03-960a-a6300d86b59e --- .../cli/src/__tests__/ci-workflow.test.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/cli/src/__tests__/ci-workflow.test.ts b/packages/cli/src/__tests__/ci-workflow.test.ts index e1e3853857..d820b5a784 100644 --- a/packages/cli/src/__tests__/ci-workflow.test.ts +++ b/packages/cli/src/__tests__/ci-workflow.test.ts @@ -33,7 +33,10 @@ describe("Merge gate (.github/workflows/pr-checks.yml)", () => { let compositeAction: any; let contributingContent: string; let readmeContent: string; + let rootPackageJson: any; + let enginePackageJson: any; let cliPackageJsonContent: string; + let engineVitestConfigContent: string; let extensionSuiteContent: string; let agentExportSuiteContent: string; let buildExeSuiteContent: string; @@ -45,7 +48,10 @@ describe("Merge gate (.github/workflows/pr-checks.yml)", () => { compositeAction = loadYamlFile(".github", "actions", "setup-node-pnpm", "action.yml").parsed; contributingContent = readFileSync(join(workspaceRoot, "docs", "contributing.md"), "utf-8"); readmeContent = readFileSync(join(workspaceRoot, "README.md"), "utf-8"); + rootPackageJson = JSON.parse(readFileSync(join(workspaceRoot, "package.json"), "utf-8")); + enginePackageJson = JSON.parse(readFileSync(join(workspaceRoot, "packages", "engine", "package.json"), "utf-8")); cliPackageJsonContent = readFileSync(join(workspaceRoot, "packages", "cli", "package.json"), "utf-8"); + engineVitestConfigContent = readFileSync(join(workspaceRoot, "packages", "engine", "vitest.config.ts"), "utf-8"); extensionSuiteContent = readFileSync( join(workspaceRoot, "packages", "cli", "src", "__tests__", "extension-integration.test.ts"), "utf-8", @@ -101,6 +107,26 @@ describe("Merge gate (.github/workflows/pr-checks.yml)", () => { ).toBe(true); }); + /* + FNXC:CITestGate 2026-06-26-06:40: + The merge gate is the thin trusted CI surface. ci-workflow.test.ts must pin not only that the Gate job invokes `pnpm test:gate`, but also test:gate's internal composition (guards + engine test:core + cli test:ci-shape) and that engine test:core references the engine-core vitest project — otherwise a rename could hollow the gate while this CI-shape test stays green (FN-7059). + */ + it("pins test:gate to the audited guard scripts and curated suites", () => { + const testGateScript = rootPackageJson.scripts?.["test:gate"] ?? ""; + + expect(testGateScript).toContain("node scripts/check-no-nohup.mjs"); + expect(testGateScript).toContain("node scripts/check-no-kill-4040.mjs"); + expect(testGateScript).toContain("node scripts/check-no-test-timeout-appeasement.mjs"); + expect(testGateScript).toContain("node scripts/check-changeset-format.mjs"); + expect(testGateScript).toContain("pnpm --filter @fusion/engine test:core"); + expect(testGateScript).toContain("pnpm --filter @runfusion/fusion test:ci-shape"); + }); + + it("pins engine test:core to the engine-core vitest project", () => { + expect(enginePackageJson.scripts?.["test:core"] ?? "").toContain("--project=engine-core"); + expect(engineVitestConfigContent).toContain('name: "engine-core"'); + }); + it("pins dependency bootstrap to frozen lockfile in every job", () => { for (const jobName of ["lint", "typecheck", "build", "gate"]) { expect(findCompositeSetupStep(workflow.jobs?.[jobName]?.steps ?? [])).toBeDefined();