1234import { spawnSync } from "node:child_process";5import { createHash } from "node:crypto";6import { readFileSync } from "node:fs";7import { dirname, resolve } from "node:path";8import { fileURLToPath } from "node:url";910const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");11const dest = resolve(root, "src/shared/noise-core-wasm");12const files = [13 "peach_noise_core.js",14 "peach_noise_core.d.ts",15 "peach_noise_core_bg.wasm",16 "peach_noise_core_bg.wasm.d.ts",17 "peach_noise_core_bytes.ts",18];1920function hashTree() {21 return Object.fromEntries(22 files.map((f) => [23 f,24 createHash("sha256").update(readFileSync(resolve(dest, f))).digest("hex"),25 ]),26 );27}2829const testConstructorPattern = /(?:WithEphemeralForTest|with_ephemeral_for_test)/;3031function assertProductionExports(files) {32 const leaked = files.filter((f) => testConstructorPattern.test(readFileSync(resolve(dest, f), "utf8")));33 if (leaked.length > 0) {34 console.error(`production Noise WASM exports test-only constructors: ${leaked.join(", ")}`);35 process.exit(1);36 }37}3839assertProductionExports(["peach_noise_core.js", "peach_noise_core.d.ts", "peach_noise_core_bg.wasm.d.ts"]);40const before = hashTree();41const build = spawnSync("npm", ["run", "build:noise-core"], { stdio: "inherit" });42if (build.status !== 0) {43 console.error(44 "noise-core rebuild failed — committed WASM provenance cannot be verified (PB-26-003)",45 );46 process.exit(build.status ?? 1);47}4849const after = hashTree();50const drifted = files.filter((f) => before[f] !== after[f]);51if (drifted.length > 0) {52 console.error(53 `committed Noise WASM does not match crypto-core/src/lib.rs — drifted: ${drifted.join(", ")}\n` +54 "run `npm run build:noise-core` and commit the regenerated files",55 );56 process.exit(1);57}58console.log("committed Noise WASM matches crypto-core source");