import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import { createRequire } from "node:module"; import { pathToFileURL } from "node:url"; const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), ".."); const build = path.resolve(process.argv[2] || path.join(root, "freecad-source/build-web/cloud-configure-r2/bin")); globalThis.__dirname = `${build}${path.sep}`; globalThis.require = createRequire(import.meta.url); const loader = await import(pathToFileURL(path.join(build, "FreeCADWebCloudKernelProbe.js")).href); const kernel = await loader.default({ wasmBinary: fs.readFileSync(path.join(build, "FreeCADWebCloudKernelProbe.wasm")) }); const record = { apiId: "py:Cloud:class:CloudWorkbench", name: "CloudWorkbench", family: "generic-object" }; const request = { cmd: "cloud.pythonFamilyBatch", args: { tier: "tier-1-readonly", records: [record] } }; const invoke = (value) => JSON.parse(String(kernel.ccall("fc_web_dispatch_json", "string", ["string"], [JSON.stringify(value)]))); const success = invoke(request); const repeated = invoke(request); const invalid = invoke({ cmd: "cloud.pythonFamilyBatch", args: { tier: "tier-1-readonly", records: [{ ...record, apiId: "py:BIM:class:CloudWorkbench" }] } }); const malformed = invoke({ cmd: "cloud.pythonFamilyBatch", args: { tier: "tier-2-pure", records: [record] } }); if (success.ok !== true || success.module !== "Cloud" || success.count !== 1 || success.resourcesReleased !== true) throw new Error("Cloud family dispatch did not return a complete result"); const result = success.records[0]; if (result.status !== "restricted" || result.code !== "gui_dependency_unavailable" || result.native !== true) throw new Error(`unexpected Cloud family status: ${JSON.stringify(result)}`); if (JSON.stringify(repeated) !== JSON.stringify(success)) throw new Error("Cloud family replay changed the native result"); if (invalid.ok !== true || invalid.records?.[0]?.status !== "not_implemented" || invalid.records?.[0]?.code !== "unmatched_source_record") throw new Error("module-scoped mismatch was not rejected"); if (malformed.ok !== false || malformed.code !== "invalid_request") throw new Error("invalid tier was not rejected"); const hash = (value) => crypto.createHash("sha256").update(JSON.stringify(value)).digest("hex"); const report = { schema: "freecad-web-p6-cloud-tier1-readonly-family/v1", taskId: "FW-P6-FPA-F1-CLOUD", module: "Cloud", tier: "tier-1-readonly", status: "pass_with_restricted", sourceRevision: "b5a086fda59b0325fe0996147e6e9b344414f9bc", sourceEntry: "src/Mod/Cloud/InitGui.py:8", route: { worker: "web/src/cloud.worker.ts", command: "cloud.pythonFamilyBatch", native: "freecad-source/src/WebAssembly/FreeCADCoreProbe/CloudKernelProbe.cpp:644" }, input: request, inputSha256: hash(request), result: success, resultSha256: hash(success), replay: { equal: true, resultSha256: hash(repeated) }, invalidRecord: { result: invalid, resultSha256: hash(invalid) }, malformedRequest: { result: malformed, resultSha256: hash(malformed) }, resources: { resourcesReleased: true, documentMutation: false }, disposition: { apiId: record.apiId, status: result.status, code: result.code, evidenceSha256: hash(result) }, boundaries: ["CloudWorkbench is declared by the GUI InitGui.py surface and is restricted without FreeCADGui.", "The classification is returned by compiled FreeCAD WebAssembly through fc_web_dispatch_json.", "No JavaScript geometry, API result, or cross-module name match is used."] }; fs.writeFileSync(path.join(root, "docs/p6/cloud-tier1-readonly-family.json"), `${JSON.stringify(report, null, 2)}\n`); fs.writeFileSync(path.join(root, "docs/freecad-p6-cloud-tier1-readonly-family.log"), `${JSON.stringify({ status: report.status, apiId: record.apiId, disposition: result.status, resultSha256: report.resultSha256 })}\n`); console.log(JSON.stringify({ status: report.status, apiId: record.apiId, disposition: result.status, resultSha256: report.resultSha256 }));