Implement AXIS parity UI and execution baseline
This commit is contained in:
590
docs/linuxcnc-axis-complete-parity-spec.md
Normal file
590
docs/linuxcnc-axis-complete-parity-spec.md
Normal file
@@ -0,0 +1,590 @@
|
||||
# LinuxCNC AXIS 完全对标规范与执行计划
|
||||
|
||||
**文档状态**:执行基线 v1.0(源程序已冻结;实现和验收按任务逐项关闭)
|
||||
**适用版本**:LinuxCNC `2.10.0~pre0` 239dcf4284762ad7e9c65d390bc5524d855c2f8e
|
||||
**项目上下文**:`linuxcnc-2.10.0-pre0-wasm-m1-py-c1`
|
||||
**主入口**:[`web/react`](../web/react)
|
||||
**原始 AXIS 入口**:[`linuxcnc/share/axis/tcl/axis.tcl`](../linuxcnc/share/axis/tcl/axis.tcl)
|
||||
**配套通信契约**:[前端与通信详细设计](linuxcnc-web-wasm-frontend-communication-design.md)
|
||||
**配套案例契约**:[案例对标计划](linuxcnc-web-wasm-case-parity-plan.md)
|
||||
|
||||
本文件是“Web 主界面完全对标 LinuxCNC 原始 AXIS”的唯一执行规范。它把原始 AXIS 的功能、界面结构、状态门控、快捷键、图标、绘图和外部集成拆成可追溯任务;没有来源、命令序列、状态结果和验收证据的功能,不得标记为完成。
|
||||
|
||||
## 1. 目标、定义和边界
|
||||
|
||||
### 1.1 对标目标
|
||||
|
||||
对标不是把网页做成相似的深色控制台,而是对同一配置、同一程序、同一输入序列满足以下四类等价:
|
||||
|
||||
1. **结构等价**:菜单、工具栏顺序、Notebook、程序区、DRO、状态栏、控制件和图标的角色与布局对应 AXIS。
|
||||
2. **操作等价**:同一用户动作发出同一 LinuxCNC 语义命令,按相同状态条件启用、禁用、暂停、恢复或拒绝。
|
||||
3. **状态等价**:任务态、解释器态、模式、轴/关节选择、位置显示、倍率、主轴、工具、冷却、报警和恢复结果来自同一权威状态,事件顺序和当前行一致。
|
||||
4. **结果等价**:native AXIS oracle 与 WASM/Worker 的 command trace、tick、快照、事件、错误和 checkpoint 哈希一致;允许的浮点误差必须在功能条目中明确,不能事后放宽。
|
||||
|
||||
### 1.2 规范性术语
|
||||
|
||||
| 词 | 含义 |
|
||||
|---|---|
|
||||
| MUST | 必须满足,否则该条目失败 |
|
||||
| MUST NOT | 严禁发生,否则停止验收 |
|
||||
| SHOULD | 默认要求;若不满足必须记录理由和影响 |
|
||||
| source oracle | 锁定 LinuxCNC 源码、原始 AXIS 运行或其确定性输出 |
|
||||
| Web-equivalent | 浏览器中实现相同工作流和状态语义的等价控件,不复制桌面窗口进程 |
|
||||
| host boundary | 原始程序依赖宿主进程、动态库、真实设备或外部窗口的边界;必须显式显示为 blocked/excluded |
|
||||
| verified | 代码、测试、native/WASM/Worker 证据、视觉证据和自哈希报告均通过 |
|
||||
| blocked | 输入、官方 oracle、浏览器能力或宿主边界不足;保留失败样本,不得伪造 verified |
|
||||
|
||||
### 1.3 明确边界
|
||||
|
||||
- LinuxCNC 原始 AXIS 是 Tk 前端;Web 采用 React/TypeScript/Worker/Three.js,实现的是 **Web-equivalent**,不是复制 Tk 窗口或在浏览器启动桌面进程。
|
||||
- `exec classicladder`、`halshow`、`halmeter`、`halscope`、`linuxcnctop`、`debuglevel`、外部编辑器、真实硬件和原始 socket 不得伪装为浏览器已支持;用 Web 面板或 `HOST_BOUNDARY` 诊断替代。
|
||||
- WASM、HAL、IO、Python、OPFS 和快照的权威状态在 Dedicated Worker;React 只能通过协议读写,不得访问 WASM 指针或直接写 OPFS。
|
||||
- 原始图标必须使用锁定源码中的字节;重新绘制、emoji、通用 icon 库或不同来源的同名图标不算对标。
|
||||
- 所有视觉结论必须在固定视口、固定字体/缩放和固定资源哈希下产生;动态 canvas 区域单独做像素/非空检查,不得用“截图看起来差不多”替代 DOM 和行为检查。
|
||||
|
||||
## 2. 锁定的 AXIS 源程序和证据入口
|
||||
|
||||
### 2.1 源文件分工
|
||||
|
||||
| 领域 | 原始来源 | 对标内容 |
|
||||
|---|---|---|
|
||||
| 主窗口、菜单、工具栏、Notebook、控件门控 | [`share/axis/tcl/axis.tcl`](../linuxcnc/share/axis/tcl/axis.tcl) | 全部主界面结构、动作、启用条件、快捷键和默认变量 |
|
||||
| 图标加载、动态帮助、控件辅助函数 | [`share/axis/tcl/support.tcl`](../linuxcnc/share/axis/tcl/support.tcl)、[`accel.tcl`](../linuxcnc/share/axis/tcl/accel.tcl) | 资源解析、tooltip、菜单/控件 accelerator |
|
||||
| 自定义下拉、滚动条、对话框 | [`share/axis/tcl/combobox.tcl`](../linuxcnc/share/axis/tcl/combobox.tcl)、[`sb.tcl`](../linuxcnc/share/axis/tcl/sb.tcl)、[`dialog.tcl`](../linuxcnc/share/axis/tcl/dialog.tcl) | Jog increment、MDI history、文件和错误对话框的交互语义 |
|
||||
| AXIS 设计说明 | [`src/emc/usr_intf/axis/README`](../linuxcnc/src/emc/usr_intf/axis/README) | AXIS 的定位是 file preview + live plot;自解释控件、tooltip 和 Quick Reference |
|
||||
| 3D/预览窗口 | [`lib/python/gremlin.py`](../linuxcnc/lib/python/gremlin.py)、[`gremlin_view.py`](../linuxcnc/lib/python/gremlin_view.py) | 视角、缩放、拖动/旋转、预览加载、live plot、当前行和绘图刷新 |
|
||||
| G-code 绘图和坐标叠加 | [`lib/python/rs274/glcanon.py`](../linuxcnc/lib/python/rs274/glcanon.py) | rapid、path、dwell、tool、origin、offset、extents、grid、limits、velocity、DTG |
|
||||
| 配置声明和 GUI 家族 | [`configs/sim/axis`](../linuxcnc/configs/sim/axis) | DISPLAY=axis、PYVCP/GLADEVCP/NGCGUI/VisMach/外部脚本及资源闭包 |
|
||||
| 原始 bitmap | [`share/axis/images`](../linuxcnc/share/axis/images) | AXIS logo、toolbar、spindle、标准报警图标、banner |
|
||||
|
||||
本文中的 `axis.tcl:N-M` 是 [`linuxcnc/share/axis/tcl/axis.tcl`](../linuxcnc/share/axis/tcl/axis.tcl) 的行号简写;`gremlin.py` 和 `glcanon.py` 同理分别指上表中的完整路径。
|
||||
|
||||
### 2.2 源哈希和变更规则
|
||||
|
||||
基线文件的初始 SHA-256 记录如下;每次源更新必须重新生成 manifest 和本文件引用,不得沿用旧报告:
|
||||
|
||||
```text
|
||||
share/axis/tcl/axis.tcl c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524
|
||||
lib/python/gremlin.py 7559a52300de92ed156fe22267c8fbca975338321cf3afada141360a244756a3
|
||||
lib/python/rs274/glcanon.py 0dfb20f1fdc05289894f3aa638357d98e1063fbd53329c723c777399ec7b33b7
|
||||
src/emc/usr_intf/axis/README 2fe357ba28bb0aa66565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524
|
||||
```
|
||||
|
||||
若报告发现文件内容与上述哈希不一致,先修正文档/manifest,再开始实现。源码树中由运行时生成的 `tool.tbl`、`sim.var`、`linuxcnc.var` 必须标明是 `source-owned` 还是 `runtime-generated-fixture`,不可混用。
|
||||
|
||||
## 3. AXIS 原始功能完整清单
|
||||
|
||||
功能 ID 是后续任务、协议、测试和验收报告的稳定主键。每个 ID 至少绑定一条源码路径、一个 Web 控件、一个命令/查询、一个状态字段和一份 evidence。
|
||||
|
||||
### 3.1 应用壳、菜单和窗口
|
||||
|
||||
| ID | 原始功能 | 原始实现/行 | Web 对标要求 |
|
||||
|---|---|---|---|
|
||||
| AXIS-SHELL-01 | 窗口标题 `AXIS <version> on <machine>`,无文件时显示 `(no file)`,有文件时显示文件名 | `axis.tcl:1755-1765` | 根据 Worker 的 machine/taskfile 快照更新标题;标题更新不能改变仿真状态 |
|
||||
| AXIS-SHELL-02 | 顶级菜单 File、Machine、View、Help | `axis.tcl:33-53,468-482` | 顺序、命名、子菜单、快捷键和 enabled 状态一致;菜单项必须有可测试的 `data-axis-command` |
|
||||
| AXIS-SHELL-03 | 最小窗口尺寸随 pane 请求尺寸更新 | `axis.tcl:2234-2240` | CSS 使用稳定最小尺寸和滚动策略;窄屏切换布局,不能让高风险按钮被裁掉 |
|
||||
| AXIS-SHELL-04 | About AXIS、Quick Reference 对话框 | `axis.tcl:453-464,1549-1632` | Web modal 保留版本、许可证、源码链接、快捷键和关闭/焦点语义;外部链接另标记 host/network boundary |
|
||||
| AXIS-SHELL-05 | 动态帮助 tooltip | `axis.tcl:2250-2270`、`accel.tcl:150-185` | 所有图标按钮的 tooltip 文案、快捷键和 disabled 原因可通过 DOM/辅助技术读取 |
|
||||
|
||||
### 3.2 File 菜单和工程入口
|
||||
|
||||
原始菜单定义位于 `axis.tcl:55-102`。Web 实现必须保留以下条目和顺序:
|
||||
|
||||
| ID | 菜单项 | 语义 |
|
||||
|---|---|---|
|
||||
| AXIS-FILE-01 | Open… (`O`) | 选择 G-code,解析、预览并进入 `PROGRAM_LOAD`; 不允许 basename 替换 |
|
||||
| AXIS-FILE-02 | Recent Files | 最近文件列表、序号快捷键、清空列表;路径/哈希来自 Worker 工程存储 |
|
||||
| AXIS-FILE-03 | Edit… | 以配置声明的 editor 或 Web G-code editor 打开;宿主 editor 必须显示 `HOST_BOUNDARY` |
|
||||
| AXIS-FILE-04 | Reload (`Ctrl-R`) | 仅在解释器 idle 且有 taskfile 时启用;重新读取精确资源 |
|
||||
| AXIS-FILE-05 | Save G-code as… (`Ctrl-S`) | 保存当前内容/版本,写 journal,返回文件哈希 |
|
||||
| AXIS-FILE-06 | Properties… | 显示程序路径、大小、行数、解析诊断、单位和 source hash |
|
||||
| AXIS-FILE-07 | Edit tool data… | Web tool table editor;原始 `tooledit` 外部窗口标为 boundary |
|
||||
| AXIS-FILE-08 | Reload tool data | 重新加载工具表并显示 table hash、当前刀、prepared/pocket |
|
||||
| AXIS-FILE-09 | Ladder Editor… | Web ClassicLadder 面板;无法运行宿主 editor 时不得静默忽略 |
|
||||
| AXIS-FILE-10 | Quit | 浏览器不能关闭宿主窗口;显示“关闭标签页”提示并记录 `WEB_EQUIVALENT` |
|
||||
|
||||
### 3.3 Machine 菜单和任务控制
|
||||
|
||||
原始定义位于 `axis.tcl:105-264`。下列条目是 P0/P1,不得只保留 Run/Pause:
|
||||
|
||||
| ID | 功能 | 关键语义 |
|
||||
|---|---|---|
|
||||
| AXIS-MACHINE-01 | Toggle Emergency Stop (`F1`) | `ESTOP` 状态机;急停时禁止运动/IO,界面进入 pressed/fault,恢复必须有独立 `IO_RECOVER`/reset 结果 |
|
||||
| AXIS-MACHINE-02 | Toggle Machine Power (`F2`) | task state OFF/ON;按钮 relief 与状态一致,不能把 recover 当作已上电 |
|
||||
| AXIS-MACHINE-03 | Run program (`R`) | 仅 task ON、程序有效、解释器 idle 时启用;返回当前行、interp state、tick |
|
||||
| AXIS-MACHINE-04 | Run from selected line | 以选中行建立确定性 seek/预读语义;没有选中行必须 disabled |
|
||||
| AXIS-MACHINE-05 | Step (`T`) | 只执行下一行/下一 canonical 单元;记录 line before/after 和状态 hash |
|
||||
| AXIS-MACHINE-06 | Pause (`P`) / Resume (`S`) | 只在对应 interp state 启用;pause 图标切换 `tool_pause`/`resume_inhibit` |
|
||||
| AXIS-MACHINE-07 | Stop (`Esc`) | 中止程序而不是销毁 session;queue、tool、spindle、IO 和恢复点结果必须明确 |
|
||||
| AXIS-MACHINE-08 | Stop at M1 | `optional_stop` checkbutton/toolbar relief 与 M1 行为一致 |
|
||||
| AXIS-MACHINE-09 | Skip lines with `/` | `block_delete` checkbutton/toolbar relief 与程序过滤语义一致 |
|
||||
| AXIS-MACHINE-10 | MDI history clear/copy/paste | `Ctrl-M`、`Ctrl-H`、`Ctrl-Shift-H`;历史只在 Worker committed state 中更新 |
|
||||
| AXIS-MACHINE-11 | Calibration | 原始 `emccalib.tcl` 是外部窗口;Web 提供能力诊断或 boundary,不得模拟完成 |
|
||||
| AXIS-MACHINE-12 | Show HAL Configuration / HAL Meter / HAL Scope | 分别映射 HAL graph、HAL sample/plot、scope;原始外部窗口路径保留诊断 |
|
||||
| AXIS-MACHINE-13 | Show LinuxCNC Status / Set Debug Level | 映射状态时间线、日志和 debug level 白名单;未经授权的 level 必须拒绝 |
|
||||
| AXIS-MACHINE-14 | Homing / Unhoming | 动态子菜单按轴/关节生成;顺序、homed、limit、门控和错误一致 |
|
||||
| AXIS-MACHINE-15 | Zero coordinate system | P1…P9/G54…G59.3/G92 全部入口;每次写入显示坐标系、旧值、新值和 hash |
|
||||
| AXIS-MACHINE-16 | Tool touch off to workpiece/fixture | `tto_g11` 两种模式;选择影响 G10/G11 语义并在快照中可见 |
|
||||
|
||||
### 3.4 View 菜单、DRO 和坐标显示
|
||||
|
||||
原始定义位于 `axis.tcl:266-449`。View 菜单必须拆成可验证状态,不得只做文字菜单:
|
||||
|
||||
| ID | 功能 | 状态字段/输出 |
|
||||
|---|---|---|
|
||||
| AXIS-VIEW-01 | Top / Rotated Top / Side / Front / Perspective | `view_type`、camera pose、视角图标 relief;对应 `set_view_z/z2/x/y/p` |
|
||||
| AXIS-VIEW-02 | Display Inches / Display MM | `metric`;DRO、速度、倍率单位同步;切换不改机床内部单位 |
|
||||
| AXIS-VIEW-03 | Show program | program path overlay 开关 |
|
||||
| AXIS-VIEW-04 | Show program rapids | rapid segments 是否显示 |
|
||||
| AXIS-VIEW-05 | Alpha-blend program | program overlay alpha |
|
||||
| AXIS-VIEW-06 | Show live plot | 已运行轨迹与预览轨迹分层;clear 不得删除程序预览 |
|
||||
| AXIS-VIEW-07 | Show tool | tool cone/model、tool position、orientation |
|
||||
| AXIS-VIEW-08 | Show extents | program/machine extents bounding box |
|
||||
| AXIS-VIEW-09 | Grid Off/Custom | grid size、origin、spacing 和自定义参数 |
|
||||
| AXIS-VIEW-10 | Show offsets | G5x/G92/tool offset 可视化和数值 |
|
||||
| AXIS-VIEW-11 | Show machine limits | axis/joint limits overlay 和 limit fault |
|
||||
| AXIS-VIEW-12 | Show velocity | velocity vector/数值;来源为 snapshot,不使用墙钟推算 |
|
||||
| AXIS-VIEW-13 | Show distance to go | DTG 与 commanded/actual、machine/relative 模式联动 |
|
||||
| AXIS-VIEW-14 | Large coordinate font | DRO 字号开关,布局必须稳定 |
|
||||
| AXIS-VIEW-15 | Clear live plot (`Ctrl-K`) | 仅清 live layer,返回新 plot revision |
|
||||
| AXIS-VIEW-16 | Show PyVCP panel (`Ctrl-E`) | 配置声明 `PYVCP` 时显示 Web VCP;缺少 host plugin 时显示 boundary |
|
||||
| AXIS-VIEW-17 | Show commanded/actual position | `display_type`,DRO 与状态栏同源 |
|
||||
| AXIS-VIEW-18 | Show machine/relative position | `coord_type`,DRO 与触碰/坐标系同源 |
|
||||
| AXIS-VIEW-19 | Joint mode / World mode | `teleop_mode`;非平凡 kinematics 未全 homed 时禁止切换到 world |
|
||||
|
||||
### 3.5 AXIS 工具栏和图标对照表
|
||||
|
||||
原始工具栏从 `axis.tcl:484-787` 创建并按 `671-787` 顺序 pack。图标文件必须来自 [`linuxcnc/share/axis/images`](../linuxcnc/share/axis/images):
|
||||
|
||||
| 序号 | 原始 widget | 图标 | 原始动作 | Web 对标 |
|
||||
|---:|---|---|---|---|
|
||||
| 1 | `machine_estop` | `tool_estop.gif` | `estop_clicked` | icon-only button,tooltip `Toggle Emergency Stop [F1]` |
|
||||
| 2 | `machine_power` | `tool_power.gif` | `onoff_clicked` | task power 状态,初始 disabled/relief 与 oracle 一致 |
|
||||
| 3 | `file_open` | `tool_open.gif` | `open_file` | 精确资源选择 + `PROGRAM_LOAD` |
|
||||
| 4 | `reload` | `tool_reload.gif` | `reload_file` | reload gate |
|
||||
| 5 | `program_run` | `tool_run.gif` | `task_run` | run gate |
|
||||
| 6 | `program_step` | `tool_step.gif` | `task_step` | step gate |
|
||||
| 7 | `program_pause` | `tool_pause.gif` / `resume_inhibit.gif` | `task_pauseresume` | pause/resume 图标切换 |
|
||||
| 8 | `program_stop` | `tool_stop.gif` | `task_stop` | stop/abort gate |
|
||||
| 9 | `program_blockdelete` | `tool_blockdelete.gif` | `toggle_block_delete` | pressed state + 程序语义 |
|
||||
| 10 | `program_optpause` | `tool_optpause.gif` | `toggle_optional_stop` | pressed state + M1 语义 |
|
||||
| 11 | `view_zoomin` | `tool_zoomin.gif` | `zoomin` | camera scale |
|
||||
| 12 | `view_zoomout` | `tool_zoomout.gif` | `zoomout` | camera scale |
|
||||
| 13 | `view_z` | `tool_axis_z.gif` | `set_view_z` | top camera |
|
||||
| 14 | `view_z2` | `tool_axis_z2.gif` | `set_view_z2` | rotated top camera |
|
||||
| 15 | `view_x` | `tool_axis_x.gif` | `set_view_x` | side camera |
|
||||
| 16 | `view_y` | `tool_axis_y.gif` | `set_view_y` | front camera |
|
||||
| 17 | `view_y2` | `tool_axis_y2.png` | `set_view_y2` | inverted front camera |
|
||||
| 18 | `view_p` | `tool_axis_p.gif` | `set_view_p` | perspective camera |
|
||||
| 19 | `rotate` | `tool_rotate.gif` | toggle drag/rotate | pressed state and pointer gesture |
|
||||
| 20 | `clear_plot` | `tool_clear.gif` | `clear_live_plot` | live layer only |
|
||||
|
||||
验收必须检查:文件名、字节 hash、实际加载 URL、`alt`/tooltip、按钮顺序、disabled/pressed relief 和点击后的命令。QtVCP 同名镜像只能用于历史兼容,不得作为 AXIS source oracle。
|
||||
|
||||
### 3.6 Manual Control Notebook
|
||||
|
||||
原始布局在 `axis.tcl:803-1213`,默认页为 `Manual Control [F3]`:
|
||||
|
||||
| ID | 控件 | 必须保留的行为 |
|
||||
|---|---|---|
|
||||
| AXIS-MANUAL-01 | 轴选择 X/Y/Z/A/B/C/U/V/W | 3×3 radio;`axis_activated`;非平凡运动学切换为动态 joint numbers |
|
||||
| AXIS-MANUAL-02 | Jog `-`/`+` | 增量模式 click 一次;Continuous 模式 pointer/key down 开始、release/leave 必须 `JOG_STOP` |
|
||||
| AXIS-MANUAL-03 | Jog increment | `Continuous`, `0.1000`, `0.0100`, `0.0010`, `0.0001`;选择变化进入命令 payload |
|
||||
| AXIS-MANUAL-04 | Home Axis | 当前轴/关节 home;Home 键快捷键;结果更新 homed/limit/position |
|
||||
| AXIS-MANUAL-05 | Touch Off | G54 当前轴;End 快捷键;保存坐标系结果 |
|
||||
| AXIS-MANUAL-06 | Tool Touch Off | Ctrl-End;只在有加载工具且模式允许时启用 |
|
||||
| AXIS-MANUAL-07 | Override Limits | 只在 `on_any_limit` 时启用;临时越限必须有 fault/recover trace |
|
||||
| AXIS-MANUAL-08 | Spindle CCW/Stop/CW | `spindledir` radio、16×16 原始图标、F10/F9;Stop 文案必须可读 |
|
||||
| AXIS-MANUAL-09 | Spindle -/+ | 按下加速/减速、释放进入 constant;F11/F12;主轴未运行时 disabled |
|
||||
| AXIS-MANUAL-10 | Brake | B/Shift-B;状态和互锁可见 |
|
||||
| AXIS-MANUAL-11 | Mist/Flood | F7/F8;冷却状态、故障和恢复来自 device IO |
|
||||
| AXIS-MANUAL-12 | Jog Speed/Max Velocity | 来源为 `jog_slider_val`/`maxvel_slider_val`,单位随 metric,显示值和内部速度转换一致 |
|
||||
|
||||
### 3.7 MDI Notebook
|
||||
|
||||
原始布局在 `axis.tcl:1215-1294`:History listbox、MDI Command entry、Go 按钮。Web 必须支持:
|
||||
|
||||
- 历史最多/最少行为与 Worker 的 `mdi_history` 一致,初始有空元素,不把草稿历史当已执行。
|
||||
- Enter 与 Go 相同,发送 `MDI_EXECUTE`,返回 command result、当前行、模式和错误行。
|
||||
- `queued_mdi_commands >= max_queued_mdi_commands` 时整个 MDI group disabled(`axis.tcl:1851-1855`)。
|
||||
- `Ctrl-M` 清历史,`Ctrl-H` history→clipboard,`Ctrl-Shift-H` clipboard→history;浏览器 clipboard 权限失败必须显式诊断。
|
||||
|
||||
### 3.8 Preview、DRO、程序和状态栏
|
||||
|
||||
原始布局在 `axis.tcl:1296-1709`:
|
||||
|
||||
| 区域 | 原始行为 | Web 必须实现 |
|
||||
|---|---|---|
|
||||
| Preview tab | Gremlin/GLCanon 预览、程序/rapid/live/tool/extents/offset/grid/limit/velocity overlays | Three.js/WebGL 只消费 Worker snapshot/trajectory;每层可独立开关,canvas 必须非空 |
|
||||
| DRO tab | 原始 AXIS DRO widget;显示 machine/relative、actual/commanded、DTG、单位、关节态 | 表格列和模式可切换;数值、单位、homed、limit、fault、tick/hash 同源 |
|
||||
| `.info.task_state` | ESTOP/OFF/ON,sunken relief | `task_state` 颜色/状态必须由快照驱动 |
|
||||
| `.info.tool` | 当前刀具/工具信息 | current/prepared/pocket/change state 和 tool table hash |
|
||||
| `.info.position` | Position + coordinate type + display type | `Machine/Relative` 与 `Actual/Commanded` 组合准确 |
|
||||
| G-code pane | 有滚动条、当前行/highlight、底部固定 pane | 编辑/选行/运行到选中行/错误定位;不能使用静态 `<pre>` 冒充 |
|
||||
| Active G-Codes | `gcodes` text,disabled、2 行起步 | modal codes、units、plane、feed/spindle/tool/coolant 同步 |
|
||||
| Jog sliders | `jogspeed`、`ajogspeed`、`maxvel`,值通过 `setval/val2vel` 转换 | 显示值与内部单位、min/max、metric 切换、键盘增量一致 |
|
||||
| Overrides | `spinoverride`、`feedoverride`、`rapidoverride`,0…120%、整数分辨率 | worker authoritative override;滑块 release/commit 和 pending/error 可见 |
|
||||
|
||||
### 3.9 状态门控、默认状态和快捷键
|
||||
|
||||
`axis.tcl:1715-1887` 是行为对标的核心,不得只按按钮标签实现。门控规则:
|
||||
|
||||
1. `ESTOP` 时 machine power、程序、jog、主轴、冷却等高风险动作禁用;estop relief 按下。
|
||||
2. task 非 ON 时 manual group disabled;task ON 且 interpreter idle 时才 enable manual group。
|
||||
3. 有 taskfile 且 idle 才能 reload、edit、properties、open、block-delete;有 taskfile 且 ON 才能 step。
|
||||
4. interpreter reading/waiting 才能 Pause;paused 才能 Resume;非 idle 才能 Stop。
|
||||
5. `on_any_limit` 才能启用 Override Limits;非自由运动学或 identity kinematics 且 idle 才能 Touch Off。
|
||||
6. 有有效工具、task ON、idle、模式允许时才能 Tool Touch Off。
|
||||
7. MDI queue 未满才启用 MDI group。
|
||||
8. 非平凡 kinematics 的自由/joint 模式显示 joint numbers;没有全 homed 不能从 joint 切换到 world。
|
||||
|
||||
默认变量见 `axis.tcl:1941-1985`,至少包含 `rotate_mode`、`taskfile`、`task_state`、`task_mode`、`task_paused`、`optional_stop`、`block_delete`、`interp_pause`、`interp_state`、`running_line`、`highlight_line`、`coord_type`、`display_type`、`spindledir`、`motion_mode`、`kinematics_type`、`metric`、`queued_mdi_commands`。Web store 必须有等价字段或明确映射,不能删除门控原因。
|
||||
|
||||
快捷键基线:
|
||||
|
||||
| 键 | 功能 | 来源 |
|
||||
|---|---|---|
|
||||
| F1/F2 | 急停/电源 | `axis.tcl:105-113` |
|
||||
| O/Ctrl-R/Ctrl-S | Open/Reload/Save | `axis.tcl:55-76` |
|
||||
| R/T/P/S/Esc | Run/Step/Pause/Resume/Stop | `axis.tcl:117-144` |
|
||||
| Ctrl-M/Ctrl-H/Ctrl-Shift-H | MDI history | `axis.tcl:158-169` |
|
||||
| Ctrl-K/Ctrl-E | Clear live plot/Show PyVCP | `axis.tcl:378-387` |
|
||||
| F3/F5 | Manual/MDI tab | `axis.tcl:820-825` |
|
||||
| Home/End/Ctrl-End | Home/Touch Off/Tool Touch Off | `axis.tcl:2258-2260` |
|
||||
| F7/F8/F9/F10/F11/F12 | Mist/Flood/Spindle/速度 | `axis.tcl:2250-2257` |
|
||||
| X/Y/Z/A/4/5 | 轴激活 | `axis.tcl:2261-2266` |
|
||||
| Ctrl-Tab | Manual/MDI 切换 | `axis.tcl:1989-1996` |
|
||||
|
||||
## 4. LinuxCNC 源功能到 Web 实现的映射
|
||||
|
||||
### 4.1 分层映射原则
|
||||
|
||||
| 原始层 | Web 层 | 强制规则 |
|
||||
|---|---|---|
|
||||
| Tk widget/variable | React component + domain store | 控件可以换实现,字段名、启用条件、事件顺序不能换 |
|
||||
| AXIS command procedure | protocol command | 每个副作用动作有 `operation_id`、pending/ack/result/error、tick/hash |
|
||||
| LinuxCNC status/NML | Worker snapshot/event | UI 不可读取指针、共享内存或宿主 NML |
|
||||
| Gremlin/GLCanon | Three.js visual workflow | 只读 pose/joints/toolpath/stock/overlay;渲染失败不能改变仿真 |
|
||||
| Tcl external exec | Web panel or host boundary | 不可静默成功;必须有 capability result 和 source path |
|
||||
| Tk image | exact bitmap URL | 记录字节 hash,禁止同名替换 |
|
||||
| `state`/`relief` | `disabled`/`aria-pressed`/visual state | 状态由 authoritative snapshot 派生,不能由点击乐观设置 |
|
||||
|
||||
### 4.2 推荐组件和协议字段
|
||||
|
||||
```text
|
||||
AxisShell
|
||||
├─ AxisMenuBar File / Machine / View / Help
|
||||
├─ AxisToolbar exact source icons, order and tooltip
|
||||
├─ AxisNotebook
|
||||
│ ├─ ManualControl axis/joint, jog, home, touch-off, spindle, coolant
|
||||
│ └─ MDIControl history, command, go, queue gate
|
||||
├─ ViewNotebook
|
||||
│ ├─ Preview Three.js/trajectory/overlays
|
||||
│ └─ DRO machine/relative × actual/commanded × DTG
|
||||
├─ ProgramPane source, line selection, current line, active G-codes
|
||||
├─ OverridePane feed/rapid/spindle/jog/max velocity
|
||||
└─ AxisInfoBar task state, tool, position, alarm/recovery
|
||||
```
|
||||
|
||||
最低命令集合:`PROGRAM_LOAD`, `PROGRAM_RUN`, `PROGRAM_SEEK`, `PROGRAM_STEP`, `PROGRAM_PAUSE`, `PROGRAM_RESUME`, `PROGRAM_ABORT`, `MDI_EXECUTE`, `JOG_START`, `JOG_STOP`, `HOME`, `SET_MODE`, `SET_OVERRIDE`, `SPINDLE_COMMAND`, `COOLANT_COMMAND`, `TOOL_PREPARE`, `TOOL_CHANGE`, `PROBE_CONFIG`, `ESTOP`, `IO_RECOVER`, `HAL_COMMAND`, `SNAPSHOT_REQUEST`, `CHECKPOINT`, `RECOVER`。新增命令必须先更新 protocol capability、source map、replay fixture 和本规范任务表。
|
||||
|
||||
## 5. 严格对标流程
|
||||
|
||||
每个 AXIS 功能 ID 都必须独立走完以下流程;不允许把多个功能合并成一张“整体通过”截图。
|
||||
|
||||
### R0:冻结基线
|
||||
|
||||
1. 读取 `context-lock.json`、`linuxcnc/VERSION` 和 source commit。
|
||||
2. 计算源文件、图标、配置入口、HAL、TBL/VAR、程序和生成资源 hash。
|
||||
3. 记录 OS、浏览器、DPR、viewport、字体、语言、单位和启动参数。
|
||||
4. 若输入有未提交 runtime fixture,先分类 `source-owned`/`runtime-generated`/`user-approved-fixture`。
|
||||
|
||||
**退出条件**:source manifest、asset manifest、case manifest、运行环境 JSON 均 self-hashed;否则 STOP。
|
||||
|
||||
### R1:提取原始功能
|
||||
|
||||
1. 从 `axis.tcl` 的 menu/widget/proc/bind/state 定义生成 `axis-source-inventory.jsonl`。
|
||||
2. 从 `support.tcl`、`accel.tcl`、`gremlin.py`、`glcanon.py` 提取依赖动作、tooltip、视觉层和状态字段。
|
||||
3. 每个条目填写 `feature_id`, `source_path`, `source_lines`, `source_hash`, `ui_role`, `command`, `state_fields`, `external_boundary`。
|
||||
4. 把源代码中实际未实现/历史 wishlist 与当前功能分开,不把 wishlist 当现状。
|
||||
|
||||
**退出条件**:功能 ID 覆盖菜单、工具栏、Notebook、DRO、程序、状态、快捷键、图形和外部集成;任何未归属文件进入 audit 缺口。
|
||||
|
||||
### R2:建立协议和状态契约
|
||||
|
||||
1. 为每个命令定义输入 schema、能力条件、幂等键、成功结果、错误码和恢复语义。
|
||||
2. 为每个 UI 状态定义 authoritative snapshot 字段、派生选择器和 enabled predicate。
|
||||
3. 固定 `pending → ack → result/error`;ACK 不得被渲染为 verified。
|
||||
4. 录制最小 native trace:启动、加载、动作、step、快照、错误、恢复。
|
||||
|
||||
**退出条件**:同一操作可在 Worker replay 中重放;未定义的门控或错误不得进入 UI 实现。
|
||||
|
||||
### R3:实现结构和图标
|
||||
|
||||
1. 先实现 AXIS shell 和稳定布局,再接入动作;禁止用临时卡片替代原始区域。
|
||||
2. 按原始 pack 顺序加载 20 个 toolbar 图标,记录每个文件 byte hash、尺寸和 URL。
|
||||
3. 实现 File/Machine/View/Help 菜单和 Notebook;所有菜单 item 带稳定测试 ID。
|
||||
4. 对 canonical 1440×900、1280×800、390×844 截图并做 DOM geometry 检查。
|
||||
|
||||
**退出条件**:结构 diff 只剩有记录的字体/平台边界;工具栏顺序和 icon hash 100% 一致。
|
||||
|
||||
### R4:实现控制和门控
|
||||
|
||||
1. 先实现 ESTOP/OFF/ON/idle/reading/waiting/paused/limit/not-homed 状态转换。
|
||||
2. 再接 program/MDI/jog/home/touch-off/spindle/coolant/override。
|
||||
3. 每个 pointer/key 事件测试按下、移动、离开、释放、重复触发和 Worker 重启。
|
||||
4. 每个 disabled 状态测试“为什么 disabled”:UI 显示 source state、predicate 和 capability。
|
||||
|
||||
**退出条件**:状态矩阵的每一格都有 command trace 或明确 blocked 证据;没有基于本地 `useState` 的假成功。
|
||||
|
||||
### R5:实现预览、DRO 和编辑器
|
||||
|
||||
1. G-code load 后先产生解析/预览结果,再允许 run;程序预览、rapid、live plot、tool、offset、limits、grid 分层。
|
||||
2. DRO 实现 machine/relative、actual/commanded、DTG、unit、joint/world、large font。
|
||||
3. G-code editor 支持行号、当前行、高亮、选中行运行、错误列、滚动和程序 hash。
|
||||
4. 3D canvas 检查非空像素、有限坐标、视角、缩放、旋转和 resize;绘图线程不得改仿真 tick。
|
||||
|
||||
**退出条件**:同一 native/WASM trace 的当前行、DRO、path layer、tool pose、状态 hash 相同。
|
||||
|
||||
### R6:案例和外部边界
|
||||
|
||||
1. `minimal_xyz.ini`:关闭 Cartesian P0 核心闭环。
|
||||
2. `corexy_by_kins.ini` 与 `corexy_by_hal.ini`:分别验证 kinematics/HAL 路径。
|
||||
3. lathe、9-axis、gantry、nontrivial kinematics、iocontrolv2、vismach、PYVCP/GLADEVCP/NGCGUI 代表案例按 family 扩展。
|
||||
4. 每个 DISPLAY/插件声明都输出 Web capability、host boundary 和缺失资源;不能把外部 Python/Tk/动态 loader 当作浏览器已完成。
|
||||
|
||||
**退出条件**:每个案例有 exact resource graph、native startup、Worker startup、frontend mapping、差异和 self-hashed report。
|
||||
|
||||
### R7:视觉、交互和故障验收
|
||||
|
||||
1. DOM:区域、顺序、role、label、tooltip、快捷键、禁用/pressed、焦点顺序。
|
||||
2. Screenshot:canonical viewport 的结构区域、工具栏顺序、icon byte/尺寸、颜色/边框、文字和间距。
|
||||
3. Interaction:每个 command 的操作序列、pending/ack/result、错误和恢复。
|
||||
4. Fault:ESTOP、limit、following error、invalid G-code、HAL blocked、tool busy、OPFS quota、Worker crash/restart。
|
||||
5. Performance:首屏、Worker ready、snapshot latency、3D frame、stream backpressure、内存和长程序编辑器。
|
||||
|
||||
**退出条件**:报告包含失败截图/DOM/trace,而不是只有通过计数;任何 STOP 条件未关闭则 milestone 保持 blocked。
|
||||
|
||||
### R8:发布门禁
|
||||
|
||||
- `source_hash`, `asset_hash`, `case_hash`, `command_trace_hash`, `endpoint_hash`, `screenshot_hash` 全部可复现。
|
||||
- native、WASM、Worker、React、浏览器矩阵版本和运行参数明确。
|
||||
- host boundary、REAL-EXCLUDED、缺资源、官方 oracle 缺失和浏览器不支持分开统计。
|
||||
- 不以“实现存在”“构建通过”替代行为或视觉验收。
|
||||
- 报告自哈希失败、首个 divergent tick 未定位、恢复重复副作用、真实硬件误报或降低检查才能通过时立即 `STOP_RELEASE`。
|
||||
|
||||
## 6. 任务分解
|
||||
|
||||
任务状态初始为 `planned`。每个任务完成时必须提交代码、专属测试和 self-hashed evidence;依赖未完成不得跳过。
|
||||
|
||||
| 任务 ID | 任务 | 具体输出 | 依赖 | 专属验收 |
|
||||
|---|---|---|---|---|
|
||||
| AXIS-INV-01 | 冻结 AXIS 源 | source/version/environment manifest | 无 | R0 manifest hash |
|
||||
| AXIS-INV-02 | 生成 Tcl UI inventory | menu/widget/proc/bind/state JSONL | INV-01 | 每行 source path/line/hash |
|
||||
| AXIS-INV-03 | 生成 bitmap inventory | 20 toolbar + logo/spindle/std icon hash/size | INV-01 | byte hash、URL、尺寸一致 |
|
||||
| AXIS-INV-04 | 生成 AXIS case inventory | `configs/sim/axis` exact graph + DISPLAY family | INV-01 | 无 basename substitution |
|
||||
| AXIS-CON-01 | 状态枚举契约 | task/interp/motion/mode/coordinate/override/device schema | INV-02 | reducer/state contract tests |
|
||||
| AXIS-CON-02 | 命令和 ledger 契约 | command schema、idempotency、ack/result/error | CON-01 | duplicate/replay/cancel tests |
|
||||
| AXIS-CON-03 | 门控谓词契约 | `state()`/`relief()` 的 Web selector | CON-01 | 全状态矩阵覆盖 |
|
||||
| AXIS-CON-04 | 诊断和 boundary 契约 | host/Python/loader/real hardware 分类 | CON-02 | blocked 不得伪造成功 |
|
||||
| AXIS-UI-01 | AXIS shell | title、menu、main panes、responsive root | INV-02 | DOM geometry + screenshot |
|
||||
| AXIS-UI-02 | File menu | Open/Recent/Edit/Reload/Save/Properties/tool/ladder/Quit | UI-01, CON-02 | menu order + command trace |
|
||||
| AXIS-UI-03 | Machine menu | task controls、history、diagnostics、homing、offset、touch-off | UI-01, CON-03 | state-gated menu matrix |
|
||||
| AXIS-UI-04 | View menu | views、units、overlays、DRO、grid、teleop | UI-01, CON-01 | setting round-trip + screenshot |
|
||||
| AXIS-UI-05 | Exact toolbar | 20 icons、顺序、tooltip、pressed/disabled | INV-03, UI-01 | asset and DOM hash |
|
||||
| AXIS-UI-06 | Notebook shell | Manual/MDI、Preview/DRO tabs,焦点/快捷键 | UI-01 | tab switching/no reinit |
|
||||
| AXIS-UI-07 | Info/program panes | task/tool/position、G-code、active G-codes、scroll | UI-06, CON-01 | current-line/scroll tests |
|
||||
| AXIS-CTRL-01 | ESTOP/power/recover | task/IO 状态机和视觉 relief | CON-02, CON-03 | ESTOP fault/recover trace |
|
||||
| AXIS-CTRL-02 | Program controls | load/run/line-run/step/pause/resume/stop/restart | CTRL-01 | native vs Worker endpoint |
|
||||
| AXIS-CTRL-03 | MDI | command、history、Go、clipboard、queue gate | CTRL-01 | queue-full/history tests |
|
||||
| AXIS-CTRL-04 | Jog | axis/joint、continuous/increment、press/release/stop | CTRL-01 | release safety and replay |
|
||||
| AXIS-CTRL-05 | Home/touch-off | home、G54、tool offset、override limits | CTRL-04 | homing/limit/offset oracle |
|
||||
| AXIS-CTRL-06 | Spindle/coolant | direction、rpm delta、brake、mist/flood | CTRL-01 | IO/device result and fault |
|
||||
| AXIS-CTRL-07 | Overrides | jog/axis/max velocity/feed/rapid/spindle、metric | CTRL-01 | conversion and range tests |
|
||||
| AXIS-CTRL-08 | Keyboard map | F1/F2/F3/F5/R/T/P/S/Esc/O/Ctrl keys/F7-F12 | UI-06, CTRL-* | keyboard replay matrix |
|
||||
| AXIS-VIEW-01 | Preview parser | G-code path、rapid、dwell、current line | CTRL-02 | preview hash/line mapping |
|
||||
| AXIS-VIEW-02 | Camera | z/z2/x/y/y2/p、zoom、drag/rotate | UI-05, VIEW-01 | canvas nonblank + camera state |
|
||||
| AXIS-VIEW-03 | Overlays | live/tool/extents/grid/offset/limits/velocity/DTG | VIEW-01 | per-layer toggle screenshots |
|
||||
| AXIS-VIEW-04 | DRO | machine/relative × actual/commanded × DTG/units/font | CON-01, VIEW-01 | numeric endpoint parity |
|
||||
| AXIS-EDIT-01 | G-code editor | line numbers、highlight、selection、error column | CTRL-02 | selected-line/run/error tests |
|
||||
| AXIS-EDIT-02 | Tool table | edit/reload/current/prepared/pocket/hash | CTRL-06 | tool IO/native trace |
|
||||
| AXIS-EDIT-03 | Config/resource UI | INI/HAL/TBL/VAR/include graph and diagnostics | INV-04 | exact-path report |
|
||||
| AXIS-EXT-01 | HAL/PLC diagnostics | graph、pin、scope、ClassicLadder Web panels | CON-04 | virtual HAL/PLC replay |
|
||||
| AXIS-EXT-02 | PyVCP/GLADEVCP/NGCGUI | descriptor→Web component、Python boundary | AXIS-EDIT-03 | capability and blocked cases |
|
||||
| AXIS-CASE-01 | Minimal XYZ | native/WASM/Worker/frontend full controls | CTRL-*, VIEW-* | `minimal-xyz` report |
|
||||
| AXIS-CASE-02 | CoreXY dual path | kins vs HAL path | CASE-01 | two independent reports |
|
||||
| AXIS-CASE-03 | Lathe/9-axis/gantry | axis/joint/lathe variations | CASE-01 | case family matrix |
|
||||
| AXIS-CASE-04 | VisMach/5-axis | pose/joint/tool orientation/model/stock | VIEW-02, CASE-01 | visual + kinematics report |
|
||||
| AXIS-TEST-01 | DOM/accessibility | roles、labels、focus、tooltip、shortcut | UI-* | browser DOM report |
|
||||
| AXIS-TEST-02 | Canonical visual | 1440×900、1280×800、390×844 screenshots | UI-05, VIEW-* | pixel/geometry report |
|
||||
| AXIS-TEST-03 | Interaction replay | command/event/ack/error/recovery sequence | CTRL-*, EDIT-* | trace hash |
|
||||
| AXIS-TEST-04 | Native/WASM parity | endpoint/tick/state/error/plot hash | CASE-* | differential report |
|
||||
| AXIS-TEST-05 | Fault matrix | estop/limit/invalid/blocked/busy/quota/restart | CTRL-01, CON-04 | all failure samples retained |
|
||||
| AXIS-TEST-06 | Browser/performance | Chromium/Firefox/Safari、WebGL、OPFS、worker | TEST-01..05 | matrix report; blocked explicit |
|
||||
| AXIS-REL-01 | Evidence index | 每功能、任务、报告、hash、owner、date | TEST-* | self-hash + link audit |
|
||||
| AXIS-REL-02 | Release gate | license/NOTICE、boundary、STOP_RELEASE 决策 | REL-01 | no unresolved P0/P1 |
|
||||
|
||||
## 7. 验收里程碑
|
||||
|
||||
里程碑是累积门槛;后一个里程碑不能覆盖前一个未关闭的失败。
|
||||
|
||||
### M0:源基线冻结
|
||||
|
||||
**目标**:AXIS source/UI/asset/case inventory 可重复生成。
|
||||
**必须通过**:AXIS-INV-01…04;全部源引用、行号、hash 有效;不存在未分类的外部依赖。
|
||||
**证据**:`coverage/axis-source-inventory.report.json`、`coverage/axis-asset-inventory.report.json`、`coverage/axis-case-inventory.report.json`。
|
||||
**失败即停止**:源码提交、资源字节、案例资源或 fixture 变化未重新生成报告。
|
||||
|
||||
### M1:像素和结构对标
|
||||
|
||||
**目标**:首屏结构与原始 AXIS 一致。
|
||||
**必须通过**:AXIS-UI-01…07、AXIS-TEST-01/02。
|
||||
**硬门槛**:菜单四项顺序;toolbar 20 个图标顺序/byte hash/tooltip;Manual/MDI 与 Preview/DRO tab;程序区、Active G-Codes、info bar;canonical 桌面和窄屏无重叠、无裁切。
|
||||
**不计入通过**:只截图而没有 DOM geometry、asset URL、aria/tooltip 检查。
|
||||
|
||||
### M2:控制和状态门控对标
|
||||
|
||||
**目标**:每个按钮在与原始 AXIS 相同的状态下启用/禁用/pressed,并产生相同语义命令。
|
||||
**必须通过**:AXIS-CON-01…04、AXIS-CTRL-01…08、AXIS-TEST-03/05。
|
||||
**硬门槛**:ESTOP、OFF、ON、idle、reading、waiting、paused、limit、not-homed、queue-full 全矩阵;jog release safety;重复 operation 不产生副作用。
|
||||
**失败分类**:首个 divergent command/tick、错误码、门控谓词和恢复状态必须定位。
|
||||
|
||||
### M3:程序、MDI、DRO、预览对标
|
||||
|
||||
**目标**:G-code、MDI、程序预览、live plot、DRO、坐标/单位/模式全部对齐。
|
||||
**必须通过**:AXIS-VIEW-01…04、AXIS-EDIT-01、AXIS-CASE-01、AXIS-TEST-04。
|
||||
**硬门槛**:native/Worker 当前行、active G-codes、machine/relative、actual/commanded、DTG、metric、path layer、tool pose、state hash 一致;canvas 非空且切换视角不改变仿真结果。
|
||||
|
||||
### M4:工具、HAL、插件和外部边界
|
||||
|
||||
**目标**:工具表、主轴/IO、HAL/PLC、PYVCP/GLADEVCP/NGCGUI/VisMach 入口可用或明确 blocked。
|
||||
**必须通过**:AXIS-EDIT-02/03、AXIS-EXT-01/02、AXIS-CASE-02…04。
|
||||
**硬门槛**:所有 host-only 能力有 capability/boundary 记录;不允许用 mock 让外部菜单显示 verified;HAL pin 类型、线程顺序和工具 IO 事件可回放。
|
||||
|
||||
### M5:案例级 native/WASM/Worker/frontend parity
|
||||
|
||||
**目标**:代表案例及全量 AXIS 案例矩阵有 exact resource、startup、control、visual、recovery 证据。
|
||||
**必须通过**:AXIS-TEST-04、案例对标计划 S8-03…S8-10。
|
||||
**硬门槛**:每案例 endpoint/checkpoint/event hash 可重放;资源 blocker、host blocker、oracle blocker、error 分开;不能把 `STATIC READY` 当 `TASK_READY`。
|
||||
|
||||
### M6:浏览器、性能和恢复
|
||||
|
||||
**目标**:支持矩阵下 UI/Worker/OPFS/3D/恢复可复现。
|
||||
**必须通过**:AXIS-TEST-01…06。
|
||||
**硬门槛**:Chromium canonical visual/performance/recovery verified;Firefox/Safari/OPFS 若环境不支持则保留 blocked 证据;Worker crash/restart、offline、quota、half-commit 不丢 journal、不重复副作用。
|
||||
|
||||
### M7:发布关闭
|
||||
|
||||
**目标**:AXIS 对标交付有可审计证据和边界声明。
|
||||
**必须通过**:AXIS-REL-01/02、所有 P0/P1 条目、所有 release gate。
|
||||
**禁止发布**:视觉只验了 React 静态 DOM;native oracle 缺失未标记;浏览器矩阵未跑却宣称全平台;真实硬件/宿主能力被算作 Web 等价;报告无法自哈希。
|
||||
|
||||
## 8. 证据格式和差异判定
|
||||
|
||||
### 8.1 单功能 evidence schema
|
||||
|
||||
每个 `feature_id` 的报告至少包含:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": "axis-feature-evidence.v1",
|
||||
"feature_id": "AXIS-MANUAL-02",
|
||||
"status": "verified",
|
||||
"source": {
|
||||
"path": "linuxcnc/share/axis/tcl/axis.tcl",
|
||||
"lines": "893-924",
|
||||
"sha256": "..."
|
||||
},
|
||||
"web": {
|
||||
"paths": ["web/react/src/App.tsx", "web/react/src/worker-client.ts"],
|
||||
"selectors": ["[data-axis-feature=AXIS-MANUAL-02]"],
|
||||
"asset_urls": []
|
||||
},
|
||||
"protocol": {
|
||||
"commands": ["JOG_START", "JOG_STOP"],
|
||||
"operation_ids": ["..."],
|
||||
"capability_predicate": "task=ON && interp=IDLE && !ESTOP"
|
||||
},
|
||||
"oracle": {
|
||||
"native_trace_hash": "...",
|
||||
"worker_trace_hash": "...",
|
||||
"endpoint_hash": "...",
|
||||
"first_divergent_tick": null
|
||||
},
|
||||
"visual": {
|
||||
"viewport": "1440x900@1x",
|
||||
"dom_hash": "...",
|
||||
"screenshot_hash": "...",
|
||||
"asset_hashes": []
|
||||
},
|
||||
"failure_policy": "blocked|host_boundary|missing_oracle|resource|error",
|
||||
"report_sha256": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 差异判定顺序
|
||||
|
||||
出现差异时按以下顺序停止和定位:
|
||||
|
||||
1. source/config/resource hash 是否相同;
|
||||
2. 启动 phase 和 capability 是否相同;
|
||||
3. command kind、payload、seq、operation_id 是否相同;
|
||||
4. 第一个不同的 `simulation_tick`、task/interp/motion state;
|
||||
5. 事件顺序、错误码、alarm/recovery、checkpoint/event hash;
|
||||
6. 最后才比较 DOM geometry、样式和 canvas 像素。
|
||||
|
||||
不能先调 CSS 掩盖状态差异,也不能先放宽数值容差。数值容差应按来源类型登记:整数/枚举必须完全相等;位置/速度按固定浮点策略;哈希、事件序号、行号和命令序列不允许容差。
|
||||
|
||||
### 8.3 视觉判定
|
||||
|
||||
- **强等价**:布局区域、菜单顺序、工具栏顺序、原始 icon byte、控件 role/label、状态颜色和 disabled/pressed 必须精确。
|
||||
- **规范化等价**:浏览器字体抗锯齿、滚动条、系统 checkbox 外观可在 report 中 mask,但区域尺寸、文本内容、边界和可访问名称不能 mask。
|
||||
- **动态图层**:Three.js canvas 进行 nonblank/finite/pixel sample/相机状态检查;预览 path、tool、origin、grid、limit、live plot 分层截图。
|
||||
- **固定视口**:`1440×900@1x`、`1280×800@1x`、`390×844@1x`;另测 DPR 2,但不能以 DPR 2 代替 canonical。
|
||||
|
||||
## 9. 当前实现状态和下一步执行顺序
|
||||
|
||||
当前 React 已具备 AXIS 风格 shell、原始 bitmap toolbar、Manual/MDI 与 Preview/DRO 结构、Worker-backed program/MDI/jog/home/override/spindle/coolant/ESTOP/recover 入口和 Three.js 视角交互;这只证明实现切片,不等于本规范的 M1…M7 已验收。
|
||||
|
||||
M0 的第一步已经执行:[`coverage/axis-source-inventory.report.json`](../coverage/axis-source-inventory.report.json) 由 [`scripts/generate_axis_source_inventory.py`](../scripts/generate_axis_source_inventory.py) 生成,专属契约测试为 [`scripts/test_axis_source_inventory.py`](../scripts/test_axis_source_inventory.py),当前 `AXIS-INV-01=verified`,报告自哈希为 `b8456ef0fd5214fdea9ef7b05682e543173c898a83658d7b005b0922f8808be0`。该报告只冻结来源,不代表任何 Web 功能已通过行为或视觉验收。
|
||||
|
||||
接续执行顺序固定为:
|
||||
|
||||
1. `AXIS-INV-01` 已完成;接着执行 `AXIS-INV-02…04`,补齐可复现 source/UI/asset/case inventory。
|
||||
2. `AXIS-CON-01…04`:补齐状态门控、命令、错误和 host boundary schema。
|
||||
3. `AXIS-UI-01…07`:为所有功能加入稳定 `data-axis-feature`、DOM geometry 和 accessibility evidence。
|
||||
4. `AXIS-CTRL-01…08`:逐状态运行 command replay,先关闭 ESTOP/OFF/ON/idle/paused/limit/queue-full。
|
||||
5. `AXIS-VIEW-01…04` 和 `AXIS-EDIT-01`:完成预览层、DRO 模式和选中行程序工作流。
|
||||
6. `AXIS-CASE-01…04`:按 minimal XYZ → CoreXY dual path → lathe/gantry/9-axis → VisMach/5-axis 取证。
|
||||
7. `AXIS-TEST-01…06`:Chromium visual/interaction/performance/recovery,外加明确的 Firefox/Safari/OPFS blocker。
|
||||
8. `AXIS-REL-01/02`:只有所有 P0/P1 和报告自哈希通过,才更新 release gate。
|
||||
|
||||
第一批可执行命令:
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_baseline.py
|
||||
python3 scripts/validate_task_pointer.py
|
||||
sha256sum linuxcnc/share/axis/tcl/axis.tcl linuxcnc/lib/python/gremlin.py linuxcnc/lib/python/rs274/glcanon.py
|
||||
find linuxcnc/share/axis/images -maxdepth 1 -type f -printf '%f\n' | sort
|
||||
npm --prefix web/react run typecheck
|
||||
npm --prefix web/react run build
|
||||
for f in web/app/test_*.mjs; do node "$f" || exit 1; done
|
||||
```
|
||||
|
||||
执行者每完成一个任务,必须在对应报告中记录:源文件行号、Web 文件、命令/状态字段、测试命令、native/WASM/Worker 哈希、视觉视口、失败分类和下一依赖。没有这些字段的“完成”只算 `implementation_present`,不算 `verified`。
|
||||
|
||||
## 10. STOP_RELEASE 条件
|
||||
|
||||
出现以下任一项,立即停止扩大范围并将当前里程碑标为 `blocked`:
|
||||
|
||||
- AXIS 源、图标或案例输入变化但未重新生成 hash;
|
||||
- 首个 divergent command/tick 未定位;
|
||||
- UI 使用本地乐观状态伪造 task/position/IO 已执行;
|
||||
- jog release、急停、恢复或 checkpoint 可能重复副作用;
|
||||
- 缺少 native oracle 却宣称结果一致;
|
||||
- host-only、真实硬件、动态 loader、外部窗口被统计为 Web 已支持;
|
||||
- 视觉测试只比较截图,没有 DOM/交互/状态证据;
|
||||
- 浏览器或 OPFS 不支持被静默降级;
|
||||
- 任何报告无法用固定输入重新生成或 self-hash 不一致。
|
||||
|
||||
本规范关闭的是“AXIS 对标工程”而不是“LinuxCNC 全功能发布”声明。所有未实现、缺资源、无官方 oracle、浏览器边界和真实硬件排除项都必须保留在最终 evidence index 中。
|
||||
49
docs/linuxcnc-web-wasm-autonomous-execution-prompt.md
Normal file
49
docs/linuxcnc-web-wasm-autonomous-execution-prompt.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# 持续执行提示词
|
||||
|
||||
本文是本仓库的持续执行操作提示词。用户只需要说“按 `nextTask1.md` 接续执行”,代理就应按当前指针自动认领并推进任务;不需要每轮重复粘贴完整规则。
|
||||
|
||||
## 可直接使用的提示词
|
||||
|
||||
```text
|
||||
你是这个仓库的持续执行工程代理。请在当前工作区内持续推进任务,不要只给计划,不要在完成一个任务后停下来询问是否继续。
|
||||
|
||||
每轮执行以下流程:
|
||||
|
||||
1. 读取 `nextTask1.md` 的 `Current`、`Task`、`Next`、`Verify`、`Stop`。
|
||||
2. 运行 `python3 scripts/validate_baseline.py` 和 `python3 scripts/validate_task_pointer.py nextTask1.md`。
|
||||
3. 认领当前 `Next` 任务,将其写为 `in_progress`,确认 task_id、context_id、直接输入和完成报告。
|
||||
4. 先写专项测试和失败边界,再实现最小可验证垂直切片;复用现有 ABI、protocol、schema、模块和测试。
|
||||
5. LinuxCNC 源测试必须保留原始路径、输入、expected/checkresult、source hash 和适配分类;不得用自建 smoke test 冒充官方 oracle。
|
||||
6. 每个任务必须保留正常、边界、错误、非有限值、容量、pause/resume/abort、恢复和确定性 hash/golden 证据(适用时)。
|
||||
7. 运行任务专属测试、`scripts/build-wasm.sh`、native CTest、全部 Worker 测试和全部 App 测试。
|
||||
8. 失败样本必须保留并明确标记为 `SOURCE_BLOCKED`、`HOST_EXCLUDED`、`REAL-EXCLUDED` 或具体 Worker/Task/motion pending;不得降低检查、删除失败或伪造通过。
|
||||
9. 任务完成后生成自哈希报告,更新 `nextTask1.md` 和 `docs/task-history.md`,将下一个依赖满足的任务写入 `Next`,然后在同一轮立即把该任务认领为 `in_progress` 并继续执行;不得在 `verified + queued` 状态结束本轮。
|
||||
10. 保留工作区已有改动,不使用 `git reset --hard`、`git checkout --` 或其他破坏性回退命令。
|
||||
11. 远程 compact、网络断开或会话恢复后,重新读取 `nextTask1.md` 和已有报告,从最近的 `in_progress` 任务继续,不从头重做。
|
||||
12. 只有 `nextTask1.md` 明确 `next_task: none`,或当前任务进入 `blocked` 且需要用户提供外部源码、权限、owner 决策或新 context 时才暂停;外部阻塞要保留证据并说明原因。
|
||||
|
||||
工作期间每隔约 30 秒发送简短进度更新。最终汇报实际完成项、测试结果、未闭合阻塞和下一个任务,不把模块测试通过说成全功能完成。
|
||||
|
||||
现在立即从 `nextTask1.md` 当前指针开始执行。
|
||||
```
|
||||
|
||||
## 执行边界
|
||||
|
||||
- `nextTask1.md` 是唯一任务状态入口;本文件只提供操作规则,不保存任务状态或聊天历史。
|
||||
- 任务只能按 `queued -> in_progress -> verified` 或 `in_progress -> blocked` 转移。
|
||||
- `SOURCE_BLOCKED`、`HOST_EXCLUDED`、`REAL-EXCLUDED` 和官方 oracle 缺失不计入通过,但必须出现在报告中。
|
||||
- 任务队列为空时不得自行发明 release、owner 或新 context 任务;需要新阶段时先创建有直接输入、专项测试和完成报告的正式任务。
|
||||
- 所有报告必须包含 context、输入/输出 hash、测试命令、差异或首个 divergent tick、已知边界和 self-hash。
|
||||
|
||||
## 标准收口门禁
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_baseline.py
|
||||
python3 scripts/validate_task_pointer.py nextTask1.md
|
||||
scripts/build-wasm.sh
|
||||
ctest --test-dir build-native --output-on-failure
|
||||
for f in web/worker/test_*.mjs; do node "$f" || exit 1; done
|
||||
for f in web/app/test_*.mjs; do node "$f" || exit 1; done
|
||||
python3 scripts/validate_baseline.py
|
||||
python3 scripts/validate_task_pointer.py nextTask1.md
|
||||
```
|
||||
153
docs/linuxcnc-web-wasm-case-parity-plan.md
Normal file
153
docs/linuxcnc-web-wasm-case-parity-plan.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# LinuxCNC Simulation Case Parity Plan
|
||||
|
||||
This plan is the execution queue for making the real cases under
|
||||
`linuxcnc/configs/sim` behave like LinuxCNC in the browser. It supplements the
|
||||
implementation roadmap with case-level acceptance rules and keeps source
|
||||
resource blockers explicit.
|
||||
|
||||
## Baseline
|
||||
|
||||
- Locked source: LinuxCNC `2.10.0~pre0`, commit `239dcf4284762ad7e9c65d390bc5524d855c2f8e`.
|
||||
- Case catalog: 235 INI entrypoints and 2,080 exact files under `configs/sim` plus LinuxCNC HAL support files.
|
||||
- Existing matrix: 264 registered configuration entries, 233 entrypoints, 56 static-ready and 208 blocked.
|
||||
- Browser entrypoint: exact-path case loader, Worker startup diagnostics, G-code/MDI/manual controls and machine view are implemented by S8-01.
|
||||
- Real LinuxCNC condition evidence: `coverage/native-linuxcnc-case-conditions.report.json`.
|
||||
- Current hard blocker: source-owned `sim.var`, `linuxcnc.var` and `tool.tbl` contents are absent for the selected minimal/CoreXY cases; S8-02 remains blocked.
|
||||
|
||||
## Parity Contract
|
||||
|
||||
An individual case is `verified` only when all of these records exist for the same locked source and case hash:
|
||||
|
||||
1. Exact INI/include/resource graph with no basename substitution.
|
||||
2. Native LinuxCNC run using the same case files and an explicit runtime directory policy.
|
||||
3. WASM core and Worker startup state, diagnostic code, source line and state hash.
|
||||
4. Fixed-tick golden covering load, home, jog, MDI, run, pause/resume, abort, estop, IO and recovery as applicable.
|
||||
5. HAL graph/component status and all unsupported host operations classified.
|
||||
6. Frontend control mapping from the case's `DISPLAY`, VCP/PyVCP/GladeVCP/QtVCP/Gscreen/Touchy/VisMach declarations to authoritative Worker state.
|
||||
7. Checkpoint/replay endpoint equality and a self-hashed case report.
|
||||
|
||||
`STATIC READY` is only an index classification. It never promotes a case to
|
||||
runtime `TASK_READY` without the native and Worker startup records above.
|
||||
|
||||
## Queue
|
||||
|
||||
### S8-02: Close One Real Case
|
||||
|
||||
Status: `verified`.
|
||||
|
||||
The user-authorized runtime fixture contract is complete. Real LinuxCNC
|
||||
execution supplied `sim.var`, generated `minimal_xyz_cmds.hal`,
|
||||
`linuxcnc.var`, and the selected sim tool table. Their target paths and SHA-256
|
||||
values are recorded in `coverage/sim-case-startup-s8-02.report.json`.
|
||||
Minimal XYZ and CoreXY both reach Worker `TASK_READY`; same-basename files from
|
||||
unrelated cases remain forbidden.
|
||||
|
||||
### S8-03: Lock Runtime Resource Inputs
|
||||
|
||||
Status: `verified`, depends on S8-02.
|
||||
|
||||
- Pin the native LinuxCNC package/source version used as oracle.
|
||||
- Decide and record whether parameter files and tool tables are source-owned,
|
||||
generated-at-startup, or approved deterministic fixtures.
|
||||
- Store every accepted fixture with source path, generator/command, bytes,
|
||||
SHA-256 and mutation policy.
|
||||
- Extend the browser workspace transaction to model LinuxCNC parameter-file
|
||||
creation/update without host filesystem access.
|
||||
- Re-run minimal and CoreXY native cases in isolated writable directories.
|
||||
|
||||
Exit: no unresolved resource input for the selected XZ batch; report
|
||||
`coverage/sim-case-batch-s8-03.report.json` records all three TASK_READY states.
|
||||
|
||||
### S8-04: Minimal XYZ Vertical Slice
|
||||
|
||||
Status: `verified`, depends on S8-03.
|
||||
|
||||
- Native/WASM/Worker startup reaches `TASK_READY` for `minimal_xyz.ini`.
|
||||
- Compare a fixed G-code program, MDI, home, XYZ jog, feed override, pause,
|
||||
abort, estop/recover and checkpoint restore.
|
||||
- Drive the frontend case panel and machine view from Worker snapshots only.
|
||||
- Preserve LinuxCNC's generated `sim.var` semantics as a workspace transaction.
|
||||
|
||||
Evidence: `coverage/minimal-xyz-vertical-s8-04.report.json`.
|
||||
|
||||
### S8-05: CoreXY Dual Path
|
||||
|
||||
Status: `verified`, depends on S8-03 and S8-04.
|
||||
|
||||
- Verify both `corexy_by_kins.ini` and `corexy_by_hal.ini`.
|
||||
- Compare CoreXY kinematics joints, HAL signal graph, home behavior and
|
||||
following-error/limit boundaries.
|
||||
- Keep the HAL implementation path distinct from the kinematics path in the
|
||||
case report and UI diagnostics.
|
||||
|
||||
Evidence: `coverage/corexy-dual-path-s8-05.report.json`.
|
||||
|
||||
### S8-06: Resource and Startup Matrix
|
||||
|
||||
Status: `verified`, depends on S8-04 and S8-05.
|
||||
|
||||
- Execute all 235 browser case bundles with exact resource closure.
|
||||
- Re-run native LinuxCNC for every case whose resources are complete.
|
||||
- Classify each case as `TASK_READY`, `BLOCKED_RESOURCE`,
|
||||
`BLOCKED_HOST_CAPABILITY`, `BLOCKED_SOURCE_ORACLE` or `ERROR`.
|
||||
- Record the first divergent startup phase, source line and missing capability;
|
||||
never collapse failures into a single count.
|
||||
|
||||
Evidence: `coverage/sim-case-matrix-s8-06.report.json`.
|
||||
|
||||
### S8-07: Display and Control Families
|
||||
|
||||
Status: `queued`, depends on S8-06.
|
||||
|
||||
Implement and verify case-declared frontend behavior in separate families:
|
||||
|
||||
- Axis: DRO, mode, jog, homing, overrides, program/run controls and plot.
|
||||
- QtVCP/Gscreen: VCP pins, dialogs, tool/probe/spindle panels and custom tabs.
|
||||
- GladeVCP/PyVCP: declared pins/widgets and explicit host-loader boundaries.
|
||||
- Touchy/halui: touchscreen jog/MDI and mode controls.
|
||||
- VisMach: kinematics-specific machine geometry, joints, toolpath and stock.
|
||||
|
||||
Each family must consume Worker authoritative state and retain unsupported
|
||||
GUI/plugin actions as diagnostics rather than silently dropping them.
|
||||
|
||||
### S8-08: Machine Families
|
||||
|
||||
Status: `verified`, depends on S8-06.
|
||||
|
||||
Close representative cases for Cartesian, lathe, gantry, CoreXY, Delta,
|
||||
Tripod, Pentapod, Hexapod, 5-axis/TRT, SCARA/PUMA/GenSer and wrapped rotary.
|
||||
Use the existing native/WASM kinematics tests as golden inputs, then add the
|
||||
case-specific INI/HAL/resource/startup and frontend evidence.
|
||||
|
||||
Current evidence: `coverage/machine-families-s8-08.report.json` covers the
|
||||
real lineardelta/rdelta cases; remaining listed families continue in later
|
||||
slices.
|
||||
|
||||
### S8-09: Program and Runtime Extensions
|
||||
|
||||
Status: `verified`, depends on S8-06.
|
||||
|
||||
Cover real cases using remap/Python, O-word/subroutines, filters, ClassicLadder,
|
||||
tool changers, spindle orient, external offsets, probing and IO acknowledgements.
|
||||
Every host-only operation must have an explicit capability result and a
|
||||
browser-equivalent path where one is supported.
|
||||
|
||||
Evidence: `coverage/runtime-extensions-s8-09.report.json`.
|
||||
|
||||
### S8-10: Full Case Acceptance
|
||||
|
||||
Status: `queued`, depends on S8-07, S8-08 and S8-09.
|
||||
|
||||
- Run the 235-case matrix in deterministic batches.
|
||||
- Compare native and Worker endpoint/checkpoint/event hashes.
|
||||
- Run the browser control matrix at the supported browser versions.
|
||||
- Publish accepted/blocked/error rows with input and report hashes.
|
||||
- Keep official oracle, license, browser and owner/release blockers separate
|
||||
from implementation coverage.
|
||||
|
||||
## Resume Gate
|
||||
|
||||
The next executable action is S8-03 only after the missing parameter/tool
|
||||
inputs are supplied or explicitly approved as deterministic fixtures. Until
|
||||
then, the project remains implementation-capable but not a complete
|
||||
LinuxCNC-parity release candidate.
|
||||
271
docs/linuxcnc-web-wasm-complete-simulation-plan.md
Normal file
271
docs/linuxcnc-web-wasm-complete-simulation-plan.md
Normal file
@@ -0,0 +1,271 @@
|
||||
# LinuxCNC Web/WASM 完整仿真移植实施计划
|
||||
|
||||
**版本**:1.0
|
||||
**状态**:implementation baseline
|
||||
**目标基线**:仓库 `context-lock.json` 锁定的 LinuxCNC 版本
|
||||
**接续入口**:[`nextTask1.md`](../nextTask1.md)
|
||||
**已有专项资料**:
|
||||
|
||||
- [`linuxcnc-web-wasm-full-port-implementation.md`](linuxcnc-web-wasm-full-port-implementation.md)
|
||||
- [`linuxcnc-web-wasm-simulation-coverage.md`](linuxcnc-web-wasm-simulation-coverage.md)
|
||||
- [`linuxcnc-web-wasm-source-map.md`](linuxcnc-web-wasm-source-map.md)
|
||||
- [`linuxcnc-web-wasm-frontend-communication-design.md`](linuxcnc-web-wasm-frontend-communication-design.md)
|
||||
- [`linuxcnc-web-wasm-kinematics-migration-plan.md`](linuxcnc-web-wasm-kinematics-migration-plan.md)
|
||||
|
||||
本文件是“完整仿真移植”实施轨道的唯一执行目录。仿真实现不依赖 release、owner、许可证审批或发布候选流程;这些内容不参与仿真任务的排队、执行和验收。
|
||||
|
||||
## 1. 目标和边界
|
||||
|
||||
### 1.1 目标
|
||||
|
||||
在浏览器 Dedicated Worker 中运行 LinuxCNC 的可观察仿真行为,使用 WASM 承载数值密集型核心,使用 Web API 承载工程、恢复、界面和可视化。用户应能:
|
||||
|
||||
1. 导入或创建一个 LinuxCNC 仿真工程。
|
||||
2. 解析 INI/HAL/工具表/参数/程序/Python/VCP/ClassicLadder 等资源。
|
||||
3. 启动仿真并看到确定性的 `READY`、`RUNNING`、`PAUSED`、`ESTOP`、`FAULT`、`STOPPED` 状态。
|
||||
4. 执行 G-code、MDI、jog、home、pause、resume、single-step、abort、override 和模式切换。
|
||||
5. 观察轴/关节/姿态/轨迹、HAL pin/signal、主轴、工具、探针、限位、冷却、报警和 Python/VCP 状态。
|
||||
6. 注入故障、暂停、导出 checkpoint、刷新 Worker、从 OPFS 恢复并得到相同的确定性终点。
|
||||
7. 对纳入范围的 `configs/sim` 入口给出 `READY` 或可定位的 `BLOCKED/ERROR`,不静默跳过资源。
|
||||
|
||||
### 1.2 仿真范围
|
||||
|
||||
以下行为必须实现或有原生/WASM 对照证据:
|
||||
|
||||
| 功能域 | 必须覆盖的行为 | 浏览器实现边界 |
|
||||
|---|---|---|
|
||||
| 工程与配置 | workspace、INI/include/变量、HAL、工具表、参数、程序、Python、VCP、ClassicLadder、资源错误 | `/workspace` 虚拟文件系统;禁止宿主绝对路径、`..`、符号链接逃逸 |
|
||||
| Task/命令 | mode、MDI、program load/run/pause/resume/step/abort、错误、状态、operation ledger | Worker 单写者;主线程只能发送版本化命令 |
|
||||
| 解释器 | G/M/O words、模态、单位、坐标、参数、子程序、循环、宏、过滤器和错误行号 | 运行在 WASM/Python Worker;能力拒绝必须稳定 |
|
||||
| TP/motion | canonical queue、直线/圆弧/同步运动、速度/加速度/jerk、blend、exact stop、暂停和恢复 | 逻辑 tick 取代硬实时墙钟,保持顺序和结果确定 |
|
||||
| 运动学 | trivkins、gantry/CoreXY、5/6 轴、TRT、机器人、Delta/Tripod/Hexapod/Pentapod、switchkins/userk | 静态链接、注册表选择;动态模块加载不进入浏览器 |
|
||||
| 轴/关节 | joint/axis 映射、home、软限位、following error、外部偏置、jog、override、estop | 由数字孪生提供输入和故障状态 |
|
||||
| HAL/组件 | pin、signal、parameter、thread、function、addf、setp、net、twopass、`.comp` 静态组件 | 组件不得访问宿主设备、进程、网络或动态库 |
|
||||
| PLC/IO | ClassicLadder scan、寄存器、定时器、计数器、数字/模拟 IO、采样、触发、背压 | 虚拟寄存器和逻辑设备;真实 transport 为 `REAL-EXCLUDED` |
|
||||
| 设备数字孪生 | 主轴、编码器、探针、限位、home、换刀、冷却/润滑、故障/延迟/抖动 | 故障注入必须可记录、回放、恢复,不使用未固定的随机数 |
|
||||
| Python/remap/VCP | 白名单模块、参数/工具/INI API、remap/filter 生命周期、VCP pin/回调/异常 | Pyodide Worker;`subprocess/socket/device files` 明确拒绝 |
|
||||
| 持久化/恢复 | journal、checkpoint、snapshot、event replay、Worker restart、OPFS quota、migration、rollback、offline | OPFS 只保存已提交数据,不参与运动计算 |
|
||||
| Web 工作流 | 编辑器、MDI、控制台、HAL/PLC 面板、报警、恢复向导、轨迹和机床可视化 | UI 只消费 authoritative snapshot/event,不反写核心状态 |
|
||||
|
||||
### 1.3 明确排除
|
||||
|
||||
以下是宿主能力排除,不是仿真行为排除:
|
||||
|
||||
- 真实 PCI/USB/串口/GPIO/并口、真实伺服和真实安全回路。
|
||||
- Linux PREEMPT_RT、内核线程、共享内存 NML/CMS 进程边界、`fork/exec` 和动态 `.so` 加载。
|
||||
- 浏览器无法提供的设备文件、任意宿主路径、任意网络 socket 和真实硬件时钟。
|
||||
|
||||
被排除的宿主层必须返回稳定的 `REAL-EXCLUDED` 错误;对应的轴、主轴、编码器、探针、限位、换刀和 IO 仍必须由数字孪生覆盖。
|
||||
|
||||
## 2. 架构和不变量
|
||||
|
||||
```text
|
||||
Web UI / Editor / Three.js
|
||||
│ protocol.v1
|
||||
Dedicated Worker
|
||||
CommandRouter → TaskLedger → SimScheduler
|
||||
├─ SimTask / rs274 / canonical
|
||||
├─ TP / posemath / kinematics
|
||||
├─ SimMotion / home / limits
|
||||
├─ SimHAL / components / ClassicLadder
|
||||
├─ SimIO / digital twins
|
||||
└─ PythonRuntime / remap / VCP
|
||||
├─ SnapshotPublisher / EventBus / TraceRecorder
|
||||
└─ WorkspaceRuntime → WasmFS/POSIX → OPFS journal/checkpoint
|
||||
│
|
||||
└─ native oracle 使用同一输入和命令序列
|
||||
```
|
||||
|
||||
必须保持以下不变量:
|
||||
|
||||
1. Worker 是唯一 authoritative state 写者;UI 不读取 WASM 指针,不直接写 HAL/OPFS。
|
||||
2. `sim_step(cycles)` 是唯一改变仿真结果的入口;墙钟只负责调度和让出事件循环。
|
||||
3. 命令按 `seq` 顺序提交,`operation_id` 幂等;确认丢失先对账,不重复执行副作用。
|
||||
4. 固定宽度 ABI、明确的 protocol/snapshot/event/workspace schema 和稳定错误码优先于 UI 便利。
|
||||
5. 状态、事件、轨迹、HAL、IO、Python 和恢复结果都能产生确定性 hash。
|
||||
6. 缺少输入、未支持能力、配额不足、非法路径、非有限数和 schema mismatch 必须 fail closed。
|
||||
7. 任何 native/WASM 差异都保留首个 divergent tick、字段路径、单位、容差和来源证据。
|
||||
|
||||
### 2.1 固定 tick 顺序
|
||||
|
||||
每一个逻辑 tick 依次执行:
|
||||
|
||||
1. 对账并去重已确认命令。
|
||||
2. 执行 Task/解释器预算,更新模态、参数、当前行和 canonical。
|
||||
3. 执行 TP 前瞻、速度/加速度/jerk、blend/exact-stop。
|
||||
4. 调用 kinematics inverse,检查奇异性、joint 数量、limits 和 NaN/Inf。
|
||||
5. 更新 motion、home、jog、following error、外部偏置、estop/limit。
|
||||
6. 按静态线程/function 顺序运行 HAL、组件、编码器、主轴、探针、换刀和 PLC scan。
|
||||
7. 运行 IO 完成、超时、报警、Python/remap/VCP 回调;回调不能越过当前 tick。
|
||||
8. 生成 snapshot/event/trace/state hash,再执行已提交 checkpoint/journal。
|
||||
|
||||
快速运行、1x、单步、暂停恢复、导出导入和 replay 在相同逻辑终点必须得到相同 hash。
|
||||
|
||||
## 3. 功能实施顺序
|
||||
|
||||
### F0:输入、来源和契约
|
||||
|
||||
- 以 `context-lock.json`、source index、manifest、config resource graph 和 protocol schema 为输入。
|
||||
- 为每个 source/file/symbol/config/test 建立 `source_id → feature_id → task_id → test_id → oracle_id` 关系。
|
||||
- 固定 `sim_task.v1`、`command-envelope.v1`、`snapshot.v1`、`event-log.v1`、`workspace-package.v1` 的字段、版本和错误策略。
|
||||
- 缺少官方测试输入时保留 `blocked`,不得用近似目录伪装官方 oracle。
|
||||
|
||||
### F1:运行时骨架
|
||||
|
||||
- 建立 `SimTask`、`SimScheduler`、`TaskLedger`、`SnapshotPublisher` 和 `EventBus`。
|
||||
- 把现有 WASM lifecycle、fixed tick、event、snapshot、G-code runner 接入 authoritative task state。
|
||||
- 增加容量、非有限值、取消、abort、pause/resume、operation replay 和 checkpoint 边界。
|
||||
|
||||
### F2:工作区和配置启动
|
||||
|
||||
- 实现虚拟 POSIX 文件 API、规范化路径、大小/配额和事务写入。
|
||||
- 解析 INI/include/变量,解析 HAL/工具表/参数/程序/Python/VCP/ClassicLadder 资源图。
|
||||
- 统一 `NEW → MOUNTED → PARSED → RESOLVED → CORE_CREATED → HAL_READY → TASK_READY` 状态机。
|
||||
- 每个 `configs/sim` 入口输出 `READY` 或带文件/行/字段/source_id 的诊断。
|
||||
|
||||
### F3:解释器、Task、TP、motion、kinematics
|
||||
|
||||
- 先让 native oracle 输出每个 block 的 modal/canonical/参数和错误,再接入 WASM。
|
||||
- 接入 O-word/子程序/循环/参数/宏/remap/filter、MDI、program state machine。
|
||||
- 将 canonical queue 连接 TP、motion 和 kinematics;实现暂停、单步、abort、jog、home、override、limits、following error。
|
||||
- 按 kinematics registry 逐族接入并保留每个族的 forward/inverse、branch、singularity 和 limit 证据。
|
||||
|
||||
### F4:HAL、PLC、IO 和数字孪生
|
||||
|
||||
- 解析并执行 pin/signal/parameter/thread/function、`loadrt/addf/setp/net/sets/link*` 和静态 `.comp`。
|
||||
- 实现 ClassicLadder 工程、scan、寄存器、计数器、定时器、HAL 绑定和诊断。
|
||||
- 接入 spindle/encoder/probe/limit/home/tool/coolant/IO,支持故障注入、延迟、抖动、恢复和回放。
|
||||
|
||||
### F5:Python、remap、VCP
|
||||
|
||||
- 固定 Pyodide 版本、manifest、模块白名单、内存/时间/源码限制。
|
||||
- 实现 `linuxcnc/hal/gstat/INI/tool/parameter/workspace/virtual-clock` 兼容 API。
|
||||
- 接入 remap/filter 生命周期、VCP descriptor、pin callback、异常隔离和权限拒绝。
|
||||
|
||||
### F6:恢复、离线和迁移
|
||||
|
||||
- 将 Task、解释器、TP、motion、kinematics、HAL、IO、Python、workspace 和 ledger 纳入 checkpoint。
|
||||
- 实现 journal prepare/commit、确认丢失对账、崩溃恢复、OPFS quota、离线包、版本迁移和 rollback。
|
||||
- 恢复必须从最近有效 checkpoint 重放已提交 event,不得只重新加载配置。
|
||||
|
||||
### F7:Web 工作流和可视化
|
||||
|
||||
- 完善工程导入、编辑器诊断、MDI、run/pause/step/abort、jog/home/override、HAL/PLC/IO/报警面板。
|
||||
- 以 authoritative snapshot/event 驱动姿态、joint、toolpath、stock、坐标系、工具、主轴和故障渲染。
|
||||
- 用 Worker 重启、离线、配额和错误场景覆盖 UI 恢复向导;不使用 mock 替代真实 Worker。
|
||||
|
||||
### F8:全量兼容、性能和交付
|
||||
|
||||
- 对所有纳入范围的 `configs/sim`、相关 tests/unit_tests 和资源入口执行 native/WASM 差异矩阵。
|
||||
- 固定至少三次重复、快速/1x/单步/恢复、浏览器矩阵、性能、内存和离线报告。
|
||||
- 许可证、来源、下载、迁移、回滚和 REAL-EXCLUDED 边界全部有证据;只有所有 gate 满足时才讨论 release candidate。
|
||||
|
||||
## 4. 任务分解
|
||||
|
||||
任务状态只能按 `queued → in_progress → verified` 或 `in_progress → blocked` 转移。每个任务只有一个主要结果,并必须提供输入 context、直接证据、专属测试、完整回归和回滚点。
|
||||
|
||||
| ID | 任务 | 依赖 | 主要产物 | 验收重点 |
|
||||
|---|---|---|---|---|
|
||||
| P0-01 | 冻结来源、工具链、schema 和 source hash | 无 | context/source baseline | baseline 可重建,缺输入 fail closed |
|
||||
| P0-02 | 建立 source→feature→task→test 图 | P0-01 | coverage graph/manifest | 无孤儿、重复、未知 ID |
|
||||
| P0-03 | 固定 ABI/protocol/snapshot/event/workspace 契约 | P0-01 | schema + compatibility tests | 版本 mismatch 和字段缺失拒绝 |
|
||||
| P1-01 | 建立 `sim_task.v1` authoritative 状态对象 | P0-03 | Task state/native/WASM tests | state hash、状态机、错误码一致 |
|
||||
| P1-02 | 固定 `sim_step` 调度顺序和 tick budget | P1-01 | scheduler + tick golden | 快速/1x/单步终点一致 |
|
||||
| P1-03 | 接入 command ledger、幂等和 abort | P1-01 | ledger/replay tests | operation replay 不重复副作用 |
|
||||
| P1-04 | 将现有 G-code/MDI runner 接入 Task snapshot | P1-01 | Worker/native/WASM report | 当前行、模态、程序状态可观察 |
|
||||
| P2-01 | 虚拟 POSIX/Workspace API | P1-01 | workspace runtime | 路径、编码、配额、事务错误稳定 |
|
||||
| P2-02 | INI/include/变量解析器 | P2-01 | parser/resource graph | 行号、循环、缺失资源可诊断 |
|
||||
| P2-03 | HAL/工具表/参数/程序/Python/VCP/CLP resolver | P2-01 | config resource graph | 所有依赖可定位、不静默替换 |
|
||||
| P2-04 | 统一配置启动状态机 | P2-02/P2-03/P1-02 | startup resolver/233-entry report | 入口只进入 READY 或 BLOCKED |
|
||||
| P3-01 | rs274 grammar/modal/parameter 完整闭环 | P1-04 | native/WASM interpreter oracle | block、错误列和 modal hash 一致 |
|
||||
| P3-02 | O-word、子程序、循环、宏和过滤器 | P3-01/P5-02 | interpreter golden | 深度、预算、异常边界完整 |
|
||||
| P3-03 | canonical queue、TP 前瞻、blend/exact-stop | P1-02/P3-01 | TP golden/diff report | segment 顺序、速度和首差 tick |
|
||||
| P3-04 | Task mode、MDI、program state machine | P1-03/P3-01 | command golden | run/pause/resume/step/abort 可恢复 |
|
||||
| P3-05 | motion、jog、override、home、limits、following error | P3-03 | motion state/故障矩阵 | 轴/关节、estop、limit、home 一致 |
|
||||
| P3-06 | kinematics registry 和 trivkins/gantry/CoreXY | P3-05 | registry + native/WASM tests | forward/inverse/branch/limits |
|
||||
| P3-07 | 5/6-axis、TRT、机器人、并联和 switch/user kins | P3-06 | 每族 report/golden | singularity、非有限、缺 oracle 明确 |
|
||||
| P4-01 | HAL graph/twopass/pin/signal/thread/function | P2-03/P1-02 | HAL graph/runtime | 顺序、类型、重复、未知组件 fail closed |
|
||||
| P4-02 | 静态 `.comp` 组件和能力 manifest | P4-01 | component manifest/tests | 不动态加载、不访问宿主 |
|
||||
| P4-03 | ClassicLadder/采样/触发/背压 | P4-01 | PLC runtime/report | scan 顺序、寄存器、故障可回放 |
|
||||
| P4-04 | spindle/encoder/probe/limit/home/tool/coolant twin | P4-01/P3-05 | device model/fault matrix | 延迟、故障、恢复、hash 一致 |
|
||||
| P4-05 | IO command/ack/timeout/estop/recover | P4-04/P1-03 | IO Worker/native tests | ack 丢失和恢复不重复副作用 |
|
||||
| P5-01 | Pyodide runtime、模块白名单和虚拟时钟 | P2-01 | runtime manifest/report | 资源和能力限制稳定 |
|
||||
| P5-02 | Python linuxcnc/hal/INI/tool/parameter API | P5-01/P3-04 | API compatibility tests | 正常、异常、禁止能力 |
|
||||
| P5-03 | remap/filter/VCP callback 和隔离 | P5-02/P4-01 | remap/VCP report | 异常不破坏 Worker 核心 |
|
||||
| P6-01 | snapshot/event/trace 全状态导出 | P1-02/P3-05/P4-05/P5-03 | schema/hash tests | 导入导出 round-trip |
|
||||
| P6-02 | journal/checkpoint/operation reconciliation | P6-01/P1-03 | recovery matrix | crash、半提交、确认丢失 |
|
||||
| P6-03 | OPFS/offline/migration/rollback | P6-02/P2-01 | browser recovery report | 离线、配额、版本迁移 |
|
||||
| P7-01 | Worker protocol/client、backpressure、cancel | P1-03/P6-01 | protocol E2E | seq、schema、timeout、cancel |
|
||||
| P7-02 | editor/diagnostic/MDI/run workflow | P3-04/P7-01 | browser E2E | 真实 Worker,不用 mock |
|
||||
| P7-03 | state/HAL/IO/Python/PLC/alarm panels | P4/P5/P7-01 | UI tests | snapshot/event 单向消费 |
|
||||
| P7-04 | Three.js pose/joint/toolpath/stock view | P3-05/P7-03 | WebGL/canvas tests | 非空、姿态和轨迹跟随 authoritative state |
|
||||
| P7-05 | recovery/offline/error/permission UX | P6-03/P7-02 | browser fault E2E | 恢复状态可操作、错误可定位 |
|
||||
| P8-01 | native oracle runner 和 golden schema | P0-03/P3/P4 | JSONL oracle | 同输入、同命令、首差 tick |
|
||||
| P8-02 | 全量 sim entrypoint matrix | P2-04/P8-01 | startup/diff matrix | 每入口 READY 或诊断 BLOCKED |
|
||||
| P8-03 | 三次重复和执行模式 determinism | P8-02/P6 | determinism report | 1x/fast/step/recover hash 一致 |
|
||||
| P8-04 | browser/performance/memory/offline matrix | P7/P8-03 | perf/compat report | P95/P99、配额、WebGL、离线 |
|
||||
| P8-05 | 来源/许可证/下载/迁移/回滚交付闭合 | P8-02/P8-04 | release evidence | 所有排除项和剩余 blocker 显式保留 |
|
||||
|
||||
## 5. 里程碑
|
||||
|
||||
| 里程碑 | 名称 | 包含任务 | 退出条件 |
|
||||
|---|---|---|---|
|
||||
| M0 | 输入和契约闭合 | P0-01..03 | context/source/schema hash 可重建;输入缺失不会被接受 |
|
||||
| M1 | Task/WASM/Worker 会话闭合 | P1-01..04 | create/load/MDI/program/tick/pause/abort/snapshot/replay 通过 native/WASM/Worker |
|
||||
| M2 | 解释器和运动主链 | P3-01..07 | G-code→canonical→TP→motion→kinematics→snapshot 闭合,首差可定位 |
|
||||
| M3 | 配置启动闭合 | P2-01..04 | 纳入范围的每个入口进入 READY 或带来源诊断的 BLOCKED |
|
||||
| M4 | HAL/IO/数字孪生闭合 | P4-01..05 | HAL/PLC/主轴/编码器/探针/限位/工具/冷却/estop 故障可执行、可回放 |
|
||||
| M5 | Python/remap/VCP 闭合 | P5-01..03 | 白名单 API、remap、VCP、异常、能力拒绝和资源限制通过 |
|
||||
| M6 | 恢复和离线闭合 | P6-01..03 | Worker 重启、OPFS checkpoint、journal、迁移、回滚、离线路径通过 |
|
||||
| M7 | Web 工作流和可视化闭合 | P7-01..05 | UI 真实消费 Worker authoritative state,Three.js/Canvas 非空并可恢复 |
|
||||
| M8 | 全量兼容和交付闭合 | P8-01..05 | 全量矩阵、三次 determinism、浏览器/性能和来源证据齐全;仿真结果独立可运行 |
|
||||
|
||||
每个里程碑完成时必须生成一份确定性 report,包含 `context_id`、任务 ID、输入/输出 hash、native/WASM/Worker 测试、已知 blocked 项和下一个依赖任务。里程碑不能从 `blocked` 自动跳回 `in_progress`。
|
||||
|
||||
## 6. 验收证据和回归门禁
|
||||
|
||||
每个任务至少保留:
|
||||
|
||||
- native test;适用时必须有 WASM/Worker 对照 test。
|
||||
- 正常、边界、非有限值、容量、错误、abort、pause/resume、恢复和离线样本。
|
||||
- 输入 context、source hash、ABI/protocol/schema 影响和直接 evidence 路径。
|
||||
- 状态 hash、event hash、首个 divergent tick 或明确的 `REAL-EXCLUDED/BLOCKED` 原因。
|
||||
- 可重跑命令和报告 self-hash。
|
||||
|
||||
技术任务的最小回归:
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_baseline.py
|
||||
python3 scripts/validate_download_index.py
|
||||
python3 scripts/validate_task_pointer.py
|
||||
scripts/build-wasm.sh
|
||||
ctest --test-dir build-native --output-on-failure
|
||||
for f in web/worker/test_*.mjs; do node "$f" || exit 1; done
|
||||
for f in web/app/test_*.mjs; do node "$f" || exit 1; done
|
||||
```
|
||||
|
||||
修改配置、协议、恢复或发布证据时,再运行对应的生成器专项测试和完整 Python unittest;生成器产生的报告不能被手工改 hash 伪装为通过。
|
||||
|
||||
## 7. 停止线
|
||||
|
||||
立即将当前任务标记为 `blocked` 并保留证据的情况:
|
||||
|
||||
1. LinuxCNC 来源、官方测试输入、配置资源或协议契约缺失。
|
||||
2. 需要改变 ABI/protocol/schema/manifest 时,必须同步更新兼容性测试和迁移证据。
|
||||
3. native/WASM 差异的首个 divergent tick 未定位。
|
||||
4. 只能删除失败样本、降低检查、静默替换资源或把缺失能力改成 `REAL-EXCLUDED` 才能通过。
|
||||
5. Python/组件/VCP 需要未经允许的宿主路径、设备、进程或网络能力。
|
||||
6. checkpoint/journal 无法验证 hash、确认丢失无法对账或恢复会重复副作用。
|
||||
7. 运行结果依赖未固定的墙钟、随机数、线程竞争或浏览器环境。
|
||||
|
||||
blocked 不是失败样本删除理由,也不是自动跳过前置任务的理由。修复后必须重新运行原任务的专属测试和完整回归,再认领下一个依赖满足的任务。
|
||||
|
||||
## 8. 当前实现基线
|
||||
|
||||
截至本计划建立时,仓库已有:
|
||||
|
||||
- WASM/native 核心构建、posemath、解释器、多个 kinematics、HAL、IO 和固定 tick 切片。
|
||||
- Worker protocol/session、虚拟设备、Python bridge、workspace recovery 和前端基础面板。
|
||||
- G-code `PROGRAM_LOAD/RUN/PAUSE/RESUME/ABORT/STEP/SEEK`、`MDI_EXECUTE` 的 Worker/WASM 垂直切片。
|
||||
|
||||
这些能力仍不能替代 M1-M8 的完整验收。下一项直接实现任务由 [`nextTask1.md`](../nextTask1.md) 指向 `P1-01`:把已有 runner、解释器、motion/kinematics、HAL、IO 和 snapshot 统一纳入 `sim_task.v1` authoritative state,并固定首个可对照的 tick 边界。
|
||||
104
docs/linuxcnc-web-wasm-continuation-plan.md
Normal file
104
docs/linuxcnc-web-wasm-continuation-plan.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# LinuxCNC Web/WASM 连续执行计划
|
||||
|
||||
更新时间:2026-08-21
|
||||
|
||||
本计划只服务于仿真实现的连续接续;`nextTask1.md` 是仿真状态入口,
|
||||
`context-lock.json` 只用于来源和工具链复现。
|
||||
|
||||
持续执行的可复制提示词集中在
|
||||
[`持续执行提示词`](linuxcnc-web-wasm-autonomous-execution-prompt.md)。实际任务状态仍只以
|
||||
`nextTask1.md` 为准。
|
||||
|
||||
## 当前状态
|
||||
|
||||
当前仿真轨道直接按 `nextTask1.md` 认领和执行,不等待外部输入。
|
||||
|
||||
- `context-lock.json` 当前 context 为 `linuxcnc-2.10.0-pre0-wasm-m1-py-c1`。
|
||||
- 已完成任务不重复执行,后续任务按依赖顺序连续认领。
|
||||
- ABI/protocol/schema 变更可以在仿真需要时实施,但必须同时更新兼容性测试和恢复证据。
|
||||
|
||||
因此采用两条泳道:
|
||||
|
||||
1. **治理泳道**:等待 owner 输入,完成 intake 校验,审查新 context,再重开 K8 release
|
||||
任务。
|
||||
2. **技术泳道**:维护 INT-01..INT-10 的有序队列、设计和测试准备;只有当前 context
|
||||
明确允许实现时才修改 ABI 或 runtime。
|
||||
|
||||
仿真轨道只有实现正确性、确定性和可恢复性状态,不设置发布泳道或 owner 阻塞状态。
|
||||
|
||||
## 连续认领规则
|
||||
|
||||
每次接续按以下固定循环执行,避免再次停在模糊的“下一步”:
|
||||
|
||||
1. 读取 `nextTask.md` 的 `Current/Task/Verify/Stop`,再读取本任务直接输入。
|
||||
2. 运行四个基线门禁:
|
||||
`validate_baseline.py`、`validate_download_index.py`、脚本 unittest、
|
||||
`validate_task_pointer.py`。
|
||||
3. 从下面队列中选择第一个依赖已满足、没有外部决策缺口的任务;不得跳过前置任务。
|
||||
4. 先写任务测试和失败边界,再实现最小垂直切片;每个任务保留 native、WASM/Worker
|
||||
和状态 hash 证据。
|
||||
5. 运行任务专属测试和回归门禁,生成确定性报告;失败时保留样本和错误码,不删样本、
|
||||
不降低检查、不把资源缺失重分类为 `REAL-EXCLUDED`。
|
||||
6. 更新任务报告和本计划的任务状态;下一项只有在依赖、测试和报告均 verified 后才能
|
||||
认领。
|
||||
7. 遇到 owner、源码、ABI、protocol、schema、浏览器或许可证外部输入时,生成 blocked
|
||||
证据并转入治理泳道;禁止自动重试同一阻塞任务。
|
||||
|
||||
任务认领必须能回答四个问题:`task_id`、`context_id`、直接输入、完成报告。没有这四项
|
||||
就不开始实现。
|
||||
|
||||
## 任务队列
|
||||
|
||||
| 顺序 | 任务 | 目标 | 主要产物 | 前置条件 | 当前状态 |
|
||||
|---|---|---|---|---|---|
|
||||
| 0 | `GOV-INTAKE-01` | 强化 owner decision 的字段、路径和证据 hash fail-closed 校验 | `scripts/validate_owner_decision_intake.py`、专项测试 | 当前 context | `verified` |
|
||||
| 1 | `OWNER-INPUT-01` | 收集并校验六项 owner decision | `coverage/owner-decisions.json`、intake report | 外部 owner 输入 | `blocked` |
|
||||
| 2 | `CONTEXT-REFRESH-01` | 审查新的锁定 context,确认源码/ABI/schema 变化 | 新 context lock、context packet | `OWNER-INPUT-01` 完整且已审查 | `blocked` |
|
||||
| 3 | `INT-01` | 建立 `sim_task` 状态对象、固定 tick 边界和 C ABI | `sim_task.h/.c`、native/WASM task test、ABI report | 新 context、protocol v1 | `queued` |
|
||||
| 4 | `INT-02` | 实现 `PROGRAM_LOAD/RUN/PAUSE/RESUME/ABORT/STEP` | minimal XYZ E2E、command golden | `INT-01`、配置 resolver | `queued` |
|
||||
| 5 | `INT-03` | 串联 TP -> IK -> motion -> FK,并实现事务回滚 | motion/gantry/TRT 差异报告 | `INT-01/02`、K0-K6 | `queued` |
|
||||
| 6 | `INT-04` | 把 HAL、IO、Python 放入同一固定 tick | IO/tool/probe/estop/remap 测试 | `INT-03`、M3-RT/PY | `queued` |
|
||||
| 7 | `INT-05` | 将配置资源解析结果接入 runtime 启动 | 233 入口 ready/blocked/error 报告 | `INT-01`、M3-CFG | `queued` |
|
||||
| 8 | `INT-06` | 执行 Python/remap/filter,保留能力拒绝边界 | remap、参数、异常、资源限制报告 | `INT-02`、M3-PY | `queued` |
|
||||
| 9 | `INT-07` | 接入真实 OPFS、journal、checkpoint 和 Worker 重启 | browser recovery/offline 矩阵 | `INT-01`、M3-FS | `queued` |
|
||||
| 10 | `INT-08` | 前端消费权威 Task snapshot/event | run/pause/step/alarm/recovery E2E | `INT-02/04`、FE-M1..M4 | `queued` |
|
||||
| 11 | `INT-09` | 用真实 pose/joints/toolpath 驱动 Three.js | vismach、canvas/WebGL、性能报告 | `INT-03`、`INT-08` | `queued` |
|
||||
| 12 | `INT-10` | 执行 233 个 sim entrypoint 的全量差异闭环 | startup matrix、source/resource/component 定位 | `INT-05..09` | `queued` |
|
||||
| 13 | `K8-REL-17+` | 重新生成 closure/audit/gate,处理六项 blocker | release candidate gate | owner decision、新 context、对应证据 | `blocked` |
|
||||
|
||||
`INT-01..INT-04` 是功能主链;`INT-05..INT-07` 是运行时闭环;`INT-08..INT-09` 是前端
|
||||
融合;`INT-10` 是规模化回归。任务状态只能按 `queued -> in_progress -> verified` 或
|
||||
`in_progress -> blocked` 转移,不允许从 `blocked` 自动回到 `in_progress`。
|
||||
|
||||
## 当前可执行动作
|
||||
|
||||
在 `OWNER-INPUT-01` 仍缺失时,只执行以下动作:
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_baseline.py
|
||||
python3 scripts/validate_download_index.py
|
||||
python3 -m unittest discover -s scripts -p 'test_*.py' -v
|
||||
python3 scripts/validate_task_pointer.py
|
||||
python3 scripts/validate_owner_decision_intake.py
|
||||
python3 scripts/test_owner_decision_intake.py
|
||||
```
|
||||
|
||||
这些动作只确认仿真基线和阻塞证据,不重复实现已经完成的矩阵。
|
||||
|
||||
收到 owner 文件后,必须先验证六个 blocker 恰好各出现一次、context 一致、字段完整、
|
||||
证据 hash 有效;即使六项都是 `approve`,也只能进入 `CONTEXT-REFRESH-01`,不能直接把
|
||||
release 状态改为 accepted。
|
||||
|
||||
## 任务完成门禁
|
||||
|
||||
每个技术任务至少需要:
|
||||
|
||||
- 明确的输入 context 和来源 hash;
|
||||
- native 测试;
|
||||
- WASM 或 Worker 对照测试(适用时);
|
||||
- 错误、非有限值、容量、abort/恢复边界;
|
||||
- 确定性状态 hash 或报告 self-hash;
|
||||
- 不改变无关任务的报告和六项 release blocker。
|
||||
|
||||
最终项目完成还必须通过完整回归、浏览器矩阵、资源闭包、许可证决策、官方 oracle 和
|
||||
owner review。任何一项缺失都只能保持 `blocked`,不能以“模块测试通过”替代端到端完成。
|
||||
112
docs/linuxcnc-web-wasm-contracts.md
Normal file
112
docs/linuxcnc-web-wasm-contracts.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# LinuxCNC Web/WASM 契约快照
|
||||
|
||||
**契约版本**:`sim-contracts.v1`
|
||||
**任务**:`P0-03`
|
||||
**Context**:`linuxcnc-2.10.0-pre0-wasm-m1-py-c1`
|
||||
**状态**:implementation-verified(只冻结现有边界;不表示 release accepted)
|
||||
|
||||
本文冻结浏览器 Dedicated Worker 与 WASM 核心之间可观察的字段、版本和错误策略。它是当前 context 的兼容性快照,不替换 `context-lock.json`,也不改变已有 C ABI、Worker protocol 或 recovery schema。`sim_task.v1` 只冻结 P1-01 将实现的状态对象形状;本任务不实现该 runtime。
|
||||
|
||||
## 1. 版本和边界
|
||||
|
||||
| 契约 | 线上的版本标识 | 当前实现边界 |
|
||||
|---|---|---|
|
||||
| `sim_task` | `sim_task.v1` | P1-01 authoritative state 预留;本任务只做形状校验 |
|
||||
| 命令信封 | `command-envelope.v1` | Worker 输入使用 `schema_version: 1` |
|
||||
| 快照 | `snapshot.v1` | `web/worker/replay.mjs` 的 snapshot 记录 |
|
||||
| 事件日志 | `event-log.v1` | `web/worker/replay.mjs` 的事件日志 |
|
||||
| 工作区包 | `workspace-package.v1` | 包 schema 固定;`format_version` 1/2 是同一 envelope 的可验证迁移 |
|
||||
|
||||
版本号是整数且不隐式降级。未知版本、缺少必填字段、未知顶层字段、非有限数、哈希或游标不一致都 fail closed。新必填字段或语义变化必须建立新 schema 标识和迁移测试;同一 v1 只允许增加明确标为可选的诊断字段。
|
||||
|
||||
## 2. `sim_task.v1`
|
||||
|
||||
这是单 Worker authoritative task 的可观察状态,不是 C ABI 结构体。字段顺序在 canonical JSON 中按键名排序,数值使用 JSON 安全整数或有限 IEEE-754 数。
|
||||
|
||||
| 字段 | 类型 | 要求 |
|
||||
|---|---|---|
|
||||
| `schema` | string | 固定 `sim_task.v1` |
|
||||
| `context_id`、`session_id` | string | 非空;恢复时必须与锁定 context/session 相符 |
|
||||
| `state` | enum | `NEW`、`READY`、`RUNNING`、`PAUSED`、`ESTOP`、`FAULT`、`STOPPED`、`DESTROYED` |
|
||||
| `mode` | enum | `MANUAL`、`MDI`、`AUTO` |
|
||||
| `program_status` | enum | `idle`、`loaded`、`running`、`paused`、`completed`、`aborted`、`fault` |
|
||||
| `seq` | positive integer | 最后应用的命令序号 |
|
||||
| `simulation_tick` | non-negative integer | 逻辑 tick;不使用墙钟 |
|
||||
| `current_line` | non-negative integer or null | 当前程序行;未知时为 null |
|
||||
| `state_hash` | string | 对除 hash 外的完整状态做确定性 hash |
|
||||
|
||||
P1-01 可以在同一 schema 内增加由契约测试先登记的可选域;改变上述语义或枚举必须升级版本。Task 状态、事件、快照和 operation ledger 必须在相同 tick 边界提交。
|
||||
|
||||
## 3. `command-envelope.v1`
|
||||
|
||||
命令及其 Worker 响应共享以下信封字段:
|
||||
|
||||
| 字段 | 要求 |
|
||||
|---|---|
|
||||
| `schema_version` | 固定整数 `1`,对应 C `sim_protocol_accept` 的 schema 参数 |
|
||||
| `kind` | 非空字符串,长度不超过 128(C `has_text` 边界);命令种类由 capability/Worker 白名单决定 |
|
||||
| `context_id` | 非空字符串,必须等于 context lock |
|
||||
| `session_id` | 非空字符串;同一会话不可改变 |
|
||||
| `seq` | 从 1 开始严格连续递增;重复副作用通过 `operation_id` 对账 |
|
||||
| `operation_id` | 副作用命令必填的非空字符串,长度不超过 128;只读查询可省略 |
|
||||
| `simulation_tick` | 可选的非负安全整数;不得小于 Worker 当前 tick |
|
||||
| `sent_at_monotonic_ms` | 可选有限数,仅用于诊断,绝不参与状态或 hash |
|
||||
| `payload` | 必填 JSON object;不能是数组、null 或包含非有限数 |
|
||||
|
||||
当前 C ABI 的状态与错误保持不变:`SIM_PROTOCOL_ERR_SCHEMA=-100`、`SEQUENCE=-101`、`STATE=-102`、`OPERATION_ID=-103`、`KIND=-104`、`ARGUMENT=-105`、`TICK=-106`。Worker 以稳定的 `protocol_*` 错误键映射这些结果,不能把错误改成成功或静默重排命令。
|
||||
|
||||
## 4. `snapshot.v1`
|
||||
|
||||
`SnapshotStore` 导出的对象固定为 `{schema, snapshots}`;每条 snapshot 使用:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": "snapshot.v1",
|
||||
"snapshot_id": "snap:<seq>:<state_hash>",
|
||||
"base_snapshot_id": null,
|
||||
"seq": 1,
|
||||
"tick": 0,
|
||||
"state": {},
|
||||
"state_hash": "fnv1a64:<16 lowercase hex>"
|
||||
}
|
||||
```
|
||||
|
||||
`seq` 为正整数且同一序号只能有一个内容,`tick` 不回退;增量 snapshot 的 `base_snapshot_id` 必须引用已导入的 snapshot。`state_hash` 和 `snapshot_id` 必须由同一 canonical state 重算。容量不足、重复序号、缺少 base、哈希不符和非有限 state 均拒绝,导入失败不得替换当前 store。
|
||||
|
||||
## 5. `event-log.v1`
|
||||
|
||||
日志对象固定为 `{schema: "event-log.v1", cursor, tick, events}`。每条事件固定字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"seq": 1,
|
||||
"tick": 0,
|
||||
"kind": "SESSION_READY",
|
||||
"payload": {},
|
||||
"payload_hash": "fnv1a64:<16 lowercase hex>"
|
||||
}
|
||||
```
|
||||
|
||||
`seq` 从 1 严格连续,`tick` 单调不减,`kind` 非空且最多 64 个字符,payload 必须是 object。C 端保留 `sim_event_record` 的固定宽度布局(`uint32_t seq/tick`、`uint64_t payload_hash`、32 字节 kind),并保留 `SIM_EVENT_CAPACITY=256` 与错误码 `-200..-204`。WASM 和 Worker 对同一输入必须得到相同 cursor/tick/hash;半成品导入不改变当前日志。
|
||||
|
||||
## 6. `workspace-package.v1`
|
||||
|
||||
包 envelope 的必填字段为 `schema`、`format_version`、`context_id`、`committed_seq`、`checkpoint`、`timeline`、`journal`、`content_hash`、`package_hash`。`format_version: 1` 是当前基线;已实现的 `format_version: 2` 只添加 `migration` 和 `integrity` 元数据,事件、snapshot、checkpoint、journal payload 保持 byte-for-byte v1 兼容。
|
||||
|
||||
迁移规则:
|
||||
|
||||
1. v1→v2 必须标记 `lossless: true`、源 package hash 和 timeline/journal/checkpoint integrity hash。
|
||||
2. v2→v1 只有在源 hash 对账成功时允许;原包不可变,回滚只生成新目标包。
|
||||
3. 不支持的版本、context、提交序号、timeline/checkpoint、content/package hash 或 journal 顺序均拒绝。
|
||||
4. 缺失/损坏资源在离线模式返回明确错误;不能用空包或当前内存状态替代已提交包。
|
||||
|
||||
## 7. 兼容性决策记录
|
||||
|
||||
- **ABI**:保留 `sim_api.h`、`sim_protocol.h`、`sim_event.h` 的函数签名、整数宽度、错误码和容量语义;没有修改锁定 ABI。
|
||||
- **协议**:Worker 继续传递 `schema_version: 1`,C validator 继续拒绝非 1、序号缺口、tick 回退和副作用命令缺失 `operation_id`。
|
||||
- **快照/事件**:沿用 `replay.mjs` 的 `schema` 字段和 FNV-1a-64 canonical hash;不把 `snapshot.v1` 或 `event-log.v1` 改成新的顶层结构。
|
||||
- **工作区**:沿用现有 workspace migration 的 v1/v2 envelope;v2 不是新的 payload schema,不修改已锁定的事件/快照/checkpoint/journal 版本。
|
||||
- **未知字段**:v1 顶层未知字段和缺失字段 fail closed;仅 `sent_at_monotonic_ms` 这一诊断字段可选且不影响 hash。需要其它字段时先建 v2 schema/迁移测试。
|
||||
- **排除边界**:真实硬件、宿主路径、实时内核和动态库仍是 `REAL-EXCLUDED`;主轴、编码器、探针、限位、换刀、冷却和 IO 的仿真契约不因此排除。
|
||||
|
||||
直接证据:`web/worker/contracts.mjs`、`web/worker/test_contracts.mjs`、`wasm-core/tests/sim_contract_test.c`、`scripts/test_sim_contract.py`、`coverage/sim-contract.report.json`。
|
||||
@@ -10,8 +10,9 @@
|
||||
|
||||
## Required Shape
|
||||
|
||||
The input must use schema `owner-decision-intake.v1`, match the locked
|
||||
`context_id`, and contain exactly one decision for each of the six blocker IDs:
|
||||
The input must use schema `owner-decision-intake.v1`, provide a non-empty
|
||||
`decision_set_id`, match the locked `context_id`, and contain exactly one
|
||||
decision for each of the six blocker IDs:
|
||||
|
||||
`manifest_seed_unassigned`, `accepted_entries_missing`,
|
||||
`official_oracle_missing`, `configuration_resources_missing`,
|
||||
@@ -19,8 +20,9 @@ The input must use schema `owner-decision-intake.v1`, match the locked
|
||||
|
||||
Each decision requires `decision` (`approve`, `reject`, or `defer`), non-empty
|
||||
`owner`, non-empty `reviewer`, a rationale, an evidence list, and an explicit
|
||||
`new_context_required` boolean. Evidence entries require a repository-relative
|
||||
path and SHA-256 hash. The validator checks shape and identity only; it never
|
||||
`new_context_required` boolean. Evidence entries require an existing
|
||||
repository-relative path and a lowercase SHA-256 hash matching the referenced
|
||||
file. The validator checks shape, identity, and evidence integrity; it never
|
||||
creates a context, changes `context-lock.json`, promotes an entry, or refreshes
|
||||
the release gate.
|
||||
|
||||
|
||||
81
docs/linuxcnc-web-wasm-simulation-gap-plan-v2.md
Normal file
81
docs/linuxcnc-web-wasm-simulation-gap-plan-v2.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# LinuxCNC Web/WASM 仿真功能补全计划
|
||||
|
||||
**版本**:3.1
|
||||
**范围**:只实现 LinuxCNC 仿真功能,不处理其他项目。
|
||||
**接续入口**:[`nextTask1.md`](../nextTask1.md)
|
||||
|
||||
## 目标
|
||||
|
||||
在 Dedicated Worker 中实现可重复的 LinuxCNC 仿真行为,并用 WASM/native/Worker 测试验证:
|
||||
|
||||
- INI、HAL、工具表、参数、程序、Python、VCP、ClassicLadder 资源加载。
|
||||
- rs274 G/M/O 解释、modal、参数、子程序、循环、宏、canned cycle 和错误定位。
|
||||
- canonical queue、TP、直线/圆弧/同步运动、速度/加速度/jerk、blend、exact-stop。
|
||||
- Task mode、MDI、run/pause/resume/step/abort/restart、jog、home、override、limits。
|
||||
- trivkins、gantry/CoreXY、5/6-axis、TRT、机器人、Delta/Tripod/Hexapod/Pentapod、switch/user kins。
|
||||
- HAL pin/signal/parameter/thread/function、静态 `.comp`、ClassicLadder、PLC、采样和背压。
|
||||
- spindle、encoder、probe、limit、home、tool、coolant、door、interlock、estop 数字孪生。
|
||||
- Python `linuxcnc/hal/INI/tool/parameter`、remap、filter、VCP callback 和异常隔离。
|
||||
- snapshot/event/trace、checkpoint、journal、Worker restart、OPFS、offline、migration、rollback。
|
||||
- editor、MDI、状态/HAL/IO/Python/PLC/alarm 面板和 pose/toolpath/stock Canvas。
|
||||
|
||||
## 不变量
|
||||
|
||||
1. Worker 是 authoritative state 唯一写者;UI 只消费 snapshot/event。
|
||||
2. `sim_step(cycles)` 是唯一改变仿真结果的入口;不使用墙钟或随机数。
|
||||
3. `seq`、`operation_id`、checkpoint、event、snapshot 和 state hash 全部确定性。
|
||||
4. 非法路径、缺失资源、非有限值、容量、未知能力和 schema 错误 fail closed。
|
||||
5. 真实硬件、设备文件、宿主进程、网络和动态库不进入仿真实现。
|
||||
|
||||
## 实施阶段
|
||||
|
||||
### S1 解释器与运动主链
|
||||
|
||||
`S1-01` rs274 完整 word/modal/system parameter;`S1-02` canonical/TP 圆弧、同步运动、accel/jerk 和暂停;`S1-03` motion/kinematics feedback、home/limit、override。
|
||||
|
||||
### S2 HAL、PLC、设备
|
||||
|
||||
`S2-01` `.clp` ClassicLadder parser/runtime;`S2-02` HAL component runtime batch;`S2-03` encoder/coolant/door/interlock/IO ack;`S2-04` 配置入口资源修复。
|
||||
|
||||
### S3 Python、恢复、浏览器
|
||||
|
||||
`S3-01` Python API compatibility;`S3-02` remap/filter/VCP;`S3-03` Worker crash/OPFS/offline/recovery;`S3-04` browser simulation compatibility/performance。
|
||||
|
||||
### S4 仿真回归
|
||||
|
||||
`S4-01` full simulation regression;`S4-02` 1x/fast/step/recover endpoint replay parity。
|
||||
|
||||
## 任务队列
|
||||
|
||||
| ID | 任务 | 依赖 | 主要输出 |
|
||||
|---|---|---|---|
|
||||
| S1-01A | implement rs274 parameter space and modal expansion | 无 | interpreter native/WASM/Worker tests |
|
||||
| S1-01B | implement rs274 G/M words, canned cycles, coordinates and compensation | S1-01A | interpreter native/WASM/Worker tests |
|
||||
| S1-02A | implement TP arcs, sync FIFO and accel/jerk bounded profile | S1-01B | TP/motion tests |
|
||||
| S1-02B | implement pause/resume and canonical multi-segment expansion | S1-02A | TP/motion tests |
|
||||
| S1-03 | implement motion/kinematics feedback, home/limit and override | S1-02B | motion fault matrix |
|
||||
| S2-01 | implement `.clp` ClassicLadder parser/runtime | S1-03 | PLC runtime/tests |
|
||||
| S2-02 | implement HAL component runtime batch | S1-03 | component runtime/tests |
|
||||
| S2-03 | implement encoder/coolant/door/interlock/IO ack parity | S1-03 | device/IO tests |
|
||||
| S2-04 | implement blocked sim entrypoint resource batch | S2-02 | startup/runtime tests |
|
||||
| S3-01 | implement Python API compatibility | S1-01 | Python bridge/session tests |
|
||||
| S3-02 | implement remap/filter/VCP callback path | S3-01 | callback tests |
|
||||
| S3-03 | implement Worker/OPFS/offline recovery | S2-03/S3-01 | recovery tests |
|
||||
| S3-04 | implement browser simulation compatibility/performance | S3-03 | app/Canvas/Worker tests |
|
||||
| S4-01 | complete simulation regression | S2-04/S3-04 | full simulation report |
|
||||
| S4-02 | complete endpoint replay parity | S4-01 | determinism/recovery report |
|
||||
|
||||
## 当前任务
|
||||
|
||||
当前直接执行 `S1-01`。它读取 `linuxcnc/src/emc/rs274ngc`、`linuxcnc/unit_tests/interp`、`wasm-core/src/sim_interpreter.c` 和 `web/worker/program-runner.mjs`,输出代码、native/WASM/Worker 测试和确定性状态报告。
|
||||
|
||||
## 验收
|
||||
|
||||
每个任务必须有正常、边界、错误、容量、暂停/恢复和非有限样本;必须运行对应 native/WASM/Worker 测试、`scripts/build-wasm.sh`、CTest 和全部 Worker/App 测试。任务报告必须包含输入、输出、测试和 self-hash。
|
||||
|
||||
## 停止条件
|
||||
|
||||
- 需要修改已冻结 ABI、protocol 或 schema。
|
||||
- 结果依赖墙钟、随机数、真实设备、宿主路径、动态库或 mock Worker。
|
||||
- checkpoint/event/hash 不可验证,或恢复会重复副作用。
|
||||
- 仿真差异未定位到具体 tick、字段、单位或错误位置。
|
||||
45
docs/linuxcnc-web-wasm-source-test-execution-plan.md
Normal file
45
docs/linuxcnc-web-wasm-source-test-execution-plan.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# LinuxCNC 源测试对标执行计划
|
||||
|
||||
本计划只服务于 LinuxCNC 仿真功能对标。LinuxCNC 源程序测试工具是行为来源,WASM/native/Worker 适配器必须保留原测试输入、期望输出、错误语义和资源依赖;不能把自建 smoke test 当作源测试替代品。
|
||||
|
||||
## 对标对象
|
||||
|
||||
- `linuxcnc/scripts/runtests`:递归发现 `test.hal`、`test.sh`、`test`,执行 `halrun`/shell/executable,并按 `expected` 或 `checkresult` 判定。
|
||||
- `linuxcnc/tests/**`:HAL regression/functional、interp、remap、IO、motion、tool、startup、经典梯形图、限位和配置测试。
|
||||
- `linuxcnc/unit_tests/interp`:`test_interp` C++ 单元测试目标。
|
||||
- `linuxcnc/unit_tests/tp`:`test_blendmath` TP 单元测试目标。
|
||||
- `linuxcnc/configs/sim/**`:INI/HAL/程序/Python/VCP/CLP 启动闭包和用户工作流入口。
|
||||
|
||||
## 适配分类
|
||||
|
||||
1. `PURE_REGRESSION`:只依赖 `halrun`/解释器/TP/固定 tick,保留 stdout 与 `expected` 字节对照。
|
||||
2. `PURE_FUNCTIONAL`:使用 `checkresult`,将检查输入和结果映射成稳定 JSON 状态。
|
||||
3. `WORKER_SIM_ADAPTER`:需要真实 Worker session、配置启动或数字孪生;输入保持源文件原样。
|
||||
4. `UNIT_NATIVE_WASM`:unit_tests C/C++ 目标建立 native 与 WASM 双 runner。
|
||||
5. `HOST_EXCLUDED`:sudo、TCP、真实设备、内核实时、动态模块、GUI/窗口或任意宿主路径;只记录稳定排除原因,不伪造通过。
|
||||
6. `SOURCE_BLOCKED`:源输入、expected、checkresult 或依赖缺失;保留 source_id 和诊断。
|
||||
|
||||
## 执行阶段
|
||||
|
||||
| 阶段 | 任务 | 产物 |
|
||||
|---|---|---|
|
||||
| S5-01 | 发现并分类源测试,复制 runtests 判定语义 | source-test matrix/report |
|
||||
| S5-02 | 执行无宿主依赖的 runtests 纯仿真子集 | native/WASM/Worker JSONL diff |
|
||||
| S5-03 | 迁移 `unit_tests/interp` 与 `unit_tests/tp` | CTest/WASM golden diff |
|
||||
| S5-04 | 迁移 `tests/interp/**`、remap、O-word、filter | block/error/canonical diff |
|
||||
| S5-05 | 迁移 HAL regression/functional 和 `.comp` | pin/signal/thread/output diff |
|
||||
| S5-06 | 迁移 IO/startup/tool/limit/ClassicLadder | device/task/recovery diff |
|
||||
| S5-07 | 批量执行 `configs/sim/**` 启动和工作流 | 233 entrypoint READY/BLOCKED/diff matrix |
|
||||
| S5-08 | 汇总差异、重复执行和恢复终点 | full source-test parity report |
|
||||
|
||||
## 每个测试的证据
|
||||
|
||||
每个 source test 必须记录:`source_id`、路径、来源 hash、runner 命令、输入 fixture hash、expected/checkresult hash、适配分类、状态、stdout/stderr hash、首个差异字段/行、逻辑 tick、state/event hash、失败原因和下一步任务。宿主排除不计入通过率;缺失输入不降级为通过。
|
||||
|
||||
## 通过条件
|
||||
|
||||
- 源测试发现数与锁定 source index 一致,无孤儿、重复或静默跳过。
|
||||
- `expected` 测试逐字节一致;`checkresult` 测试使用同一判定条件并输出结构化差异。
|
||||
- native/WASM/Worker 使用同一输入和命令序列,首个差异可定位到 tick/字段/单位/错误列。
|
||||
- 1x、fast、single-step、recover 的源测试终点 hash 一致。
|
||||
- `HOST_EXCLUDED`、`SOURCE_BLOCKED` 独立统计,不伪造为 `PASSED`。
|
||||
@@ -68,6 +68,7 @@
|
||||
| `PROJECT-AUDIT-01` | 整体审计确认 K0-K6 运动学实现和 15 项 native CTest 已通过;运动学 `partial/blocked` 仅因锁定来源缺少官方 oracle;当前开发瓶颈转为配置启动闭包,下一任务为 M3-CFG-01,K8 release 六项 blocker/`STOP_RELEASE` 独立保留 | `docs/linuxcnc-web-wasm-next-work.md`, `coverage/kinematics-registry.report.json`, `coverage/kinematics-motion.report.json`, `coverage/kinematics-feedback.report.json`, `coverage/kinematics-home-limit.report.json`, `coverage/configuration-regression.report.json` |
|
||||
| `PROJECT-AUDIT-02` | 重新梳理任务图确认 M3/FE/REG 实现证据均已 verified;K8-REL-17 owner_inputs=0、gate_refresh=blocked,发现旧 Next 自引用风险;生成 GOV-01 readiness 后进入不自动重试的 WAIT-OWNER-01,六项 blocker 和 `STOP_RELEASE` 保持 verified | `docs/linuxcnc-web-wasm-task-map.md`, `coverage/project-task-readiness.report.json`, `nextTask.md` |
|
||||
| `OWNER-INTAKE-01` | 建立六项 owner decision 输入模板、结构/identity/context/evidence hash 验证器和 blocked report;当前输入文件缺失,验证结果为 blocked,gate refresh 永远 blocked,不修改 context lock 或 release gate | `coverage/owner-decision-intake.template.json`, `coverage/owner-decision-intake.report.json`, `docs/linuxcnc-web-wasm-owner-decision-intake.md`, `scripts/validate_owner_decision_intake.py`, `scripts/test_owner_decision_intake.py` |
|
||||
| `GOV-INTAKE-01` | 强化 owner decision intake 的持续接续门禁;非 approve、缺少 decision_set_id、仓库外/缺失证据路径、非十六进制或实际 hash 不匹配均 fail-closed;当前 owner 输入仍缺失,release gate 和 context lock 未修改 | `scripts/validate_owner_decision_intake.py`, `scripts/test_owner_decision_intake.py`, `docs/linuxcnc-web-wasm-continuation-plan.md` |
|
||||
| `M3-CFG-01` | 确定性配置 resolver 和 Worker preflight 完成;16,093 条资源全部分类,15,112 resolved、981 blocked;显式 `LIB:`、参数尾缀、相对路径、仓库外路径和宿主路径均有明确策略;原始索引 hash、context lock、187 个脚本测试、15 个 native CTest 和 Worker/workspace 测试通过 | `web/workspace/configuration.mjs`, `web/worker/sim-session.mjs`, `coverage/configuration-startup-closure.report.json`, `scripts/generate_configuration_startup_closure.py`, `scripts/test_configuration_startup_closure.py`, `web/workspace/test_configuration.mjs`, `web/worker/test_configuration_preflight.mjs` |
|
||||
| `M3-RT-02` | 生成 145 个 `.comp` 组件 manifest、1,220 pins、140 params、530 functions 和 193 个 HAL 文件的 4,566 条配置图记录;manifest、容量、资源边和动态加载拒绝检查 verified,29 个 `loadusr` 与 124 个变量化/未声明 `loadrt` 保持 blocked;190 个脚本测试、15 个 native CTest 和 Worker/workspace 测试通过 | `coverage/hal-component-manifest.report.json`, `scripts/generate_hal_component_manifest.py`, `scripts/test_hal_component_manifest.py`, `web/workspace/hal-configuration.mjs`, `web/worker/sim-session.mjs`, `web/worker/test_hal_preflight.mjs` |
|
||||
| `M3-RT-03` | 虚拟设备故障矩阵完成;26 个 spindle/tool/probe/limit/estop/非有限/恢复场景进入 EventLog,连续执行与 replay state hash 一致,设备 checkpoint 增量恢复通过;192 个脚本测试、15 个 native CTest 和 Worker/workspace 测试通过 | `coverage/virtual-device-fault-matrix.report.json`, `scripts/generate_virtual_device_fault_matrix.py`, `scripts/test_virtual_device_fault_matrix.py`, `web/worker/virtual-devices.mjs`, `web/worker/test_virtual_devices.mjs`, `web/worker/test_device_recovery.mjs` |
|
||||
@@ -77,6 +78,46 @@
|
||||
| `FE-M2` | 完成核心 operation controls 和权威 state panel;run/pause/resume/abort/home/estop/recover 控制、operation 去重、错误/报警状态和窄屏布局 smoke 通过;200 个脚本测试、15 个 native CTest 和 Worker/workspace/Python 回归通过 | `coverage/frontend-m2.report.json`, `scripts/generate_frontend_m2.py`, `scripts/test_frontend_m2.py`, `web/app/controls.mjs`, `web/app/state-panel.mjs`, `web/app/test_frontend_m2.mjs` |
|
||||
| `FE-M3` | 项目/恢复 workflow 完成;journal 导入导出、checkpoint/package、v1↔v2 migration、offline ready 和 half-commit 状态展示 smoke 通过;202 个脚本测试、15 个 native CTest 和 Worker/workspace/Python 回归通过 | `coverage/frontend-m3.report.json`, `scripts/generate_frontend_m3.py`, `scripts/test_frontend_m3.py`, `web/app/project-workflow.mjs`, `web/app/recovery-panel.mjs`, `web/app/test_frontend_m3.mjs` |
|
||||
| `FE-M4` | 完成 HAL/tool/IO/3D frontend workflows;设备命令、HAL diagnostics、稳定 canvas machine view 和故障状态展示 smoke 通过;204 个脚本测试、15 个 native CTest 和 Worker/workspace/Python 回归通过 | `coverage/frontend-m4.report.json`, `scripts/generate_frontend_m4.py`, `scripts/test_frontend_m4.py`, `web/app/device-panel.mjs`, `web/app/hal-panel.mjs`, `web/app/machine-view.mjs`, `web/app/test_frontend_m4.mjs` |
|
||||
| `S5-02` | 真实 LinuxCNC `runtests` 代表性纯仿真基线 12/12 native 通过;abort/G64 超时不伪造为回归通过,明确保留 Worker Task/motion 适配边界 | `coverage/linuxcnc-source-test-execution-s5.report.json`, `scripts/test_linuxcnc_source_test_execution.py` |
|
||||
| `S5-03` | `unit_tests/interp` 与 `unit_tests/tp` 的 9 个可移植源断言由同一 native/WASM adapter 执行,CTest 通过且 JSON golden 字节一致;上游 Meson oracle 缺失标记 `SOURCE_BLOCKED`,G64/abort 保持 `WORKER_TASK_MOTION_PENDING` | `coverage/linuxcnc-source-unit-execution-s5.report.json`, `wasm-core/tests/source_unit_adapter_test.c`, `scripts/test_linuxcnc_source_unit_s5.py` |
|
||||
| `S5-04` | `tests/interp`、`tests/oword` 与 `tests/remap` 的 8 个真实 fixture 由 WASM-backed Worker 执行;6 项 block/error/canonical/callback 适配通过,DO/G64 2 项明确保持 `WORKER_TASK_MOTION_PENDING`,26 个源/expected/checkresult/config 文件哈希闭合;源 canonical logger 继续 `SOURCE_BLOCKED` | `coverage/linuxcnc-source-interp-s5.report.json`, `web/worker/test_source_interpreter_s5.mjs`, `scripts/test_linuxcnc_source_interpreter_s5.py` |
|
||||
| `S5-05` | HAL `abs`/`edge` 与 starting-high 边界由 Worker 静态运行时执行通过;native/WASM `sim_hal_test` golden 字节一致;自定义 `.comp`、相对头文件和 userspace/RTAPI 路径分别保留 `SOURCE_BLOCKED`/`HOST_EXCLUDED`,8 个源案例和 23 个 fixture 文件均有哈希 | `coverage/linuxcnc-source-hal-s5.report.json`, `web/worker/test_source_hal_s5.mjs`, `scripts/test_linuxcnc_source_hal_s5.py` |
|
||||
| `S5-06` | IO/limit/tool ack Worker 适配 3 项通过;native/WASM `sim_io` 与 `sim_device_io` golden 字节一致;startup tool table 2 项 `SOURCE_BLOCKED`、ClassicLadder 1 项 `HOST_EXCLUDED`、motion-logger abort 1 项 `WORKER_TASK_MOTION_PENDING`,30 个 fixture 文件哈希闭合 | `coverage/linuxcnc-source-io-s5.report.json`, `web/worker/test_source_io_s5.mjs`, `scripts/test_linuxcnc_source_io_s5.py` |
|
||||
| `S5-07` | 批量读取并哈希全部 264 个配置矩阵条目(216 个 `configs/sim`、48 个 tests 配置);56 READY、208 BLOCKED,逐项保留资源/诊断状态;batch checkpoint/restore、native/WASM/Worker startup probes 通过,静态 preflight 不提升为官方 runtime oracle | `coverage/linuxcnc-source-config-s5.report.json`, `web/worker/test_source_config_s5.mjs`, `scripts/test_linuxcnc_source_config_s5.py` |
|
||||
| `S5-08` | 汇总 S5-01..S5-07 源证据;关键适配器重复运行稳定,native/WASM 静态 golden 全部一致,1x/fast/recovery/trace import 终点一致且 `first_divergence=null`;SOURCE_BLOCKED/HOST_EXCLUDED/WORKER_TASK_MOTION_PENDING 与官方 oracle 阻塞均保留 | `coverage/linuxcnc-source-parity-s5.report.json`, `web/worker/test_source_parity_s5.mjs`, `scripts/test_linuxcnc_source_parity_s5.py` |
|
||||
| `S6-01` | 对完整仿真计划 P0-P8 的 39 个任务逐项对齐证据;S5 源测试链全部 verified;识别 authoritative sim_task tick integration、官方 native oracle、配置资源、source adapter 和浏览器/OPFS 五类开放 gap;创建下一执行任务 S6-02 | `coverage/full-linuxcnc-simulation-gap-audit.report.json`, `scripts/generate_full_linuxcnc_simulation_gap_audit.py`, `scripts/test_full_linuxcnc_simulation_gap_audit.py`, `nextTask1.md` |
|
||||
| `S6-02` | 新增 authoritative runtime:程序行在 task phase 执行,XYZ/trivkins planner 在 tp/kinematics phase 更新,motion/HAL/IO 共用固定 tick;state 纳入 snapshot/checkpoint/trace/endpoint,1x/fast、recovery/trace import parity 通过;非 trivkins和完整 canonical oracle 保持后续/blocked | `coverage/authoritative-sim-task-s6.report.json`, `web/worker/authoritative-runtime.mjs`, `web/worker/test_authoritative_sim_task_s6.mjs`, `scripts/test_authoritative_sim_task_s6.py` |
|
||||
| `S6-03` | authoritative runtime 扩展 CoreXY:XYZ pose `[4,2,3]` 映射到 joints `[6,2,3]`;native/WASM kinematics 与 kinematics-motion golden、1x/fast/recovery endpoint parity 通过;unsupported `puma` 稳定拒绝,其他 families 和官方 oracle 保留后续/blocked | `coverage/authoritative-kinematics-s6.report.json`, `web/worker/test_authoritative_kinematics_s6.mjs`, `scripts/test_authoritative_kinematics_s6.py` |
|
||||
| `S6-04` | authoritative runtime 接入一个可验证的并联 Tripod family:真实 `tripodkins` 配置/几何 `[0,0],[10,0],[5,7.071]`,pose `[2,3,4]` 逆映射为三支杆 `[5.385164807,9.433981132,6.447715952]`;native/WASM kinematics 与 kinematics-motion golden、1x/fast/recovery endpoint parity 和首差诊断通过;TRT、机器人、Delta/Hexapod/Pentapod、switch/user 与官方 oracle 明确保留 queued/blocked | `coverage/authoritative-kinematics-s6-04.report.json`, `web/worker/test_authoritative_kinematics_s6_04.mjs`, `scripts/test_authoritative_kinematics_s6_04.py`, `web/worker/authoritative-runtime.mjs` |
|
||||
| `S6-05` | 新增 OPFS Dedicated Worker 探针、逻辑 journal/offline integrity 测试和确定性报告;Playwright headed Chromium 140 两次完成 sync-access-handle 写入/读取/清理并稳定一致,headless timeout 作为边界保留;Safari/Firefox 明确 OUT_OF_SCOPE,物理 crash/restart oracle 和 release/oracle blocker 不被升级为闭合 | `coverage/authoritative-browser-s6-05.report.json`, `web/workspace/opfs-runtime.mjs`, `scripts/test_browser_opfs_playwright_s6_05.mjs`, `web/app/test_opfs_runtime_s6_05.mjs`, `scripts/test_authoritative_browser_s6_05.py` |
|
||||
| `S6-06` | 使用同一 headed Chromium 140 persistent profile:第一阶段提交 OPFS record 后关闭 browser context,第二阶段重开 profile 读取相同 content hash 并清理;两次运行稳定,profile restart slice verified;真实进程 crash/power-loss oracle 和 release blocker 保留,Safari/Firefox 明确 OUT_OF_SCOPE | `coverage/authoritative-browser-restart-s6-06.report.json`, `scripts/test_browser_opfs_restart_s6_06.mjs`, `scripts/test_authoritative_browser_restart_s6_06.py`, `web/workspace/opfs-runtime.mjs` |
|
||||
| `S6-07` | 使用 Playwright BrowserServer kill 真实终止 Chromium 进程,再以同一 profile 重开并读取 committed OPFS record;两次运行 process-kill、hash continuity 和 cleanup 均 verified;power-loss/filesystem-corruption 与 release/oracle blocker 保留,Safari/Firefox 明确 OUT_OF_SCOPE | `coverage/authoritative-browser-crash-s6-07.report.json`, `scripts/test_browser_opfs_crash_s6_07.mjs`, `scripts/test_authoritative_browser_crash_s6_07.py`, `web/workspace/opfs-runtime.mjs` |
|
||||
| `S7-AUDIT` | 重新梳理 LinuxCNC 完整仿真计划、264 配置入口、S5 source parity、S6 authoritative/runtime/browser evidence;确认配置 `56 READY/208 BLOCKED`、DO/ENDDO 与 G64/G61 pending、剩余 kinematics queued、官方 oracle/release blocked;创建并认领 S7-01 | `coverage/simulation-alignment-s7.report.json`, `scripts/generate_simulation_alignment_audit_s7.py`, `scripts/test_simulation_alignment_s7.py` |
|
||||
| `S7-01` | 接入锁定 `linuxcnc/tests/interp/do-while-break/test.ngc` 的 DO/ENDDO/BREAK 后测循环 slice;嵌套 BREAK、named parameters、pause/resume、malformed ENDDO、depth budget 和 checkpoint recovery parity 通过;上游 canonical expected 保持 `SOURCE_BLOCKED` | `coverage/source-do-s7-01.report.json`, `web/worker/test_source_do_s7_01.mjs`, `scripts/test_source_do_s7_01.py`, `web/worker/program-runner.mjs`, `web/worker/sim-session.mjs` |
|
||||
| `S7-02` | 接入锁定 `linuxcnc/tests/interp/g6164/test.ngc` 的 G64 continuous/P/Q、G61 exact-path、G61.1 exact-stop modal state;负 tolerance/unsupported code、pause/recovery parity 通过;S5-04 pending 清零,canonical logger 与 TP numeric parity 仍保持明确边界 | `coverage/source-g6164-s7-02.report.json`, `web/worker/test_source_g6164_s7_02.mjs`, `scripts/test_source_g6164_s7_02.py`, `web/worker/program-runner.mjs`, `web/worker/sim-session.mjs` |
|
||||
| `S7-03` | 选择有真实配置/native-WASM 样本且保持 XYZ/3-joint 形状的 `lineardeltakins`,接入 authoritative fixed tick;pose `[0,0,64.636584194]` 映射三 carriage joints `[300,300,300]`,1x/fast/recovery parity、无解 fail-closed 和 unsupported TRT boundary 通过 | `coverage/authoritative-kinematics-s7-03.report.json`, `web/worker/test_authoritative_kinematics_s7_03.mjs`, `scripts/test_authoritative_kinematics_s7_03.py`, `web/worker/authoritative-runtime.mjs` |
|
||||
| `S7-04` | 接入 `rotarydeltakins` authoritative fixed tick;pose `[0,0,-3.793360169]` 映射 rotary joints `[10,10,10]`,1x/fast/recovery parity、z=0 singular fail-closed 和 unsupported TRT boundary 通过;缺失 rdelta HAL 与官方 oracle 保持边界 | `coverage/authoritative-kinematics-s7-04.report.json`, `web/worker/test_authoritative_kinematics_s7_04.mjs`, `scripts/test_authoritative_kinematics_s7_04.py`, `web/worker/authoritative-runtime.mjs` |
|
||||
| `S7-05` | 对齐真实 `corexy_by_kins.ini` 的 LinuxCNC `#INCLUDE`、HAL 变量和反斜杠续行;HAL 72 条 preflight records 全部 ready,但 runtime 正确 BLOCKED 在缺失 `linuxcnc.var/tool.tbl`,未提升 static READY | `coverage/configuration-corexy-s7-05.report.json`, `web/worker/test_configuration_corexy_s7_05.mjs`, `scripts/test_configuration_corexy_s7_05.py`, `web/workspace/ini-parser.mjs`, `web/workspace/hal-configuration.mjs`, `web/workspace/configuration-startup.mjs` |
|
||||
| `S7-06` | verified:依据 `stepconf/build_INI.py` 的精确 `INTRO_GRAPHIC = linuxcnc.gif` 约定,将 `linuxcnc/linuxcnc.gif` 作为 DISPLAY-only shared simulation asset;同 basename 的 tool/parameter/HAL/program 和非 DISPLAY 键保持 blocked;资源图 state hash、source fixture、self-hash 和 native/Worker/App 全量回归通过。S7 后续技术任务未定义,指针保持 `next_task: none` | `coverage/resource-intro-graphic-s7-06.report.json`, `web/worker/test_resource_intro_graphic_s7_06.mjs`, `scripts/test_resource_intro_graphic_s7_06.py`, `web/workspace/resource-resolver.mjs`, `nextTask1.md` |
|
||||
| `S8-01` | verified:从真实 `linuxcnc/configs/sim` 生成 235 个 INI 案例和 2,080 个精确文件索引;递归 INI/HAL/resource loader 保留缺失诊断并把 static READY 与 runtime READY 分开;AppShell 提供案例筛选、Worker startup、G-code、MDI、Run/Pause/Step、Home/Jog、倍率、主轴/刀具/探针/急停和 machine view。235 个案例中 4 个 loader-ready、其余保留实际资源/HAL blockers | `coverage/sim-case-catalog.report.json`, `scripts/generate_sim_case_catalog.py`, `scripts/test_sim_case_catalog.py`, `web/workspace/sim-case-catalog.mjs`, `web/workspace/sim-case-loader.mjs`, `web/workspace/test_sim_case_loader.mjs`, `web/app/app.mjs`, `web/app/styles.css` |
|
||||
| `S8-02` | verified:用户授权从真实 LinuxCNC 仿真执行复制 runtime fixtures;`minimal_xyz` 的 `sim.var`/生成 HAL 和 CoreXY 的 `linuxcnc.var`/`tool.tbl` 均 exact-path hash-lock;预加载 `corexykins/motmod/pid/stepgen` 与虚拟 `hal_manualtoolchange` 适配通过,两个案例 Worker startup 均达到 `TASK_READY`,未知 `loadusr` 仍 blocked | `coverage/sim-case-startup-s8-02.report.json`, `web/worker/test_sim_case_startup_s8_02.mjs`, `scripts/generate_sim_case_startup_s8_02.py`, `scripts/test_sim_case_startup_s8_02.py`, `web/workspace/hal-configuration.mjs`, `web/workspace/sim-case-loader.mjs` |
|
||||
| `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-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 聚合;WASM/native/Worker/App 构建与回归 72/72 通过,10 个案例 TASK_READY、225 个案例保留 resource/HAL/INI/STARTUP blockers,display/machine family 与 runtime extension 证据已汇总;official full LinuxCNC oracle 仍 source-gated,Chromium/Firefox/Safari minimums 仍 TBD/Safari unavailable;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` |
|
||||
| `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` |
|
||||
| `FE-M4-GUI-02` | verified:集中 React GUI domain model,定义 12 family、23 个 protocol.v1 Worker command、panel/capability/boundary 映射;PY-WASM、SIM-DEVICE、WEB-EQUIV、REAL-EXCLUDED 和 Worker/OPFS ownership 均有 contract evidence | `coverage/react-gui-domain-fe-m4.report.json`, `web/react/src/gui-domain.ts`, `scripts/generate_react_gui_domain_report.py`, `scripts/test_react_gui_domain_report.py` |
|
||||
| `FE-M4-GUI-03` | verified:对照 LinuxCNC AXIS/Gremlin/glcanon 完成 React AXIS Web-equivalent workflow;program/MDI/run/pause/step/restart/abort/jog/home/override/spindle/tool/probe/coolant/estop/recover/DRO/Three.js 由 Worker 驱动,minimal_xyz Worker regression 和 React build 通过 | `coverage/axis-web-workflow-fe-m4.report.json`, `web/react/src/App.tsx`, `web/react/src/worker-client.ts`, `scripts/generate_axis_web_workflow_report.py`, `scripts/test_axis_web_workflow_report.py` |
|
||||
| `FE-M4-GUI-04` | verified:将 Gmoccapy/Touchy/Gscreen/QtVCP/QtDragon/PyVCP/GladeVCP/Vismach/NGCGUI/QtPlasmaC/Plasma 转为 family descriptor;Web Component、Three.js、PY-WASM 和 REAL-EXCLUDED 边界集中定义,12 family contract 通过 | `coverage/gui-family-adapter-fe-m4.report.json`, `web/react/src/gui-family-adapter.ts`, `scripts/generate_gui_family_adapter_report.py`, `scripts/test_gui_family_adapter_report.py` |
|
||||
| `FE-M4-GUI-05` | verified:建立 vismach/glcanon/NGCGUI/QtPlasmaC 的 Three.js visual workflow mapping;pose/joints/toolpath/stock/material/torch 只读 Worker snapshot,PY-WASM/真实硬件边界保留 | `coverage/gui-visual-workflow-fe-m4.report.json`, `web/react/src/visual-workflow.ts`, `scripts/generate_gui_visual_workflow_report.py`, `scripts/test_gui_visual_workflow_report.py` |
|
||||
| `FE-M4-GUI-06` | blocked(正式停止条件):现有 Chromium production preview desktop/mobile DOM、截图、Three.js canvas smoke verified;三浏览器 minimum matrix仍 TBD,Safari/Firefox 和 OPFS recovery 保持 blocked/STOP_RELEASE,不把 Chromium smoke 误报为全 GUI release | `coverage/gui-browser-visual-fe-m4.report.json`, `scripts/generate_gui_browser_visual_report.py`, `scripts/test_gui_browser_visual_report.py`, `nextTask1.md` |
|
||||
| `REAL-CASE-CONDITIONS-01` | 真实 LinuxCNC `linuxcnc -r` 临时目录执行 verified:minimal_xyz 和 CoreXY 均进入真实 TASK tick;当前环境使用 `linuxcnc-uspace 2.10.0~pre1`、非 `PREEMPT_RT` 内核的 POSIX fallback、X11 DISPLAY;CoreXY 缺 tool.tbl 时出现官方 tool-table error,补入临时 linuxcnc.var/tool.tbl 后持续运行;参数文件会在可写目录中生成/更新,临时 fixture 不纳入 source parity | `coverage/native-linuxcnc-case-conditions.report.json`, `scripts/generate_native_linuxcnc_case_conditions.py`, `scripts/test_native_linuxcnc_case_conditions.py`, `linuxcnc/docs/src/getting-started/system-requirements.adoc` |
|
||||
| `CASE-PARITY-PLAN-01` | 建立以真实 `configs/sim` 案例为中心的 S8-03..S8-10 执行队列;定义每案例 native/Worker/frontend parity contract、资源生成条件、Axis/QtVCP/Gscreen/Touchy/GladeVCP/PyVCP/VisMach 家族和 235-case full acceptance;S8-02 blocker 未被绕过 | `docs/linuxcnc-web-wasm-case-parity-plan.md`, `nextTask1.md` |
|
||||
|
||||
## 追溯规则
|
||||
|
||||
|
||||
Reference in New Issue
Block a user