项目接续文件：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 更新。
