import { createHash } from "node:crypto"; import { readFile } from "node:fs/promises"; import { describe, expect, it } from "vitest"; import { verifyBuildManifestOutputs } from "../../scripts/lib/build-manifest-outputs.ts"; import { dependencyInventoryArtifactSchema, fieldWebVitalsArtifactSchema, jsonSchemaDocumentArtifactSchema, labPerformanceArtifactSchema, parseBuildManifestArtifact, parseReleaseArtifact, parseRuntimeConfigArtifact, projectReleaseTokens, registrySnapshotArtifactSchema, supplyChainVerificationArtifactSchema, } from "../../scripts/contracts/release-artifacts.ts"; const EMPTY_CONTRACT_SET_DIGEST = "sha256:ad6aab71fea6a9ff87cbd170b984b339965afc90d85bb57f87801c9e0c020da2"; const releaseV2 = { schemaVersion: 2, appVersion: "0.1.0", buildId: "build-a", commitSha: "abc1234", configSchemaVersion: "2.0", assetManifestHash: "asset-hash", releaseId: "release-a", builtAt: "2026-08-01T00:00:00.000Z", routeChunks: { "route-home": "assets/home.js" }, contractSet: { setAlgorithm: "CA_CONTRACT_SET_V1", setDigest: EMPTY_CONTRACT_SET_DIGEST, packages: [], }, } as const; const buildManifest = { schemaVersion: 1, buildId: "build-a", commitSha: "abc1234", releaseId: "release-a", moduleInventoryHash: "inventory-hash", generatedAt: "2026-08-01T00:00:00.000Z", buildContext: { nodeVersion: "v24.14.0", packageManagerVersion: "11.17.0", runnerImage: "linux-x64", sourceDateEpoch: null, }, outputs: { directory: "dist", viteManifest: "dist/.vite/manifest.json", moduleInventory: "artifacts/quality/vite-module-inventory.json", routeChunks: { "route-home": "assets/home.js" }, runtimeConfigSchema: "dist/runtime-config.schema.json", }, } as const; describe("release artifact contracts", () => { it("verifies confined build outputs and the raw module inventory bytes", async () => { const moduleInventoryBytes = Buffer.from( '{"schemaVersion":1,"chunks":[]}\n', ); const files = new Map([ ["/repo/dist/.vite/manifest.json", Buffer.from("{}\n")], ["/repo/artifacts/quality/vite-module-inventory.json", moduleInventoryBytes], ["/repo/dist/runtime-config.schema.json", Buffer.from("{}\n")], ["/repo/dist/assets/home.js", Buffer.from("chunk\n")], ]); const manifest = { ...buildManifest, moduleInventoryHash: createHash("sha256") .update(moduleInventoryBytes) .digest("hex"), }; await expect( verifyBuildManifestOutputs(manifest, { repositoryRoot: "/repo", readBytes: async (target) => files.get(target) ?? Promise.reject(Object.assign(new Error("missing"), { code: "ENOENT" })), realpathPath: async (target) => target, assertRegularFile: async () => undefined, assertDirectory: async () => undefined, }), ).resolves.toEqual([]); }); it.each([ ["missing", undefined, /moduleInventory:missing/u], [ "tampered", Buffer.from('{"schemaVersion":1,"chunks":[{"fileName":"other.js","modules":[]}]}\n'), /moduleInventoryHash/u, ], ] as const)("rejects a %s module inventory", async (_name, bytes, expected) => { const files = new Map([ ["/repo/dist/.vite/manifest.json", Buffer.from("{}\n")], ["/repo/dist/runtime-config.schema.json", Buffer.from("{}\n")], ["/repo/dist/assets/home.js", Buffer.from("chunk\n")], ...(bytes ? [["/repo/artifacts/quality/vite-module-inventory.json", bytes] as const] : []), ]); const mismatches = await verifyBuildManifestOutputs(buildManifest, { repositoryRoot: "/repo", readBytes: async (target) => files.get(target) ?? Promise.reject(Object.assign(new Error("missing"), { code: "ENOENT" })), realpathPath: async (target) => target, assertRegularFile: async () => undefined, assertDirectory: async () => undefined, }); expect(mismatches.join("\n")).toMatch(expected); }); it.each(["../outside", "/absolute", "dist\\escape"])( "rejects unsafe build-manifest output path %s", async (unsafePath) => { const mismatches = await verifyBuildManifestOutputs( { ...buildManifest, outputs: { ...buildManifest.outputs, moduleInventory: unsafePath }, }, { repositoryRoot: "/repo", realpathPath: async (target) => target, }, ); expect(mismatches).toContain("buildManifest:moduleInventory:path"); }, ); it("requires the canonical Vite manifest declared by the build writer", async () => { const mismatches = await verifyBuildManifestOutputs( { ...buildManifest, outputs: { ...buildManifest.outputs, viteManifest: "dist/.vite/tampered-manifest.json", }, }, { repositoryRoot: process.cwd() }, ); expect(mismatches).toContain("buildManifest:viteManifest:path"); }); it("rejects a realpath escape from a declared build output", async () => { const mismatches = await verifyBuildManifestOutputs(buildManifest, { repositoryRoot: "/repo", realpathPath: async (target) => target.endsWith("vite-module-inventory.json") ? "/outside/inventory.json" : target, assertRegularFile: async () => undefined, assertDirectory: async () => undefined, readBytes: async () => Buffer.from("inventory\n"), }); expect(mismatches).toContain("buildManifest:moduleInventory:path"); }); it("rejects a nested symlink that resolves inside the repository but outside dist", async () => { const moduleInventoryBytes = Buffer.from( '{"schemaVersion":1,"chunks":[]}\n', ); const mismatches = await verifyBuildManifestOutputs( { ...buildManifest, moduleInventoryHash: createHash("sha256") .update(moduleInventoryBytes) .digest("hex"), }, { repositoryRoot: "/repo", realpathPath: async (target) => target === "/repo/dist/assets/home.js" ? "/repo/src/home.js" : target, assertRegularFile: async () => undefined, assertDirectory: async () => undefined, readBytes: async () => moduleInventoryBytes, }, ); expect(mismatches).toContain("buildManifest:routeChunk:route-home:path"); }); it("allows a legal dist child whose name begins with two dots", async () => { const moduleInventoryBytes = Buffer.from( '{"schemaVersion":1,"chunks":[]}\n', ); const files = new Map([ ["/repo/dist/.vite/manifest.json", Buffer.from("{}\n")], ["/repo/artifacts/quality/vite-module-inventory.json", moduleInventoryBytes], ["/repo/dist/runtime-config.schema.json", Buffer.from("{}\n")], ["/repo/dist/..assets/home.js", Buffer.from("chunk\n")], ]); const mismatches = await verifyBuildManifestOutputs( { ...buildManifest, moduleInventoryHash: createHash("sha256") .update(moduleInventoryBytes) .digest("hex"), outputs: { ...buildManifest.outputs, routeChunks: { "route-home": "..assets/home.js" }, }, }, { repositoryRoot: "/repo", readBytes: async (target) => files.get(target) ?? Promise.reject(new Error("missing")), realpathPath: async (target) => target, assertRegularFile: async () => undefined, assertDirectory: async () => undefined, }, ); expect(mismatches).toEqual([]); }); it.each([ ["viteManifest", "package.json"], ["runtimeConfigSchema", "schemas/artifacts/build-manifest.schema.json"], ["moduleInventory", "package.json"], ] as const)("rejects %s outside its approved output root", async (field, value) => { const mismatches = await verifyBuildManifestOutputs( { ...buildManifest, outputs: { ...buildManifest.outputs, [field]: value }, }, { repositoryRoot: process.cwd() }, ); expect(mismatches).toContain(`buildManifest:${field}:path`); }); it("rejects a parse-invalid module inventory even when its raw hash matches", async () => { const bytes = Buffer.from("{}\n"); const mismatches = await verifyBuildManifestOutputs( { ...buildManifest, moduleInventoryHash: createHash("sha256").update(bytes).digest("hex"), }, { repositoryRoot: "/repo", readBytes: async () => bytes, realpathPath: async (target) => target, assertRegularFile: async () => undefined, assertDirectory: async () => undefined, }, ); expect(mismatches).toContain("buildManifest:moduleInventory:invalid"); }); it("projects the nested V2 contract-set digest without a legacy scalar", () => { const release = parseReleaseArtifact(releaseV2); expect(projectReleaseTokens(release)).toMatchObject({ schemaVersion: 2, buildId: "build-a", contractSetDigest: EMPTY_CONTRACT_SET_DIGEST, }); expect(projectReleaseTokens(release)).not.toHaveProperty( "apiContractVersion", ); }); it("projects the legacy scalar only for V1", () => { const { contractSet: _contractSet, ...releaseWithoutContractSet } = releaseV2; void _contractSet; const release = parseReleaseArtifact({ ...releaseWithoutContractSet, schemaVersion: 1, configSchemaVersion: "1", apiContractVersion: "1.4.0", }); expect(projectReleaseTokens(release)).toMatchObject({ schemaVersion: 1, apiContractVersion: "1.4.0", }); expect(projectReleaseTokens(release)).not.toHaveProperty( "contractSetDigest", ); }); it("rejects a V2 release carrying the removed scalar", () => { expect(() => parseReleaseArtifact({ ...releaseV2, apiContractVersion: "1", }), ).toThrow(); }); it("accepts the exact build manifest emitted by the generator", () => { expect(parseBuildManifestArtifact(buildManifest)).toEqual(buildManifest); }); it("rejects unknown build manifest output fields", () => { expect(() => parseBuildManifestArtifact({ ...buildManifest, outputs: { ...buildManifest.outputs, unexpected: "value" }, }), ).toThrow(); }); it("accepts Runtime Config V2 without a legacy API scalar", () => { expect( parseRuntimeConfigArtifact({ APP_ENV: "local", API_BASE_URL: "http://localhost:8080/", REQUEST_TIMEOUT_MS: 10_000, MAX_RETRY_ATTEMPTS: 2, TELEMETRY_ENABLED: false, AUTH_MODE: "demo", CONFIG_SCHEMA_VERSION: "2.0", RELEASE_MANIFEST_URL: "/release-manifest.json", BUILD_ID: "build-a", RELEASE_ID: "release-a", CAPABILITY_OVERRIDES: { REALTIME: "DEFAULT", WEB_WORKER: "DEFAULT", SERVICE_WORKER: "DEFAULT", OFFLINE_COMMANDS: "DEFAULT", }, }), ).not.toHaveProperty("API_CONTRACT_VERSION"); }); it("enforces dependency inventory counts at the executable writer boundary", () => { const inventory = { schemaVersion: 2, packageManager: "pnpm@11.17.0", lockfileSha256: "a".repeat(64), dependencyCount: 1, directDependencyCount: 1, dependencies: [ { name: "zod", version: "4.4.3", direct: true, scope: "production", optional: false, license: "MIT", integrity: `sha512-${"a".repeat(86)}`, dependencies: [], }, ], } as const; expect(dependencyInventoryArtifactSchema.parse(inventory)).toEqual( inventory, ); expect(() => dependencyInventoryArtifactSchema.parse({ ...inventory, dependencyCount: 2, }), ).toThrow(); expect(() => dependencyInventoryArtifactSchema.parse({ ...inventory, dependencyCount: 0, directDependencyCount: 0, dependencies: [], }), ).toThrow(); }); it("rejects undeclared supply-chain verification evidence", () => { const verification = { schemaVersion: 1, localStatus: "PASS", promotionStatus: "FAIL_UNVERIFIED", lockfileSha256: "a".repeat(64), sourceSetSha256: "b".repeat(64), distSha256: "c".repeat(64), sbomSha256: "d".repeat(64), dependencyDiff: { added: [], removed: [], changed: [], upgrades: [], }, highRiskReview: [], vulnerabilityStatus: "FAIL_UNVERIFIED", provenanceAttestationStatus: "FAIL_UNVERIFIED", failures: [], } as const; expect(supplyChainVerificationArtifactSchema.parse(verification)).toEqual( verification, ); expect(() => supplyChainVerificationArtifactSchema.parse({ ...verification, undocumented: true, }), ).toThrow(); }); it("preserves no-baseline and failure registry evidence", () => { const failureEvidence = { schemaVersion: 2, generatedAt: "2026-08-01T00:00:00.000Z", baselineDigest: null, currentDigest: "a".repeat(64), compatibility: { impact: "not-evaluated", changes: [] }, failures: ["missing registry source"], registries: [], } as const; expect(registrySnapshotArtifactSchema.parse(failureEvidence)).toEqual( failureEvidence, ); }); it("requires the complete repository registry set for success evidence", () => { const successfulEvidence = { schemaVersion: 2, generatedAt: "2026-08-01T00:00:00.000Z", baselineDigest: null, currentDigest: "a".repeat(64), compatibility: { impact: "not-evaluated", changes: [] }, failures: [], registries: Array.from({ length: 11 }, (_, index) => ({ registryId: `registry-${index}`, owner: "platform", source: `src/registry-${index}.ts`, rowCount: 0, contract: {}, rows: {}, })), } as const; expect(registrySnapshotArtifactSchema.parse(successfulEvidence)).toEqual( successfulEvidence, ); expect(() => registrySnapshotArtifactSchema.parse({ ...successfulEvidence, registries: [], }), ).toThrow(); }); it("preserves unverified field evidence when no samples are eligible", () => { const report = { schemaVersion: 1, generatedAt: "2026-08-01T00:00:00.000Z", window: { days: 28, start: "2026-07-04T00:00:00.000Z", end: "2026-08-01T00:00:00.000Z", }, context: { source: "config/performance/field-input.example.json", sourceSystem: null, exportId: null, network: "production-real-user", routeAggregation: "route-id-only", releaseId: null, privacyApprovalRef: null, thresholdDecisionRef: null, validationFailures: ["input: invalid evidence"], }, metrics: { p75LcpMs: null, p75Cls: null, p75InpMs: null }, thresholds: { p75LcpMs: 2_500, p75Cls: 0.1, p75InpMs: 200, minimumEligibleSamples: null, }, eligibility: { consentRequired: true, totalSamples: 0, eligibleSamples: 0, minimumEligibleSamples: null, routeSamples: {}, }, status: "FAIL_UNVERIFIED", passed: false, } as const; expect(fieldWebVitalsArtifactSchema.parse(report)).toEqual(report); }); it("preserves verified field evidence that fails an approved threshold", () => { const report = { schemaVersion: 1, generatedAt: "2026-08-01T00:00:00.000Z", window: { days: 28, start: "2026-07-04T00:00:00.000Z", end: "2026-08-01T00:00:00.000Z", }, context: { source: "provider.json", sourceSystem: "provider", exportId: "export-1", network: "production-real-user", routeAggregation: "route-id-only", releaseId: "release-1", privacyApprovalRef: "privacy-1", thresholdDecisionRef: "decision-1", validationFailures: [], }, metrics: { p75LcpMs: 2_501, p75Cls: 0.1, p75InpMs: 200 }, thresholds: { p75LcpMs: 2_500, p75Cls: 0.1, p75InpMs: 200, minimumEligibleSamples: 1, }, eligibility: { consentRequired: true, totalSamples: 1, eligibleSamples: 1, minimumEligibleSamples: 1, routeSamples: { APP_HOME: 1 }, }, status: "FAIL_THRESHOLD", passed: false, } as const; expect(fieldWebVitalsArtifactSchema.parse(report)).toEqual(report); }); it("accepts the lab writer's nested browser context as JSON evidence", () => { const report = { schemaVersion: 1, generatedAt: "2026-08-01T00:00:00.000Z", context: { runner: { platform: "linux", architecture: "x64", nodeVersion: "v24" }, browser: { name: "chromium", version: "140" }, viewport: { width: 1280, height: 720 }, network: { profile: "contract-fast-4g", latencyMs: 40, downloadBytesPerSecond: 200_000, uploadBytesPerSecond: 93_750, }, cpu: { throttlingRate: 4 }, cache: { state: "cold", isolation: "new-browser-context" }, build: { buildId: "build-1", releaseId: "release-1" }, }, metrics: { lcpMs: 1_000, cls: 0.01, namedInteractionMs: 100 }, thresholds: { lcpMs: 2_500, cls: 0.1, namedInteractionMs: 200 }, fixtures: [ { name: "missing-context", passed: true }, { name: "lcp-over-threshold", passed: true }, ], passed: true, } as const; expect(labPerformanceArtifactSchema.parse(report)).toEqual(report); }); it("rejects non-JSON values in generated schema documents", () => { expect(() => jsonSchemaDocumentArtifactSchema.parse({ $schema: "https://json-schema.org/draft/2020-12/schema", invalid: () => undefined, }), ).toThrow(); }); it("keeps machine-readable evidence publishers on the validated writer", async () => { const writerFiles = [ "scripts/generate-build-manifest.ts", "scripts/generate-supply-chain.ts", "scripts/collect-web-vitals-evidence.ts", "scripts/test-performance.ts", "scripts/verify-release.ts", "scripts/drill-runbook.ts", "scripts/check-registries.ts", ] as const; const sources = await Promise.all( writerFiles.map(async (file) => ({ file, source: await readFile(file, "utf8"), })), ); for (const { file, source } of sources) { const directWrites = source.match(/\bwriteFile\s*\(/gu) ?? []; if (file === "scripts/generate-supply-chain.ts") { expect(directWrites, file).toHaveLength(1); expect(source, file).toMatch( /writeFile\(\s*["']artifacts\/release\/checksums\.txt["']/u, ); } else { expect(directWrites, file).toHaveLength(0); } } expect( sources.flatMap(({ source }) => source.match(/\bwriteValidatedJsonArtifact\s*\(/gu) ?? [], ), ).toHaveLength(19); }); });