configs/sim 全面测试下一步实施计划 生成时间:2026-06-09 15:00 CST 本计划接替 `text2.txt`。后续 `configs/sim` 相关工作以本文件为准。 目标定义: - 这里的“全部完成全面测试”不等于“让 `linuxcnc/configs/sim` 下所有 `.ngc` 在 standalone `bin/rs274` 下全部 PASS”。 - 正确目标是: 1. 对 `configs/sim` 下所有 `.ngc` 建立完整 inventory; 2. 每个文件都被归入明确类别; 3. 每个类别都有正确入口点和验证层; 4. 能在 standalone native/WASM/browser 中运行的,必须补齐覆盖; 5. 不能在 standalone 路径中真实复现的,必须记录为 blocked,并写清依赖; 6. 不通过修改 G-code 语义、JS 解释逻辑、或 project-owned standalone interpreter 语义让测试“看起来通过”。 项目纪律: - CNC 语义来源只能是 LinuxCNC upstream 或 vendored LinuxCNC source。 - `configs/sim` 程序必须在完整上下文下判断:INI、tool table、parameter file、 `SUBROUTINE_PATH`、`USER_M_PATH`、remap-NGC、Python remap、task/runtime 边界都要按 LinuxCNC 真实归属处理。 - browser 不能依赖目录枚举;Node/browser staging 继续优先使用 `tools/source-manifest.txt` + INI 文本生成计划。 - 不为了“全面测试”而把 full-process / HAL / UI / linuxcncrsh / Python binding 误降级为 standalone interpreter file execution。 当前真实基线: - Layer 2: `wasm-port/tests/native/verify_sim_configs.sh` 当前基线:`total 159, pass 151, expected_fail 8, unexpected_fail 0`。 - Layer 3: `wasm-port/tests/native/verify_native_probes.sh` 当前通过,已经覆盖代表性 runtime edge: `axis/foam` U/V、bridge-mill W/remap、`axis/geometry` M110、 `axis/external_offsets` M111、`opa_demo.ngc -> circles.ngc`。 - Layer 4: `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` 当前通过,但只覆盖 representative subset,不是全量 `configs/sim`。 当前已知剩余 expected failure: - `axis/foam/foam.ngc` native upstream standalone `rs274` 缺 U/V axis reader,上层 runtime 已覆盖。 - `axis/vismach/5axis/bridgemill/5axisgui.ngc` native upstream standalone `rs274` 缺 W axis reader,上层 runtime 已覆盖。 - `axis/geometry/xyzc.ngc` native upstream standalone `rs274` 缺 `USER_M_PATH` M110 注册,上层 runtime 已覆盖。 - `axis/external_offsets/dyn_demo.ngc` - `axis/external_offsets/eoffsets.ngc` - `axis/external_offsets/jwp_z.ngc` - `axis/external_offsets/opa_demo.ngc` native upstream standalone `rs274` 缺 `USER_M_PATH` M111 注册,上层 runtime 已覆盖; 其中 `opa_demo.ngc` 还依赖 `SUBROUTINE_PATH` `circles.ngc`,上层 runtime 已覆盖。 - `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_g533.ngc` 保持 upstream demo expected failure;禁止通过修改 G-code 或 JS 解释逻辑让它 PASS。 全面测试还缺哪些工作: 1. 完整建立 `configs/sim` 程序级覆盖矩阵 当前问题: - 我们有 harness summary,但还没有一份“每个 `.ngc` 的归属矩阵”: 哪些是 `main`、哪些是 `macro_load`、哪些是 `remap_subroutine`、 哪些只是 LinuxCNC native baseline、哪些已经进入 Layer 3、哪些已经进入 Layer 4、 哪些仍 blocked。 需要产出: - 一份 tracked matrix,建议新增: ```text wasm-port/docs/sim-configs-coverage-matrix.md ``` 矩阵至少包含列: - `path` - `class` - `native_rs274_status` - `expected_failure_reason` - `layer3_runtime_probe` - `layer4_node` - `layer4_browser` - `blocked_dependency` - `notes` 通过条件: - `wasm-port/build/native/sim-configs/summary.tsv` 中所有 159 条记录都能映射到 matrix。 - matrix 中不能有“未分类”行。 2. 明确“全部”里的 blocked 边界,而不是继续误扩面 当前问题: - `configs/sim` 下面并不是所有 `.ngc` 都应该被强行推进到 browser full execution。 - 还缺一份 `configs/sim` 专属 blocked policy,用来区分: - pure interpreter / remap / INI-context 可移植程序; - task/user-M/runtime edge 程序; - Python remap/full-process/HAL/UI 依赖程序; - demo edge / upstream malformed demo。 需要明确加入 blocked 的类: - 任何本质依赖 linuxcncrsh、GUI driver、HAL process、实时 motion 状态反馈、 外部 userspace component、或 Python binding API 的 sim-config path。 - `mdi-*`、UI action、或只能通过 full task process 触发的配置流。 - 不能通过 NGC-only subpath 提纯的 Python/full-process config family。 执行: - 从 `verify_sim_configs.sh` summary 和 `configs/sim` 路径结构出发, 逐目录补 blocked classification。 - 先补 family-level blocked,再细化到 program-level。 产出: - 更新 `docs/linuxcnc-test-porting-tracker.md` blocked table; - 更新 `docs/compatibility-validation.md` 的 `configs/sim` 边界说明; - 在新 matrix 中写出每个 blocked 程序或目录的 dependency。 3. 把 representative coverage 扩展成 class coverage,而不是盲目追求全量 browser 当前问题: - Layer 4 现在只覆盖 representative subset: `foam`、`geometry`、`external_offsets`、bridge-mill。 - 这还不足以支撑“全面测试完成”的说法,因为 `configs/sim` 还包含多种 machine class: - plain INI/tool-table/main program; - Python remap main program; - remap subroutine only; - five-axis switchkins / TWP / TDR / TRT; - macro-only config families; - on_abort / macro load / tool-change style files。 实施原则: - 不是把 159 个程序都复制进 browser smoke。 - 是每种独立 runtime class 至少补一个 native + Node + browser representative, 并且 class 到 program 的归因在 matrix 中完整记录。 最低还要补齐的 representative class: - TWP `table-rotary_spindle-rotary-nutating`: 当前 native baseline 已有 14/15 passing inventory,但 Layer 4 还没有代表性 TWP runtime smoke。 - gmoccapy Python remap family: native inventory 已通过,但 Layer 4 还没有任何 gmoccapy representative。 - axis/laser Python remap family: native inventory 已通过,但 Layer 4 还没有任何 laser representative。 - generic `macro_load` family: 当前 Layer 4 基本聚焦 main programs,缺少“宏文件只验证 load/parse,不伪造 main” 的 shared assertion。 - `on_abort` / deterministic user-action macro family: 当前 native inventory大量 PASS,但 Node/browser 尚未有独立 representative class。 通过条件: - 每个 runtime class 在 `docs/sim-configs-coverage-matrix.md` 中都能对应至少一个 Layer 3/Layer 4 representative。 - 不要求 159 个程序全部进入 browser smoke; 但要求每个 class 都有代表 sample,且每个非代表 sample 都有“为什么不需要单独进 browser”的记录。 4. 补 `configs/sim` 专属全量 Node inventory runner 当前问题: - Node 侧现在只有 representative smoke,没有一个“只跑能在 standalone/WASM 路径中合理成立的 `configs/sim` 全量 inventory”。 需要新增: ```text wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.mjs wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh ``` 职责: - 读取 native `summary.tsv` 或同等来源; - 只挑选: - native PASS 条目; - 以及 Layer 2 expected_fail 但 Layer 3/4 已知有 runtime adapter coverage 的条目; - 跳过已标记 blocked 的 full-process/HAL/UI-only family; - 对 Node WASM 做 inventory run; - 输出 Node 侧 summary.tsv。 重要限制: - 不把 browser 作为 first target; - 不新增 JS CNC 语义; - 不把 Python/full-process family 强行塞进 Emscripten,除非已存在 LinuxCNC-owned runtime path。 通过条件: - Node inventory summary 可重跑、可对比、可纳入 CI; - unexpected failure 为 0; - expected skip / blocked 有明确计数。 5. 再决定 browser inventory,而不是直接上全量 browser 当前问题: - browser 环境成本高,且不能依赖目录枚举。 - 如果先做 browser 全量 inventory,会把大量问题混在 host boundary、 asset staging、Emscripten runtime、Playwright orchestration 里,定位价值低。 实施顺序: - 先完成 Node inventory; - 从 Node inventory 中挑出最有价值的 browser representative 扩展; - browser 保持 focused class smoke,不追求一次性全量 159。 可以进入 browser 扩展候选的 class: - TWP representative; - gmoccapy Python remap representative; - axis/laser representative; - one deterministic macro-only family; - one toolchange / on_abort family。 通过条件: - browser 侧 class coverage 明确,不再只是 `foam/geometry/external_offsets/bridgemill`; - 仍然保持稳定、可复现、非目录枚举。 6. 把 `verify_sim_configs.sh` 从 inventory 提升为 coverage source-of-truth 当前问题: - native `summary.tsv` 已经是事实来源,但还缺少稳定的 machine-readable 统计, 用来支撑 docs、Node inventory 和后续 CI 对账。 需要增强: - 保持 `summary.tsv` 不变; - 增加稳定派生 artifact,建议: ```text wasm-port/build/native/sim-configs/class-summary.tsv wasm-port/build/native/sim-configs/path-matrix.tsv ``` 最少字段: - `path` - `class` - `status` - `expected_failure` - `ini` - `tbl` - `runtime_family` - `blocked` 注意: - 如果不想提交 generated artifact,就由脚本生成并由 docs 读取规则描述; - 但字段模型要先定下来。 7. 清理 `configs/sim` 文档的“完成”定义 当前问题: - 现有 `docs/sim-configs-completion-plan.md` 更多描述了“把当前大块 runtime edge 打通”的完成,不是“全面测试完成”的完成。 需要文档调整: - 新增一节:`Definition of Done for Full configs/sim coverage` - 明确: - inventory complete - blocked table complete - native source-of-truth complete - Node inventory complete - browser class coverage complete - every expected failure justified - no accidental standalone semantic ownership 8. 最后再谈“还能不能把 Layer 2 的 8 个 expected_fail 变少” 原则: - `foam` / `bridgemill` / `M110` / `M111` 这些 expected_fail 不是当前首要问题; 它们已经由 Layer 3/4 runtime path 证明。 - 只有当能够通过 vendored LinuxCNC source path 合法地把 native strict baseline 改造成更贴近 runtime 的入口点时,才讨论减少 expected_fail。 - 在那之前,不改 `verify_sim_configs.sh` 的语义口径,不把 expected_fail 硬改成 PASS。 优先级排序: 1. coverage matrix 2. blocked table 3. Node inventory 4. browser class expansion 5. docs done-definition 6. 再评估 Layer 2 baseline 是否需要新入口点 推荐执行顺序: 1. 先建立 coverage matrix 执行: ```bash wasm-port/tests/native/verify_sim_configs.sh cat wasm-port/build/native/sim-configs/summary.tsv ``` 产出: - 新增 `wasm-port/docs/sim-configs-coverage-matrix.md` - 159 条记录全部分类 2. 再补 blocked table 和 class taxonomy 执行: - 逐目录梳理 `linuxcnc/configs/sim` - 对照 `verify_sim_configs.sh` summary - 把 full-process/HAL/UI-only family 写进 tracker blocked table 产出: - 更新 `docs/linuxcnc-test-porting-tracker.md` - 更新 `docs/compatibility-validation.md` 3. 实施 Node inventory runner 执行: ```text wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.mjs wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh ``` 通过条件: - Node inventory 只跑可移植条目 - unexpected failure = 0 4. 扩 browser class coverage 执行: - 先补 TWP representative - 再补 gmoccapy representative - 再补 axis/laser representative - 最后补 macro-only / on_abort representative 通过条件: - `verify_interp_browser.sh` 和 `verify_host_smokes.sh` 仍稳定通过 - browser 不引入目录枚举 5. 更新完成定义和漂移控制 执行: - 更新 `docs/sim-configs-completion-plan.md` - 更新 `docs/compatibility-validation.md` - 更新 `docs/source-reuse-map.md` 完成判定: - `configs/sim` 每个 `.ngc` 都有明确分类; - 每个类别都有合适层级的验证入口; - blocked dependency 清单完整; - Node inventory 可重跑; - browser class coverage 覆盖所有重要 runtime family; - Layer 2 的 8 个 expected_fail 都有稳定归因; - 没有通过 project-owned CNC 语义让测试看起来通过。 不做事项: - 不把 159 个程序全部塞进 browser smoke; - 不把 full-process/HAL/UI/linuxcncrsh 依赖程序误降级为 standalone file execution; - 不修改 `linuxcnc/configs/sim` upstream 文件; - 不通过 JS 解释逻辑、临时字符串匹配、或 standalone `Interp::...` 新语义实现来换取 PASS。