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 outputPath = path.join(root, "tests/golden/corrective/rehydration/M12-provenance-intake.json"); const driftPath = path.join(root, "tests/golden/corrective/rehydration/M12-manifest-sha-drift.json"); const snapshotArgument = process.argv.indexOf("--snapshot"); const requestedSnapshot = snapshotArgument >= 0 ? process.argv[snapshotArgument + 1] : null; const write = process.argv.includes("--write"); const relative = (file) => path.relative(root, file).replaceAll(path.sep, "/"); const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex"); const readJson = (file) => JSON.parse(fs.readFileSync(file, "utf8")); const drift = readJson(driftPath); function emptyReport(reason) { return { schemaVersion: 1, operation: "M12_IMMUTABLE_SNAPSHOT_PROVENANCE_INTAKE", historicalEvidencePreserved: true, immutableSourceSnapshotAvailable: false, provenanceState: "BLOCKED_SOURCE_LOST", sourceSnapshot: null, sourceSnapshotManifestSha256: null, driftEntries: drift.entries.length, restoredEntries: 0, remainingEntries: drift.entries.length, reason, entries: drift.entries.map((entry) => ({ ...entry, provenanceState: "BLOCKED_SOURCE_LOST" })), }; } function resolveSnapshot(value) { if (!value) return null; const candidate = path.resolve(root, value); if (!fs.existsSync(candidate)) return null; const manifestPath = fs.statSync(candidate).isDirectory() ? path.join(candidate, "snapshot-manifest.json") : candidate; if (!fs.existsSync(manifestPath)) return null; const manifest = readJson(manifestPath); assert.equal(manifest.schemaVersion, 1, "snapshot manifest schema must be 1"); assert.ok(["IMMUTABLE_ARCHIVE", "IMMUTABLE_REPOSITORY", "SIGNED_ARTIFACT"].includes(manifest.mode), "snapshot mode is not immutable"); assert.equal(manifest.authorized, true, "snapshot must be authorized"); assert.ok(Array.isArray(manifest.files), "snapshot manifest files are missing"); const rootPath = path.dirname(manifestPath); const files = new Map(); for (const entry of manifest.files) { assert.equal(typeof entry.path, "string"); assert.match(entry.sha256 ?? "", /^[a-f0-9]{64}$/u); const sourcePath = path.resolve(rootPath, entry.snapshotPath ?? entry.path); assert.ok(sourcePath === rootPath || sourcePath.startsWith(`${rootPath}${path.sep}`), `snapshot path escapes root: ${entry.path}`); assert.ok(fs.existsSync(sourcePath), `snapshot file is missing: ${entry.path}`); assert.equal(sha256(sourcePath), entry.sha256, `snapshot hash drift: ${entry.path}`); if (entry.bytes !== undefined) assert.equal(fs.statSync(sourcePath).size, entry.bytes, `snapshot byte drift: ${entry.path}`); const key = `${entry.path}\0${entry.sha256}`; if (files.has(key)) throw new Error(`duplicate snapshot path/SHA pair: ${entry.path}`); files.set(key, { ...entry, sourcePath }); } return { rootPath, manifestPath, manifest, files }; } let report; if (!requestedSnapshot) { report = emptyReport("immutable snapshot was not supplied; no historical source may be inferred from the current worktree"); } else { const snapshot = resolveSnapshot(requestedSnapshot); if (!snapshot) { report = emptyReport(`immutable snapshot is unavailable or invalid: ${requestedSnapshot}`); } else { const restored = []; const remaining = []; for (const entry of drift.entries) { const source = snapshot.files.get(`${entry.path}\0${entry.originalSha256}`); if (source) { restored.push({ ...entry, snapshotPath: relative(source.sourcePath), provenanceState: "PROVENANCE_RESTORED" }); } else { remaining.push({ ...entry, snapshotPath: source ? relative(source.sourcePath) : null, provenanceState: "BLOCKED_SOURCE_LOST" }); } } report = { schemaVersion: 1, operation: "M12_IMMUTABLE_SNAPSHOT_PROVENANCE_INTAKE", historicalEvidencePreserved: true, immutableSourceSnapshotAvailable: true, provenanceState: remaining.length === 0 ? "PROVENANCE_RESTORED" : "BLOCKED_SOURCE_LOST", sourceSnapshot: relative(snapshot.rootPath), sourceSnapshotManifestSha256: sha256(snapshot.manifestPath), snapshotMode: snapshot.manifest.mode, driftEntries: drift.entries.length, restoredEntries: restored.length, remainingEntries: remaining.length, reason: remaining.length === 0 ? "all observed M12 drift entries match the immutable source snapshot" : "snapshot supplied but some historical hashes remain unresolved", entries: [...restored, ...remaining].sort((a, b) => `${a.task}:${a.artifact}:${a.path}`.localeCompare(`${b.task}:${b.artifact}:${b.path}`)), }; } } if (write) { fs.mkdirSync(path.dirname(outputPath), { recursive: true }); fs.writeFileSync(outputPath, `${JSON.stringify(report, null, 2)}\n`, "utf8"); } else { assert.ok(fs.existsSync(outputPath), "provenance intake report is missing; run with --write"); assert.deepEqual(readJson(outputPath), report, "provenance intake report is stale or source changed"); } process.stdout.write(`m12-provenance-intake-ok state=${report.provenanceState} drift=${report.driftEntries} restored=${report.restoredEntries} remaining=${report.remainingEntries} snapshot=${report.immutableSourceSnapshotAvailable} write=${write}\n`);