Files
linuxcncWebWASM/doc-rtcp/xyzac-trt-web-wasm-source-parity-contract.md

441 lines
18 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.
# XYZAC TRT Web/WASM 源码对标与唯一权威合同
文档状态:强制实施合同 v1.0
本合同是 [`xyzac-trt-web-wasm-implementation-plan.md`](xyzac-trt-web-wasm-implementation-plan.md) 的约束性补充。它回答一个更严格的问题:Web 控制面板如何证明自己是 LinuxCNC 源码行为的 Web/WASM 等价实现,并且所有控制功能唯一来自 LinuxCNC WASM,而不是来自 React、浏览器状态或第二套 JavaScript 运动模型。
适用案例:
```text
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini
```
## 1. 强制结论
### 1.1 唯一权威
以下数据只能由 LinuxCNC WASM runtime 产生;React、TypeScript、Three.js、Worker UI adapter 和浏览器不能自行生成“看起来合理”的替代值:
- task state、task mode、interpreter state、current line、queued MDI。
- program parse state、canonical events、trajectory queue、active segment。
- Cartesian pose、X/Y/Z/A/C 轴位置、五个 joint 位置、速度、加速度和 limits。
- XYZAC forward/inverse kinematics、switchkins type、TCP/RTCP tool compensation。
- tool table、tool offset、G43/G49/G43.1、spindle、coolant、probe、home、limit、following error。
- HAL pin/signal/parameter 读值、PyVCP state、IO ack、报警、错误和恢复结果。
- checkpoint、journal、replay、recovery endpoint 和 state hash。
前端可以拥有以下本地状态,但必须明确标记为非权威:
- 编辑器 draft、搜索词、文件选择、当前 tab、camera、图层显示、窗口尺寸、pending operation。
- 尚未提交的配置表单、UI 偏好和输入法状态。
### 1.2 严禁的替代 authority
下列行为一律视为实现失败:
1. React 根据按钮点击直接把 task/mode/position/kinematics 写成目标状态。
2. JS 根据 A/C 角度和 tool length 自行计算 X/Y/Z 补偿并展示为实际 pose。
3. JS G-code preview、Three.js preview 或 canvas 轨迹被当作 canonical motion。
4. UI 通过 `setTimeout`、墙钟、`requestAnimationFrame` 或点击次数推进仿真 tick。
5. 浏览器直接访问 WASM 指针、导出内部内存、写 OPFS journal 或调用宿主 LinuxCNC。
6. 前端绕过 Worker gateway 直接发送 HAL pin 写入、M428/M429 或模拟 IO 副作用。
7. 收不到 `COMMAND_RESULT` 时把 pending 命令当作成功,或超时后无 ledger reconcile 直接重发。
8. 把 native/AXIS 行为复制成新的 JS 状态机,再用 WASM 只做最终演示。
9. 以截图、按钮存在、模块测试或“曲线看起来一样”宣称完整五轴 parity。
10. 把 HOST_BOUNDARY、REAL-EXCLUDED、SOURCE_BLOCKED 或缺少官方 oracle 的结果改写为 verified。
## 2. 对标单位:source behavior slice
对标的最小单位不是“页面”或“组件”,而是 source behavior slice:
```text
source symbol/control
→ input/event/command
→ native state gate
→ LinuxCNC canonical result
→ status/event/visual output
→ error/abort/recovery behavior
```
每个 slice 必须有唯一 `slice_id`。示例:
```text
AXIS-XYZAC-AUTO-RUN
AXIS-XYZAC-M428-TCP
AXIS-XYZAC-JOG-C
AXIS-XYZAC-HOME-JOINT-3
AXIS-XYZAC-LOAD-PROGRAM
AXIS-XYZAC-VISMACH-POSE
```
### 2.1 Slice manifest 必填字段
```json
{
"slice_id": "AXIS-XYZAC-M428-TCP",
"source": {
"path": "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"symbols": ["428remap"],
"lines": "1-24",
"sha256": "..."
},
"inputs": ["MDI_EXECUTE:M428", "task_state", "motion.switchkins-type"],
"native_commands": ["M68 E3 Q1", "M66 E0 L0"],
"wasm_commands": ["MDI_EXECUTE", "KINEMATICS_SELECT"],
"authoritative_outputs": ["kinematics.active_type", "state_hash"],
"ui_controls": ["AXIS-RTCP-TCP-XYZAC"],
"gates": ["interp_idle", "hal_pin_present", "switchkins_net_present"],
"normal_cases": [],
"boundary_cases": [],
"error_cases": [],
"recovery_cases": [],
"status": "queued"
}
```
没有 source path、symbol、输入、native command、WASM command、输出、gate 和测试的功能,不得进入“实现完成”统计。
## 3. 源码到 WASM 的闭合分层
### 3.1 Source inventory 层
必须锁定并哈希以下来源:
| 层 | 来源 |
|---|---|
| AXIS controls | `linuxcnc/share/axis/tcl/axis.tcl`、`support.tcl`、`accel.tcl`、`dialog.tcl`、`combobox.tcl`、`sb.tcl` |
| AXIS Python | `linuxcnc/src/emc/usr_intf/axis/scripts/axis.py` |
| Preview/canon | `linuxcnc/lib/python/rs274/glcanon.py`、`gremlin.py`、`vismach.py` |
| Case config | `xyzac-trt.ini`、`xyzac-trt.xml`、`switchkins_postgui.hal`、`xyzac-trt.tbl`、`xyzac.var` |
| Program/remap | `demos/*.ngc`、`remap_subs/*.ngc` |
| Kinematics | `xyzac-trt-kins.c`、`xyzbc-trt-kins.c`、`trtfuncs.c`、`switchkins.c/h`、`kins_util.c` |
| Motion/TP | `motion/command.c`、`motion/control.c`、`motion/homing.c`、`motion/motion.c`、`tp/tp.c`、`tp/tcq.c`、`tp/blendmath.c` |
| Interpreter | `rs274ngc/interp_read.cc`、`interp_execute.cc`、`interp_queue.cc`、`interp_convert.cc`、`modal_state.cc` |
| HAL/IO | `task/emctaskmain.cc`、`iotask/ioControl.cc`、HAL component source and `basic_sim.tcl` |
Inventory 不能只记录目录;必须展开到具体文件、source hash、引用关系和运行时 fixture。生成的 `sim.var`、`position`、journal 和临时 tool table 必须单独标为 `runtime-generated-fixture`。
### 3.2 Compat API 层
WASM 不直接向 React 暴露 C 内部函数。应建立有限、版本化的 `LinuxCncCompat`:
```text
LinuxCncCompat
├── task: state/mode/interpreter/queue
├── program: load/parse/run/pause/resume/step/abort/seek
├── mdi: execute/cancel/result
├── motion: jog/home/limit/override/spindle
├── kinematics: forward/inverse/select/diagnostics
├── hal: read/write/subscribe/type-check
├── io: tool/coolant/probe/spindle ack
├── snapshot: full/delta/hash
└── recovery: checkpoint/replay/reconcile
```
每个方法必须映射到 source symbol 和固定 tick 位置;不允许添加“为了 UI 方便”的隐式状态改变。
### 3.3 Worker protocol 层
Worker gateway 负责 schema、capability、gate、ledger、seq、operation id 和错误包装;不负责猜测 motion 结果。协议命令必须能够回到 compat API,并最终回到 WASM canonical state。
```text
UI event
→ WorkerClient
→ protocol validator
→ capability/gate validator
→ CommandLedger.prepare
→ LinuxCncCompat
→ fixed-tick WASM runtime
→ snapshot/event/hash
→ CommandLedger.commit
→ UI projection
```
### 3.4 Projection 层
React reducer 只做:
- 校验消息。
- 保存 authoritative snapshot/event/result。
- 派生按钮 gate、标签、错误和可视化 props。
- 保留 pending/draft/ack/reconcile 状态。
Reducer 不得:
- 生成新的 motion/joint/pose。
- 依据 UI 点击顺序补齐缺少的状态。
- 在没有 Worker 快照时把按钮变为成功。
- 把 preview segment 当成 active motion segment。
## 4. 完整功能对标登记
### 4.1 控制面板域
以下域必须全部有 source slice;每项还要登记 menu/toolbar/button/keyboard/HAL 入口:
| 域 | 最低条目 |
|---|---|
| Shell | title、machine name、version、about、quick reference、window/min-size、focus、tooltip |
| File | open、recent、reload、save-as、properties、tool data、quit、exact path |
| Machine | ESTOP、power、reset、home all、home joint、unhome、override limits、touch-off |
| Mode | manual、mdi、auto、joint/world/teleop、mode denial |
| Program | run、pause、resume、step、abort、restart、run-from-line、optional stop、block delete |
| MDI | input、history、queue、clear、calculator、error/ack |
| Jog | axis/joint selection、continuous/incremental、linear/angular speed、press/release/stop |
| DRO | actual/commanded/relative/machine、G5x/G92/tool offsets、DTG、rotation |
| Preview | perspective/X/Y/Z、zoom、pan/rotate、grid、rapids、tool、limits、extents、live plot、clear |
| Tool | tool table、reload、tool change、tool offset、G43/G49/G43.1、manual toolchange |
| Spindle/IO | direction、speed、override、brake、coolant、lube、probe、digital/analog |
| HAL/PLC | HAL graph/scope/command、PyVCP、ClassicLadder/PLC state、capability denial |
| Diagnostics | alarm、error、event log、command trace、snapshot diff、runtime overrun、recovery |
| Case-specific | XYZAC/XYZBC type buttons、M428/M429/M430、A/C limits、RTCP offsets、Vismach clear |
### 4.2 对标登记状态
每项只能处于:
```text
UNREGISTERED → SOURCE_MAPPED → WASM_IMPLEMENTED → WORKER_VERIFIED → UI_VERIFIED → PARITY_VERIFIED
```
任意阶段失败都必须停留在对应状态并保存原因。`UI_VERIFIED` 不能越过 `WASM_IMPLEMENTED`;`PARITY_VERIFIED` 不能只用浏览器截图证明。
## 5. 状态和 gate 的唯一实现
### 5.1 Native gate 取证
对于每个按钮,必须从原始 AXIS/LinuxCNC 源码提取:
- handler 名和绑定位置。
- 读取的 `stat`、HAL pin、INI 值和局部变量。
- 允许状态/拒绝状态。
- 发送的 command 和参数。
- command 后检查的 state。
- 错误对话框/状态栏/恢复行为。
### 5.2 WASM gate 复现
WASM gate 只允许读取 WASM snapshot:
```text
gate(action, authoritative_snapshot, capability, configuration)
→ { enabled, reason, required_state, source_slice_id }
```
React 可以显示 gate,但不能覆盖 gate。若 native 与 WASM gate 不同,先生成差异报告;不能在 React 中添加特殊分支“修正”显示。
### 5.3 XYZAC 特殊 gate
```text
M428/TCP = interpreter_idle && HAL_PIN_VARS && switchkins_net && finite_offsets
M429/identity = interpreter_idle && HAL_PIN_VARS && switchkins_net
M430/userk = interpreter_idle && userk_capability
A/C jog = manual_ok && axis_enabled && angular_limits && no_fault
RTCP motion = active_type == 1 && pose/joint transform verified
Vismach clear = visual-only,不改变 task/motion/program/hash
```
## 6. Native/WASM 等价证明
### 6.1 输入冻结
每次 parity run 固定:
- context id、case source hashes、browser/runtime build hash。
- INI/HAL/NGC/TBL/VAR/Python/XML exact resources。
- 程序文本、MDI 文本、按钮动作序列、固定 logical tick 数量。
- 初始 task/mode/home/tool/offset/kinematics state。
### 6.2 Trace 规范
```json
{
"slice_id": "AXIS-XYZAC-M428-TCP",
"step": 7,
"input": {"kind": "MDI_EXECUTE", "line": "M428"},
"native": {
"task_mode": "MDI",
"motion_switchkins_type": 1,
"state_hash": "..."
},
"wasm": {
"task_mode": "MDI",
"motion_switchkins_type": 1,
"state_hash": "..."
},
"equal": true,
"first_divergent_tick": null
}
```
### 6.3 等价层级
1. **Protocol**:信封、seq、operation id、command/result/error schema。
2. **Control**:按钮 gate、模式转换、队列、取消、abort/reconcile。
3. **State**:task/interp/motion/home/limit/tool/IO/kinematics snapshot。
4. **Canonical**:canonical events、TP queue、pose/joints/toolpath。
5. **Recovery**:checkpoint、replay、endpoint hash、无重复副作用。
6. **Visual**:DRO、当前行、轨迹、A/C pose、Vismach 非空和布局。
低层级通过不能替代高层级缺口;visual 通过尤其不能替代 canonical/control 失败。
## 7. WASM-only 前端实施拆分
### 7.1 Runtime 完整性
WASM bundle 必须包含或明确拒绝:
- RS274NGC parser/interpreter、modal state、canonical events。
- TP queue/blend/arc/helix、fixed tick。
- XYZAC/XYZBC TRT forward/inverse、tool offset、rotation points、limits。
- task/motion/home/limit/IO/tool/probe/spindle/coolant。
- remap/Python capability model(无能力时稳定拒绝)。
- snapshot/event/hash/checkpoint/recovery。
`REAL-EXCLUDED` 能力不能通过宿主 LinuxCNC fallback 伪装成 WASM 支持。
### 7.2 Worker 完整性
Worker 必须是:
- WASM runtime 的唯一调度者。
- protocol schema 和 capability 的唯一入口。
- OPFS journal/checkpoint 的唯一写者。
- command ledger 和 reconcile 的唯一实现者。
- snapshot/event/trajectory 的发布者。
Worker 不得把某些命令转给主线程 JS authority;若能力未实现,返回 `capability_unavailable`/`source_blocked`。
### 7.3 Web 控制台完整性
React 页面必须从 `PanelSnapshotV1`/扩展快照显示:
- case/configuration/source hash。
- task/mode/interpreter/kinematics state。
- gates 和 reason。
- program/line/preview/active segment。
- Cartesian pose、XYZAC joints、tool offset、A/C limits。
- HAL/IO/tool/spindle/coolant/probe/alarms。
- pending/ack/result/reconcile/recovery。
所有 button handler 只能调用 `WorkerClient`/`AxisOperationController`;禁止 `setState` 直接表示 command 已完成。
## 8. 里程碑增强版
在原 `M0-M7` 上增加“源码唯一权威”退出条件:
### M0-SOURCE:完整 source manifest
- AXIS、G-code、motion、TP、kinematics、HAL、IO、Vismach 所有功能已登记 slice。
- source hash、symbol、resource graph 和 version lock 可复现。
- unregistered count = 0;blocked count 单独报告。
### M1-WASM-AUTHORITY:无 JS authority
- 所有 task/motion/kinematics/program state 均由 WASM snapshot 产生。
- JS authority call count = 0;可以使用的 JS 只剩 projection/ledger/UI。
- 损坏/篡改 snapshot fail closed。
### M2-CONTROL-PARITY:按钮和命令对标
- 每个 source slice 有 native/WASM button gate trace。
- 正常、拒绝、ESTOP、limit、pause、abort、reconcile 全部通过。
- gate mismatch count = 0。
### M3-CANONICAL-PARITY:解释器、TP、运动学
- program/canonical/TP/XYZAC pose/joint/toolpath trace 一致。
- M428/M429/M430、helix、A/C 姿态和 tool offset 一致。
- first divergent tick 可定位且 verified 样本无差异。
### M4-FRONTEND-PARITY:React/Three.js
- 所有 UI controls 只消费 WASM state。
- Three.js 不重算姿态;canvas 与 snapshot hash 对账。
- DOM、keyboard/touch、错误、pending、recovery UI 通过。
### M5-RECOVERY-PARITY:恢复和离线
- command ledger、checkpoint、journal、Worker restart endpoint 一致。
- 无重复 M-code、tool/IO side effect、trajectory segment。
- offline/OPFS quota/schema mismatch 证据完整。
### M6-RELEASE-PARITY:严格发布门
- source slice coverage = 100%(verified + explicit blocked 分开统计)。
- native/WASM/Worker trace、hash、错误、恢复和 browser matrix 报告齐全。
- 任何外部 oracle/browser/hardware/license/owner blocker 都保持 `STOP_RELEASE`。
## 9. 任务新增与调整
在 `xyzac-trt-web-wasm-implementation-plan.md` 的 `RTCP-00..12` 之前增加以下治理任务:
### SRC-00:AXIS/XYZAC Source Slice Inventory
**输出**:`coverage/xyzac-trt-source-slice-inventory.report.json`、`web/workspace/xyzac-trt-source-slices.mjs`。
**门禁**:所有 source controls、handlers、commands、state fields、visual outputs 和 errors 有唯一 slice id;unregistered=0。
### WASM-00:唯一权威审计
**输出**:`coverage/xyzac-trt-wasm-authority-audit.report.json`。
**门禁**:扫描 JS/TS/React/WASM bridge,证明没有 JS task/motion/kinematics authority、JS G-code execution 或 OPFS direct writer。
### PARITY-00:Native/WASM Trace Comparator
**输出**:`scripts/compare_xyzac_native_wasm_trace.py`、`web/worker/test_xyzac_trace_parity.mjs`、parity report。
**门禁**:协议、control、state、canonical、recovery 五级比较器能报告 first divergent tick,而不是只比较最终位置。
### UI-00:Source Control Binding Audit
**输出**:React control manifest、每个 control 的 source slice/gate/command/result 映射。
**门禁**:每个 button/menu/keyboard/gesture 都能追溯到 source id;每个 UI action 都通过 WorkerClient。
### RELEASE-00:WASM-only Release Gate
**输出**:`coverage/xyzac-trt-wasm-only-release-gate.report.json`。
**门禁**:WASM-only capability、source coverage、trace parity、browser matrix、recovery、错误和 blocker identity 全部审计;任何缺口都输出 `STOP_RELEASE`。
## 10. 测试和证据规则
每个 source slice 最少包含:
```text
native normal
native boundary
native error
WASM normal
WASM boundary
WASM error
Worker command/result
UI gate projection
pause/resume/abort
checkpoint/recovery(适用时)
deterministic state hash
```
测试不能只调用纯 JS helper;必须运行真实 WASM module、Dedicated Worker/session、固定 logical tick 和实际 snapshot publisher。`mock` 只能用于协议单元测试,不能用于功能通过。
报告必须记录:source hash、input hash、output hash、command sequence、tick sequence、state hash、first divergent tick、error code、failure sample、environment and exclusion reason。
## 11. 停止条件
下列任一条件出现,停止当前“完全对标”声明:
- 任意功能没有 source slice 或 source hash。
- 任意程序/运动/RTCP 结果来自 JS/React/Three.js 推算。
- 任意 button gate 与 native 不一致且没有明确 source/version 差异。
- `M428/M429/M430` 没有通过 WASM remap/kinematics 状态确认。
- canonical trace 只比较最终坐标,未比较首个 divergent tick。
- recovery 可能重复 segment、M-code、tool/IO side effect。
- browser 截图通过但 Worker/WASM authority 或 state hash 未验证。
- 缺少官方 oracle、浏览器、实时硬件、OPFS crash 或 owner 输入时试图 promote release。
## 12. 对当前项目状态的诚实结论
当前仓库已有通用 AXIS gate、Worker protocol、React reducer、Three.js workflow 和选定案例证据,但这些不能直接等同于 `xyzac-trt.ini` 的完整 WASM-only parity。按照本合同,下一步应先执行 `SRC-00` 和 `WASM-00`,再实现 `RTCP-01..12` 中的缺口;在 source slice coverage、WASM authority audit、RTCP trace parity 和 recovery 完成前,状态必须保持 `in_progress` 或 `blocked`,不能写成 `verified` 或全功能完成。