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 inputPath = path.join(root, "tests/golden/M15-02A/blender-parity-map.json"); const output = path.resolve(process.argv[2] ?? path.join(root, "tests/golden/M15-02B/blender-gap-audit.json")); const map = JSON.parse(fs.readFileSync(inputPath, "utf8")); const seen = new Set(); const duplicateIds = []; const unmapped = []; const summaryOnly = []; const proxyOnly = []; const routeOnly = []; for (const entry of map.entries) { if (seen.has(entry.id)) duplicateIds.push(entry.id); seen.add(entry.id); if (!entry.ownerFamily || !entry.implementationClass || !Array.isArray(entry.tests) || !Array.isArray(entry.evidence)) unmapped.push(entry.id); if (entry.implementationClass === "INVENTORY_BASELINE") summaryOnly.push(entry.id); if (entry.implementationClass === "PROXY_ONLY") proxyOnly.push(entry.id); if (entry.implementationClass === "ROUTE_ONLY") routeOnly.push(entry.id); } for (const values of [duplicateIds, unmapped, summaryOnly, proxyOnly, routeOnly]) values.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); const audit = { schemaVersion: 1, task: "M15-02B", operation: "BLENDER_PARITY_GAP_AUDIT", source: { path: "tests/golden/M15-02A/blender-parity-map.json", sha256: crypto.createHash("sha256").update(fs.readFileSync(inputPath)).digest("hex") }, summary: { inventoried: map.entries.length, unmapped: unmapped.length, duplicate: duplicateIds.length, summaryOnly: summaryOnly.length, proxyOnly: proxyOnly.length, routeOnly: routeOnly.length, gapCount: unmapped.length + duplicateIds.length + summaryOnly.length + proxyOnly.length + routeOnly.length }, gaps: { unmapped, duplicateIds, summaryOnly, proxyOnly, routeOnly }, interpretation: { inventoryBaseline: "SUMMARY_ONLY", parityClaims: "NONE", nextTaskPerEntry: false }, nextTask: "M15-02C", }; fs.mkdirSync(path.dirname(output), { recursive: true }); fs.writeFileSync(output, `${JSON.stringify(audit, null, 2)}\n`); process.stdout.write(`blender-gap-audit-generated inventoried=${audit.summary.inventoried} gaps=${audit.summary.gapCount} summaryOnly=${audit.summary.summaryOnly} output=${output}\n`);