结论:完成 LinuxCNC kinematics WASM ABI 覆盖,并将 web-rtcp-5axis-sim-plan 的 RTCP frame/boundary adapter 接到 xyzac-trt kinematics SDK;Node、build、browser smoke 验证通过。
539 lines
14 KiB
Plaintext
539 lines
14 KiB
Plaintext
项目接续文件:WASM + OPFS 环境下 tool DB 完全解锁可行性与实施步骤
|
||
|
||
生成时间:2026-06-18 CST
|
||
|
||
本文件接替 `text20.txt`,进一步回答:在以 WASM 和 OPFS 为技术基础的 Web 技术环境下,
|
||
`L4-TOOL-DB` 是否可以完全解锁,以及怎样以可实现、可验证、不过度伪装的方式解锁。
|
||
|
||
重要状态说明:本文件是 future feasibility / architecture note,不是当前阶段执行计划。
|
||
当前阶段必须按铁律收束:virtual HAL 成果只作为 sim config promotion 证据基础;
|
||
`L4-PYTHON-REMAP`、`L4-TOOL-DB`、`L4-USER-M-PROCESS` 仍保持 hard block,不做解锁。
|
||
本文件中的 WASM + OPFS tool DB 解锁路线只能作为后续专门 milestone 使用,不能用于
|
||
当前 baseline promotion。
|
||
|
||
一、结论
|
||
|
||
可以实现“项目定义下的完全解锁”,但不能通过浏览器原生 spawn LinuxCNC native process
|
||
的方式实现。
|
||
|
||
更准确地说:
|
||
|
||
```text
|
||
如果“完全解锁”要求浏览器直接启动 native linuxcnc/milltask/halcmd/DB_PROGRAM 进程,
|
||
答案是不可以。
|
||
|
||
如果“完全解锁”定义为:在 WASM + OPFS 中保留 LinuxCNC-owned tool DB protocol、
|
||
执行配置声明的 DB_PROGRAM 行为、持久化 DB state、并通过 native/WASM/browser/release
|
||
proof chain 证明行为等价,答案是可以。
|
||
```
|
||
|
||
因此可行路线不是 `.tbl` fallback,也不是 JS 手写 tool semantics,而是:
|
||
|
||
```text
|
||
WASM 内运行 LinuxCNC tooldata DB protocol owner + WASM/Worker 隔离的 DB_PROGRAM runtime +
|
||
OPFS-backed flat-file persistence + source-derived proof gates。
|
||
```
|
||
|
||
二、必须保持的语义边界
|
||
|
||
`axis/db_demo/base.ngc` 的 LinuxCNC-owned 行为来自:
|
||
|
||
- `db_nonran.ini` 中的 `DB_PROGRAM = ./db_nonran.py`;
|
||
- LinuxCNC task/tooldata DB mode;
|
||
- `tooldata_db.cc` 的 DB process protocol;
|
||
- `tooldb.py` 的 protocol loop;
|
||
- `db.py` / `db_nonran.py` 的 callback/state behavior;
|
||
- flat-file database persistence。
|
||
|
||
WASM + OPFS 解锁时必须保持:
|
||
|
||
- `v2.1` startup handshake;
|
||
- `g` get-all until `FINI`;
|
||
- `l` spindle load notify;
|
||
- `u` spindle unload notify;
|
||
- `p` tool offset notify;
|
||
- nonrandom `T10..T19` startup state;
|
||
- DB file persistence;
|
||
- `DB_PROGRAM` 是配置声明的 runtime dependency;
|
||
- `.tbl` fallback 仍然标记为 insufficient。
|
||
|
||
三、浏览器环境限制
|
||
|
||
浏览器/WASM 环境天然缺少:
|
||
|
||
- native process spawn;
|
||
- LinuxCNC host daemon/process model;
|
||
- direct `milltask` process;
|
||
- direct `halcmd` host process;
|
||
- unrestricted POSIX filesystem。
|
||
|
||
但浏览器/WASM 环境具备:
|
||
|
||
- WASM module execution;
|
||
- Web Worker 隔离执行单元;
|
||
- MessageChannel / stream-style protocol;
|
||
- OPFS 持久文件系统;
|
||
- Emscripten FS 与 OPFS bridge;
|
||
- 可移植 Python/WASM runtime 选项;
|
||
- release/browser diagnostics artifact。
|
||
|
||
所以解锁方法必须把 native process boundary 改写为“协议等价 boundary”,而不是假装浏览器
|
||
可以直接运行 native child process。
|
||
|
||
四、推荐总体架构
|
||
|
||
### 1. Tool DB protocol owner 仍在 LinuxCNC/WASM core
|
||
|
||
将 LinuxCNC tooldata DB protocol owner 保持在 C/C++ WASM 侧:
|
||
|
||
- 复用/移植 `tooldata_db.cc`;
|
||
- 复用/移植 `tooldata_common.cc`;
|
||
- 保留 protocol message 生成与解析;
|
||
- 只把 process I/O edge 抽象为 host adapter。
|
||
|
||
建议新增抽象:
|
||
|
||
```text
|
||
ToolDbProcessPort
|
||
```
|
||
|
||
职责:
|
||
|
||
- start configured DB program;
|
||
- write protocol line;
|
||
- read reply line;
|
||
- close / cleanup;
|
||
- expose protocol transcript for diagnostics。
|
||
|
||
不允许职责:
|
||
|
||
- 自行解释 tool table;
|
||
- 自行构造 `T10..T19`;
|
||
- 跳过 `tooldb.py`;
|
||
- 用 `.tbl` fallback。
|
||
|
||
### 2. DB_PROGRAM 在 Web Worker / WASM Python runtime 中运行
|
||
|
||
推荐把 `db_nonran.py` 放进独立 Web Worker,使用 WASM Python runtime 执行。
|
||
|
||
可选实现:
|
||
|
||
- CPython/WASM;
|
||
- Pyodide;
|
||
- 项目内裁剪 Python/WASM runtime;
|
||
- 后续若项目已有 Python-remap runtime,可复用同一个 Python runtime substrate。
|
||
|
||
Worker 内需要挂载:
|
||
|
||
- `db_nonran.py`;
|
||
- `db.py`;
|
||
- `tooldb.py`;
|
||
- minimal `linuxcnc` Python compatibility module;
|
||
- OPFS-backed DB flat file。
|
||
|
||
这里的 minimal `linuxcnc` module 只能覆盖 DB demo 必需的 integration surface,例如:
|
||
|
||
- `linuxcnc.command().load_tool_table`
|
||
|
||
并且必须作为 process integration shim 记录,不允许承载 tool semantics。
|
||
|
||
### 3. OPFS 负责 DB persistence
|
||
|
||
将 DB demo 的 flat-file database 映射到 OPFS,例如:
|
||
|
||
```text
|
||
/machines/<machine-id>/tool-db/db_nonran_file
|
||
```
|
||
|
||
要求:
|
||
|
||
- startup 前可加载已有 OPFS DB file;
|
||
- protocol mutation 后写回 OPFS;
|
||
- reload session 后 DB state 保持;
|
||
- diagnostics artifact 导出 DB file hash / state summary / transcript hash;
|
||
- tests 能验证 persistence roundtrip。
|
||
|
||
### 4. Browser diagnostics 只证明,不伪装
|
||
|
||
browser UI / diagnostics 需要记录:
|
||
|
||
- DB runtime mode:`wasm-tool-db-protocol-worker`;
|
||
- DB program path;
|
||
- protocol transcript;
|
||
- OPFS DB file path;
|
||
- source files;
|
||
- `.tbl fallback sufficient = false`;
|
||
- Python-only sufficient = false;
|
||
- native proof status;
|
||
- WASM proof status;
|
||
- browser proof status。
|
||
|
||
五、分阶段实施路线
|
||
|
||
### Phase 0:保持当前 lock,不改 baseline
|
||
|
||
当前状态仍是:
|
||
|
||
```text
|
||
axis/db_demo/base.ngc SKIP L4-TOOL-DB
|
||
executed=28
|
||
passed=28
|
||
skipped=131
|
||
unexpected_fail=0
|
||
```
|
||
|
||
先不要改成 PASS。
|
||
|
||
保留:
|
||
|
||
- `promotion_allowed=0`
|
||
- `execution_enabled=0`
|
||
- `promotion_lock_active=1`
|
||
|
||
### Phase 1:native proof 先闭环
|
||
|
||
目的:证明 source-derived protocol contract 与真实 LinuxCNC DB runtime 一致。
|
||
|
||
在完整 LinuxCNC host runtime 中执行:
|
||
|
||
```text
|
||
wasm-port/tests/native/probe_tool_db_runtime.sh
|
||
ENABLE_TOOL_DB_RUNTIME_PROBE=1 wasm-port/tests/native/probe_tool_db_runtime.sh
|
||
```
|
||
|
||
目标输出:
|
||
|
||
```text
|
||
tool_db_runtime_probe_status=runtime_protocol_probe_passed
|
||
```
|
||
|
||
然后刷新:
|
||
|
||
```text
|
||
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
|
||
```
|
||
|
||
预期 artifact 转为:
|
||
|
||
```text
|
||
source_proof_ready=1
|
||
runtime_ready=1
|
||
native_evidence_ready=1
|
||
gate_status=native_probe_passed_waiting_for_node_browser_promotion_proof
|
||
promotion_allowed=0
|
||
```
|
||
|
||
### Phase 2:设计 WASM tool DB process port
|
||
|
||
新增 C/C++ 或 JS/WASM bridge 层,但协议 owner 必须保留 LinuxCNC source-derived 逻辑。
|
||
|
||
建议新增文件范围:
|
||
|
||
```text
|
||
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_tool_db_process_port.*
|
||
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_tool_db_protocol_harness.*
|
||
wasm-port/runtime/sdk/src/linuxcnc-tool-db.js
|
||
wasm-port/runtime/opfs/linuxcnc-tool-db-store.js
|
||
```
|
||
|
||
核心 API 草案:
|
||
|
||
```text
|
||
createLinuxCncToolDbRuntime({
|
||
dbProgramPath,
|
||
sourceFiles,
|
||
opfsRoot,
|
||
pythonRuntime,
|
||
})
|
||
|
||
startToolDbProgram()
|
||
sendToolDbProtocolMessage(line)
|
||
readToolDbProtocolReply()
|
||
runToolDbTransactionPlan(plan)
|
||
exportToolDbDiagnostics()
|
||
```
|
||
|
||
验证要求:
|
||
|
||
- API 返回 protocol transcript;
|
||
- transcript 包含 `v2.1` / `g` / `FINI` / `l` / `p` / `u`;
|
||
- DB state 不能来自 JS fixture hardcode;
|
||
- source file hash 必须可追踪。
|
||
|
||
### Phase 3:WASM Python / DB_PROGRAM runtime
|
||
|
||
新增或接入 Python/WASM runtime。
|
||
|
||
最低目标不是完整 Python remap runtime,而是 tool DB demo runtime:
|
||
|
||
- 能 import `tooldb.py`;
|
||
- 能 import `db.py` / `db_nonran.py`;
|
||
- 能读写 OPFS-backed DB file;
|
||
- 能通过 stdin/stdout 或 MessageChannel 模拟 process protocol;
|
||
- 能提供 minimal `linuxcnc.command().load_tool_table` integration shim。
|
||
|
||
必须新增 negative tests:
|
||
|
||
- 没有 `db_nonran.py` 时 fail;
|
||
- 没有 `tooldb.py` 时 fail;
|
||
- 只有 `python3` / Python runtime 但没有 protocol transcript 时 fail;
|
||
- 使用 `.tbl` fallback 时 fail;
|
||
- JS 直接返回 `T10..T19` 而没有 DB_PROGRAM transcript 时 fail。
|
||
|
||
### Phase 4:WASM protocol transaction tests
|
||
|
||
新增 Node/WASM tests,先不改 full inventory baseline。
|
||
|
||
建议新增:
|
||
|
||
```text
|
||
wasm-port/tests/wasm/node/verify_tool_db_process_wasm.sh
|
||
wasm-port/tests/wasm/node/verify_tool_db_process_wasm.mjs
|
||
```
|
||
|
||
测试内容:
|
||
|
||
1. stage `db_nonran.ini` / `db_nonran.py` / `db.py` / `tooldb.py`;
|
||
2. start WASM DB program runtime;
|
||
3. verify startup `v2.1`;
|
||
4. send `g` and verify `T10..T19` plus `FINI`;
|
||
5. send `l` load notify and verify pocket/spindle state;
|
||
6. send `p` offset/update notify and verify DB mutation;
|
||
7. send `u` unload notify and verify unload state;
|
||
8. persist to OPFS-backed store;
|
||
9. reload and verify state survives;
|
||
10. export transcript artifact。
|
||
|
||
输出建议:
|
||
|
||
```text
|
||
tool_db_process_wasm_protocol=ok
|
||
tool_db_process_wasm_persistence=ok
|
||
tool_db_process_wasm_no_tbl_fallback=ok
|
||
```
|
||
|
||
### Phase 5:接入 inventory pre-promotion artifacts
|
||
|
||
在不改 baseline 的前提下,新增或扩展 artifact:
|
||
|
||
```text
|
||
tool-db-process-wasm-protocol-proof.tsv
|
||
tool-db-process-opfs-persistence-proof.tsv
|
||
tool-db-process-browser-proof-gate.tsv
|
||
```
|
||
|
||
字段建议:
|
||
|
||
- path;
|
||
- ini;
|
||
- db_program;
|
||
- protocol_transcript_hash;
|
||
- opfs_db_file;
|
||
- startup_handshake_passed;
|
||
- get_all_passed;
|
||
- load_notify_passed;
|
||
- offset_notify_passed;
|
||
- unload_notify_passed;
|
||
- persistence_passed;
|
||
- tbl_fallback_sufficient;
|
||
- python_only_sufficient;
|
||
- source_derived;
|
||
- execution_enabled;
|
||
- promotion_allowed。
|
||
|
||
在这一阶段:
|
||
|
||
```text
|
||
execution_enabled=0
|
||
promotion_allowed=0
|
||
```
|
||
|
||
仍保持 lock。
|
||
|
||
### Phase 6:Browser proof
|
||
|
||
新增 browser proof,但只证明 protocol runtime 和 OPFS persistence,不直接宣称 inventory pass。
|
||
|
||
建议新增或扩展:
|
||
|
||
```text
|
||
wasm-port/tests/browser/verify_real_simulation_browser.sh
|
||
wasm-port/tests/browser/real_simulation_page_smoke.html
|
||
```
|
||
|
||
验证:
|
||
|
||
- browser 可以启动 tool DB Worker;
|
||
- browser diagnostics 包含 DB protocol transcript summary;
|
||
- OPFS persistence roundtrip 成功;
|
||
- `.tbl fallback sufficient=false`;
|
||
- `python_only_sufficient=false`;
|
||
- release artifact URL workflow 能显示 tool DB proof;
|
||
- missing DB proof negative fixture 会 fail。
|
||
|
||
### Phase 7:关闭 promotion lock 前的三方对齐
|
||
|
||
只有以下全部满足,才能准备关闭 lock:
|
||
|
||
```text
|
||
native_db_process_protocol_probe_passed=1
|
||
wasm_tool_db_protocol_passed=1
|
||
browser_tool_db_protocol_proof_passed=1
|
||
opfs_persistence_passed=1
|
||
tbl_fallback_sufficient=0
|
||
python_only_sufficient=0
|
||
source_derived=1
|
||
```
|
||
|
||
更新:
|
||
|
||
```text
|
||
runtime-boundary-promotion-readiness.tsv
|
||
runtime-boundary-promotion-blockers.tsv
|
||
runtime-boundary-post-native-pass-gates.tsv
|
||
runtime-boundary-native-evidence-acceptance-gate.tsv
|
||
blocked-runtime-promotion-lock.tsv
|
||
promotion-candidates.tsv
|
||
```
|
||
|
||
目标状态:
|
||
|
||
```text
|
||
native_evidence_ready=1
|
||
node_inventory_gate_complete=1
|
||
browser_smoke_gate_complete=1
|
||
promotion_lock_active=0
|
||
promotion_ready=1
|
||
promotion_allowed=1
|
||
```
|
||
|
||
### Phase 8:正式 inventory baseline promotion
|
||
|
||
更新 `verify_sim_configs_inventory_wasm.mjs`,允许 `axis/db_demo/base.ngc` 走 tool DB
|
||
protocol execution path。
|
||
|
||
要求:
|
||
|
||
- 执行时必须通过 WASM tool DB protocol runtime;
|
||
- 不能直接使用 `.tbl`;
|
||
- 失败时不能降级为 SKIP;
|
||
- protocol proof 缺失时必须 FAIL,而不是 silent fallback。
|
||
|
||
预期 `summary.tsv`:
|
||
|
||
```text
|
||
axis/db_demo/base.ngc PASS - main PASS -
|
||
```
|
||
|
||
预期 baseline:
|
||
|
||
```text
|
||
executed=29
|
||
passed=29
|
||
skipped=130
|
||
unexpected_fail=0
|
||
```
|
||
|
||
同步更新:
|
||
|
||
```text
|
||
VIRTUAL_HAL_SIM_CONFIG_INVENTORY_BASELINE
|
||
project release readiness fixture
|
||
coverage matrix Current Node inventory
|
||
compatibility validation current gate text
|
||
skip-summary expected count
|
||
promotion candidate expected status
|
||
release readiness artifact
|
||
batch acceptance artifact
|
||
```
|
||
|
||
六、可实现性的关键判断
|
||
|
||
### 可以实现的部分
|
||
|
||
1. WASM 内保存 LinuxCNC tool DB protocol owner。
|
||
2. Web Worker 作为 DB_PROGRAM process boundary 等价层。
|
||
3. WASM Python runtime 执行 `db_nonran.py` / `tooldb.py`。
|
||
4. OPFS 保存 DB flat-file。
|
||
5. Node/WASM/browser 三层 proof。
|
||
6. release artifact 记录 proof chain。
|
||
7. inventory baseline 从 `28/28/131/0` 推进到 `29/29/130/0`。
|
||
|
||
### 不应承诺的部分
|
||
|
||
1. 浏览器直接运行 native `milltask`。
|
||
2. 浏览器直接运行 host `halcmd`。
|
||
3. 浏览器直接 spawn OS child process。
|
||
4. 不经 Python DB program 而直接伪造 DB state。
|
||
5. 用 `.tbl` 替代 `DB_PROGRAM`。
|
||
|
||
七、推荐实施顺序
|
||
|
||
最务实顺序:
|
||
|
||
```text
|
||
1. 先在 native host 上跑通 ENABLE_TOOL_DB_RUNTIME_PROBE=1。
|
||
2. 加 tool DB WASM protocol proof,不改 baseline。
|
||
3. 加 OPFS persistence proof,不改 baseline。
|
||
4. 加 browser diagnostics proof,不改 baseline。
|
||
5. 更新 promotion readiness / lock。
|
||
6. 最后才把 axis/db_demo/base.ngc 纳入 inventory PASS。
|
||
```
|
||
|
||
八、最小验证命令
|
||
|
||
native:
|
||
|
||
```text
|
||
wasm-port/tests/native/probe_tool_db_runtime.sh
|
||
ENABLE_TOOL_DB_RUNTIME_PROBE=1 wasm-port/tests/native/probe_tool_db_runtime.sh
|
||
```
|
||
|
||
WASM/Node:
|
||
|
||
```text
|
||
wasm-port/tests/wasm/node/verify_tool_db_process_wasm.sh
|
||
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
|
||
```
|
||
|
||
Browser:
|
||
|
||
```text
|
||
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh
|
||
```
|
||
|
||
Release:
|
||
|
||
```text
|
||
wasm-port/tests/sdk/node/verify_sdk_surface.sh
|
||
wasm-port/tests/sdk/node/verify_project_release_gate_manifest.sh
|
||
wasm-port/tests/host/verify_project_release_readiness_artifact.sh
|
||
```
|
||
|
||
Safety:
|
||
|
||
```text
|
||
git diff --check
|
||
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
|
||
```
|
||
|
||
九、下一步工作内容
|
||
|
||
下一轮建议不要直接改 `axis/db_demo/base.ngc` 的 inventory status。先做最小可行
|
||
WASM proof:
|
||
|
||
```text
|
||
新增 verify_tool_db_process_wasm.mjs / .sh,证明 tool DB protocol transcript 和 OPFS
|
||
persistence 可以在 WASM + OPFS 环境中闭环,同时继续保持 promotion_allowed=0。
|
||
```
|
||
|
||
该 proof 的完成标准:
|
||
|
||
- `db_nonran.py` / `tooldb.py` 被真实加载;
|
||
- protocol transcript 中出现 `v2.1`、`g`、`FINI`、`l`、`p`、`u`;
|
||
- OPFS persistence roundtrip 通过;
|
||
- `.tbl fallback` negative fixture 失败;
|
||
- artifact 明确记录 `promotion_allowed=0`。
|
||
|
||
完成后再进入 browser proof 和 promotion lock 更新。
|