import assert from "node:assert/strict"; import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); const abs = (file) => path.join(root, file); const read = (file) => fs.readFileSync(abs(file), "utf8"); const json = (file) => JSON.parse(read(file)); const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex"); const arg = (name) => { const index = process.argv.indexOf(name); return index >= 0 ? process.argv[index + 1] : null; }; const task = arg("--task"); if (!task || !process.argv.includes("--write")) throw new Error("usage: node tools/web/reuse-wbv2-source-dependencies.mjs --task --write"); const inventoryPath = "tests/golden/WBV2/dynamic-inventory.json"; const inventory = json(inventoryPath); const index = json("tests/golden/WBV2/task-index.json"); const plan = json(index.source.path); const record = plan.tasks.find((candidate) => candidate.id === task); const module = record?.module; assert.ok(module?.dependencyReuse?.length, `task ${task} has no dependency reuse map`); const bindings = json("tests/golden/WBV2/dynamic-coverage-bindings.json"); const bindingByUnit = new Map(bindings.filter((binding) => binding.status === "VERIFIED").map((binding) => [binding.unitId, binding])); function validateEvidence(evidencePath) { const evidence = json(evidencePath); assert.equal(evidence.browser, "chromium", `evidence is not Chromium: ${evidencePath}`); assert.equal(evidence.queueMutation, false, `evidence mutated queue: ${evidencePath}`); const fixturePaths = Array.isArray(evidence.fixtures) ? evidence.fixtures : evidence.fixture ? [evidence.fixture] : []; assert.ok(fixturePaths.length, `evidence has no fixture(s): ${evidencePath}`); const entries = Array.isArray(evidence.fixtures) ? fixturePaths.map((fixture) => evidence[fixture]) : [evidence]; for (const entry of entries) { assert.ok(entry && entry.error === undefined, `evidence fixture failed: ${evidencePath}`); if (entry.saveReopenExact !== undefined) assert.equal(entry.saveReopenExact, true); if (entry.deterministicExact !== undefined) assert.equal(entry.deterministicExact, true); if (entry.exact !== undefined) assert.equal(entry.exact, true); } if (Array.isArray(evidence.fixtures)) { for (const fixture of fixturePaths) assert.equal(evidence.fixtureSha256?.[fixture], sha(fixture), `fixture hash drift: ${fixture}`); } else { assert.equal(evidence.fixtureSha256, sha(evidence.fixture), `fixture hash drift: ${evidence.fixture}`); } return { path: evidencePath, sha256: sha(evidencePath), fixtures: fixturePaths }; } const proofs = []; const reusedEvidence = new Map(); for (const dependency of module.dependencyReuse) { const unit = inventory.units.find((candidate) => candidate.id === dependency.unitId); assert.ok(unit, `dynamic unit missing: ${dependency.unitId}`); assert.equal(unit.coverageStatus, "UNVERIFIED", `dependency unit is already verified: ${dependency.unitId}`); const representative = bindingByUnit.get(dependency.representativeUnitId); assert.ok(representative, `verified representative binding missing: ${dependency.representativeUnitId}`); assert.equal(representative.sourceTreeSha256, inventory.authority.sourceTreeSha256); assert.ok(fs.existsSync(abs(dependency.proofSource)), `dependency proof source missing: ${dependency.proofSource}`); const proofText = read(dependency.proofSource); assert.ok(proofText.includes(dependency.marker), `dependency marker missing: ${dependency.marker}`); assert.ok(fs.existsSync(abs(unit.locations?.[0]?.path)), `dependency source missing: ${unit.locations?.[0]?.path}`); assert.ok(read(unit.locations[0].path).includes(dependency.marker), `dependency source marker missing: ${dependency.marker}`); const evidence = validateEvidence(dependency.productionEvidence); reusedEvidence.set(evidence.path, evidence); proofs.push({ unitId: dependency.unitId, sourceLocation: unit.locations?.[0], representativeUnitId: dependency.representativeUnitId, representativeBinding: { task: representative.task, productionEvidence: representative.productionEvidence }, proofSource: dependency.proofSource, proofSourceSha256: sha(dependency.proofSource), marker: dependency.marker, productionEvidence: evidence, sourceTreeSha256: inventory.authority.sourceTreeSha256, }); } const reportPath = module.evidencePaths?.[0] ?? `tests/golden/${task}/source-dependency-reuse-production.json`; const report = { schemaVersion: 1, task, operation: "SOURCE_DEPENDENCY_REUSE_CHROMIUM_RECEIPT", status: "PASS", browser: "chromium", queueMutation: false, sourceUnits: module.coverageBindings, sourceTreeSha256: inventory.authority.sourceTreeSha256, dependencyProofs: proofs, reusedEvidence: [...reusedEvidence.values()], efficiency: { existingChromiumReceiptsReused: reusedEvidence.size, browserRuns: 0, buildRuns: 0, policy: "verified-downstream-receipt-plus-source-dependency" }, }; fs.mkdirSync(path.dirname(abs(reportPath)), { recursive: true }); fs.writeFileSync(abs(reportPath), `${JSON.stringify(report, null, 2)}\n`); process.stdout.write(`wbv2-source-dependency-reuse-ok task=${task} units=${proofs.length} receipts=${reusedEvidence.size} browserRuns=0\n`);