按“建议下一步不要继续扩大测试面，先把“已发现但边界清楚的问题”收敛掉。推荐按这个顺序推进：”，推进项目执行
# OPFS helper 需要兼容 Node 和 browser：Node 可以读目录，但 browser 不能列目录，所以我会用已有 tools/source-manifest.txt 作为文件索引。helper 只根据 INI 和 manifest 生成 {sourceRel, wasmPath, executable} 计划，实际 fetch/read 仍由测试层完成。


数控系统仿真软件，从 LinuxCNC 移植过来。主要程序功能必须直接来源于 LinuxCNC 源程序，不自己重写 G-code 语义。这是一条铁的纪律。

下一步工作重点是继续对标 LinuxCNC 功能，使用 LinuxCNC 自身测试程序验证本项目。

测试范围：
- linuxcnc/nc_files：先作为基础 G-code 程序测试来源。
- linuxcnc/configs/sim：作为带机床配置、工具表、宏、remap、USER_M_PATH 的系统级测试来源。
- 需要机床/工具表上下文的程序，必须通过对应 INI、tool table、parameter file、SUBROUTINE_PATH、USER_M_PATH 运行，不能脱离配置单独判断。

测试口径：
- configs/sim 下带 M2/M30/% 的完整程序做严格执行。
- 不带程序结束的宏/子程序追加临时 M2 做装载/语法检查。
- remap 子程序只做装载检查，因为它们通常由 INI 的 REMAP 入口调用。
- 按 INI 所在目录执行，保证相对 SUBROUTINE_PATH、REMAP、USER_M_PATH 与真实 LinuxCNC sim 配置一致。
- 功能语义只来自 LinuxCNC 源码；本项目只允许写构建、适配、文件系统、WASM/浏览器边界和测试胶水。

G-code 执行时，后续 UI/调试输出应显示运行进度、当前行号、当前执行语句、各轴当前位置，让程序是否在运行可以直观看到。

建议下一步不要继续扩大测试面，先把“已发现但边界清楚的问题”收敛掉。推荐按这个顺序推进：

1. 做运行状态输出

优先级最高，因为这是后续调试和 UI 验证的基础。

目标：

执行 G-code 时输出当前行号
输出当前执行语句
输出运行进度
输出各轴当前位置
后续 UI 能直观看到程序正在运行
原则：

轴位置、状态、canonical event 尽量从 LinuxCNC interpreter/canonical 状态读取
不自己推导 G-code 运动语义
先在 linuxcnc/nc_files 基础程序上验证，再放到 configs/sim 代表程序上验证
2. 固化基础 G-code 测试集

从 linuxcnc/nc_files 中选一组稳定基础程序，作为日常 smoke：

简单直线、圆弧、单位切换
O-word / subroutine
canned cycle
tool change / tool table 相关程序
已知需要上下文的程序单独分类为 expected failure 或 sim-config 测试
目标是形成一个“快速基础回归”，不要每次都只跑大而全的 sim-config。

3. 收敛 configs/sim 剩余 expected failure

当前完整基线是：

total: 159
pass: 151
expected_fail: 8
unexpected_fail: 0
下一步重点看这 8 个里哪些能继续收敛：

axis/foam/foam.ngc：确认 U/V 轴配置在 standalone/WASM runtime 已覆盖
bridgemill/5axisgui.ngc：确认 W 轴配置路径
axis/geometry/xyzc.ngc：确认 M110 USER_M_PATH 边界
axis/external_offsets/*.ngc：确认 M111 USER_M_PATH 边界
incremental_repetition_g533.ngc：保留 upstream demo expected failure，不私自改语义
注意：native bin/rs274 baseline 里的 expected failure 不一定要强行变成 pass，关键是 standalone/WASM runtime 要有对应验证。

4. 完善文件上下文 staging 规则

你已经明确了“不能脱离 INI/tool table/parameter/SUBROUTINE_PATH/USER_M_PATH 判断”。下一步应把这个规则制度化：

从 INI 自动收集 TOOL_TABLE
自动收集 PARAMETER_FILE
自动收集 SUBROUTINE_PATH
自动收集 USER_M_PATH
WASM/browser staging 必须把这些文件放到与 INI 一致的相对路径
刚刚修掉的 axis/foam/sim.tbl 就是这个方向的典型问题。

5. 文档化测试分层

建议把测试分成四层：

Layer 1: linuxcnc/nc_files 基础 G-code smoke
Layer 2: configs/sim native strict harness
Layer 3: standalone native runtime probes
Layer 4: WASM Node/browser representative smoke
每层记录：

测试入口命令
当前通过数
expected failure
不允许修改 LinuxCNC 语义的边界
哪些只是 host/WASM 文件系统适配
推荐立即做的具体任务

下一步最值得做的是：

实现/完善 G-code 执行状态输出：
当前行号 + 当前语句 + 进度 + 轴位置
验证顺序：

1. linuxcnc/nc_files/3D_Chips.ngc
2. linuxcnc/nc_files 中几个基础程序
3. configs/sim 中 axis/foam、axis/geometry、external_offsets 代表程序
4. Node WASM smoke
5. browser smoke
这样做收益最大：后面无论继续修解释器边界、做 UI、还是跑更复杂的 sim 配置，都能直接看到程序是否真实推进。

规划 i 执行记录：G-code 运行状态输出

本轮已推进“实现/完善 G-code 执行状态输出”的第一阶段。

目标：

- 当前行号
- 当前执行语句
- 运行进度
- 各轴当前位置

实现内容：

1. 在 WASM interpreter file execution 路径中新增 run_step 状态输出。

run_step 数据来源：

- line 来自 LinuxCNC interpreter 的 _setup.sequence_number。
- statement_uri 来自 LinuxCNC interpreter 的 _setup.linetext，使用 percent encoding。
- x/y/z 来自 _setup.current_x/current_y/current_z。
- a/b/c 来自 _setup.AA_current/BB_current/CC_current。
- u/v/w 来自 _setup.u_current/v_current/w_current。
- rc 来自 LinuxCNC Interp::read() / Interp::execute()。

示例：

run_step phase=read step=1 rc=0 line=1 x=0 y=0 z=0 a=0 b=0 c=0 u=0 v=0 w=0 statement_uri=G0%20X1.0%20Y2.0%20%28Comment%29
run_step phase=execute step=2 rc=0 line=2 x=3 y=4 z=0 a=0 b=0 c=0 u=0 v=0 w=0 statement_uri=G1%20X3.0%20Y4.0%20F120.0

说明：

statement 使用 statement_uri 编码，不直接输出裸文本。原因是部分 upstream LinuxCNC 回归测试源码中包含未执行的 “fail:” 文本；裸输出会污染既有 absent=fail: 断言。UI 侧 decodeURIComponent 后显示原始语句。

2. native minimal harness 同步输出 run_step。

native 和 WASM file execution 现在可以使用同一类状态格式，后续可在 native probes 中继续扩展断言。

3. INI panel UI 优先解析 run_step。

UI 现在优先从 run_step phase=execute 读取：

- line
- statement_uri
- X/Y/Z/A/B/C/U/V/W

如果没有 run_step，则保留原来的 canonical motion event fallback。运动类型仍从 LinuxCNC canonical event 识别，不自己推导 G-code 语义。

4. 新增 Node/browser 状态输出断言。

minimal_linear.ngc 文件执行现在验证：

- run_step phase=read
- run_step phase=execute
- line=1 / line=2
- statement_uri 编码语句
- x=1 y=2 z=0
- x=3 y=4 z=0

修改文件：

- wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_wasm.cpp
- wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_interp_minimal_harness.cpp
- wasm-port/runtime/ui/ini-panel/app.js
- wasm-port/tests/wasm/node/verify_interp_wasm.mjs
- wasm-port/tests/browser/interp_smoke.html
- wasm-port/docs/compatibility-validation.md

验证命令：

wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/browser/verify_ini_panel_browser.sh
wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
wasm-port/tests/native/verify_native_probes.sh

验证结果：

interp_wasm_node_smoke=ok
browser_interp_smoke=ok
browser_ini_opfs_smoke=ok
sim_configs_wasm_node_smoke=ok
native probe validation complete

native 汇总仍保持：

sim-configs: total 159, pass 151, fail 8, expected_fail 8, unexpected_fail 0
nc_files basic: total 107, pass 101, fail 6, expected_fail 6, unexpected_fail 0

结论：

规划 i 的核心目标已完成第一阶段。G-code file execution 现在有可机器解析的 run_step 状态输出，UI 可以显示当前行号、当前语句、进度和轴位置。后续可以继续把同样的状态输出推广到 fiveaxis/remap 专用执行路径，以及更复杂的 configs/sim 程序运行视图。


规划 ii 执行记录：固化基础 G-code 测试集

本轮按“不要继续扩大测试面，先收敛已发现边界清楚的问题”的顺序，推进第二项“固化基础 G-code 测试集”。

目标：

- 继续使用 LinuxCNC 自身 `linuxcnc/nc_files` 作为基础 G-code 程序来源。
- 先固定日常 smoke 的代表程序，不扩大到新的大范围测试面。
- 对需要上下文的程序，必须通过 INI/tool table 等上下文运行，不能脱离配置单独判断。
- 保持 G-code 语义来自 LinuxCNC interpreter；本项目只做 vendor、staging、WASM/browser 测试胶水和文档。

实现内容：

1. 将 upstream `linuxcnc/nc_files/3D_Chips.ngc` 加入 WASM vendor 代表集。

该文件已复制到：

- `wasm-port/vendor/linuxcnc/nc_files/3D_Chips.ngc`

并加入：

- `wasm-port/tools/source-manifest.txt`

`verify_vendor_sync.sh` 会继续校验该文件与 upstream LinuxCNC 原文件逐字一致。

2. 明确 `3D_Chips.ngc` 的上下文边界。

裸 `runFile()` 执行会在 upstream `T1 M6` 处失败：

- `file_error_text=Requested tool 1 not found in the tool table`

因此该文件不能作为脱离上下文的裸文件判断。Node/browser smoke 现在通过最小 INI + `tool.tbl` staging 执行：

- `[EMCIO] TOOL_TABLE = tool.tbl`
- `T1 P1 D10.000000 Z+0.000000`
- `[TRAJ] COORDINATES = X Y Z A B C U V W`

这符合“需要工具表上下文的程序必须带上下文运行”的规则。

3. 扩展 Node WASM `nc_files` smoke。

修改文件：

- `wasm-port/tests/wasm/node/verify_nc_files_wasm.mjs`

新增 `3D_Chips.ngc` 代表程序断言：

- `file_open=0`
- `file_read_count=4706`
- `file_execute_count=4706`
- `file_saw_error=0`
- `run_step phase=execute step=18 rc=2 line=18`
- `statement_uri=N50T%23%3Ctoolno%3EM6`
- `canon_event=CHANGE_TOOL`
- `canon_event=START_SPINDLE_CLOCKWISE`
- `canon_event=STRAIGHT_TRAVERSE`
- `canon_event=STRAIGHT_FEED`
- `canon_event=PROGRAM_END`
- `absent=Requested tool 1 not found`

4. 扩展 browser interpreter `nc_files` smoke。

修改文件：

- `wasm-port/tests/browser/interp_smoke.html`

browser 侧使用同样的 INI/tool table staging，通过 `runFileWithIni()` 执行 `3D_Chips.ngc`，断言与 Node WASM 路径保持一致。

5. 更新文档中的测试分层和 source reuse 记录。

修改文件：

- `wasm-port/docs/source-reuse-map.md`
- `wasm-port/docs/compatibility-validation.md`
- `wasm-port/docs/linuxcnc-test-porting-tracker.md`

文档现在明确：

- representative `nc_files` WASM/browser 子集包含 `3D_Chips.ngc`、`arcspiral.ngc`、`hole-circle.ngc`、`factorial.ngc`、`m6demo.ngc`。
- `3D_Chips.ngc` 必须通过 INI-declared tool table 上下文运行。
- JS/browser 只负责文件 staging 和调用 LinuxCNC-backed `Interp::open()` / `read()` / `execute()`，不实现 G-code、换刀或 M-code 语义。

验证命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_nc_files_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/native/verify_nc_files.sh --only 3D_Chips.ngc
```

验证结果：

```text
vendor sync validation complete
nc_files_wasm_node_smoke=ok
browser_interp_smoke=ok
nc_files harness summary
suite: basic
total: 1
pass: 1
fail: 0
timeout: 0
expected_fail: 0
unexpected_fail: 0
```

结论：

规划 ii 已完成一个收敛点：`3D_Chips.ngc` 已从“建议验证顺序中的首个基础程序”固化为 native/WASM/browser 都可验证的代表程序。它的工具表依赖也已制度化为 INI/tool table staging，而不是误判为解释器问题或裸文件 expected failure。下一步可继续按同一口径收敛 configs/sim 剩余 expected failure 或进一步完善文件上下文 staging 自动收集规则。


规划 iii 执行记录：收敛 configs/sim 剩余 expected failure

本轮按第三项“收敛 configs/sim 剩余 expected failure”推进，原则仍是：

- native `bin/rs274` baseline 的 expected failure 不强行改成 pass。
- standalone/WASM/browser runtime 必须有对应代表验证。
- 需要 INI/tool table/parameter/SUBROUTINE_PATH/USER_M_PATH 的程序必须按对应配置 staging，不能脱离配置单独判断。
- 不修改 LinuxCNC G-code 语义。

当前 native 完整基线仍保持：

```text
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0
```

本轮发现并修正一个明确上下文问题：

`wasm-port/tests/native/verify_sim_configs.sh` 原先在同目录多 INI 的情况下只取排序后的第一个 nearest INI。这样会导致：

- `axis/external_offsets/eoffsets.ngc`
- `axis/external_offsets/jwp_z.ngc`
- `axis/external_offsets/opa_demo.ngc`

被错误配到 `dynamic_offsets.ini`。

修正后规则：

- 同目录存在多个 INI 时，优先按 `[DISPLAY]OPEN_FILE` 指向当前 `.ngc` 的 INI 匹配。
- 找不到 OPEN_FILE 匹配时，再回退原来的 nearest INI 规则。

修正后的 native expected failure 8 行中，external_offsets 已按对应 INI 记录：

```text
axis/external_offsets/dyn_demo.ngc      dynamic_offsets.ini
axis/external_offsets/eoffsets.ngc      eoffsets.ini
axis/external_offsets/jwp_z.ngc         jwp_z.ini
axis/external_offsets/opa_demo.ngc      opa.ini
```

这些仍在 native `bin/rs274` baseline 中 expected fail，原因仍是 `M111` 属于 sim/task USER_M_PATH 边界，standalone rs274 入口不会执行真实 task/user-M 进程。

WASM/browser 代表覆盖已补齐 external_offsets 4 个 M111 程序：

- `dyn_demo.ngc` + `dynamic_offsets.ini`
- `eoffsets.ngc` + `eoffsets.ini`
- `jwp_z.ngc` + `jwp_z.ini`
- `opa_demo.ngc` + `opa.ini`

新增 vendored upstream 文件：

- `configs/sim/axis/external_offsets/eoffsets.ngc`
- `configs/sim/axis/external_offsets/eoffsets.ini`
- `configs/sim/axis/external_offsets/jwp_z.ngc`
- `configs/sim/axis/external_offsets/jwp_z.ini`
- `configs/sim/axis/external_offsets/opa_demo.ngc`
- `configs/sim/axis/external_offsets/opa.ini`
- `configs/sim/axis/external_offsets/circles.ngc`

这些文件已加入：

- `wasm-port/tools/source-manifest.txt`

WASM/browser smoke 现在验证：

- `USER_M_PATH` 注册真实 executable `M111`。
- `M111` 不再报 `Unknown m code used: M111`。
- `opa_demo.ngc` 通过 `SUBROUTINE_PATH = .` 找到并执行 `circles.ngc`。
- 运动和程序结束仍来自 LinuxCNC-backed `Interp::open()` / `read()` / `execute()` 输出。

修改文件：

- `wasm-port/tests/native/verify_sim_configs.sh`
- `wasm-port/tests/wasm/node/verify_sim_configs_wasm.mjs`
- `wasm-port/tests/browser/interp_smoke.html`
- `wasm-port/tools/source-manifest.txt`
- `wasm-port/docs/source-reuse-map.md`
- `wasm-port/docs/compatibility-validation.md`
- `wasm-port/docs/linuxcnc-test-porting-tracker.md`
- `wasm-port/docs/sim-configs-completion-plan.md`

验证命令：

```bash
wasm-port/tests/native/verify_sim_configs.sh --only axis/external_offsets
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/native/verify_sim_configs.sh
```

验证结果：

```text
native external_offsets targeted:
total: 6
pass: 2
fail: 4
expected_fail: 4
unexpected_fail: 0

sim_configs_wasm_node_smoke=ok
vendor sync validation complete
browser_interp_smoke=ok

native full sim-config baseline:
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0
```

结论：

规划 iii 已完成一个明确收敛点：`configs/sim/axis/external_offsets` 的 4 个 M111 expected failure 已按真实对应 INI 区分，并全部有 Node WASM/browser 代表验证。native `bin/rs274` 的 8 个 expected failure 仍保留为入口/运行时边界，不改 LinuxCNC 语义。剩余未进一步收敛的主要是 upstream demo `incremental_repetition_g533.ngc`，按当前规则应继续保留 expected failure，不私自改语义。下一步可进入第 4 项：把 INI 自动收集 TOOL_TABLE、PARAMETER_FILE、SUBROUTINE_PATH、USER_M_PATH 的 staging 规则继续制度化。


规划 iv 执行记录：完善文件上下文 staging 规则

本轮按第四项“完善文件上下文 staging 规则”推进，目标是把前几轮已经确认的规则制度化：

- 从 INI 自动收集 `TOOL_TABLE`
- 从 INI 自动收集 `PARAMETER_FILE`
- 从 INI 自动收集 `SUBROUTINE_PATH`
- 从 INI 自动收集 `USER_M_PATH`
- WASM/browser staging 必须把这些文件放到与 INI 一致的相对路径
- JS/host 只能做文件 staging 和 C ABI 调用，不能实现 G-code、tool、parameter、remap、user-M 语义

实现内容：

1. 新增 SDK staging planner。

新增文件：

- `wasm-port/runtime/sdk/src/sim-config-staging.js`

导出：

- `planSimConfigStaging()`

该 helper 输入：

- vendored `tools/source-manifest.txt` 文本
- `machineRel`
- `iniFile`
- `iniText`
- 可选 `programFile`
- 可选 `wasmDir`

该 helper 输出：

- `iniPath`
- `programPath`
- `files[]`

`files[]` 中每项包含：

- `sourceRel`
- WASM 目标 `path`
- `executable`

自动收集规则：

- `[DISPLAY] OPEN_FILE`
- `[EMCIO] TOOL_TABLE`
- `[RS274NGC] PARAMETER_FILE`
- `[RS274NGC] SUBROUTINE_PATH`
- `[RS274NGC] USER_M_PATH`
- `[RS274NGC] REMAP` 中的 `ngc=...`

说明：

- helper 只解析 INI 文本和 source manifest。
- helper 只生成 staging plan。
- helper 不解释 G-code，不实现 tool/parameter/remap/user-M 语义。
- 相对路径按 INI 所在目录解析；缺失于 manifest 的可选文件不强制 staging。

2. SDK 统一导出 staging helper。

修改文件：

- `wasm-port/runtime/sdk/src/index.js`

现在可以从 SDK 入口导入：

```js
import { planSimConfigStaging } from "../../../runtime/sdk/src/index.js";
```

3. Node WASM sim-config smoke 改用自动 staging。

修改文件：

- `wasm-port/tests/wasm/node/verify_sim_configs_wasm.mjs`

原先手工列文件：

- `sim.tbl`
- `5axis.tbl`
- `remap_subs/*.ngc`
- `M110`
- `M111`
- `eoffset.tbl`
- `circles.ngc`

现在改为：

- 读取对应 INI 文本
- 读取 `tools/source-manifest.txt`
- 调用 `planSimConfigStaging()`
- 按 planner 输出复制 vendored 文件到 Emscripten filesystem
- 再调用 LinuxCNC-backed `runSimConfigProgram()`

新增 synthetic staging-plan 断言，明确验证以下 INI 字段会被收集：

- `TOOL_TABLE`
- `PARAMETER_FILE`
- `SUBROUTINE_PATH`
- `USER_M_PATH`

4. Browser interpreter smoke 改用同一 staging helper。

修改文件：

- `wasm-port/tests/browser/interp_smoke.html`

browser 侧现在同样：

- fetch INI
- fetch `tools/source-manifest.txt`
- 调用 `planSimConfigStaging()`
- fetch planner 给出的 vendored source files
- 写入 WASM filesystem
- 调用 LinuxCNC-backed execution path

这使 Node/browser 的 sim-config staging 规则一致。

5. 文档更新。

修改文件：

- `wasm-port/runtime/sdk/README.md`
- `wasm-port/docs/drift-report.md`
- `wasm-port/docs/compatibility-validation.md`

文档现在明确：

- `planSimConfigStaging()` 是 host-boundary file planner。
- `runSimConfigProgram()` 是 execution convenience。
- 二者都不实现 LinuxCNC 语义。
- 当前 smoke 已验证 INI/tool table/parameter/subroutine/user-M/remap-NGC staging。

验证命令：

```bash
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tools/verify_vendor_sync.sh
```

验证结果：

```text
sim_configs_wasm_node_smoke=ok
browser_interp_smoke=ok
vendor sync up to date
```

结论：

规划 iv 已完成第一阶段：sim-config WASM/browser 文件上下文 staging 不再依赖各测试手工列出工具表、user-M、子程序和 remap 文件，而是由 INI + source manifest 自动生成 staging plan。下一步可进入第 5 项：文档化测试分层，整理四层测试入口、当前通过数、expected failure 和“不允许改 LinuxCNC 语义”的边界。


规划 v 执行记录：文档化测试分层

本轮按第五项“文档化测试分层”推进，目标是把当前测试体系整理成四层，并记录：

- 测试入口命令
- 当前通过数
- expected failure
- 不允许修改 LinuxCNC 语义的边界
- 哪些只是 host/WASM 文件系统适配

执行内容：

1. 刷新 Layer 1 / Layer 2 当前基线。

执行：

```bash
wasm-port/tests/native/verify_nc_files.sh
```

结果：

```text
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0
```

Layer 2 使用上轮完整 sim-config baseline：

```text
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0
```

2. 在 compatibility validation 文档中新增四层测试分层。

修改文件：

- `wasm-port/docs/compatibility-validation.md`

新增章节：

- `Validation Layers`

分层如下：

Layer 1: `linuxcnc/nc_files` 基础 G-code smoke

- 入口：`wasm-port/tests/native/verify_nc_files.sh`
- 当前：`total 107 / pass 101 / expected_fail 6 / unexpected_fail 0`
- 边界：W 轴机床上下文、lathe tool/cutter-comp 上下文、upstream O-word syntax edge、probe runtime context。

Layer 2: `linuxcnc/configs/sim` native strict harness

- 入口：`wasm-port/tests/native/verify_sim_configs.sh`
- 当前：`total 159 / pass 151 / expected_fail 8 / unexpected_fail 0`
- 边界：native `bin/rs274` 不提供 task/user-M 进程执行，也不覆盖部分 INI axis-mask/runtime context；`incremental_repetition_g533.ngc` 保留 upstream demo expected failure，不私自改语义。

Layer 3: standalone native runtime probes

- 入口：`wasm-port/tests/native/verify_native_probes.sh`
- 当前：通过时输出 `native probes complete`
- 边界：runtime adapters 可以覆盖 filesystem、HAL/user-M、remap、parameter、tool、kinematics、TP、WASM/browser boundary，但 CNC 语义仍必须来自 vendored LinuxCNC source。

Layer 4: WASM Node/browser representative smoke

- 聚合入口：`wasm-port/tests/host/verify_host_smokes.sh`
- 目标入口：
  - `wasm-port/tests/wasm/node/verify_ini_wasm.sh`
  - `wasm-port/tests/wasm/node/verify_interp_wasm.sh`
  - `wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh`
  - `wasm-port/tests/wasm/node/verify_nc_files_wasm.sh`
  - `wasm-port/tests/wasm/node/verify_tp_wasm.sh`
  - `wasm-port/tests/opfs/node/verify_file_service.sh`
  - `wasm-port/tests/browser/verify_ini_panel_browser.sh`
  - `wasm-port/tests/browser/verify_interp_browser.sh`
  - `wasm-port/tests/host/verify_host_smokes.sh`
- 当前已知通过标记：
  - `sim_configs_wasm_node_smoke=ok`
  - `nc_files_wasm_node_smoke=ok`
  - `browser_interp_smoke=ok`
  - `browser_ini_opfs_smoke=ok`
  - `host_wasm_opfs_browser_smokes=ok`
- 边界：JS/browser 只能 staging 文件、设置 executable bit、做 OPFS 文本持久化、转发 C ABI 路径；不能实现 G-code、remap、tool-table、parameter、planner、kinematics、user-M 语义。

3. 明确 Layer 4 sim-config staging 规则。

文档现在明确：

- `planSimConfigStaging()` 从 vendored source manifest + INI 收集：
  - `[DISPLAY]OPEN_FILE`
  - `[EMCIO]TOOL_TABLE`
  - `[RS274NGC]PARAMETER_FILE`
  - `[RS274NGC]SUBROUTINE_PATH`
  - `[RS274NGC]USER_M_PATH`
  - remap-NGC files
- planner 是 host filesystem helper。
- 执行仍进入 vendored LinuxCNC interpreter/remap/tool/parameter code。

4. 更新 porting tracker。

修改文件：

- `wasm-port/docs/linuxcnc-test-porting-tracker.md`

新增状态项：

- `Document validation layers | Done`

说明 `compatibility-validation.md` 已记录 Layer 1 到 Layer 4 的入口命令、当前结果、expected boundary 和 no-LinuxCNC-semantics rule。

验证命令：

```bash
wasm-port/tests/native/verify_nc_files.sh
cat wasm-port/build/native/nc-files/summary.txt
cat wasm-port/build/native/sim-configs/summary.txt
```

验证结果：

```text
nc_files basic:
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

sim-configs:
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0
```

结论：

规划 v 已完成：当前测试体系已经按 Layer 1 到 Layer 4 文档化，包含入口命令、当前基线、expected failure 和 LinuxCNC 语义边界。下一步建议不再扩文档，而是回到执行层：根据 Layer 4 聚合入口跑一次完整 `wasm-port/tests/host/verify_host_smokes.sh`，确认前面新增的 run_step、nc_files、sim-config staging 和 browser smoke 在共享构建路径下仍能整体通过。


规划 vi 执行记录：Layer 4 聚合 host smoke 验证

本轮按规划 v 的结论执行 Layer 4 聚合入口，目标是确认前面新增的内容在共享构建路径下整体通过：

- `run_step` 状态输出
- `nc_files` representative smoke，包括 `3D_Chips.ngc`
- sim-config 自动 staging，包括 `planSimConfigStaging()`
- Node WASM smokes
- OPFS host-boundary smoke
- browser INI/OPFS smoke
- browser interpreter smoke

执行命令：

```bash
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出：

```text
ini_wasm_node_smoke=ok
interp_wasm_node_smoke=ok
sim_configs_wasm_node_smoke=ok
nc_files_wasm_node_smoke=ok
tp_wasm_node_smoke=ok
opfs_file_service_node_smoke=ok
browser_ini_opfs_smoke=ok
browser_interp_smoke=ok
host_wasm_opfs_browser_smokes=ok
```

执行中出现的非致命输出：

```text
link (updating variable file): No such file or directory
warning: code 'G88.1' : no modalgroup=<int> given, using default group 1 : 8:REMAP = G88.1 ngc=rg881
warning: code 'M410' : no modalgroup=<int> given, using default group 10 : 16:REMAP = M410  ngc=rm410
sp_scurve_init: planner created with cycle_time=0.001000 (logging disabled)
```

这些来自 LinuxCNC-backed runtime 路径和既有 smoke 输出，命令退出码为 0，不影响聚合验证结论。

结论：

Layer 4 聚合验证已通过。前面新增的 G-code 运行状态输出、`nc_files` 代表集、configs/sim expected failure 收敛、INI-driven staging helper、Node/browser smoke 和 OPFS 路径在共享构建下整体闭环。下一步建议进入一次收尾整理：检查当前工作区新增文件和文档记录，确认是否需要提交前再跑完整 native `verify_native_probes.sh` 或只保留当前分层验证结果。


规划 vii 执行记录：完整 native 总验证

本轮按规划 vi 的建议执行完整 native 总验证，目标是确认前面改动在 native 侧总验证链路下仍然闭环：

- upstream baseline
- vendor sync
- standalone CNC semantics guard
- native LinuxCNC fixture baseline
- native probes build/cache
- configs/sim native strict harness
- nc_files basic harness
- native probe stdout/exit-code assertions

执行命令：

```bash
wasm-port/tests/native/verify_native_probes.sh
```

验证输出摘要：

```text
upstream baseline validation complete
vendor sync up to date
standalone CNC semantics guard complete
native LinuxCNC fixture baseline up to date
native probes up to date

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete
```

结论：

完整 native 总验证已通过。当前 native 层和 Layer 4 host/WASM/browser 聚合层都已闭环：native 保持 `sim-configs 159/151/8 expected/0 unexpected` 与 `nc_files 107/101/6 expected/0 unexpected`，Layer 4 保持 `host_wasm_opfs_browser_smokes=ok`。下一步建议进入提交前整理：审查当前工作区变更清单，确认新增 vendored LinuxCNC 文件、SDK staging helper、测试、文档和 `text.txt` 记录是否都应纳入同一次提交；如需要，可以再运行一次 `git diff --check` 或按模块分批提交。

---

2026-06-09 07:27 CST 清理记录：

`test-results/` 为浏览器/Playwright 测试生成目录，当前未被 git 跟踪，大小约 `1004M`。已在确认 `git status --short` 不再列出该目录后，将其作为临时测试产物清理，以释放工作区磁盘空间；其他源码、文档和 vendored 文件改动保持不变。

---

2026-06-09 07:30 CST 提交前整理记录：

已按提交前建议完成当前变更面复查与聚合验证。

执行命令：

```bash
git diff --check
wasm-port/tests/host/verify_host_smokes.sh
wasm-port/tests/native/verify_native_probes.sh
```

验证输出摘要：

```text
git diff --check: clean for tracked project-owned changes before staging

ini_wasm_node_smoke=ok
interp_wasm_node_smoke=ok
sim_configs_wasm_node_smoke=ok
nc_files_wasm_node_smoke=ok
tp_wasm_node_smoke=ok
opfs_file_service_node_smoke=ok
browser_ini_opfs_smoke=ok
browser_interp_smoke=ok
host_wasm_opfs_browser_smokes=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation up to date
```

结论：

当前变更可作为一个提交单元：新增 `planSimConfigStaging()` 文件规划 helper，扩大 WASM/browser sim-config 与 `nc_files/3D_Chips.ngc` 覆盖，增加 `run_step` 执行状态观测，更新 native sim-config INI 选择逻辑，并同步文档与 vendored manifest。`text.txt` 仍为 ignored 本地记录，不纳入提交。

暂存后补充：

`git diff --cached --check` 对两个新增 vendored LinuxCNC 原始资产报出上游 whitespace：

- `wasm-port/vendor/linuxcnc/configs/sim/axis/external_offsets/opa.ini:86`
- `wasm-port/vendor/linuxcnc/nc_files/3D_Chips.ngc:4707`

已用 `cmp` 确认它们分别与 ignored 上游源文件 `linuxcnc/configs/sim/axis/external_offsets/opa.ini` 和 `linuxcnc/nc_files/3D_Chips.ngc` 字节一致，因此保持 vendored 原样，不为通过 whitespace check 修改上游资产。

---

2026-06-09 07:40 CST 继续推进记录：

按 tracker 的下一步，选择新的纯解释器 upstream fixture `linuxcnc/tests/interp/g33.1` 作为小批次推进。该用例只依赖 `rs274 -g g33.1.ngc` 文件执行路径，不涉及 Python、HAL、UI 或 full LinuxCNC task 进程。

本批变更：

- 将 `tests/interp/g33.1/{expected,g33.1.ngc,test.sh}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/g33.1/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- 在 Node WASM 与 browser interpreter smoke 中加入 `G33.1` 刚性攻丝断言，覆盖 spindle start、speed/feed sync、`RIGID_TAP`、`PROGRAM_END` 和 `run_step` source statement。
- 更新 compatibility validation、source reuse map 和 porting tracker。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
```

结论：

`tests/interp/g33.1` 已完成 native、WASM Node、browser 三层闭环，且 vendor byte sync 与 host 聚合验证均通过。本批可单独提交。

---

2026-06-09 07:48 CST 继续推进记录：

按 tracker 的纯解释器用例方向，评估下一批 upstream `linuxcnc/tests/interp/*` 候选。`inverse-time-with-comp` 在当前 standalone 文件执行路径触发 `I word missing in absolute center arc`，暂不作为小批次推进对象，后续可单独分析。选择 `linuxcnc/tests/interp/flowsnake` 作为本批目标：它是纯文件执行用例，覆盖递归 O-word subroutine、表达式计算、注释实参和长 toolpath canonical 输出，不依赖 Python、HAL、UI 或 full LinuxCNC task 进程。

本批变更：

- 将 `tests/interp/flowsnake/{README,expected,flowsnake.ngc,test.sh}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/flowsnake/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- 在 Node WASM 与 browser interpreter smoke 中加入窄断言，验证 `flowsnake` 完整执行到 `file_read_count=6414`、`file_saw_error=0`，并覆盖关键 comment、spindle、recursive feed endpoints 和最终 setup position。
- 更新 compatibility validation、source reuse map 和 porting tracker。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
```

结论：

`tests/interp/flowsnake` 已完成 native、WASM Node、browser 三层闭环，vendor byte sync 与 host 聚合验证均通过。本批可单独提交。

---

2026-06-09 08:00 CST 继续推进记录：

继续评估纯解释器 upstream `linuxcnc/tests/interp/*` 候选。`inside-corners`、`crazy-paths` 和 `tests/interp/good/*` 在当前 standalone file runner 下触发 arc center/radius 相关错误，暂不作为小批次直接推进对象，后续可单独做差异分析。选择 `linuxcnc/tests/interp/bad` 的 4 个小型负向 file-execution fixture 作为本批目标：

- `nested.ngc`
- `no-feed-rate.ngc`
- `no-ijr.ngc`
- `probe-no-axes.ngc`

本批变更：

- 将上述 4 个 upstream `.ngc` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/bad/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- 在 Node WASM 与 browser interpreter smoke 中加入错误文本、读/执行计数和 `ON_RESET` 断言。
- 更新 compatibility validation、source reuse map 和 porting tracker。

调试记录：

初次把 4 个 bad fixture 都按 native `--continue-on-error` 跑时，`probe-no-axes.ngc` 在 `read()` 阶段错误后持续读到 EOF 错误，最终 60 秒超时并产生约 1.4G native stdout 日志。已修正 native probe build：这批 selected bad fixture 使用普通 file-error 路径，在首个错误处停止。已删除超时产生的大日志，`wasm-port/build/native` 回到约 `97M`。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
```

结论：

selected `tests/interp/bad` file-error fixture 已完成 native、WASM Node、browser 三层闭环，vendor byte sync 与 host 聚合验证均通过。本批可单独提交。

---

2026-06-09 08:08 CST 继续推进记录：

继续扩展 upstream `linuxcnc/tests/interp/bad` 的小型负向 file-execution fixture。本批选择 `exists-1.ngc` 到 `exists-7.ngc`，覆盖 malformed `EXISTS[]` parameter expression 的 LinuxCNC 错误文本路径。

本批变更：

- 将 `tests/interp/bad/exists-{1..7}.ngc` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/bad/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- 扩展 Node WASM 与 browser interpreter smoke 的 selected bad fixture table，断言错误文本、读/执行计数、`file_saw_error=1` 和 `ON_RESET`。
- 更新 source reuse map 和 porting tracker。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
```

结论：

`tests/interp/bad/exists-{1..7}.ngc` 已完成 native、WASM Node、browser 三层闭环，vendor byte sync 与 host 聚合验证均通过。本批可单独提交。

---

2026-06-09 09:25 CST 继续推进记录：

继续扩展 upstream `linuxcnc/tests/interp/bad` 的小型负向 file-execution fixture。本批选择 6 个 center-format arc 半径不一致用例：

- `bad-arc.big.imperial.center-format.ngc`
- `bad-arc.big.metric.center-format.ngc`
- `bad-arc.medium.imperial.center-format.ngc`
- `bad-arc.medium.metric.center-format.ngc`
- `bad-arc.small.imperial.center-format.ngc`
- `bad-arc.small.metric.center-format.ngc`

这些 fixture 都是纯文件执行负向用例，覆盖 LinuxCNC interpreter 的 arc start/end radius mismatch 错误文本路径，不涉及 Python、HAL、UI 或 full LinuxCNC task 进程。

本批变更：

- 将 6 个 upstream `.ngc` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/bad/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- 扩展 Node WASM 与 browser interpreter smoke 的 selected bad fixture table，断言错误文本、`file_read_count=6`、`file_execute_count=6`、`file_saw_error=1` 和 `ON_RESET`。
- 更新 compatibility validation、source reuse map 和 porting tracker。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/host/verify_host_smokes.sh
git diff --check
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
git diff --check clean
```

结论：

6 个 `tests/interp/bad/bad-arc.*.center-format.ngc` fixture 已完成 native、WASM Node、browser 三层闭环，vendor byte sync、native 总验证、host 聚合验证和 whitespace 检查均通过。本批可单独提交。

---

2026-06-09 09:40 CST 继续推进记录：

继续沿 upstream arc tolerance 边界推进。本批选择 `linuxcnc/tests/interp/good` 的 6 个 center-format arc 正向容差用例：

- `good-arc.big.imperial.center-format.ngc`
- `good-arc.big.metric.center-format.ngc`
- `good-arc.medium.imperial.center-format.ngc`
- `good-arc.medium.metric.center-format.ngc`
- `good-arc.small.imperial.center-format.ngc`
- `good-arc.small.metric.center-format.ngc`

这些 fixture 与上一批 `bad-arc.*.center-format.ngc` 形成正反边界：bad fixture 验证半径不一致错误路径，good fixture 验证 LinuxCNC 允许的 center-format arc tolerance acceptance。它们都是纯文件执行用例，不涉及 Python、HAL、UI、tool table、INI 或 full LinuxCNC task 进程。

本批变更：

- 将 6 个 upstream `.ngc` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/good/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- 扩展 Node WASM 与 browser interpreter smoke，断言 `file_read_count=5`、`file_execute_count=5`、`file_saw_error=0`、`run_step` line 4 endpoint、LinuxCNC `ARC_FEED` canonical output、`PROGRAM_END`，并断言 absent `Radius to end of arc differs from radius to start`。
- 更新 compatibility validation、source reuse map 和 porting tracker，明确 arc tolerance 仍来自 LinuxCNC interpreter，不在胶水层实现。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
```

结论：

6 个 `tests/interp/good/good-arc.*.center-format.ngc` fixture 已完成 native、WASM Node、browser 三层闭环，vendor byte sync、native 总验证和 host 聚合验证均通过。本批可单独提交。

---

2026-06-09 11:50 CST 继续推进记录：

继续评估剩余 upstream `linuxcnc/tests/interp/*` 候选。`value-returned` 涉及 Python O-word 子程序，`subroutine-return` 需要额外 INI/subroutine 上下文，暂不作为本轮小批次对象。`g76` 需要 tool table 上下文，留到后续按 INI/tool table staging 规则处理。本批选择边界更小且当前 standalone file runner 可稳定完成的 G72 lathe facing canned-cycle regression：

- `g72-facing/g72-iterations-present.ngc`
- `g72-missing-iteration/g72-iterations-missing.ngc`

这两个 fixture 来自 LinuxCNC issue 707 相关回归，验证 G72 facing canned cycle 不会卡死，并覆盖有/无最后一次迭代的终点差异。它们通过 LinuxCNC interpreter file execution 路径运行，不涉及 Python、HAL、UI 或 full LinuxCNC task 进程。

本批变更：

- 将 `tests/interp/g72-facing/{expected,g72-iterations-present.ngc,test.sh}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/g72-facing/`。
- 将 `tests/interp/g72-missing-iteration/{expected,g72-iterations-missing.ngc,test.sh}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/g72-missing-iteration/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- 扩展 Node WASM 与 browser interpreter smoke，断言 `file_read_count=10`、`file_execute_count=10`、`file_saw_error=0`、line 8 `run_step`、G72-generated `STRAIGHT_FEED` endpoints、`PROGRAM_END`，并断言 absent `program seem to be stuck`。
- 更新 compatibility validation、source reuse map 和 porting tracker，明确 G72 canned-cycle 行为仍来自 LinuxCNC interpreter，不在胶水层实现。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
```

结论：

`tests/interp/g72-facing` 和 `tests/interp/g72-missing-iteration` 已完成 native、WASM Node、browser 三层闭环，vendor byte sync、native 总验证和 host 聚合验证均通过。本批可单独提交。

---

2026-06-09 12:15 CST 继续推进记录：

继续评估剩余 upstream `linuxcnc/tests/interp/*` 候选。本批选择 `tests/interp/g76`：

- `g76/g76only.ngc`
- `g76/test.tbl`

该 fixture 裸文件执行会在 `T4 M6` 处失败：

```text
Requested tool 4 not found in the tool table
```

因此本批按既定规则处理为“需要 tool table 上下文”的程序：通过最小 INI 声明 upstream `test.tbl` 后运行，工具表加载仍走 LinuxCNC `tooldata_load()` / `Interp::load_tool_table()` 路径，JS/native 胶水只负责 staging 文件和调用 C ABI，不实现 G76/threading/tool 语义。

本批变更：

- 将 `tests/interp/g76/{README,expected,g76only.ngc,test.sh,test.tbl}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/g76/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- native probe 侧生成最小 INI：`[EMCIO] TOOL_TABLE = test.tbl` 与 `[TRAJ] COORDINATES = X Y Z A B C U V W`。
- Node WASM 与 browser smoke staging `g76only.ngc` 和 `test.tbl`，生成同等最小 INI 后调用 `runFileWithIni()`。
- 断言 `file_read_count=30`、`file_execute_count=30`、`file_saw_error=0`、`T4 M6` run_step、tool select/change、spindle start、G76 speed-feed sync、threading traverse/feed canonical events、`PROGRAM_END`，并断言 absent `Requested tool 4 not found`。
- 更新 compatibility validation、source reuse map 和 porting tracker，明确 G76/threading 行为来自 LinuxCNC interpreter，不在胶水层实现。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
```

结论：

`tests/interp/g76` 已完成 native、WASM Node、browser 三层闭环，vendor byte sync、native 总验证和 host 聚合验证均通过。本批可单独提交。

---

2026-06-09 12:45 CST 继续推进记录：

继续评估剩余 upstream `linuxcnc/tests/interp/*` 候选。`cam-nisley` 裸跑会在 `T #1113 M6` 处因缺 tool table 失败，且程序更长，暂留到后续按工具表上下文单独处理。本批选择当前 standalone file runner 可稳定完成的 G71/G70 lathe canned-cycle 回归组：

- `g71-endless-loop/g71-endless-loop.ngc`
- `g71-endless-loop2/g71-endless-loop2.ngc`
- `g71-endless-loop_2/g71-endless-loop_2.ngc`
- `g71-with-g70/g71-with-g70.ngc`

这些 upstream `test.sh` 的核心目标是确认程序不会卡死。它们通过 LinuxCNC interpreter file execution 路径运行，不涉及 Python、HAL、UI、tool table 或 full LinuxCNC task 进程。

本批变更：

- 将 `tests/interp/g71-endless-loop/{expected,g71-endless-loop.ngc,test.sh}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/g71-endless-loop/`。
- 将 `tests/interp/g71-endless-loop2/{expected,g71-endless-loop2.ngc,test.sh}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/g71-endless-loop2/`。
- 将 `tests/interp/g71-endless-loop_2/{expected,g71-endless-loop_2.ngc,test.sh}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/g71-endless-loop_2/`。
- 将 `tests/interp/g71-with-g70/{expected,g71-with-g70.ngc,test.sh}` byte-for-byte vendored 到 `wasm-port/vendor/linuxcnc/tests/interp/g71-with-g70/`。
- 更新 `tools/source-manifest.txt` 和 native probe build/run 验证。
- 扩展 Node WASM 与 browser interpreter smoke，断言各文件的 `file_read_count`、`file_execute_count`、`file_saw_error=0`、关键 G71/G70-generated feed/arc/traverse canonical endpoints、`PROGRAM_END`，并断言 absent `program seem to be stuck` 和 `killing`。
- 更新 compatibility validation、source reuse map 和 porting tracker，明确 G71/G72 canned-cycle 行为仍来自 LinuxCNC interpreter，不在胶水层实现。

执行命令：

```bash
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
vendor sync validation complete

interp_wasm_node_smoke=ok
browser_interp_smoke=ok

sim config harness summary
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
skipped: 0

nc_files harness summary
suite: basic
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0

native probe validation complete

host_wasm_opfs_browser_smokes=ok
```

结论：

4 个 selected `tests/interp/g71-*` fixture 已完成 native、WASM Node、browser 三层闭环，vendor byte sync、native 总验证和 host 聚合验证均通过。本批可单独提交。

---

2026-06-09 13:15 CST 继续推进记录：

按“完善文件上下文 staging 规则”收敛已知边界。本批没有扩大 LinuxCNC
语义测试面，重点是把 Node 和 browser 可共用的 INI 关联文件规划制度化。

背景：

- Node 测试可以直接读本地目录，但 browser 不能列目录。
- 因此 staging helper 必须只依赖 `tools/source-manifest.txt` 和 INI 文本。
- helper 只生成 `{sourceRel, wasmPath, executable}` 文件计划；实际 fetch/read/write
  仍由测试层或调用方完成。
- 不实现 G-code、tool table、parameter、remap、USER_M 语义。

实现内容：

1. 在 SDK staging 层新增通用 `planIniFileContextStaging()`。

输入：

- `manifestText`
- `sourceRootRel`
- `iniFile`
- `iniText`
- `wasmDir`
- 可选 `programFile`
- 可选 `sourceSearchRootRel`

输出：

- `wasmDir`
- `iniPath`
- `programPath`
- `files[]`

每个 `files[]` 项包含：

- `sourceRel`
- `wasmPath`
- `path` 兼容旧调用方
- `executable`

2. `planIniFileContextStaging()` 现在根据 INI 和 manifest 收集：

- INI 本身
- `[DISPLAY]OPEN_FILE`
- `[EMCIO]TOOL_TABLE`
- `[RS274NGC]PARAMETER_FILE`
- 一个或多个 `[RS274NGC]SUBROUTINE_PATH`
- 一个或多个 `[RS274NGC]USER_M_PATH`
- `REMAP ... ngc=...` 关联的 NGC remap 文件

3. 保留 `planSimConfigStaging()` 作为兼容 wrapper。

`planSimConfigStaging()` 现在调用 `planIniFileContextStaging()`，并使用：

- `sourceRootRel = configs/sim/<machine>`
- `sourceSearchRootRel = configs/sim`

这样继续支持 sim-config 中 tool table、parameter file、subroutine、user-M
文件向上按 basename 查找的既有行为。

4. 更新 SDK stable export。

`runtime/sdk/src/index.js` 现在导出：

- `planIniFileContextStaging`
- `planSimConfigStaging`

5. 扩展 Node WASM sim-config smoke 断言。

新增 synthetic generic INI staging plan 覆盖：

- `TOOL_TABLE`
- `PARAMETER_FILE`
- 多目录 `SUBROUTINE_PATH = subs:more-subs`
- `USER_M_PATH = .`
- executable `M145`
- `wasmPath` 输出

6. 更新 SDK README。

文档明确 `planIniFileContextStaging()` 是 host-boundary 文件规划器，只读取
INI 引用和 manifest，不实现 LinuxCNC 语义；`planSimConfigStaging()` 是
面向 `configs/sim` 的 convenience wrapper。

修改文件：

- `wasm-port/runtime/sdk/src/sim-config-staging.js`
- `wasm-port/runtime/sdk/src/index.js`
- `wasm-port/tests/wasm/node/verify_sim_configs_wasm.mjs`
- `wasm-port/runtime/sdk/README.md`

执行命令：

```bash
wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
sim_configs_wasm_node_smoke=ok
browser_interp_smoke=ok
host_wasm_opfs_browser_smokes=ok
```

结论：

文件上下文 staging 规则已抽成通用 SDK helper。后续 Node/browser 测试可以
用同一套 manifest-based 规划 staging INI、tool table、parameter file、
subroutine、USER_M 和 remap NGC 文件，避免 browser 依赖目录枚举，同时继续
保持 LinuxCNC 语义只来自 vendored C/C++ 路径。

---

2026-06-09 13:35 CST 继续推进记录：

继续收敛“完善文件上下文 staging 规则”的 browser 闭环。

上一批已经在 Node WASM sim-config smoke 中验证了通用
`planIniFileContextStaging()`，但 browser interpreter smoke 只通过
`planSimConfigStaging()` 间接覆盖。由于 browser 不能列目录，本批补上真实
browser module 环境里的 synthetic manifest 断言。

实现内容：

1. `tests/browser/interp_smoke.html` 导入 `planIniFileContextStaging()`。

2. 新增 `verifyBrowserIniContextStagingPlan()`。

该断言完全使用内联 manifest text 和 INI text，不读取目录，覆盖：

- INI 本身
- `[DISPLAY]OPEN_FILE`
- `[EMCIO]TOOL_TABLE`
- `[RS274NGC]PARAMETER_FILE`
- `SUBROUTINE_PATH = subs:more-subs`
- `USER_M_PATH = .`
- executable `M145`
- `wasmPath` 输出

3. 在创建 interpreter/INI WASM SDK 前先执行该断言。

这样如果 generic staging helper 在真实 browser module loader 下不可用，
`wasm-port/tests/browser/verify_interp_browser.sh` 会直接失败。

4. 更新文档。

- `docs/compatibility-validation.md` 现在描述 Layer 4 使用通用
  `planIniFileContextStaging()`，`planSimConfigStaging()` 只是 `configs/sim`
  wrapper。
- `docs/drift-report.md` 将 “Sim-config SDK staging” 更新为
  “INI-context SDK staging”，明确 helper 只依赖 INI 文本和
  `tools/source-manifest.txt`，不依赖 browser 目录枚举。

修改文件：

- `wasm-port/tests/browser/interp_smoke.html`
- `wasm-port/docs/compatibility-validation.md`
- `wasm-port/docs/drift-report.md`
- `text.txt`

执行命令：

```bash
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
browser_interp_smoke=ok
host_wasm_opfs_browser_smokes=ok
```

结论：

generic INI-context staging helper 已在 Node 和真实 browser smoke 中都有
synthetic 覆盖。后续新增 browser 测试时，可以继续用 manifest-based plan
生成 staging 文件清单，不需要 browser 侧目录枚举，也不把 LinuxCNC 语义放进
JavaScript。

---

2026-06-09 13:50 CST 继续推进记录：

继续收敛 generic INI-context staging helper 的覆盖缺口。

上一批 synthetic 断言已经覆盖：

- INI
- `[DISPLAY]OPEN_FILE`
- `[EMCIO]TOOL_TABLE`
- `[RS274NGC]PARAMETER_FILE`
- 多目录 `[RS274NGC]SUBROUTINE_PATH`
- `[RS274NGC]USER_M_PATH`
- executable user-M 文件
- `wasmPath`

本批补上 `REMAP ... ngc=...` 关联 NGC 文件收集，确保 helper 的文档承诺也
有 Node 和 browser 双侧断言。

实现内容：

1. Node WASM synthetic generic staging plan 增加：

- manifest entry: `tests/interp/example/subs/rm145.ngc`
- INI entry: `REMAP = M145 modalgroup=10 ngc=rm145`
- expected file: `/work/interp/example/subs/rm145.ngc`

2. Browser interpreter synthetic staging plan 增加：

- manifest entry: `tests/browser-staging/example/subs/rm145.ngc`
- INI entry: `REMAP = M145 modalgroup=10 ngc=rm145`
- expected file: `/work/browser-staging/example/subs/rm145.ngc`

3. 更新 compatibility validation。

`tests/wasm/node/verify_sim_configs_wasm.sh` 和
`tests/browser/verify_interp_browser.sh` 的说明现在都明确 synthetic staging
断言覆盖 `REMAP ... ngc=...` file collection。

修改文件：

- `wasm-port/tests/wasm/node/verify_sim_configs_wasm.mjs`
- `wasm-port/tests/browser/interp_smoke.html`
- `wasm-port/docs/compatibility-validation.md`
- `text.txt`

执行命令：

```bash
wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
```

验证输出摘要：

```text
sim_configs_wasm_node_smoke=ok
browser_interp_smoke=ok
host_wasm_opfs_browser_smokes=ok
```

结论：

generic INI-context staging helper 现在对 INI/program/tool/parameter/
subroutine/user-M/remap-NGC 的 manifest-based file collection 都有 Node 和
browser 覆盖。该 helper 仍只生成文件计划，不执行或实现 LinuxCNC remap 语义。

---

2026-06-09 14:05 CST 继续推进记录：

按规划推进第 5 项“文档化测试分层”。

目标：

- 把测试分成四层并写清每层职责。
- 每层记录入口命令、当前通过情况、expected failure 口径。
- 明确 LinuxCNC-owned behavior 和 host/WASM adapter allowance 的边界。
- 明确 JS/browser 只能做 staging、OPFS、路径转发和 C ABI 调用，不能实现
  G-code、remap、tool、parameter、planner、kinematics 或 user-M 语义。

实现内容：

1. 更新 `docs/compatibility-validation.md`。

在现有 Validation Layers 表之后新增 “Layer responsibilities” 表，逐层记录：

- Layer 1 `nc_files` native smoke：
  LinuxCNC-owned behavior 是 upstream `rs274` parsing/execution；
  host allowance 只允许生成 native harness INI/tool-table context；
  expected failure 必须记录缺失 machine/task context 或 upstream example edge，
  不能通过改 G-code 语义变成 pass。

- Layer 2 `configs/sim` native strict harness：
  LinuxCNC-owned behavior 是 upstream `rs274` + sim INI context；
  host allowance 是定位 INI/tool table 并分类 main program、macro、remap
  subroutine；
  expected failure 记录 upstream standalone `rs274` 限制，例如 task/user-M
  process edge 和保留的 `incremental_repetition_g533.ngc` demo edge。

- Layer 3 standalone native runtime probes：
  LinuxCNC-owned behavior 是 vendored interpreter/remap/tool/parameter/
  kinematics/planner source；
  adapter allowance 是 deterministic filesystem、HAL/user-M、machine status、
  build/source-probe boundary；
  standalone pass 可以覆盖 Layer 1/2 没有的 runtime edge，但 CNC 行为仍必须
  来自 vendored LinuxCNC source。

- Layer 4 WASM Node/browser representative smoke：
  LinuxCNC-owned behavior 是 generated WASM modules 暴露的 C ABI；
  adapter allowance 是 staging files、chmod executable bits、OPFS text
  persistence、manifest-based staging plans 和 JS/browser 到 C ABI 的 path/result
  forwarding；
  WASM/browser pass 只证明 host boundary 能复现 staged LinuxCNC context，不能
  替代 native source validation，也不能支持 JS-owned CNC semantics。

2. 更新 `docs/source-reuse-map.md`。

Representative sim-config row 现在明确：

- standalone/WASM boundary 会复制 INI、tool table、G-code、executable user-M、
  `SUBROUTINE_PATH` files 和 remap-NGC files；
- `planIniFileContextStaging()` 是 generic manifest-based file-plan helper；
- `planSimConfigStaging()` 是 `configs/sim` wrapper；
- `runSimConfigProgram()` 只写入 Emscripten FS、设置 executable bit、转发到
  LinuxCNC-backed C ABI；
- `M110`/`M111` process execution 仍是 deterministic `USER_M_COMMAND` runtime
  boundary。

修改文件：

- `wasm-port/docs/compatibility-validation.md`
- `wasm-port/docs/source-reuse-map.md`
- `text.txt`

验证命令：

```bash
git diff --check
```

验证结果：

```text
clean
```

结论：

规划第 5 项的核心文档化要求已补齐。现在四层测试不仅有入口命令和当前结果，
也明确写出了每层 LinuxCNC-owned behavior、host/WASM adapter allowance 和
expected-failure policy，便于后续继续收敛 configs/sim expected failure 或
新增 upstream tests 时保持边界一致。
