Complete 3axis tutorial native and Web/WASM parity tools

This commit is contained in:
2026-08-24 14:01:30 +08:00
parent 938654b19d
commit 7e90142b63
147 changed files with 17639 additions and 557 deletions

View File

@@ -0,0 +1,285 @@
# 3axis Tutorial Web 控制面板源程序对标实施方案
## 目标
为固定案例 `linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini` 建立与 LinuxCNC AXIS 控制面板可观察行为一致的 Web 控制面板。
唯一运行时数据来源是 LinuxCNC 源码编译得到的 WASM core,以及由 Dedicated Worker 投影的 authoritative snapshot/event。React 只能发送命令、显示状态和呈现诊断;不得在浏览器端重新推导任务状态、运动轨迹、DRO、工具状态、门禁或错误结果。
本方案是固定案例的控制面板实施合同,不宣称全量 LinuxCNC、实时硬件或 release candidate。机器可读的源语义规则见 [`coverage/linuxcnc-source-semantics-contract.json`](../coverage/linuxcnc-source-semantics-contract.json),共享实现见 [`web/workspace/linuxcnc-source-semantics.mjs`](../web/workspace/linuxcnc-source-semantics.mjs)。
## 硬约束和功能矩阵
以下约束是所有 PANEL 任务的共同通过条件:
1. 网页控制面板的唯一数据来源是 LinuxCNC WASM;React 不得生成、修正或覆盖 canonical state。
2. 状态机严格对标 LinuxCNC 源程序;状态数值、迁移顺序、错误码和 gate reason 必须有 source line 和 WASM/Worker evidence。
3. 所有按钮逻辑制约必须与 LinuxCNC AXIS 源程序一致;按钮 disabled/enabled、模式切换、ESTOP/limit/fault gate 不允许由 UI 自行猜测。
4. 刀具路径预览必须来自 WASM canonical motion events,并与原生 LinuxCNC 的 segment 顺序、source line、端点、圆弧中心/法向、turn、units 和最终 hash 一致;没有 WASM event 时必须 fail-closed。
| # | 功能 | LinuxCNC 原生 | WASM 支持 | Web 实现状态 | 优先级 | 主要任务 |
|---:|---|:---:|:---:|---|:---:|---|
| 1 | 加载数控程序 | ✅ | ✅ | `PANEL-07` | P0 | `PROGRAM_LOAD`、exact source/hash、diagnostic |
| 2 | 刀具路径预览 | ✅ | ✅ | `PANEL-11` | P0 | WASM motion event、segment golden、no JS preview |
| 3 | 取消急停 | ✅ | ✅ | `PANEL-05` | P0 | `ESTOP_RESET`/recover source state transition |
| 4 | 上电 | ✅ | ✅ | `PANEL-05` | P0 | `STATE_OFF -> STATE_ON` and gate |
| 5 | 复位 | ✅ | ✅ | `PANEL-05`/`PANEL-12` | P0 | task reset、fault clear、checkpoint reconciliation |
| 6 | HOME 回零 | ✅ | ✅ | `PANEL-06` | P0 | individual/all home、home sequence、home-limit ABI |
| 7 | 执行 G 代码 | ✅ | ✅ | `PANEL-07` | P0 | run/pause/resume/step/abort/restart |
| 8 | 实时路径显示 | ✅ | ✅ | `PANEL-10` | P0 | authoritative pose/toolpath -> Three.js |
| 9 | 实时坐标显示 | ✅ | ✅ | `PANEL-08` | P0 | commanded/actual/relative DRO、units |
| 10 | MDI 功能 | ✅ | ✅ | `PANEL-07` | P1 | MDI mode、queue limit、active program rejection |
| 11 | JOG 功能 | ✅ | ✅ | `PANEL-06` | P1 | manual mode、continuous/incremental、stop |
| 12 | 按钮逻辑制约 | ✅ | ✅ | `PANEL-03` | P0 | complete AXIS gate matrix and error reasons |
表中的“Web 实现状态”在任务完成前只能是 `queued`、`in_progress` 或 `blocked`;现有 selected-case smoke/Worker evidence 不得自动把矩阵项标记为 `verified`。
### 功能项统一验收证据
每个矩阵项必须同时保存:LinuxCNC source path/line/hash、WASM export/state field、Worker command/event、React control ID、normal/boundary/error/ESTOP/recovery sample、native/WASM/Worker logical tick、输入/输出/state/event hash 和 self-hashed report。P0 项缺任一项即保持 `blocked`;P1 项不能阻塞 P0 实施,但不能被宣称完成。
## 源程序映射
| Web 控制面板区域 | LinuxCNC 源输入 | WASM/Worker 唯一来源 | React 允许行为 | 禁止行为 |
|---|---|---|---|---|
| 电源、急停、状态灯 | `axis.py` 状态更新、`linuxcnc` `STATE_*`/`MODE_*`/`INTERP_*` | `sim_task` canonical + `axis_state` | 显示、发送命令、显示 gate reason | 本地切换 ON/ESTOP |
| File/Program | `axis.py` `open_file_guts`, `reload_file`, `task_run` | WASM interpreter events + Worker program state | 编辑器输入、发送 LOAD/RUN/RESTART | JS 解析 G-code 或伪造当前行 |
| MDI | `axis.py` `ensure_mode`, `send_mdi_command` | WASM interpreter/task mode/queue | 提交文本、显示拒绝 | 本地判断 MDI 成功 |
| Manual/Jog/Home | `axis.py` `jog_plus`, `jog_minus`, `home_all_joints`, `home_joint` | WASM motion queue + home/limit ABI | 按钮、方向、速度输入 | JS 插值、修改 position/home |
| DRO/active codes | `axis.py` `update`, `task_modename`, `motion_modename`, `interp_statename` | WASM task/interpreter/motion snapshot | 格式化显示 | 从命令文本推导状态 |
| Feed/spindle override | `axis.py` `set_feedrate`, `set_spindlerate` | WASM/Worker device canonical | slider/number input | 直接修改 React store |
| Spindle/coolant/tool/probe | `axis.py` manual controls、案例 HAL、`sim_io` | WASM IO/device canonical | 显示、发送命令、fault recovery | mock device response |
| Preview/3D | `axis.py` preview/canon、案例 Vismach executable | WASM canonical motion + Worker visual snapshot | Three.js 渲染 | JS G-code preview/几何 authority |
| 配置诊断 | `linuxcnc-source-semantics-contract.v1` | Worker startup snapshot | 显示 `TASK_READY`/`BLOCKED_*`、source/line | basename 替换、隐藏缺失资源 |
源代码锚点:
- AXIS startup/open-file:`linuxcnc/src/emc/usr_intf/axis/scripts/axis.py` 约 3991-3998 行。
- AXIS status projection:同文件 `update`、`task_modename`、`motion_modename`、`interp_statename`。
- AXIS command gates:同文件 `ensure_mode`、`task_run`、`task_pause`、`task_resume`、`task_stop`、`jog_*`、`home_*`、`estop_clicked`。
- 参数文件和程序前缀:`linuxcnc/src/emc/rs274ngc/rs274ngc_pre.cc`、`linuxcnc/src/emc/task/emctask.cc`。
- 案例 UI/HAL/Vismach:`linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini`、`.hal` 和 `3axis-tutorial`。
## 控制面板数据契约
Worker 每次响应必须能追溯到同一个 `context_id`、`session_id`、`logical_tick` 和 `state_hash`。控制面板消费以下投影字段:
```yaml
snapshot:
task: wasm sim_task canonical state
program: WASM interpreter/program state
motion: WASM motion queue state
home_limit: WASM kinematics home/limit state
hal: static/virtual HAL projection with source diagnostics
devices: WASM sim_io/tool/spindle/coolant/probe state
configuration: startup state, exact resources, optional_missing, runtime_fixtures
axis_state: additive AXIS state/mode/interpreter view
visual: pose, joints, toolpath and Vismach pose projection
state_hash: hash of the canonical projection
```
每个命令必须携带 `operation_id`,并产生 pending/result/error event。UI gate 只读取上一份 authoritative snapshot;命令被拒绝时显示 Worker 返回的 stable error code、message key、source/line 和 gate reason。错误、ESTOP、limit、following-error、资源缺失和能力边界必须可见,不能变成静默 disabled。
### 分层接口责任
| 层 | 必须提供 | 允许缓存 | 不得提供 |
|---|---|---|---|
| LinuxCNC source/native recorder | 常量、状态迁移、命令顺序、错误/拒绝语义、segment golden | stdout/log/screenshot hash | 浏览器状态 |
| `wasm-core` | canonical task/interpreter/motion/home-limit/HAL/IO state、fixed tick、canonical event | raw ABI bytes、read-only sample | UI 文案或按钮 gate |
| Dedicated Worker | command ledger、session lifecycle、snapshot/event 转发、diagnostic/source line、checkpoint/trace | 序列化协议和 operation trace | JS authority mirror、JS G-code 解析 |
| React/Web panel | command input、snapshot projection、accessibility、visual rendering | 最近一份 snapshot 用于显示 | 改写 state、推导成功、推导轨迹 |
任何层违反责任都必须在测试中以 `authority_violation` 失败;“结果看起来一致”不能替代唯一来源证明。
### 面板命令 envelope
所有 P0/P1 命令使用已有 `protocol.v1` envelope,不为 UI 单独发明协议:
```json
{
"schema_version": 1,
"context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1",
"session_id": "axis3-panel",
"seq": 42,
"operation_id": "axis-program-run-000042",
"kind": "PROGRAM_RUN",
"payload": {}
}
```
响应至少包含 `kind`、`seq`、`operation_id`、`logical_tick`、`payload.task`、`payload.program`、`payload.motion`、`payload.axis_state`、`payload.state_hash`。错误响应必须包含 `code`、`message_key`、`source`/`line`(若有)、`gate_reason` 和拒绝时的完整 snapshot。
## 严格状态机和按钮真值表
源常量和 AXIS 视图必须使用 [`docs/linuxcnc-web-wasm-3axis-tutorial-state-machine.md`](linuxcnc-web-wasm-3axis-tutorial-state-machine.md) 中的数值,不得只使用同名字符串:
| AXIS 状态 | LinuxCNC source state | 允许的面板操作 | 必须拒绝 |
|---|---|---|---|
| `ESTOP` | `STATE_ESTOP` | cancel ESTOP、显示诊断 | power/home/run/MDI/JOG |
| `ESTOP_RESET` | `STATE_ESTOP_RESET` | power on、ESTOP | run/home/MDI/JOG |
| `OFF` | `STATE_OFF` | power/reset、ESTOP | run/home/MDI/JOG |
| `ON`/`IDLE` | `STATE_ON + INTERP_IDLE` | load/run/MDI/manual/home/jog/device | 与当前 mode/limit/fault 冲突的操作 |
| `HOME` | source home transient | 等待 home result、ESTOP | run/MDI/重复 home |
| `RUNNING` | `INTERP_READING/WAITING` | pause/abort/ESTOP | home/jog/MDI/load |
| `PAUSED` | `INTERP_PAUSED` | resume/abort/ESTOP/step(按源 gate) | home/jog/普通 MDI |
按钮 gate 的可执行真值样本必须至少包含:
| 操作 | 正常条件 | 拒绝样本 |
|---|---|---|
| 加载程序 | `ON + INTERP_IDLE` 或源允许的 manual load | `OFF`、`RUNNING`、资源缺失 |
| 预览 | WASM motion events 已存在 | WASM event 缺失、解析错误 |
| 取消急停 | `ESTOP`/`ESTOP_RESET` 按源状态转换 | snapshot 过期、seq/tick 错误 |
| 上电 | `ESTOP_RESET -> ON` 或源定义 reset 流程 | `ESTOP` 未 reset、fault latch |
| 复位 | abort/clear/recover 的源顺序 | active motion、坏 checkpoint |
| HOME | `ON + MANUAL + INTERP_IDLE` | `OFF`、AUTO/MDI、limit/fault、未满足 previous home |
| G-code run | `ON + AUTO + IDLE + taskfile` | 无程序、MDI、paused、ESTOP |
| 实时路径/DRO | snapshot tick/hash 可验证 | snapshot stale、state hash mismatch |
| MDI | `ON + MDI` 且 queue 未满 | AUTO active、queue full、ESTOP |
| JOG | `ON + MANUAL + IDLE` | AUTO/MDI、未 home、limit/fault |
## 刀具路径预览一致性算法
预览和执行都必须使用 WASM interpreter canonical motion event;Web 不得将原始 G-code 再解析一遍。每个 segment 的比较字段固定为:
```yaml
segment:
source_line: integer
motion_type: rapid|linear|arc
start: pose(x,y,z,a,b,c,u,v,w)
end: pose(x,y,z,a,b,c,u,v,w)
center: pose_or_null
normal: vector_or_null
turn: integer
velocity: finite_number
units: mm|inch
plane: G17|G18|G19
sequence: integer
```
验收顺序:
1. native recorder 使用固定程序和固定 units/modal 初始状态生成 segment JSONL。
2. WASM `sim_interpreter_read_motion` 生成同字段事件;Worker 只排序/封装,不补字段。
3. 比较 segment count、source line、顺序、字段值和 canonical hash;浮点比较使用 source/ABI 规定的 exact或明确 tolerance,不能用截图相似度替代。
4. Three.js 只渲染已比较的 `visual` projection;canvas 非空是必要条件,不是轨迹正确性的充分条件。
5. 任意字段首差必须记录 `first_divergent_segment`、`source_line`、`logical_tick`、`field`、`native`、`wasm`,并阻止 preview/execute 继续宣称一致。
禁止条件:WASM event buffer 为空时调用 JS `previewGcode`;用当前 DRO 终点反推完整路径;用 native screenshot 通过 Web segment hash;用墙钟时间推进路径。
## 功能矩阵报告模板
每个功能项使用同一结构,便于控制面板任务和后续自动聚合:
```yaml
feature_id: PANEL-07
matrix_item: execute_gcode
priority: P0
status: queued|in_progress|verified|blocked
source:
paths: []
lines: []
sha256: []
authority:
wasm_exports: []
canonical_fields: []
worker:
commands: []
events: []
react:
control_ids: []
projection_fields: []
samples:
normal: []
boundary: []
error: []
estop_or_fault: []
recovery: []
comparison:
native_hash: null
wasm_hash: null
worker_hash: null
first_divergent_tick: null
stop_reason: null
report_sha256: null
```
`verified` 只允许在 `source`、`authority`、`worker`、`react`、5 类 samples、comparison 和 self-hash 全部存在时使用。任何 `REAL-EXCLUDED`、`SOURCE_BLOCKED`、`WASM_CAPABILITY_BLOCKED` 都必须保持 `blocked`,并带 failure sample。
## 面板布局和交互范围
桌面和移动布局都必须保持以下固定区域,不因动态文字改变尺寸:
1. 顶栏:案例名、WASM capability、连接/session、`TASK_READY`/`BLOCKED`、ESTOP 和 recover。
2. 左侧状态:machine power、task mode、interp state、program status、current line、logical tick、state hash。
3. 中央机床视图:Three.js Vismach 3-axis model、tool pose、joints、limits、toolpath、axis labels。
4. 右侧 DRO:commanded/actual/relative 的 X/Y/Z、unit、feed/spindle override、active G/M codes。
5. 下方 tabs:Manual、MDI、Program、Diagnostics;每个 tab 的控件 gate 来自 Worker snapshot。
6. 操作条:Home all/individual、jog +/-/stop、Run/Pause/Resume/Step/Abort/Restart、spindle/coolant/tool/probe/ESTOP。
7. 诊断面板:按事件顺序显示 source path、line、code、reason、first divergent tick、recovery status。
熟悉符号使用 AXIS 源图标或 lucide icon;按钮必须有 accessible name、disabled reason 和 keyboard path。控件不能仅通过颜色表示 fault/ESTOP。
## 功能缺口移植流程
当 WASM/Worker 当前能力不满足 AXIS 行为时,严格按以下顺序处理:
1. 从 LinuxCNC 源文件定位函数、状态常量、命令顺序和错误语义,记录 source path、line、source hash。
2. 判断是否属于纯仿真可移植行为。实时内核、真实硬件、宿主动态 loader、宿主 GUI/Python 进程只能登记 `REAL-EXCLUDED`/`HOST_EXCLUDED`,不能伪造 WASM parity。
3. 先增加 native source sample 和失败测试,再在 `wasm-core` 增加 C ABI/状态实现;ABI 变更必须建立新 context,不能就地改锁定 ABI。
4. 增加真实 WASM module 测试,再接 `web/worker` adapter;Worker 只投影 WASM canonical,不保留 JS authority 镜像。
5. 最后接 React 命令/渲染,补 normal、boundary、error、non-finite、capacity、pause/resume、ESTOP、recovery 样本。
6. 记录首个 divergent phase/tick、native/WASM/Worker hash、checkpoint/trace/recovery hash,更新 self-hashed report。
## 详细实施任务
### P0/P1 执行顺序
先完成 P0 的 authority、状态机、按钮 gate、程序加载/执行、preview、实时路径和实时坐标,再实现 P1 的 MDI/JOG 扩展。P0 任务之间按 `PANEL-01 -> PANEL-02 -> PANEL-03 -> PANEL-05 -> PANEL-06/PANEL-07 -> PANEL-08/PANEL-10/PANEL-11 -> PANEL-14 -> PANEL-15` 执行;P1 的 MDI/JOG 只能复用同一 WASM/Worker authority,不能另建一套 UI state。
P0 完成的硬条件:12 项矩阵中的 1-9、12 有 native source reference、真实 WASM module、Worker sequence 和 React evidence;刀具路径 preview 与 native canonical segments 的 hash/端点一致;所有按钮 gate 在正常、运行、暂停、MDI、ESTOP、limit、fault、未 home 和 queue-full 样本中一致。P1 完成的硬条件:10-11 的 MDI/JOG 与 P0 状态机、queue、home/limit、ESTOP gate 共用同一 snapshot,不能产生 divergent tick。
| ID | 任务 | 主要实现 | 直接源输入 | 验收输出 | 依赖 |
|---|---|---|---|---|---|
| `PANEL-01` | 源控件 inventory | 把 AXIS 菜单、toolbar、快捷键、Manual/MDI/Auto、DRO、诊断控件登记为稳定 IDs | `axis.py`、AXIS Tcl UI、案例 INI | source inventory + control ID contract | 无 |
| `PANEL-02` | snapshot projection contract | 固定 task/program/motion/home/hal/devices/configuration/axis_state/visual 字段、tick/hash 和 event envelope | `sim-session.mjs`、T4/T3 reports | schema-compatible projection test | 01 |
| `PANEL-03` | source gate matrix | 逐命令复刻 AXIS `ensure_mode`、状态和 gate;禁止 React 自判定 | `axis.py` command functions、`axis-contract.mjs` | gate matrix normal/error/ESTOP test | 01/02 |
| `PANEL-04` | startup/config panel | 显示 exact resources、optional `OPEN_FILE`/graphic、HAL/resource/INI diagnostics 和 runtime fixtures | source semantics contract、案例 INI/HAL | `TASK_READY`/`BLOCKED_*` UI test | 02 |
| `PANEL-05` | power/ESTOP/recover | 对齐 `STATE_OFF/ON/ESTOP/ESTOP_RESET` 和 recover transition | `axis.py`、`sim_task`、`sim_io` | transition/event/hash report | 02/03 |
| `PANEL-06` | Manual/Home/Jog | 对齐 individual/all home、continuous/incremental jog、stop、joint/teleop gate | `axis.py` `jog_*`/`home_*`、T4 home-limit | native/WASM/Worker sequence report | 03/05 |
| `PANEL-07` | Program/MDI | 对齐 open/load/reload/run/pause/resume/step/abort/restart/MDI queue and active-program rejection | `axis.py`、WASM interpreter/task | program control and current-line report | 03/05 |
| `PANEL-08` | DRO/active codes | 对齐 actual/commanded/relative、units、feed/spindle、active G/M/modal display | AXIS `update`/stat mixins、WASM snapshot | DRO golden and unit switch test | 02/06/07 |
| `PANEL-09` | device panels | 对齐 spindle ramp/at-speed, coolant, tool prepare/change, probe, limit/FERROR faults |案例 HAL、`sim_io`、tool-IO report | device fault/recovery report | 05/06/07 |
| `PANEL-10` | Vismach/3D | 按 `3axis-tutorial` Python model 和 HAL pins 实现 geometry/pose/tool continuity | 案例 executable、Vismach source、Three.js view | canvas pixel/nonblank/pose report | 02/06/08/09 |
| `PANEL-11` | editor/preview | Worker WASM preview、source line highlighting、active G-code 和 diagnostics | `sim_interpreter`、AXIS editor/preview | no-JS-preview test + source-line parity | 07/08 |
| `PANEL-12` | persistence/recovery UI | checkpoint, journal, trace import, `.var/.bak/position/tool.tbl` restart and fail-closed recovery | T4/T6 reports、workspace recovery | recovered endpoint and no duplicate side effects | 05/07/09 |
| `PANEL-13` | keyboard/accessibility/layout | AXIS shortcut mapping、focus order、ARIA、desktop/mobile no-overlap | AXIS shortcut table、React source | DOM/accessibility/visual report | 01/03/08/10/11 |
| `PANEL-14` | native/Worker/UI recorder | 同一 operation sequence、same logical ticks、first divergence and hash comparison | native runner、Dedicated Worker、React | sequence ledger and diff report | 05..13 |
| `PANEL-15` | selected-case acceptance | 汇总所有面板区域、normal/boundary/error/recovery 和 release boundaries | all PANEL evidence | self-hashed closure report | 14 |
## 验收和停止条件
通过条件:每个 PANEL row 有 source reference、WASM authority、Worker test、UI evidence、state/event hash 和 recovery sample;同一操作序列 native/WASM/Worker/UI 的首个差异可定位;控制面板无 JS authority、无 JS G-code preview、无 basename 替换。
保持 `blocked`:缺 source/oracle/resource、WASM ABI 不足、首个 divergent tick 未定位、Worker snapshot/hash 不稳定、恢复重复副作用、只在 Chromium 可见但 browser minimum 未锁定,或只能靠 mock/墙钟/宿主能力通过。
停止发布:不把固定案例 verified 写成全量 LinuxCNC parity;Firefox/Safari、OPFS 物理崩溃、实时硬件、官方 oracle、许可证和 owner release gate 继续保持 `STOP_RELEASE`。
## 证据命令
```bash
python3 scripts/validate_baseline.py
python3 scripts/validate_task_pointer.py nextTask1.md --lock context-lock.json
python3 scripts/test_source_semantics_contract.py
node web/workspace/test_source_semantics.mjs
node web/workspace/test_sim_case_loader.mjs
node web/worker/test_sim_case_matrix_s8_06.mjs
node web/worker/test_wasm_canonical_state.mjs
node web/worker/test_wasm_canonical_state_checkpoint.mjs
node web/worker/test_axis3_selected_case.mjs
node web/worker/test_axis3_visible_completion.mjs
npm --prefix web/react run typecheck
npm --prefix web/react run build
```
每个 PANEL 任务必须增加专属测试和 self-hashed report;未完成的任务保留 `queued`/`blocked`,不能从 UI smoke 直接升级为 parity。

View File

@@ -0,0 +1,49 @@
# 3axis-tutorial Native/Web 工具对标验证
本验证使用两个独立工具执行同一案例:
- native AXIS:`tool/linuxcnc-axis-manual-execution`
- Web/WASM:`tool/linuxcnc-web-wasm-manual-execution`
案例和程序固定为:
- `linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini`
- `linuxcnc/nc_files/3dtest.ngc`
## 执行流程
两边均执行同一操作意图:
1. 启动前清理 LinuxCNC 仿真和 stale lock。
2. 打开案例并确认界面可见。
3. F1 取消急停。
4. F2 上电。
5. Home All / `Ctrl+Home`。
6. 运行 G-code。
7. 采集窗口或页面、DRO、运行态、Canvas/截图和最终状态。
8. 退出并再次清理 LinuxCNC。
native 使用真实 AXIS 窗口和 Xlib 键盘事件;Web 使用真实 Chromium CDP DOM 点击、production Vite preview、真实 WASM module 和 Dedicated Worker。两边都不使用物理硬件。
## 结果
机器可读结果见 [comparison report](../coverage/axis3-tutorial-native-web-tool-comparison.report.json)。
报告字段:
- native AXIS 标题:`3dtest.ngc - AXIS 2.10.0~pre1 on 3axis-tutorial`
- native 窗口:`1300x1297`
- Web browser:Google Chrome headless + SwiftShader
- native screenshots:4
- Web screenshots:4
- Web Canvas:非空,`941x471`
- Web exact source:54 行 `3dtest.ngc`
- Web canonical toolpath:49 segments
- selected-case WASM acceptance:`20/20`
- report self-hash:见 comparison report 的 `report_sha256`
结论为 `native_and_web_tools_match_selected_case_workflow`,表示在固定案例的仿真控制流程、状态门禁、程序加载/运行、HOME 和可视化证据范围内对标通过。
## 边界
该结论仅覆盖固定 `3axis-tutorial` 案例。native 使用 POSIX non-realtime 仿真,Web 使用 Chromium SwiftShader;不代表实时硬件、真实 LinuxCNC 全量配置、Safari 或全量 LinuxCNC parity。

View File

@@ -66,6 +66,14 @@ ESTOP, ESTOP_RESET, OFF, ON, HOME, IDLE, RUNNING, PAUSED
- Home 需要 machine on、manual mode、interpreter idle;本案例 UI 逐轴执行。
- Tool/spindle/coolant/probe 操作必须同时受 ESTOP、fault、interlock、spindle busy 和 tool lifecycle gate 约束。
## Web AXIS 操作映射
- 页面上的“取消急停”先发送 `ESTOP(active=false)`,等待 `ESTOP_RESET`,再发送 `IO_RECOVER` 进入 `ON/IDLE`;急停置位始终只发送 `ESTOP(active=true)`,其错误响应仍携带完整 `task/motion/axis_state` 快照。
- “上电”使用 `IO_RECOVER`;“复位机床”先停止 AUTO 解释器、清除急停(如有),再执行 `IO_RECOVER`。协议层 `RESET` 仍是生命周期复位,不能作为机床复位按钮,否则会按源协议清零序号。
- Manual 页签切换会先发 `SET_MODE(MANUAL)`。因此 `HOME`、逐轴 `JOG_*`、主轴和冷却只在 `STATE_ON + MODE_MANUAL + INTERP_IDLE` 开放;MDI/AUTO、fault、限位和急停均 fail-closed。
- Home All 遵循本案例未定义统一 `HOME_SEQUENCE` 时的源 AXIS 行为,固定按 `Z -> X -> Y` 逐轴发送并等待每个 `COMMAND_RESULT`。
- G-code 预览可以在加载前显示确定性解析轨迹;执行轨迹只使用 Worker authoritative planner 快照,已完成段和 active 段分层显示,DRO 从 Worker 的 motion/interpreter 快照更新。
## 验证
- 单元状态契约:`node web/worker/test_axis_state.mjs`

View File

@@ -0,0 +1,41 @@
# Selected-Case Release Authorization
The workspace user explicitly authorized publication of the selected
`3axis-tutorial` Web/WASM simulation bundle on 2026-08-24. This authorization
is recorded in `coverage/release-authorization.json` and is intentionally
separate from the historical `STOP_RELEASE` evidence.
The six K8 prerequisites are treated as explicit release waivers for this
scope. Their source reports remain immutable evidence and are not rewritten as
resolved facts. The user has accepted responsibility for the project's license
position; no SPDX inference or license metadata mutation is required for this
selected-case bundle. The release claim is limited to:
- the exact `3axis-tutorial` configuration and its Worker/WASM runtime;
- the verified native, WASM, Worker, and React regression slice;
- Chromium and Firefox smoke coverage already present in the workspace.
This authorization does not claim full LinuxCNC parity, official kinematics or
recovery oracle parity, all configuration startup coverage, Safari support, or
ownership closure for the entire source manifest. Those facts are outside the
selected-case publication claim and must not be inferred from the release
authorization.
The active release artifact is generated by:
```bash
python3 scripts/generate_release_authorized_gate.py
python3 scripts/test_release_authorized_gate.py
python3 scripts/validate_publish_gate.py
```
Before generating the gate, refresh the command evidence with:
```bash
python3 scripts/generate_release_verification.py
python3 scripts/test_release_verification.py
```
The generator fails closed when the authorization is missing, malformed,
tampered with, scoped beyond the selected case, or any waiver evidence hash no
longer matches its source report.

View File

@@ -0,0 +1,20 @@
# LinuxCNC Source Semantics Contract
This contract freezes source-derived configuration behavior for the future Web control panel. The machine-readable copy is [`coverage/linuxcnc-source-semantics-contract.json`](../coverage/linuxcnc-source-semantics-contract.json); the shared Worker/workspace implementation is [`web/workspace/linuxcnc-source-semantics.mjs`](../web/workspace/linuxcnc-source-semantics.mjs).
## Rules
- LinuxCNC AXIS reads `[DISPLAY] OPEN_FILE` as an initial UI hint. The source checks whether the selected file exists before opening it, so an empty or missing `OPEN_FILE` is `optional_missing`, not a startup resource failure.
- `[DISPLAY] INTRO_GRAPHIC` is also an optional display asset.
- Missing exact `HAL`/`HALFILE` paths are classified as `BLOCKED_HAL`; they must not be reported as generic resource failures.
- Other missing exact paths are `BLOCKED_RESOURCE`. The resolver never substitutes a same-basename file from another configuration directory.
- Parameter files and tool tables may use the existing explicit runtime-fixture policy. This is a deterministic simulation fixture, not a claim that a host file exists.
- `linuxcnc/nc_files/lathe_pawn.ngc` exists, while the path requested by `lathe_multispindle.ini` (`.../nc_files/examples/lathe_pawn.ngc`) does not. The mismatch remains an optional `OPEN_FILE` diagnostic rather than a fabricated alias.
## Control Panel Boundary
The Web control panel is projection-only. It should consume Worker configuration/session snapshots and render `state`, `status`, `diagnostics`, `resources`, `hal`, `optional_missing`, `runtime_fixtures`, and `state_hash`. It must not infer readiness from file basenames, write task/motion authority, or turn `BLOCKED_*` into `TASK_READY`.
The startup states remain `NEW -> MOUNTED -> PARSED -> RESOLVED -> CORE_CREATED -> HAL_READY -> TASK_READY`, with `BLOCKED` as the fail-closed terminal state. The source semantics contract does not modify ABI, protocol, schema versions, context lock, or release blockers.
Source evidence: `linuxcnc/src/emc/usr_intf/axis/scripts/axis.py` around the `OPEN_FILE` startup path, `linuxcnc/src/emc/rs274ngc/rs274ngc_pre.cc` for parameter-file handling, and `linuxcnc/src/emc/task/emctask.cc` for program-prefix handling.

View File

@@ -0,0 +1,98 @@
# 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 均由该契约决定。

View File

@@ -104,11 +104,11 @@
| `S8-03` | verified:真实执行 `xz.ini`、`xz_both.ini`、`xz_both_auto.ini` 取得 `xz.var` 和三份生成 HAL fixture;同案例 `xz.tbl` 精确复用;三案 Worker startup 均 `TASK_READY`、HAL blocked_count=0,identity/BOTH/AUTO state hash 分别保留 | `coverage/sim-case-batch-s8-03.report.json`, `web/worker/test_sim_case_batch_s8_03.mjs`, `scripts/generate_sim_case_batch_s8_03.py`, `scripts/test_sim_case_batch_s8_03.py` |
| `S8-04` | verified:minimal_xyz 真实 fixture 达到 TASK_READY;固定 tick 覆盖 Home/Jog/override、G-code Run/Pause/Resume/Abort/Restart、MDI、estop/recover 和 checkpoint recovery endpoint parity;前端 AppShell/state panel/machine view 继续消费 Worker 权威状态 | `coverage/minimal-xyz-vertical-s8-04.report.json`, `web/worker/test_minimal_xyz_vertical_s8_04.mjs`, `scripts/generate_minimal_xyz_vertical_s8_04.py`, `scripts/test_minimal_xyz_vertical_s8_04.py` |
| `S8-05` | verified:`corexy_by_kins.ini` 与 `corexy_by_hal.ini` 均使用真实 fixtures 达到 TASK_READY;同一 pose `[4,2,3]` 映射 joints `[6,2,3]`,HAL records 72/100,1x/fast/recovery parity 均通过;kins path 与 HAL-trivkins transform path 保持明确区分,未知 HAL 命令仍 fail-closed | `coverage/corexy-dual-path-s8-05.report.json`, `web/worker/test_corexy_dual_path_s8_05.mjs`, `scripts/generate_corexy_dual_path_s8_05.py`, `scripts/test_corexy_dual_path_s8_05.py`, `web/workspace/hal-configuration.mjs` |
| `S8-06` | verified:235 个真实 `configs/sim` 案例全部执行 exact-path loader/startup 两次;分类为 TASK_READY=7、BLOCKED_RESOURCE=221、BLOCKED_HAL=4、BLOCKED_INI=3;每案保留 fixture、missing、first diagnostic、resource/HAL counts 和 deterministic state hash,不把 blocked 提升为 ready | `coverage/sim-case-matrix-s8-06.report.json`, `web/worker/test_sim_case_matrix_s8_06.mjs`, `scripts/generate_sim_case_matrix_s8_06.py`, `scripts/test_sim_case_matrix_s8_06.py` |
| `S8-06` | verified:235 个真实 `configs/sim` 案例全部执行 exact-path loader/startup 两次;按 LinuxCNC source 语义处理 optional `DISPLAY/OPEN_FILE`、缺失 HALFILE 分类和真实路径;分类为 TASK_READY=96、BLOCKED_RESOURCE=11、BLOCKED_HAL=106、BLOCKED_INI=19、BLOCKED_STARTUP=3;每案保留 fixture、missing、first diagnostic、resource/HAL counts 和 deterministic state hash | `coverage/sim-case-matrix-s8-06.report.json`, `web/worker/test_sim_case_matrix_s8_06.mjs`, `scripts/generate_sim_case_matrix_s8_06.py`, `scripts/test_sim_case_matrix_s8_06.py`, `web/workspace/sim-case-loader.mjs` |
| `S8-07` | verified:从真实 INI/include declarations 生成 235-case display family catalog;Axis 85、QtVCP 61、Gscreen 14、VisMach 21、GladeVCP 6、Touchy 6、PyVCP 5、other 37;AppShell 按案例显示 family capabilities/host plugin boundaries,未改变 Worker 权威状态或 blocked 语义 | `coverage/sim-display-families-s8-07.report.json`, `web/app/sim-display-families.mjs`, `web/app/display-family.mjs`, `web/app/test_display_family_s8_07.mjs`, `scripts/generate_sim_display_families_s8_07.py`, `scripts/test_sim_display_families_s8_07.py` |
| `S8-08` | verified:ldelta/rdelta 真实案例通过 HALLIB exact resolution、sim.var/sim.tbl fixtures、lineardelta/rotarydelta virtual adapters;nominal joints `[300,300,300]`/`[10,10,10]`、1x/fast/recovery parity 和 TASK_READY 通过,official oracle 与其它机床族边界保留 | `coverage/machine-families-s8-08.report.json`, `web/worker/test_machine_families_s8_08.mjs`, `scripts/generate_machine_families_s8_08.py`, `scripts/test_machine_families_s8_08.py` |
| `S8-09` | verified:10 个真实 Worker runtime extension runners 全部通过,覆盖 remap/O-word/filter、Python callbacks、tool/probe/IO ack、virtual devices 和 PLC;固定 tick、能力拒绝和 recovery/ack 边界保留,host Python/dynamic loader 不被误报为浏览器 parity | `coverage/runtime-extensions-s8-09.report.json`, `scripts/generate_runtime_extensions_s8_09.py`, `scripts/test_runtime_extensions_s8_09.py` |
| `S8-10` | blocked(正式停止条件):资源运行时语义修复后重新聚合 235-case acceptance;95 个案例 TASK_READY、140 个案例保留 HAL/INI/资源/STARTUP blockers,WASM/native/Worker/App 技术回归通过;official full LinuxCNC oracle 仍 source-gated,Chromium/Firefox/Safari minimums 仍 TBD/Safari unavailable,OPFS recovery 仍 blocked;implementation coverage=verified、acceptance=blocked、`STOP_RELEASE`,不宣称 LinuxCNC 全功能 release | `coverage/full-case-acceptance-s8-10.report.json`, `scripts/generate_full_case_acceptance_s8_10.py`, `scripts/test_full_case_acceptance_s8_10.py`, `nextTask1.md` |
| `S8-10` | blocked(正式停止条件):按修复后的 source-backed 235-case matrix 重新聚合;96 个案例 TASK_READY、139 个案例保留 HAL/INI/资源/STARTUP blockers,WASM/native/Worker/App 技术回归通过;official full LinuxCNC oracle 仍 source-gated,Chromium/Firefox/Safari minimums 仍 TBD/Safari unavailable,OPFS recovery 仍 blocked;implementation coverage=verified、acceptance=blocked、`STOP_RELEASE`,不宣称 LinuxCNC 全功能 release | `coverage/full-case-acceptance-s8-10.report.json`(`b2230390241a9fb8fb723af3847baeec251e8b49526d264c8bd5ccef4e5d3133`), `scripts/generate_full_case_acceptance_s8_10.py`, `scripts/test_full_case_acceptance_s8_10.py`, `nextTask1.md` |
| `TUTORIAL-00` | verified:固定唯一案例 `linuxcnc/configs/sim/axis/vismach/3axis-tutorial`;隔离目录先运行官方 `update_ini -f`,再以真实 DISPLAY 启动 LinuxCNC;AXIS `axis/Axis` 窗口 1300x1293 可见;Web exact bundle/Worker `TASK_READY` 和功能操作序列通过,Vismach executable 作为唯一 `WEB-EQUIV` model adapter 资源加载 | `coverage/axis3-tutorial-native-run.report.json`, `scripts/run_axis3_tutorial_native.py`, `web/worker/test_axis3_selected_case.mjs`, `docs/linuxcnc-web-wasm-3axis-tutorial-parity.md` |
| `TUTORIAL-01` | in_progress:锁定 4 个案例源文件、运行时 `.var/.bak/position_mm.txt` 生成规则、共享 intro graphic、HAL source lines 和 Vismach Python imports;下一步生成 exact resource/source graph 自哈希报告 | `docs/linuxcnc-web-wasm-3axis-tutorial-parity.md`, `linuxcnc/configs/sim/axis/vismach/3axis-tutorial`, `linuxcnc/lib/python/vismach.py`, `linuxcnc/lib/python/hal.py` |
| `TUTORIAL-01..03` | verified:3axis tutorial exact resource graph、Vismach `loadusr ./3axis-tutorial` 唯一 `WEB-EQUIV` HAL adapter、startup phase `NEW→TASK_READY` 和 deterministic loader/startup hash 通过;运行时 `3axis-tutorial_mm.var` 在 workspace exact path 生成 | `coverage/axis3-tutorial-resource-graph.report.json`, `web/worker/test_axis3_tutorial_hal_adapter.mjs`, `web/worker/test_axis3_tutorial_startup.mjs`, `scripts/test_axis3_tutorial_resource_graph.py`, `scripts/test_axis3_tutorial_hal_adapter.py`, `scripts/test_axis3_tutorial_startup.py` |
@@ -119,6 +119,13 @@
| `TUTORIAL-12` | verified:参考 AXIS/QtVCP 源码遵循案例未定义 `HOME_SEQUENCE` 时的 individual home 语义,真实 native 按 `Z -> X -> Y` home;参考 `hal_manualtoolchange.py` 的 `change_button` pin,通过真实 HAL ACK 完成 T1 M6;native/Worker 同序列无首差,保留 source-defined semantics | `coverage/axis3-tutorial-sequence.report.json`, `coverage/axis3-tutorial-native-sequence.report.json`, `web/worker/test_axis3_tutorial_sequence.mjs`, `scripts/run_axis3_tutorial_native_sequence.py` |
| `TUTORIAL-13` | verified:修复 program recovery replay 顺序,selected case checkpoint 后连续/recovered endpoint hash 相等;坏 checkpoint fail-closed,runtime `.var/tool.tbl/position` policy 和无重复副作用均有证据 | `coverage/axis3-tutorial-persistence.report.json`(`a2d125b06fe81ad8442c3b2b1f766e2a01e8a3160b4738ebc1cba59f565800f2`), `web/worker/test_axis3_tutorial_persistence.mjs`, `web/worker/sim-session.mjs` |
| `TUTORIAL-14` | verified(selected-case closure index):所有 native/Worker/Chromium/tool-IO/persistence/sequence 证据冻结;native individual home 和 `change_button` tool ACK 已按源程序语义闭合;release action 仍为 `STOP_RELEASE`,外部浏览器/OPFS/硬件边界独立保留 | `coverage/axis3-tutorial-closure-index.report.json`, `scripts/generate_axis3_tutorial_closure_index.py`, `scripts/test_axis3_tutorial_closure_index.py` |
| `T3-COMPLETE-01` | verified(selected-case scope):`3axis-tutorial` trivkins 运行期间 pose/velocity/queue depth 由 WASM `sim_motion_queue` 驱动;JS `AuthoritativeRuntime` authority 调用为 0;pause/resume/PROGRAM_STEP/abort、queue drain completion、checkpoint/trace import/recovery endpoint parity 和 damaged queue fail-closed 通过。非 selected-case compatibility mirror、T4 task/motion/HAL/IO canonical state、全量矩阵和 release blockers 保持 blocked;LinuxCNC source matrix 的旧 fixture drift 已由 loader 源语义修复 | `coverage/wasm-motion-authority-t3.report.json`(`8424f3bae26ff0b16868ddc1dde4f40e14fc64288aea3d9aba983cc46d62c967`), `web/worker/test_wasm_motion_authority.mjs`, `web/worker/test_wasm_motion_checkpoint.mjs`, `scripts/generate_wasm_motion_authority_t3.py`, `coverage/wasm-only-source-audit.report.json` |
| `T4-CANONICAL-STATE-01` | verified(selected-case scope):`SimTask` 通过 `sim_task_canonical` 成为 Worker task authority;`WasmHomeLimit` 通过锁定 `sim_kinematics_home_limit_*` ABI 成为 trivkins home/limit authority;snapshot、HOME/JOG/LIMIT、checkpoint、trace/import/recovery 的 task/motion/home-limit state hash 稳定,JS task tamper 被 WASM canonical 覆盖,损坏 home-limit state fail-closed。HAL/IO/tool/probe、外部设备输入、非 selected-case compatibility 和全量 release 仍 blocked | `coverage/wasm-canonical-state-t4.report.json`(`5f51ea1f766d7e3bf336c3dd11575a97fbdc1f340db58762ba4526c80b0de336`), `web/worker/wasm-home-limit.mjs`, `web/worker/test_wasm_canonical_state.mjs`, `web/worker/test_wasm_canonical_state_checkpoint.mjs`, `scripts/generate_wasm_canonical_state_t4.py` |
| `T5-FULL-MATRIX-01` | blocked:生成九领域 native/WASM/Worker 功能矩阵;按 LinuxCNC AXIS 源语义修复空/缺失 `OPEN_FILE` 处理和 HALFILE 分类,235-case matrix 恢复 verified,分类为 `BLOCKED_HAL=106/BLOCKED_RESOURCE=11/TASK_READY=96`;T5 28 个矩阵命令全部通过,source semantics contract 已纳入输入闭合,完整 parity 与官方 oracle/配置资源/浏览器/OPFS 边界继续 blocked | `coverage/wasm-feature-matrix-t5.report.json`(`08c1229072214407d0efbcb1f939834b470b160b31bbf7211123dc43306434fa`), `coverage/linuxcnc-source-semantics-contract.json`, `web/workspace/linuxcnc-source-semantics.mjs`, `scripts/generate_wasm_feature_matrix_t5.py` |
| `T6-FUNCTION-CLOSURE-01` | blocked:对 T5 八个 blocked rows 完成 source-backed closure audit;每行保留 source reference、WASM/Worker capability、已验证 slice、差异、停止原因和下一步。23 个专项命令全部通过,4 个 failure samples 保留 official oracle、资源、宿主能力和浏览器输入缺口;T5 fixture drift 已由源语义修复,不使用 JS fallback 或 selected-case promotion,`STOP_RELEASE` 保持 | `coverage/wasm-function-closure-t6.report.json`(`46230d88ac0f7687b81c148657dd4af51da2c60a99c3f8e0777e4e8ec57a82d3`), `scripts/generate_wasm_function_closure_t6.py`, `scripts/test_wasm_function_closure_t6.py`, `web/worker/test_wasm_function_closure_t6.mjs`, `nextTask1.md` |
| `T7-RELEASE-GATE-01` | blocked:完成 simulation-track 只读 release-gate audit;T6 dependency、context consistency、candidate eligibility、`STOP_RELEASE`、六项 blocker identity、owner refresh 和 remediation self-hash 全部核对通过;8 个 blocker 与 3 个 failure samples 保留。未刷新 K8 owner gate,未修改 context lock、manifest、许可证或 owner decision | `coverage/wasm-simulation-release-gate-t7.report.json`(`3375aa400ed4b21c5ae020c22f39f5d212db26373aee6c245b7bc87d09312bba`), `scripts/generate_wasm_simulation_release_gate_t7.py`, `scripts/test_wasm_simulation_release_gate_t7.py`, `nextTask1.md` |
| `SOURCE-SEMANTICS-CONTRACT-01` | verified:将 LinuxCNC AXIS `OPEN_FILE` optional、`INTRO_GRAPHIC` optional、HALFILE/resource 缺失分类、exact-path/no-basename-substitution、runtime fixture 和 Web 控制面板 projection-only 规则固化为共享模块与机器契约;源文件哈希、契约 self-hash、loader/matrix regression 通过,不修改 ABI/protocol/schema/context lock | `coverage/linuxcnc-source-semantics-contract.json`(`ff1ce5e1c3251b82e4298a084146e1eb64fb608ef5f7922c69cec10faba77d83`), `web/workspace/linuxcnc-source-semantics.mjs`, `web/workspace/test_source_semantics.mjs`, `scripts/generate_source_semantics_contract.py`, `scripts/test_source_semantics_contract.py`, `docs/linuxcnc-web-wasm-source-semantics.md` |
| `PANEL-PLAN-01` | queued:建立固定 `3axis-tutorial` Web 控制面板源程序对标实施合同;固化“WASM 是唯一数据来源、状态机严格对标源程序、按钮 gate 完全一致、preview 与 native canonical motion 一致”四项硬约束;登记 12 项功能矩阵(P0: 1-9/12,P1: 10-11)、分层 envelope、状态真值表、preview segment 比较算法、统一报告模板、15 个详细实施任务、依赖、验收和 STOP_RELEASE 边界;不改变 ABI/protocol/schema/context lock | `docs/linuxcnc-web-wasm-3axis-tutorial-control-panel-implementation.md`, `nextTask1.md`, `coverage/linuxcnc-source-semantics-contract.json` |
| `AXIS-STATE-CONTRACT` | verified:新增 additive `axis_state` 视图,严格记录 LinuxCNC `STATE_*`/`MODE_*`/`INTERP_*` 数值、ESTOP_RESET/上电/关机/individual HOME/IDLE/RUNNING/PAUSED 迁移和 AXIS button gate;不修改 `sim_task.v1` | `docs/linuxcnc-web-wasm-3axis-tutorial-state-machine.md`, `web/worker/axis-state.mjs`, `web/worker/test_axis_state.mjs`, `web/react/src/store.ts`, `web/react/src/App.tsx` |
| `FE-M1-REACT` | verified:按技术路线新增 React 19/TypeScript/Vite/Tailwind/Radix/Three.js 前端入口;Dedicated Worker/WASM bundle、protocol.v1 reducer、exact-path `configs/sim` loader、LinuxCNC AXIS source icons 和 Three.js r185 三轴 viewer 通过 typecheck/build/preview;OPFS 仍 Worker-owned | `coverage/react-frontend-m1.report.json`, `web/react`, `scripts/generate_react_frontend_m1.py`, `scripts/test_react_frontend_m1.py` |
| `FE-M4-GUI-01` | verified:扫描 LinuxCNC AXIS/Gmoccapy/Touchy/Gscreen/QtVCP/PyVCP/GladeVCP/Vismach/NGCGUI/QtPlasmaC 等 GUI 源码、Python 库、sim descriptors/assets,1837 条文件记录、12 个 family、source hash/path 通过;341 条 manifest 反向归属缺口保留审计,许可证不阻塞技术移植 | `coverage/gui-source-inventory-fe-m4.report.json`, `scripts/generate_gui_source_inventory.py`, `scripts/test_gui_source_inventory.py`, `nextTask1.md` |