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

44 KiB
Raw Blame History

LinuxCNC AXIS 完全对标规范与执行计划

文档状态:执行基线 v1.0(源程序已冻结;实现和验收按任务逐项关闭) 适用版本:LinuxCNC 2.10.0~pre0 239dcf4284762ad7e9c65d390bc5524d855c2f8e 项目上下文:linuxcnc-2.10.0-pre0-wasm-m1-py-c1 主入口:web/react 原始 AXIS 入口:linuxcnc/share/axis/tcl/axis.tcl 配套通信契约:前端与通信详细设计 配套案例契约:案例对标计划

本文件是“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 全部主界面结构、动作、启用条件、快捷键和默认变量
图标加载、动态帮助、控件辅助函数 share/axis/tcl/support.tcl、accel.tcl 资源解析、tooltip、菜单/控件 accelerator
自定义下拉、滚动条、对话框 share/axis/tcl/combobox.tcl、sb.tcl、dialog.tcl Jog increment、MDI history、文件和错误对话框的交互语义
AXIS 设计说明 src/emc/usr_intf/axis/README AXIS 的定位是 file preview + live plot;自解释控件、tooltip 和 Quick Reference
3D/预览窗口 lib/python/gremlin.py、gremlin_view.py 视角、缩放、拖动/旋转、预览加载、live plot、当前行和绘图刷新
G-code 绘图和坐标叠加 lib/python/rs274/glcanon.py rapid、path、dwell、tool、origin、offset、extents、grid、limits、velocity、DTG
配置声明和 GUI 家族 configs/sim/axis DISPLAY=axis、PYVCP/GLADEVCP/NGCGUI/VisMach/外部脚本及资源闭包
原始 bitmap share/axis/images AXIS logo、toolbar、spindle、标准报警图标、banner

本文中的 axis.tcl:N-M 是 linuxcnc/share/axis/tcl/axis.tcl 的行号简写;gremlin.py 和 glcanon.py 同理分别指上表中的完整路径。

2.2 源哈希和变更规则

基线文件的初始 SHA-256 记录如下;每次源更新必须重新生成 manifest 和本文件引用,不得沿用旧报告:

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:

序号 原始 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 推荐组件和协议字段

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 的报告至少包含:

{
  "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 由 scripts/generate_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 固化状态枚举、18 个 command gate、幂等边界和 host-boundary 标签,专属测试为 scripts/test_axis_contract_report.py。
  3. AXIS-UI-01…07 已完成 Chromium 结构证据: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 固化 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 固化 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 中 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:Chromium visual/interaction/performance/recovery,外加明确的 Firefox/Safari/OPFS blocker。
  8. AXIS-REL-01/02:只有所有 P0/P1 和报告自哈希通过,才更新 release gate。

第一批可执行命令:

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 中。