const MACHINE_FILE_FLAGS = [ "fiveaxis_ini_open=1", "fiveaxis_remaps_ready=1", "fiveaxis_file_reached_exit=1", ]; export function createFullLinuxCncExecutionBoundary(state = {}) { const adapter = state.linuxCncBoundaryAdapter || {}; const frame = state.rtcpFrame || {}; const programExecution = state.programExecution || null; const machineFileExecution = state.machineFileExecution || null; const machineFileText = String(machineFileExecution?.resultText || ""); const kinematicsReady = Boolean( adapter.linuxCncKinematicsReady || frame.readiness?.linuxCncKinematicsReady, ); const interpreterReady = Boolean( adapter.linuxCncInterpreterReady || state.interpreterRuntimeReadiness?.loaded, ); const canonicalProgramReady = Boolean( programExecution?.sourceMode === "linuxcnc-interpreter-wasm" && programExecution?.summary?.motionEventCount > 0, ); const machineFileStagingReady = state.machineFileStaging?.status === "staged" && state.machineFileStaging?.fileCount > 0; const machineFileRemapReady = Boolean( machineFileExecution?.sourceMode === "linuxcnc-machine-file-remap-wasm" && machineFileExecution?.summary?.machineFileExecutionReady === true, ); const remapRuntimeReady = Boolean( machineFileExecution?.summary?.remapRuntimeReady === true || MACHINE_FILE_FLAGS.every((flag) => machineFileText.includes(flag)), ); const plannerRuntimeReady = Boolean( programExecution?.summary?.plannerRuntimeReady === true && programExecution?.plannerTiming?.plannerRuntimeReady === true, ); const halSwitchkinsEvidenceReady = machineFileText.includes("fiveaxis_hal_switchkins: rc=0 found=1"); const taskHalSummary = state.taskHalStatus?.summary || {}; const taskRuntimeReady = Boolean( taskHalSummary.taskRuntimeReady === true || state.taskHalRuntimeReadiness?.taskRuntimeReady === true, ); const motionRuntimeReady = Boolean( taskHalSummary.motionRuntimeReady === true || state.taskHalRuntimeReadiness?.motionRuntimeReady === true, ); const halRuntimeReady = Boolean( taskHalSummary.halRuntimeReady === true || state.taskHalRuntimeReadiness?.halRuntimeReady === true, ); const halSyncReady = Boolean( taskHalSummary.halSyncReady === true || state.taskHalRuntimeReadiness?.halSyncReady === true, ); const taskHalComparisonReady = Boolean(taskHalSummary.taskHalComparisonReady === true); const nativeTaskReady = taskRuntimeReady; const nativeHalSyncReady = halRuntimeReady && motionRuntimeReady && halSyncReady; const toolDbReadiness = state.toolDbReadiness || {}; const controlledUserMReadiness = state.controlledUserMReadiness || {}; const toolDbProcessReady = toolDbReadiness.toolDbProcessReady === true; const externalUserMProcessReady = controlledUserMReadiness.externalUserMProcessReady === true; const fullLinuxCncProgramExecutionReady = Boolean( kinematicsReady && interpreterReady && canonicalProgramReady && machineFileStagingReady && machineFileRemapReady && plannerRuntimeReady && nativeTaskReady && nativeHalSyncReady && taskHalComparisonReady && toolDbProcessReady && externalUserMProcessReady ); const satisfied = [ kinematicsReady ? "linuxcnc-kinematics-wasm" : null, interpreterReady ? "linuxcnc-interpreter-wasm" : null, canonicalProgramReady ? "canonical-motion-events" : null, machineFileStagingReady ? "machine-file-staging" : null, machineFileRemapReady ? "fiveaxis-remap-machine-file-run" : null, plannerRuntimeReady ? "linuxcnc-tp-queue-runtime-timing" : null, halSwitchkinsEvidenceReady ? "switchkins-hal-bridge-evidence" : null, taskRuntimeReady ? "linuxcnc-task-runtime" : null, motionRuntimeReady ? "linuxcnc-motion-runtime" : null, halRuntimeReady ? "linuxcnc-hal-runtime" : null, halSyncReady ? "task-motion-hal-sync" : null, taskHalComparisonReady ? "task-hal-cycle-artifact" : null, toolDbProcessReady ? "tool-db-web-simulation" : null, externalUserMProcessReady ? "controlled-user-m-web-simulation" : null, ].filter(Boolean); const missing = []; if (!kinematicsReady) missing.push("linuxcnc kinematics WASM frame"); if (!interpreterReady) missing.push("linuxcnc interpreter WASM runtime"); if (!canonicalProgramReady) missing.push("linuxcnc canonical motion execution"); if (!machineFileStagingReady) missing.push("LinuxCNC machine-file staging"); if (!machineFileRemapReady) missing.push("machine-file backed five-axis remap run"); if (!plannerRuntimeReady) missing.push("LinuxCNC trajectory planner queue timing runtime"); if (!halSwitchkinsEvidenceReady) missing.push("switchkins HAL bridge evidence"); if (!taskRuntimeReady) missing.push("LinuxCNC task runtime"); if (!motionRuntimeReady) missing.push("LinuxCNC motion runtime"); if (!halRuntimeReady) missing.push("LinuxCNC HAL runtime"); if (!halSyncReady) missing.push("task/motion/HAL synchronization"); if (!taskHalComparisonReady) missing.push("task cycle and HAL servo cycle artifact"); if (!toolDbProcessReady) missing.push("tool DB Web/WASM simulation process"); if (!externalUserMProcessReady) missing.push("controlled user-M Web/WASM simulation process"); const blockers = []; if (!nativeTaskReady) blockers.push("LinuxCNC task runtime is not promoted"); if (!nativeHalSyncReady) blockers.push("realtime HAL synchronization is not promoted"); if (!toolDbProcessReady) blockers.push("tool DB Web simulation process is not ready"); if (!externalUserMProcessReady) blockers.push("controlled user-M Web simulation process is not ready"); blockers.push("host external user-M process and host tool DB process remain disabled; Web simulation boundary only"); if (!plannerRuntimeReady) { blockers.push("LinuxCNC trajectory planner queue is not promoted as browser runtime"); } return { apiName: "web-rtcp-5axis-full-linuxcnc-execution-boundary", profileId: state.machineProfile || adapter.profileId || "unknown", phase: fullLinuxCncProgramExecutionReady ? "linuxcnc-task-motion-hal-simulation-runtime" : machineFileRemapReady ? "partial-linuxcnc-remap-boundary" : canonicalProgramReady ? "canonical-interpreter-boundary" : "blocked", semanticBoundary: fullLinuxCncProgramExecutionReady ? "linuxcnc_task_motion_hal_wasm_simulation_runtime" : machineFileRemapReady ? "linuxcnc_machine_file_remap_ready_planner_task_hal_blocked" : canonicalProgramReady ? "linuxcnc_interpreter_canonical_ready_planner_task_hal_blocked" : "linuxcnc_full_execution_boundary_blocked", sourceMode: machineFileRemapReady ? "linuxcnc-machine-file-remap-wasm" : programExecution?.sourceMode || state.programExecutionSourceMode || "fixture-line-playback", readyForUiSimulation: kinematicsReady && interpreterReady && canonicalProgramReady, machineFileBackedRemapReady: machineFileRemapReady, remapRuntimeReady, halSwitchkinsEvidenceReady, plannerRuntimeReady, taskRuntimeReady, motionRuntimeReady, halRuntimeReady, halSyncReady, taskHalComparisonReady, nativeTaskReady, nativeHalSyncReady, fullLinuxCncProgramExecutionReady, promotionAllowed: fullLinuxCncProgramExecutionReady, hardwareDrive: false, hostRealtimeKernel: false, externalUserMProcessReady, externalUserMProcessScope: externalUserMProcessReady ? "web_simulation_only" : "not_ready", toolDbProcessReady, toolDbProcessScope: toolDbProcessReady ? "web_simulation_only" : "not_ready", hostExternalUserMProcessReady: false, hostToolDbProcessReady: false, arbitraryUserMExecution: false, satisfied, missing, blockers, evidence: { kinematics: kinematicsReady ? frame.semanticBoundary || adapter.semanticBoundary : null, interpreter: interpreterReady ? state.interpreterRuntimeReadiness?.semanticBoundary || adapter.semanticBoundary : null, canonicalMotionEvents: programExecution?.summary?.motionEventCount || 0, canonicalEventCount: programExecution?.summary?.canonicalEventCount || 0, plannerTiming: plannerRuntimeReady ? programExecution.plannerTiming?.semanticBoundary : null, machineFileFlags: MACHINE_FILE_FLAGS.filter((flag) => machineFileText.includes(flag)), machineFileExecutionReady: machineFileExecution?.summary?.machineFileExecutionReady === true, remapRuntimeReady, stagedFileCount: state.machineFileStaging?.fileCount || 0, taskHal: taskHalSummary, taskCycle: state.taskHalStatus?.ui?.taskCycle || 0, servoCycle: state.taskHalStatus?.ui?.servoCycle || 0, motionQueueDepth: state.taskHalStatus?.ui?.motionQueueDepth || 0, halChangedPinCount: state.taskHalStatus?.ui?.halChangedPinCount || 0, toolDb: toolDbReadiness, controlledUserM: controlledUserMReadiness, }, }; }