Files
linuxcncWebWASM/docs/linuxcnc-axis-complete-parity-spec.md

592 lines
45 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`(同一 self-hashed 报告包含 source/UI/asset/case inventory)。
**失败即停止**:源码提交、资源字节、案例资源或 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 桌面和窄屏无重叠、无裁切。
当前 Chromium 结构证据:`coverage/gui-browser-visual-fe-m4.report.json`,报告哈希 `0df7a7c9c663292bbf1f764946032fb4ba1b882b23532863569470c723401ae1`;Firefox/Safari/OPFS 不随该授权切片关闭。
**不计入通过**:只截图而没有 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 的 `AXIS-INV-01…04` 已执行:[`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),当前冻结 10 个源码入口、31 个 bitmap 资源和 115 个精确 AXIS INI 案例,报告自哈希为 `0ec92a467ca13700bd12a7f2889ada8aa11588ca50858dbe25f84a5c946b8176`。该报告只冻结来源,不代表任何 Web 功能已通过行为或视觉验收。
接续执行顺序固定为:
1. `AXIS-INV-01…04` 已完成;报告保留 exact path、source hash、asset hash 和 DISPLAY 声明。
2. `AXIS-CON-01…04` 已完成:[`coverage/axis-contract.report.json`](../coverage/axis-contract.report.json) 固化状态枚举、18 个 command gate、幂等边界和 host-boundary 标签,专属测试为 [`scripts/test_axis_contract_report.py`](../scripts/test_axis_contract_report.py)。
3. `AXIS-UI-01…07` 已完成 Chromium 结构证据:[`coverage/gui-browser-visual-fe-m4.report.json`](../coverage/gui-browser-visual-fe-m4.report.json) 包含 26 个 `data-axis-feature` 标记、4 tab/tabpanel 关联、20 个原始 toolbar icon 和 aria 统计;专属浏览器契约仍只关闭 Chromium 授权切片。
4. `AXIS-CTRL-01…08` 已完成:[`coverage/axis-control.report.json`](../coverage/axis-control.report.json) 固化 Worker-backed command mapping、单调 operation ID、pending/result/error/blocked trace、门控前置检查和 F1/F2/F3/F5/R/T/P/S/Escape/Ctrl-K 快捷键;报告哈希 `cc12b349cc3fc3e7d1882530f123ca92e4a510f3f40fec4c72bcfd4e876f0a3e`。
5. `AXIS-VIEW-01…04` 和 `AXIS-EDIT-01` 已完成:[`coverage/axis-view-edit.report.json`](../coverage/axis-view-edit.report.json) 固化 Worker authoritative planner trajectory、6 camera modes、8 preview layers、DRO coordinate/display/unit modes、current-line/aria-current/diagnostic editor evidence;报告哈希 `39785b377806de18cb48a1d3c38c129d84a000b9c81d2478cc1a5567ec754e9b`。
6. `AXIS-CASE-01…04` 已形成案例矩阵:[`coverage/axis-case-parity.report.json`](../coverage/axis-case-parity.report.json) 中 Minimal XYZ、CoreXY kins/HAL、Linear/Rotary Delta representative verified;lathe/gantry/VisMach-5-axis 仍按 exact resource/startup 与 official kinematics oracle 保持 blocked。报告哈希 `a6fcc5eec964a02b821f9a52f30b8e0d3303b8c94507b6d44d6cc75b7a7089e4`。
7. `AXIS-TEST-01…06` 已形成测试矩阵:[`coverage/axis-test-matrix.report.json`](../coverage/axis-test-matrix.report.json) 中 DOM/accessibility、Chromium visual、operation replay、Worker case parity 和 Chromium repeat performance 已验证;Firefox/Safari minimum matrix、OPFS recovery 和 6 个案例资源/oracle blocker 仍明确 blocked。报告哈希 `9ba5de25bd8cfbfd61bd0a87bcb282170fa1de44b28a172b1c6ba649f580c357`。
8. `AXIS-REL-01/02` 已完成 AXIS 专用 evidence index:[`coverage/axis-release-evidence.report.json`](../coverage/axis-release-evidence.report.json) 索引 7 份报告、file/report hash、owner、verified/partial 状态和 blocker 分类;release gate 保持 `STOP_RELEASE`,报告哈希 `1a0d3add58fcddf8a6a2a81a7197d91c45a1c94fabb7db75033c4b2f0f3da777`。
第一批可执行命令:
```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 中。