import { createHash } from 'node:crypto' import { access, readFile } from 'node:fs/promises' import { dirname, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { loadGoldenManifest } from './freecad-golden-contract.mjs' const root = resolve(dirname(fileURLToPath(import.meta.url)), '..') const readJson = async (relative) => JSON.parse(await readFile(resolve(root, relative), 'utf8')) const fail = (message) => { throw new Error(message) } const baseline = await readJson('config/freecad-baseline.json') const toolchain = await readJson('config/freecad-toolchain.json') const nativeBuild = await readJson('config/freecad-native-build.json') const runtime = await readJson('config/runtime-baseline.json') const packageJson = await readJson('package.json') const nodeRuntime = await readFile(resolve(root, 'config/node-runtime.env'), 'utf8') if (baseline.baselineId !== toolchain.baselineId || baseline.freecadVersion !== toolchain.source.tag) fail('FreeCAD baseline and toolchain tag disagree.') if (!baseline.sourceRef.endsWith(`@${toolchain.source.commit}`) || !/^[0-9a-f]{40}$/.test(toolchain.source.commit)) fail('FreeCAD source commit is not an exact 40-character revision.') if (nativeBuild.baselineId !== baseline.baselineId || nativeBuild.source.commit !== toolchain.source.commit) fail('Native oracle build manifest does not match the locked FreeCAD source.') if (!nodeRuntime.includes(`NODE_VERSION=${packageJson.engines.node}`) || runtime.projectRuntime.node !== packageJson.engines.node) fail('Project Node runtime declarations disagree.') for (const [packageName, expectedVersion] of [['@bitbybit-dev/occt', runtime.geometry.version], ['@bitbybit-dev/occt-worker', runtime.geometry.version], ['three', runtime.viewport.version], ['@sqlite.org/sqlite-wasm', '3.53.0-build1']]) { const declared = packageJson.dependencies[packageName] const installed = await readJson(`node_modules/${packageName}/package.json`) if (declared !== expectedVersion || installed.version !== expectedVersion) fail(`${packageName} must be declared and installed at ${expectedVersion}.`) } const wasmFile = resolve(root, 'node_modules/@bitbybit-dev/occt/bitbybit-dev-occt/bitbybit-dev-occt.a4a6ec2a.wasm') const wasmHash = createHash('sha256').update(await readFile(wasmFile)).digest('hex') if (wasmHash !== runtime.geometry.wasmSha256) fail(`OCCT WASM checksum mismatch: ${wasmHash}.`) const manifest = await loadGoldenManifest(resolve(root, toolchain.goldenContract.manifest)) if (manifest.baselineId !== baseline.baselineId || manifest.driver !== toolchain.goldenContract.driver) fail('Golden manifest does not match the locked baseline contract.') if (nativeBuild.verification.goldenManifest !== toolchain.goldenContract.manifest || nativeBuild.verification.scenarioCount !== manifest.scenarios.length) fail('Native oracle verification does not match the golden manifest.') const nativeOracle = resolve(root, nativeBuild.artifact.path) try { await access(nativeOracle) const nativeHash = createHash('sha256').update(await readFile(nativeOracle)).digest('hex') if (nativeHash !== nativeBuild.artifact.sha256) fail(`Native FreeCADCmd checksum mismatch: ${nativeHash}.`) } catch (error) { if (error?.code !== 'ENOENT') throw error } console.log(`Baseline contract OK: FreeCAD ${baseline.freecadVersion} @ ${toolchain.source.commit.slice(0, 12)}, ${manifest.scenarios.length} golden scenarios, OCCT WASM ${wasmHash.slice(0, 12)}.`)