Files
linuxcncWebWASM/doc-rtcp/xyzac-panel-button-parity-test-report.md

329 lines
20 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 面板按钮对标测试报告
## 结论
本报告针对当前选定案例
`linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini`,
按 LinuxCNC AXIS 的命令、门控、状态和错误语义执行了一轮完整面板验收。
`selected_case_status: VERIFIED_WITH_SCOPE_GAPS`
`release_status: STOP_RELEASE`
这表示已执行并通过选定 XYZAC 案例的 WASM/Worker 控制闭环,但不宣称整个 LinuxCNC 或所有 AXIS 配置已经数值完全对标。
本项目铁律:所有 G-code、运动、门控、I/O、HAL、刀具和状态业务不得由 JavaScript 模拟;React/Three 只做用户输入与显示投影。
## 对标输入
| 作用 | LinuxCNC 原始输入 | Web/WASM 输入 |
| --- | --- | --- |
| AXIS 菜单、快捷键、状态轮询 | `linuxcnc/src/emc/usr_intf/axis/scripts/axis.py`、`linuxcnc/share/axis/tcl/axis.tcl` | `web/react/src/App.tsx`、`web/app/axis-contract.mjs` |
| 程序/暂停/恢复/停止 | `axis.py:task_run/task_step/task_pause/task_resume/task_stop` | `PROGRAM_RUN/STEP/PAUSE/RESUME/ABORT` -> `SimTask` + LinuxCNC source TP |
| JOG/HOME | `axis.py:jog_on/jog_off/home_all_joints/home_joint` | `JOG_START/JOG_STOP/HOME` -> `WasmLinuxcncTp/WasmHomeLimit` |
| MDI/Touch Off | `axis.py:send_mdi_command/touch_off_system/touch_off_tool` | `MDI_EXECUTE` -> `linuxcnc-wasm-sim_program` |
| Feed/rapid/spindle override | `axis.py:set_feedrate/set_rapidrate/set_spindlerate` | `SET_OVERRIDE` -> WASM TP/IO |
| 主轴、刹车、冷却、刀具、探针 | `axis.py:spindle/brake/mist/flood/change_tool` | `SPINDLE_COMMAND/SPINDLE_BRAKE/COOLANT_COMMAND/TOOL_*/PROBE_CONFIG` -> WASM IO |
| 预览、实时轨迹、清屏 | `linuxcnc/lib/python/rs274/glcanon.py` | `XyzacToolPreview`,只投影 WASM preview/motion trace |
| XYZAC M428/M429/M430 | `switchkins_postgui.hal`、`remap_subs/428remap.ngc` 等 | `KINEMATICS_SELECT` -> WASM kinematics/switchkins |
源码输入哈希:
```text
axis.py 328c038a1e8fefd952e53c8e398e3fa98b04602351c44318edd1b044e8f63ffa
glcanon.py 0dfb20f1fdc05289894f3aa638357d98e1063fbd53329c723c777399ec7b33b7
xyzac-trt.ini f985970db293b70c055e4c41fc316d0c16037b5dc7ce07490e18f554e851f811
source slices c9f0b4dc686717b37565f85fb0ab8cc8ded9cfa0028cc0aaaccdbcf808c4c524
```
AXIS 源控件清单:菜单 80、工具栏 20、快捷键 10,共 110 条,来自 `web/workspace/xyzac-trt-source-slices.mjs`。
## 权威状态边界
选定 `xyzac-trt` 配置时,Worker 强制建立 LinuxCNC WASM TP,不接受缺省 planner 降级。前端只负责输入和显示投影,业务值、门控、运动和设备状态均来自以下 WASM 边界:
| 数据/动作 | 唯一来源 | 前端使用方式 |
| --- | --- | --- |
| G-code 解析、当前行、活动段、预览 | `WasmProgramRuntime` (`linuxcnc-wasm-sim_program`) | 显示源代码和路径,不在 React 重解析 |
| XYZAC 位姿、速度、队列、前瞻 | `WasmLinuxcncTp` (`linuxcnc-source-tp`) | DRO、实时刀具、执行状态 |
| 五关节命令值 | WASM TP 当前 pose + `sim_kinematics_switch_inverse_mode` | 关节/DRO 投影;无 JS 插值 |
| JOG 目标、速度和限位 | `sim_linuxcnc_tp_jog`、WASM TP axis limits/jog scale | Worker 只传递轴、方向、步长 |
| HOME、逐关节 homed、limit | `WasmHomeLimit` (`homed_mask`) | Home 按钮和轴状态门控 |
| ESTOP、POWER、主轴、探针、HAL | `WasmXyzacIo` / `sim_io` / `sim_hal` | 设备状态、报警和命令结果 |
| Task/程序门控 | `SimTask` `sim_task_command_gate` | 所有按钮 `disabled` 和错误原因 |
| Feed/Jog/Max/Spindle override | WASM TP/IO getter/setter | 受控 slider,值由快照回读 |
| 视图缩放、旋转、平移、tab | React/Three 本地 UI | 仅显示交互,不参与运动计算 |
实时参数区显示:主轴实际转速 `speed_rpm`、主轴指令转速 `command_rpm`、G-code `S` 值、TP 实际进给 `velocity_mm_min`、G-code `F` 值、TP 速度/上限、F/S override、队列深度、活动段和当前执行行。所有值来自 WASM program/TP/IO 快照,参数区的 `data-xyzac-parameter-source` 为 `linuxcnc-wasm`;未取得快照时显示 `-`。
程序预览替换规则:`PROGRAM_LOAD` 开始时先清空旧的 canonical preview;如果 WASM 解析或子程序加载失败,错误响应中的路径仍为空,不会把旧程序刀路重新投影出来。新的 WASM preview 成功后才替换为新程序路径。
在 WASM 快照尚未到达前,界面显示 `WASM PENDING` 并禁用运动操作;不会使用 JS 默认轴值、任务状态或 override 值。浏览器定时器只发送 `SIM_STEP` 采样请求,不执行 G-code、轨迹、运动学或设备状态计算。React/Three 中的定时器、相机、网格、刀具网格和文本格式化均为显示层,不产生或修改任何 CNC 状态。
## 按钮/控件矩阵
下表中的“通过”包含正常路径和刻意触发的 LinuxCNC 门控拒绝;拒绝不是失败,必须返回可解释的 gate/error key。
| 面板区域 | Web 控件 | LinuxCNC 命令/源函数 | WASM 权威输出 | 结果 |
| --- | --- | --- | --- | --- |
| 会话 | HELLO、SESSION_ATTACH | AXIS 启动/状态轮询 | `sim_protocol`、`SimTask` | 通过 |
| Machine | Emergency Stop、Release E-stop | `General_Halt`、`emcTaskAbort` | WASM IO + Task ESTOP/RESET | 通过 |
| Machine | Power On/Off | `commands.power`、`emcTaskSetState` | `sim_io_set_power` | 通过 |
| Machine | Reset | `commands.reset` | WASM Task/IO reset | 通过 |
| Machine | HOME ALL | `home_all_joints` | `WasmHomeLimit` 五关节回零 | 通过 |
| Machine | Home X/Y/Z/A/C | `home_joint` | `WasmHomeLimit.homed_mask` 逐关节回零 | 通过 |
| Machine | Run Startup Sequence | release -> power -> home -> run | Worker 固定顺序 | 通过 |
| Program | Load | `open_file_guts` | WASM interpreter preview | 通过 |
| Program | Run | `task_run` / `AUTO_RUN` | WASM program + source TP | 通过 |
| Program | Pause / Resume | `task_pause` / `task_resume` | WASM interpreter + TP pause/resume | 通过 |
| Program | Stop | `task_stop` / `c.abort` | WASM TP abort,队列清零 | 通过 |
| Program | Restart | `reload_file` / first line | WASM program reload | 通过 |
| Program | Step / Seek | `task_step` / `set_first_line` | WASM interpreter | 通过 |
| JOG | X、Y、Z、A、C +/-、Stop | `jog_plus/jog_minus/jog_on/jog_off` | WASM source TP jog velocity/queue | 通过 |
| JOG | 越界/非有限速度 | LinuxCNC motion limit/ferror | WASM 错误 key | 通过拒绝 |
| MDI | Go、历史命令 | `send_mdi_command` | WASM interpreter/canonical | 通过 |
| MDI | 运行中 MDI | `manual_ok` | `mdi_while_program_active` | 通过拒绝 |
| Override | Feed Override 50%/200% | `set_feedrate` | WASM TP feed override | 通过 |
| Override | Feed > 200% | `set_feedrate` range | `motion_override_range` | 通过拒绝 |
| Spindle | CW/CCW/Stop | `spindle_forward_toggle/spindle` | WASM spindle command | 通过 |
| Spindle | +/- | `SPINDLE_INCREASE/DECREASE` | WASM signed delta | 通过 |
| Spindle | Brake | `EMC_SPINDLE_BRAKE_ENGAGE/RELEASE` | WASM IO brake state | 通过 |
| Coolant | Mist/Flood | `mist_toggle/flood_toggle` | WASM device IO | 通过 |
| Tool | Prepare、Prepared、Change、Changed | iocontrol/tool handler | WASM IO tool state | 通过 |
| Probe | Arm、Disarm、Trip | probe canonical/HAL | WASM IO + HAL | 通过 |
| Switchkins | Identity/M429、TCP: XYZAC/M428、User K/M430 | `switchkins_postgui.hal` + remap files | WASM kinematics `active_type` | 通过 |
| Switchkins | IDENTITY <-> TCP: XYZAC <-> USERK 任意切换 | `KINEMATICS_SELECT` / `M429` / `M428` / `M430` | 当前 WASM TP pose + WASM inverse/forward | 通过 |
| Preview | Preview、DRO、路径/实时/限位/速度/偏置/范围 | `glcanon.py` draw layers | WASM pose/joints/toolpath | 通过投影 |
| Preview | 缩放、平移、旋转、原点坐标系 | AXIS view handlers | React/Three display-only state | 通过显示 |
| Diagnostics | 状态、门控、错误、恢复 | AXIS status/error channel | Worker snapshot/ledger | 通过 |
## 本轮自动化结果
聚合用例:`web/worker/test_xyzac_panel_buttons.mjs`
```json
{
"schema": "xyzac-panel-button-parity.v1",
"source": "linuxcnc-wasm-worker",
"verified_paths": 97,
"expected_error_paths": 8,
"blocked_by_abi_paths": 4,
"selected_case_release_status": "STOP_RELEASE"
}
```
97 条通过路径包括:
- Machine:HELLO、SESSION_ATTACH、LOAD_WORKSPACE、ESTOP、ESTOP_RESET、POWER、RESET、HOME ALL、启动序列;
- Machine:五个轴的独立 HOME、`homed_mask` 聚合和部分回零门控;
- Program:LOAD、RUN、SIM_STEP、PAUSE、SNAPSHOT、RESUME、ABORT/STOP、RESTART、STEP、SEEK、按行恢复;
- JOG:XYZAC 五轴启动、固定 tick 采样和停止;
- MDI:正常 G-code、运行中门控和非法 G-code 错误回显;
- Feed Override:50%、200% 和 201% 拒绝;
- 主轴:CW、signed increase/decrease、Stop、Brake engage/release;
- Coolant、Tool prepare/change ack、Probe arm/disarm、ESTOP recovery;
- M428/M429/M430、VISUAL_CLEAR 和诊断快照。
- Switchkins 直接按钮在非零姿态下 `0 -> 1 -> 2 -> 0 -> 1 -> 2 -> 0` 循环切换;每一步的 kinematics pose 与 TP pose 逐轴一致。
8 条错误路径是刻意验证的拒绝:OFF 状态 Run/HOME/JOG/MDI/M428、Feed 201%、非法 MDI、运行中 MDI。它们均返回 LinuxCNC/WASM 可读原因,没有把拒绝当成成功。
3D_Chips 长程序补充验证:
```text
source_length: 200509
line_count: 4711
preview_segments: 4684
fixed_tick_samples: 3000
execution_line: 337
execution_trace_entries: 335
motion_authority: wasm
motion_delta_snapshots: 0
ledger_audit_window: 32
running_queue_gaps: 0 (excluding the initial startup tick)
```
## 长距离连续性判定
`3D_Chips.ngc` 第 17 行设置 `G64 P.1`,后续是大量连续短段。对标 LinuxCNC source TP 时,正常表现是 TP 在当前段运行期间持续保留前瞻队列;G64 不应在普通同模式段之间出现人为的零速度空队列 tick。此前 Worker 在等待当前段完全结束后才入队下一段,造成截图中可见的短暂停顿,这不是源 LinuxCNC 的合理结果。
已修复为:同一运动学模式的下一段可在当前 TC 活动时进入 source TP;M428/M429/M430 模式变化仍由 WASM Task/TP 同步边界约束;队列容量由 `sim_linuxcnc_tp_queue_capacity` 读取,按真实 `TP_DEFAULT_QUEUE_SIZE` 限流。1000 tick 连续性回归中,除启动第 1 tick 外 `program_status=running && queue_depth=0` 的次数为 `0`;第 82 行附近仍保持 31 段前瞻队列。
## 当前未闭合项
以下项目仍明确记录为 `blocked_by_abi`,没有伪造通过:
1. `Override Limits`:原始 AXIS `toggle_override_limits` 有独立 motion command;选定 XYZAC WASM 配置目前把 limits 作为配置所有权,尚无等价 command ABI。
2. `Block delete` 和 `Optional pause`:当前 AXIS 图标已禁用,尚未写入 WASM interpreter modal/control state;不保留本地假状态。
3. `Tool Touch Off`:当前按钮发送固定 `G43`;原始 AXIS 先取得用户值,再发送 `G10 L10/L11` 和 `G43`,交互输入流程尚未闭合。
4. `Edit tool data`、`Quit`:依赖桌面进程/外部编辑器,属于浏览器 `HOST_BOUNDARY`,不在仿真 Web 范围内。
## 复现命令
```bash
scripts/build-wasm.sh
npm run build --prefix web/react
node --experimental-strip-types web/worker/test_xyzac_panel_buttons.mjs
node --experimental-strip-types web/worker/test_xyzac_trt_case.mjs
node --experimental-strip-types web/worker/test_xyzac_button_constraints.mjs
node --experimental-strip-types web/worker/test_xyzac_workflow.mjs
node --experimental-strip-types web/worker/test_xyzac_manual_control.mjs
node --experimental-strip-types web/worker/test_xyzac_feed_override.mjs
node --experimental-strip-types web/worker/test_xyzac_trt_io_authority.mjs
node --experimental-strip-types web/worker/test_xyzac_3d_chips.mjs
bash -n run-5axis-rtcp.sh
```
本轮结果:WASM 构建通过,原生 CTest 22/22 通过,XYZAC 聚合按钮测试通过,3D_Chips 固定 tick 长程序测试通过。Jog Speed、Max Velocity、Spindle Override 已改为 WASM TP/IO 状态和命令;前端运行态不再使用 React 默认值。发布站点 UI 运行/暂停/恢复/停止也已在 Chromium 仿真环境执行;Safari 和真实物理断电不属于本项目范围。
本轮连续性修复后,`3D_Chips.ngc` 3000 tick 执行到第 337 行,`running_queue_gaps=0`;这证明长距离运行中的中间停顿已不再由 Worker 队列饥饿制造。
暂停/恢复修复:暂停期间若有一个 `SIM_STEP` 已在浏览器与 Worker 之间传输,WASM protocol 现在接受该帧为稳定无动作轮询,不会消耗错误序号;随后 `PROGRAM_RESUME` 正常恢复 source TP。
发布站点 r11 暂停/恢复验证:
```text
url: https://49.232.250.35:58010/
release: 20260902-linuxcnc-wasm-pause-resume-r11
resource_sha256: index-EXbw4yiL.js 6759738df285bc5e2f5c3fb84043dc09fb82292bbc1c3c1011a558c8654c96ab
sim-worker-entry-DjXIMZ0D.js 190515af943d70e93037e88a5cf63b3b8e9cda675a8338cfc1fb4bb954bfd685
linuxcnc-sim-core-D3Qw0e1g.wasm f1b1961279cf8ff7ef2e3fcd0068b3ba79de57abe1e56d5c32b16d17568b9536
before_pause: line=62, tick=140, queue_depth=1, velocity=28.2842712475
paused: line=62, tick=145, queue_depth=1, velocity=28.2842712475
paused_after_1.5s: tick=145 (stable)
resumed: line=62, tick=160, queue_depth=1, velocity=4.96408252063
after_resume: line=68, tick=360, queue_depth=2, velocity=32.8295260060
PROGRAM_RESUME: acknowledged; browser_errors: 0
screenshot: /tmp/published-pause-resume-final-r11c.png
screenshot_sha256: 9d1660fd043dd0628ff2989a3e139a3239acd6386d141657a5834c9d2f1bc5a7
```
发布站点 r13 实时参数验证:
```text
url: https://49.232.250.35:58010/
release: 20260902-linuxcnc-wasm-live-parameters-r13
parameter_source: linuxcnc-wasm
idle: Spindle 0.0 rpm / Feed actual 0.0 mm/min / TP velocity 0.000 mm/s / Planner 0 queued
running: Feed actual 540.0 mm/min / TP velocity 9.000 mm/s / Planner 1 queued / Segment 13 / Line 65
fields: spindle actual+command+program S, feed actual+program F, TP velocity+limit,
F/S override, queue depth, active segment, execution line
browser_errors: 0
screenshot: /tmp/published-live-parameters-r13.png
screenshot_sha256: 4e25750136d9b5a8ed633a15091128a94fc9bbec9af857c71d9bf5dd01270fb6
```
发布站点 r14(程序主轴同步 + 实时参数)验证:
```text
url: https://49.232.250.35:58010/
release: 20260902-linuxcnc-wasm-live-parameters-r14
resource_sha256: index-CDC5yZJC.js c3a6aa009e091d5fcb2098c7254313d987229abc1e4765052edb15b465ca0fc4
sim-worker-entry-BQKHHWpv.js e72d80d9ae0fd679d92d3efbad4dba1eef55f9ce7b54bcd06e4a0d644c3cfb1a
linuxcnc-sim-core-fuIvKetC.wasm ad4e17ecbf73afbad0d9f069ab20ba3c66b6cc4d75ecdb2b3182673490ee916d
3D_Chips.ngc running: spindle_actual=210 rpm, spindle_command=1600 rpm, program_S=1600 rpm,
feed_actual=1200 mm/min, program_F=2250000 mm/min,
tp_velocity=20 mm/s, queue_depth=22, active_segment=21, line=38
browser_errors: 0
screenshot: /tmp/published-live-parameters-r14.png
screenshot_sha256: 7f5307c913d8bc4e60c2a31c29aacc9afd1b0d91fac4a4f22e8a64fc2ea37a1e
```
发布站点 r15(程序预览原子替换)验证:
```text
url: https://49.232.250.35:58010/
release: 20260902-linuxcnc-wasm-program-replace-r15
initial preview: 29 segments
invalid PROGRAM_LOAD: preview 0 segments, error shown, old path not retained
valid PROGRAM_LOAD: preview 1 new segment
browser_errors: 0
screenshot: /tmp/published-program-replace-r15.png
screenshot_sha256: c3e0a5b992381e7b6cb26f98a30338935df5239c875755727fc678911452ac24
resource_sha256: index-DUB3ldSh.js 4d71a2eb0b162608d7a47b63274cf274a57b1c2f2620b69af139b12c2ba22cce
sim-worker-entry-yfjiq6MN.js a0cf75522ddc9c6712126de86937ec89f24574bf0e0dad3dbddc6d807fb352b7
linuxcnc-sim-core-fuIvKetC.wasm ad4e17ecbf73afbad0d9f069ab20ba3c66b6cc4d75ecdb2b3182673490ee916d
```
发布站点 r10 连续性验证:
```text
url: https://49.232.250.35:58010/
release: 20260902-linuxcnc-wasm-continuous-r10
resource_sha256: index-Byst0JhC.js 26d3f21f496c8223218761ba641dab8b4f36fd18892f260c7bf5b5cfa83cafec
sim-worker-entry-BTVfbu6g.js adf2ac5621ba388408f31ceab4bbcbfa6ba2923577d8eb69aa79ea54f3be0134
linuxcnc-sim-core-B2786u4k.wasm 3163f5ff63c5f3e1d2c07d1d948fce328bf3ad919eee188e432f7ba57468fc71
3D_Chips.ngc: loaded -> POWER -> HOME ALL -> RUNNING
sampled_running_frames: 33
queue_gaps: 0
first_running: current_line=62, queue_depth=3, velocity=20, active_id=16
last_running: current_line=69, queue_depth=2, velocity=16.6666666667, active_id=17
browser_errors: 0
screenshot: /tmp/published-r10-continuous.png
screenshot_sha256: c93fd23e648e49bfa9359af245372f03f3fccee123497909f3dcc005f5a59749
```
发布站点 r5 浏览器冒烟:
```text
url: https://49.232.250.35:58010/
result: verified
startup -> pause -> resume -> stop: verified
pause_tick: 140 (position held while PAUSED)
resume_tick: 160 -> continued running
stop: IDLE / queue cleared
JOG X/Y/Z/A/C, spindle CW/CCW/+/-/brake, coolant, tool/probe,
Feed Override, M428/M429/M430, VISUAL_CLEAR, Preview/DRO/MDI/Diagnostics
and view controls: clicked with no browser errors
output_sha256: bdf705473e6cda94d721aa23329257adf4a68b705add7650da5cc47012ab70b0
```
发布站点 r6(历史 WASM authority 版本)浏览器验收:
```text
url: https://49.232.250.35:58010/
release: 20260902-linuxcnc-wasm-authority-r6
resource_sha256: index-DEinWp01.js 79f5e933909fc631186db9b5091b6239f30c1ade612bb908a4ab9fcf79965343
sim-worker-entry-7q53Ew6x.js e5c239104d6676f242ea45cb3ddaf78a379aaaecaca5ff26031dee1ba9496e7c
linuxcnc-sim-core-CJilJ2YZ.wasm 13e2746899b0cac5cf91189c00a6174160202f8e632b53c5701e9664335c97cf
initial_dom: data-axis-authority=linuxcnc-wasm-worker, data-axis-state-source=linuxcnc-wasm,
data-axis-motion-authority=wasm, data-axis-task-authority=wasm_task_canonical
3D_Chips.ngc: loaded from published workspace, preview 100%, source TP running current line 22
browser_errors: 0
screenshots: /tmp/published-r6-authority.png (e58205228a04b386c7b7514bf03c71df7b53f66f2d9ebe2292931b36ef0edb55)
/tmp/published-r6-running.png (7fc474d0cb31a0fdd4afb198061e9812c753684e3d2963cc004ec4483c5c4990)
```
当前发布资源为 r10;r6 资源 hash 仅作为历史记录保留。
发布站点 r7(IDENTITY/TCP: XYZAC/USERK 切换版本)浏览器验收:
```text
url: https://49.232.250.35:58010/
release: 20260902-linuxcnc-wasm-switchkins-r7
startup: WASM authority ready, initial machine OFF
power -> HOME ALL -> IDENTITY -> TCP: XYZAC -> USERK -> IDENTITY -> TCP: XYZAC -> USERK: verified
active modes: 0 -> 1 -> 2 -> 0 -> 1 -> 2
browser_errors: 0
screenshot: /tmp/published-switchkins-r7.png
screenshot_sha256: 920b85ad7fd6451dfb134255ffdcc4f03a7aa615ebf486c63cde8582e17af195
```
## 证据哈希
```text
panel_button_test_output 9bddcd8b0219925e00598e081dc7a4ed0f4868e8822a21f0ccd08d8e9d355d45
button_constraints_output 5b6f4ce1dec03764dcb234793ff96fc2f04d15ab954620a44dbb1210ec64a5a5
feed_authority_output deab4a51ee0e56d4f8134efba4b7a97a2b88f37d9165cf730207f71886df8526
3d_chips_test_output c97caef2ea5cf3841e1238ec443d0eebadad8cb0048af829111c06e99c9fcdd7
3d_chips_no_gap_output c97b5fbb43a6e81a8ee15272bf71aa75ec0ba79be28a34f30b4221d50251c77d
wasm_io_source 1cb066d185dd2c5bbf435e022c2518483bd44962e5a0303248757b2da51740f7
wasm_io_c_source 09bce1430d6f71702ca0b3bf29ac50db377a6f232ce0d1a9b2c1eaac7ea2162e
panel_button_test_source 80782fc1f85f88beb48ec3dfaf638a93f2edb912e694840199dbff504477fe74
switchkins_direct_test_output 24e6cb8ec1195a97f71294b49217db0cbc0d7c3ecfa4bc8aa244ba3921c816a7
panel_r10_output 9bddcd8b0219925e00598e081dc7a4ed0f4868e8822a21f0ccd08d8e9d355d45
pause_resume_browser_screenshot 9d1660fd043dd0628ff2989a3e139a3239acd6386d141657a5834c9d2f1bc5a7
live_parameters_browser_screenshot 7f5307c913d8bc4e60c2a31c29aacc9afd1b0d91fac4a4f22e8a64fc2ea37a1e
program_replace_browser_screenshot c3e0a5b992381e7b6cb26f98a30338935df5239c875755727fc678911452ac24
```
报告对应提交前工作树保留了既有 coverage 大文件和 LinuxCNC 子模块改动;本轮提交包含 WASM TP/IO/HOME authority、无 JS JOG 运动计算、前端 pending 投影、长程序快照性能修正、聚合测试和本报告。