72 lines
3.5 KiB
JavaScript
72 lines
3.5 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
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 docs = path.join(root, "docs");
|
|
const p6 = path.join(docs, "p6");
|
|
const read = (file) => JSON.parse(fs.readFileSync(path.join(p6, file), "utf8"));
|
|
const hash = (file) => crypto.createHash("sha256").update(fs.readFileSync(path.join(p6, file))).digest("hex");
|
|
const chrome = read("core-shell-chrome.json");
|
|
const cases = Object.fromEntries(chrome.cases.map((item) => [item.id, item]));
|
|
const required = ["core-ready", "core-action", "core-duplicate", "core-expected-error", "core-cancel", "core-reset", "core-repeat"];
|
|
const action = cases["core-action"]?.state;
|
|
const native = action?.response?.result?.native;
|
|
const contracts = Object.fromEntries(required.map((id) => [id, {
|
|
status: cases[id]?.status ?? "missing",
|
|
stage: cases[id]?.state?.stage ?? "missing",
|
|
responseKind: cases[id]?.state?.response?.kind ?? null,
|
|
error: cases[id]?.state?.response?.error?.code ?? null,
|
|
progressEvents: cases[id]?.state?.progress?.length ?? 0,
|
|
}]));
|
|
const result = chrome.result === "pass"
|
|
&& required.every((id) => cases[id]?.status === "pass")
|
|
&& action?.stage === "success"
|
|
&& action?.response?.kind === "result"
|
|
&& action?.progress?.length === 3
|
|
&& cases["core-duplicate"]?.state?.response?.error?.code === "duplicate_request"
|
|
&& cases["core-cancel"]?.state?.response?.error?.code === "cancelled"
|
|
&& native?.recomputeCount === 1
|
|
&& native?.transactionUndoVolume > 0
|
|
&& native?.transactionRedoVolume > native?.transactionUndoVolume;
|
|
const report = {
|
|
schema: "freecad-web-p6-core-shell-gate/v1",
|
|
taskId: "FW-P6-FPA-B",
|
|
result: result ? "pass" : "fail",
|
|
contracts,
|
|
native: {
|
|
document: action?.response?.result?.document ?? null,
|
|
values: native ?? null,
|
|
resourcesReleased: action?.response?.result?.resourcesReleased ?? false,
|
|
},
|
|
chrome: {
|
|
artifact: "docs/p6/core-shell-chrome.json",
|
|
sha256: hash("core-shell-chrome.json"),
|
|
screenshot: chrome.evidence?.screenshot ?? null,
|
|
screenshotSha256: chrome.evidence?.screenshotSha256 ?? null,
|
|
browser: chrome.chrome?.version ?? null,
|
|
externalRequests: chrome.cases.flatMap((item) => item.externalRequests ?? []).length,
|
|
exceptions: chrome.cases.flatMap((item) => item.exceptions ?? []).length,
|
|
},
|
|
architecture: {
|
|
schema: "freecad-web-core/v1",
|
|
worker: "web/src/core.worker.ts",
|
|
runtime: "web/src/core-runtime.ts",
|
|
shell: "web/src/core-shell.tsx",
|
|
nativeProbe: "FreeCADWebDocumentProbe",
|
|
queue: "one serial queue per Worker; duplicate and cancellation are typed terminal events",
|
|
},
|
|
boundaries: [
|
|
"B closes the reusable React/Worker/Document actor substrate and one native multi-step contract only.",
|
|
"403 object types, 236 format records, full FCStd graph coverage, and the 13,385 Python API dispositions remain later cards.",
|
|
"The page does not claim desktop GUI or arbitrary Python execution.",
|
|
],
|
|
};
|
|
fs.writeFileSync(path.join(p6, "core-shell-gate.json"), `${JSON.stringify(report, null, 2)}\n`);
|
|
fs.writeFileSync(path.join(docs, "freecad-p6-core-shell-gate.log"), `${JSON.stringify({ result: report.result, cases: required.length, externalRequests: report.chrome.externalRequests, exceptions: report.chrome.exceptions })}\n`);
|
|
console.log(JSON.stringify({ result: report.result, cases: required.length, externalRequests: report.chrome.externalRequests, exceptions: report.chrome.exceptions }));
|
|
if (!result) process.exitCode = 1;
|