import assert from "node:assert/strict"; import { createFullLinuxCncExecutionBoundary } from "../../app/src/runtime/full-execution-boundary.js"; const blocked = createFullLinuxCncExecutionBoundary({}); assert.equal(blocked.apiName, "web-rtcp-5axis-full-linuxcnc-execution-boundary"); assert.equal(blocked.phase, "blocked"); assert.equal(blocked.promotionAllowed, false); assert.equal(blocked.fullLinuxCncProgramExecutionReady, false); assert.equal(blocked.missing.includes("linuxcnc kinematics WASM frame"), true); assert.equal(blocked.blockers.some((blocker) => blocker.includes("LinuxCNC task runtime")), true); const canonicalState = { machineProfile: "xyzac-trt", linuxCncBoundaryAdapter: { linuxCncKinematicsReady: true, linuxCncInterpreterReady: true, }, rtcpFrame: { semanticBoundary: "linuxcnc_kinematics_wasm_c_abi", readiness: { linuxCncKinematicsReady: true }, }, interpreterRuntimeReadiness: { loaded: true, semanticBoundary: "linuxcnc_interpreter_wasm_canonical_events", }, programExecutionSourceMode: "linuxcnc-interpreter-wasm", programExecution: { sourceMode: "linuxcnc-interpreter-wasm", summary: { motionEventCount: 3, canonicalEventCount: 8, }, }, }; const canonical = createFullLinuxCncExecutionBoundary(canonicalState); assert.equal(canonical.readyForUiSimulation, true); assert.equal(canonical.machineFileBackedRemapReady, false); assert.equal(canonical.semanticBoundary, "linuxcnc_interpreter_canonical_ready_planner_task_hal_blocked"); assert.equal(canonical.satisfied.includes("canonical-motion-events"), true); assert.equal(canonical.plannerRuntimeReady, false); assert.equal(canonical.missing.includes("machine-file backed five-axis remap run"), true); const canonicalWithPlanner = createFullLinuxCncExecutionBoundary({ ...canonicalState, programExecution: { ...canonicalState.programExecution, plannerTiming: { plannerRuntimeReady: true, semanticBoundary: "linuxcnc_tp_queue_runtime_timing_from_canonical_motion", }, summary: { ...canonicalState.programExecution.summary, plannerRuntimeReady: true, }, }, }); assert.equal(canonicalWithPlanner.plannerRuntimeReady, true); assert.equal(canonicalWithPlanner.satisfied.includes("linuxcnc-tp-queue-runtime-timing"), true); assert.equal(canonicalWithPlanner.nativeTaskReady, false); assert.equal(canonicalWithPlanner.nativeHalSyncReady, false); const remap = createFullLinuxCncExecutionBoundary({ ...canonicalState, programExecution: { ...canonicalState.programExecution, plannerTiming: { plannerRuntimeReady: true, semanticBoundary: "linuxcnc_tp_queue_runtime_timing_from_canonical_motion", }, summary: { ...canonicalState.programExecution.summary, plannerRuntimeReady: true, }, }, machineFileStaging: { status: "staged", fileCount: 12, }, machineFileExecution: { sourceMode: "linuxcnc-machine-file-remap-wasm", summary: { machineFileExecutionReady: true, }, resultText: [ "fiveaxis_ini_open=1", "fiveaxis_remaps_ready=1", "fiveaxis_file_reached_exit=1", "fiveaxis_hal_switchkins: rc=0 found=1 value=0", ].join("\n"), }, }); assert.equal(remap.machineFileBackedRemapReady, true); assert.equal(remap.remapRuntimeReady, true); assert.equal(remap.halSwitchkinsEvidenceReady, true); assert.equal(remap.plannerRuntimeReady, true); assert.equal(remap.nativeTaskReady, false); assert.equal(remap.nativeHalSyncReady, false); assert.equal(remap.fullLinuxCncProgramExecutionReady, false); assert.equal(remap.promotionAllowed, false); assert.equal(remap.semanticBoundary, "linuxcnc_machine_file_remap_ready_planner_task_hal_blocked"); assert.equal(remap.satisfied.includes("fiveaxis-remap-machine-file-run"), true); assert.equal(remap.evidence.machineFileFlags.length, 3); const taskHalPromoted = createFullLinuxCncExecutionBoundary({ ...canonicalState, programExecution: remap.programExecution || { ...canonicalState.programExecution, plannerTiming: { plannerRuntimeReady: true, semanticBoundary: "linuxcnc_tp_queue_runtime_timing_from_canonical_motion", }, summary: { ...canonicalState.programExecution.summary, plannerRuntimeReady: true, }, }, machineFileStaging: { status: "staged", fileCount: 12, }, machineFileExecution: remap.evidence ? { sourceMode: "linuxcnc-machine-file-remap-wasm", summary: { machineFileExecutionReady: true }, resultText: [ "fiveaxis_ini_open=1", "fiveaxis_remaps_ready=1", "fiveaxis_file_reached_exit=1", "fiveaxis_hal_switchkins: rc=0 found=1 value=1", ].join("\n"), } : null, taskHalRuntimeReadiness: { taskRuntimeReady: true, motionRuntimeReady: true, halRuntimeReady: true, halSyncReady: true, }, taskHalStatus: { summary: { taskRuntimeReady: true, motionRuntimeReady: true, halRuntimeReady: true, halSyncReady: true, taskHalComparisonReady: true, }, ui: { taskCycle: 2, servoCycle: 20, motionQueueDepth: 0, halChangedPinCount: 4, }, }, }); assert.equal(taskHalPromoted.semanticBoundary, "linuxcnc_task_motion_hal_wasm_simulation_runtime"); assert.equal(taskHalPromoted.nativeTaskReady, true); assert.equal(taskHalPromoted.nativeHalSyncReady, true); assert.equal(taskHalPromoted.fullLinuxCncProgramExecutionReady, true); assert.equal(taskHalPromoted.promotionAllowed, true); assert.equal(taskHalPromoted.hardwareDrive, false); assert.equal(taskHalPromoted.hostRealtimeKernel, false); assert.equal(taskHalPromoted.externalUserMProcessReady, false); assert.equal(taskHalPromoted.toolDbProcessReady, false); assert.equal(taskHalPromoted.evidence.taskCycle, 2); console.log("full_execution_boundary_smoke=ok");