#!/usr/bin/env node import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), ".."); const docs = path.join(root, "docs/p6"); const read = (name) => JSON.parse(fs.readFileSync(path.join(docs, name), "utf8")); const kernel = read("jtreader-action-03-kernel.json"); const recovery = read("jtreader-action-03-recovery.json"); const facade = read("jtreader-action-03-facade.json"); const chrome = read("jtreader-action-03-chrome.json"); const contracts = { C: kernel, D: recovery, E: facade, F: chrome }; const status = Object.values(contracts).every((item) => item.result === "pass") ? "pass" : "fail"; const roundTrip = kernel.resultSummary; const report = { schema: "freecad-web-p6-jtreader-action-03-persistence/v1", taskId: "FW-P6-JTR-ACT-03-G", module: "JtReader", action: "save/reopen", result: status, applicable: true, format: roundTrip.format, path: roundTrip.path, objectCount: roundTrip.objectCount, objectType: roundTrip.objectType, roundTrip: roundTrip.roundTrip, artifactSize: kernel.replay.first.size, replay: kernel.replay, contracts: Object.fromEntries(Object.entries(contracts).map(([step, value]) => [step, { result: value.result, sha256: crypto.createHash("sha256").update(JSON.stringify(value)).digest("hex") }])), state: { documentMutation: true, resourcesReleased: roundTrip.resourcesReleased && recovery.recovery.resourcesReleased, recoveryStateUnchanged: recovery.state.unchanged && recovery.state.recovered, facadeCancelUnchanged: facade.state.unchangedAfterCancel, externalRequests: chrome.network.externalRequestCount, runtimeExceptions: chrome.exceptions.length, }, commands: ["node tools/run_p6_jtreader_action03_persistence.mjs"], artifacts: { kernel: "docs/p6/jtreader-action-03-kernel.json", recovery: "docs/p6/jtreader-action-03-recovery.json", facade: "docs/p6/jtreader-action-03-facade.json", chrome: "docs/p6/jtreader-action-03-chrome.json", screenshot: "docs/p6/jtreader-action-03-chrome.png", workerLog: "docs/freecad-p6-jtreader-action-03-g-persistence.log", }, boundaries: [ "Only the deterministic App::InventorObject FCStd fixture is covered.", "Archive byte size may vary with FCStd metadata; semantic object/attribute round-trip is the stable contract.", "Cross-version FCStd migration, multi-object persistence, and GUI document state remain out of scope.", ], }; fs.writeFileSync(path.join(docs, "jtreader-action-03-persistence.json"), `${JSON.stringify(report, null, 2)}\n`); fs.writeFileSync(path.join(root, "docs/freecad-p6-jtreader-action-03-g-persistence.log"), `${JSON.stringify({ result: report.result, applicable: report.applicable, roundTrip: report.roundTrip, objectCount: report.objectCount, objectType: report.objectType, externalRequests: report.state.externalRequests })}\n`); console.log(JSON.stringify({ result: report.result, applicable: report.applicable, roundTrip: report.roundTrip }));