// Validate compiler-owned plans and immutable artifact receipts before publishing check outputs. import { readFile, writeFile } from "node:fs/promises"; import { createHash } from "node:crypto"; import { pathToFileURL } from "node:url"; import { join } from "node:path"; const [compilerPath, planPath, checksPath, output] = process.argv.slice(2); const compiler = await import(pathToFileURL(compilerPath)); const plan = JSON.parse(await readFile(planPath, "utf8")); const checks = JSON.parse(await readFile(checksPath, "utf8")); compiler.compileWorkspaceEntry(plan, JSON.parse(await readFile(join(output, "entry.json"), "utf8"))); const roots = Object.create(null); for (const check of checks) { if (Object.hasOwn(roots, check.packageRevisionId)) throw Error("Duplicate checked package revision"); roots[check.packageRevisionId] = check.artifactPath; } const generator = createHash("sha256") .update(await readFile(compilerPath)) .digest("hex"); // These compiler-dependent checks belong to the Nix build, not runtime recovery. const candidate = JSON.parse(await readFile(join(output, "candidate.json"), "utf8")); const { executionContracts: _legacyContracts, ...workspace } = candidate; if (compiler.hexDigest(compiler.compileExecutionPlan(workspace)) !== compiler.hexDigest(plan)) throw Error("CANDIDATE_PLAN_MISMATCH: build plan differs from source compilation"); const checked = await compiler.loadCheckedArtifactWorld(plan, roots, generator); const installation = await compiler.loadExecutionInstallation(plan, roots); const kernel = compiler.compileKernelProgram(plan), queries = compiler.compileQueryProgram(plan); for (const [file, value] of [ ["execution-world.json", checked.world], ["installation.json", installation], ["kernel.json", kernel], ["queries.json", queries], [ "execution-artifacts.json", { codec: "camino-checked-execution-v2", generator, roots, manifests: checked.manifests, programs: { kernel: compiler.hexDigest(kernel), queries: compiler.hexDigest(queries) }, }, ], ]) await writeFile(join(output, file), JSON.stringify(value) + "\n");