# LinuxCNC Web/WASM 唯一来源迁移计划 ## 目标 Web 仿真的行为、预览、轨迹、状态和错误必须由 LinuxCNC 源码编译出的 WASM core 决定。React/UI 只负责输入和渲染;Worker 只负责协议、生命周期和快照转发;不得由 JavaScript 重复解释 G-code、复制 TP/kinematics 规则或伪造 canonical state。 ## 来源分层 | 层 | 唯一来源 | Web 允许做什么 | 禁止做什么 | |---|---|---|---| | RS274 | `wasm-core/src/sim_interpreter.c` 与 LinuxCNC `rs274ngc` | 分配内存、读取状态 | JS 重新解析 G/M/O 词 | | Canonical motion | WASM interpreter motion event API | 排序、序列化协议 | JS 推导圆弧/整圆/终点 | | TP/motion | `sim_motion_queue` / `sim_kinematics_motion` WASM API | 调用 tick、读取 sample | JS 插值、速度、队列进度 | | Task | `sim_task` WASM state/canonical | 映射按钮状态 | JS 自己改变任务状态 | | HAL/IO/tool/probe | WASM runtime canonical | 显示/转发事件 | JS 模拟设备结果 | | UI | React | 发送命令、渲染 snapshot | 直接成为 authority | ## 任务安排 ### T0 基线审计和门禁 输入:WASM exports、Worker/React source、现有 native/WASM/Worker reports。 产出:来源审计报告、JS authority 清单、当前功能矩阵、固定 3-axis baseline hash。 验收:报告能明确列出每个用户可见行为的唯一来源;现有 `3dtest.ngc` Web/native baseline 可重复。 停止条件:来源或 ABI 不明确时,不把 JS fallback 标为 WASM parity。 ### T1 WASM canonical motion event 输入:`sim_interpreter` state/modal implementation、LinuxCNC `rs274ngc` canonical callbacks、posemath segment types。 产出:WASM `sim_interpreter_read_motion`/motion-event buffer,覆盖 G0/G1/G2/G3、G17/G18/G19、IJK/R、G20/G21、G90/G91、螺旋轴变化和 source line。 验收:C native test、WASM test、Worker test 对同一程序输出相同 segment count、source line、端点、center、normal、turn、units 和 hash。 ### T2 WASM-backed preview 输入:T1 motion events。 产出:Worker `PROGRAM_PREVIEW`,React 只消费 snapshot/toolpath;删除 `previewGcode` 作为行为来源。 验收:`3dtest.ngc` 三个整圆和 XYZ extents 与原生 AXIS 对齐;无 WASM event 时 fail closed,不回退到 JS 解析器。 ### T3 WASM-backed visible execution 输入:T1 events、WASM TP/kinematics/motion APIs。 产出:运行、暂停、恢复、单步、停止、末段排空全部由 WASM tick/queue state 驱动;移除 `AuthoritativeRuntime` 的运动 authority。 验收:浏览器点击 Power/Home All/Run 后 DRO、当前行、Three.js tool pose、queue depth、最终 M2 endpoint 与 native sequence 对齐。 ### T4 WASM canonical state 输入:WASM task/motion/HAL/IO/tool/probe canonical APIs。 产出:Worker snapshot 只转发 WASM canonical;React gate 只读取 snapshot;逐轴 home、limit、estop、tool、spindle、coolant、probe 状态一致。 验收:snapshot hash、event hash、checkpoint/recovery hash 在 native/WASM/Worker 重复运行中稳定。 ### T5 完整功能矩阵 输入:LinuxCNC source inventory、unit tests、真实 INI/HAL/NGC fixtures。 产出:按 RS274、TP、kinematics、HAL、IO、Python/remap、配置、恢复、浏览器 UX 分层的 native/WASM/Worker matrix。 验收:每项为 `verified`、`blocked` 或 `queued`,均有 owner、输入、测试、差异和停止原因;不允许用 selected-case 结果覆盖全量。 ### T6 功能闭合 按矩阵逐项实现:RS274 G/M/O/canned/compensation,TP blend/exact-stop/accel/jerk,HAL component/PLC,IO/tool/probe,Python/remap/filter/VCP,配置资源和恢复边界。 每一项必须先有 LinuxCNC source reference,再有 WASM C test,再接 Worker/UI;任何宿主进程、动态库、真实设备或墙钟行为保持排除。 ### T7 发布门禁 必须同时通过:WASM build、CTest、native source adapters、Worker tests、React typecheck/build、浏览器可见执行、native AXIS screenshot、功能矩阵和 release closure。仍有 `STOP_RELEASE` blocker 时只能报告 blocked,不能宣称完成。 ## 当前执行状态 `T0` 已完成:来源审计报告为 `coverage/wasm-only-source-audit.report.json`,selected-case baseline 通过但整体保持 blocked。 `T1` 已完成第一切片:`sim_interpreter_read_motion` 和 `sim_interpreter_motion_size` 已导出,Worker `ProgramRunner` 能读取 WASM canonical segment;native/WASM interpreter test 和 `web/worker/test_wasm_motion_event.mjs` 通过。T1 的完整覆盖仍需补齐 R 弧、螺旋、同步运动和 canonical queue 排序。 当前 `T2` 的 selected-case 切片已完成:`PROGRAM_LOAD` 返回 WASM canonical preview segments,React 只消费 Worker toolpath;`visual-workflow.ts` 不再参与行为预览。T2 仍需扩展到完整 canonical callback、canned cycle、R 弧、同步运动和所有配置族。 `T3` 的 selected-case 切片已完成:WASM motion queue 接收 interpreter canonical segments,负责固定 tick 的 position/velocity/queue depth;`3axis-tutorial` trivkins 运行路径不调用 `AuthoritativeRuntime.syncProgram/step/applyMotion`,pause/resume、PROGRAM_STEP、abort 和末段排空均由 queue 状态驱动。queue raw state、active segment、tick、controls、position 和 hash 已纳入 checkpoint、trace/workspace state;恢复 replay 与连续 endpoint hash 相同,损坏 queue state fail-closed。Worker snapshot 公开 `motion_authority: wasm` 与 `source: wasm_motion_queue`。JS `AuthoritativeRuntime` 仍只作为非 selected-case/非 trivkins 兼容镜像,`program-runner`/`motion-state`/`sim-task` 的其它 canonical state 仍待 T4/T5;因此整体 source-of-truth audit 仍为 blocked。 `T4` selected-case 切片已完成:Worker `SimTask` 通过 `sim_task_canonical` 读取 WASM task state,`WasmHomeLimit` 通过锁定 `sim_kinematics_home_limit_*` ABI 读取 trivkins home/limit state;snapshot、checkpoint、trace/import 和 recovery 都带 task/home-limit authority、state hash 和 logical tick。JS task tamper 不覆盖 WASM canonical state,损坏 home-limit bytes fail-closed。HAL/IO/tool/probe canonical state、外部设备 limit 输入和非 selected-case compatibility 仍保持开放,整体 audit 仍 blocked。 `T5` 已生成 `coverage/wasm-feature-matrix-t5.report.json`:RS274、TP、kinematics、HAL、IO、Python/remap、configuration、recovery、browser UX 九个领域均有 native/WASM/Worker 行、输入 hash、测试命令、覆盖样本、差异和停止原因。对照 LinuxCNC AXIS 源码修复空/缺失 `OPEN_FILE` 语义并将缺失 HALFILE 分类为 `BLOCKED_HAL` 后,235-case matrix 恢复 verified,分类为 `BLOCKED_HAL=106/BLOCKED_RESOURCE=11/TASK_READY=96`;完整 oracle、配置资源、三浏览器 minimum 和物理 OPFS recovery 仍 blocked,不将 selected-case 结果提升为全量 parity。 `T6` 已完成 source-backed closure audit,但保持 `blocked`:八个矩阵 closure row 均有真实 source reference、可执行 WASM/Worker slice 和 23 个通过的专项命令,另保留 4 个 failure samples。完整 RS274/TP/kinematics 仍缺官方 oracle,配置仍有 exact-resource blockers,HAL/IO/Python 仍受 REAL-EXCLUDED 能力边界限制,恢复和浏览器仍缺物理 OPFS/三浏览器输入;没有使用 JS fallback 或 selected-case promotion。 `T7` 已完成 simulation-track 的只读 release-gate audit,报告为 `blocked`:T6 closure、既有 release/remediation evidence、owner refresh 和六项 blocker identity 均核对通过,但 candidate 仍不可 eligible、`STOP_RELEASE` 保持。该 audit 不刷新 K8 gate、不修改 context lock、manifest、许可证或 owner decision;没有新输入时不自动重试或升级 release。 源语义已固化为 `coverage/linuxcnc-source-semantics-contract.json` 与 `web/workspace/linuxcnc-source-semantics.mjs`,供后续 Web 控制面板直接复用。控制面板只能投影 Worker 的 startup snapshot;`OPEN_FILE`/`INTRO_GRAPHIC` optional、`BLOCKED_HAL`/`BLOCKED_RESOURCE` 分类、exact-path 和 runtime fixture policy 均由该契约决定。