From 74be85cd01fc4654fc834c898581cecac2bc50f5 Mon Sep 17 00:00:00 2001 From: wangdequan Date: Sun, 14 Jun 2026 00:43:02 +0800 Subject: [PATCH] Guard browser OPFS saved text helper --- text8.txt | 277 ++++++++++++++++++++++ wasm-port/tests/browser/interp_smoke.html | 32 ++- 2 files changed, 296 insertions(+), 13 deletions(-) create mode 100644 text8.txt diff --git a/text8.txt b/text8.txt new file mode 100644 index 0000000..02248b4 --- /dev/null +++ b/text8.txt @@ -0,0 +1,277 @@ +项目整体完成情况与后续执行计划 + +生成时间:2026-06-14 CST + +本文件接替 `text7.txt`。后续工作按 `text8.txt` 执行;除非明确要求审计旧记录, +不要再回到 `text1/text2/text3/text4/text5/text6/text7` 扩展进度。`text7.txt` +作为历史归档保留。 + +一、续接状态与防重规则 + +1. 当前续接点。 + +`text7.txt` 已推进到: + +```text +四十六、2026-06-14 继续执行记录:browser OPFS machine file readback helper guard +``` + +该批已提交: + +```text +c35b8bb Guard browser OPFS machine file readback helper +``` + +本文件从 `text8.txt` 重新开始记录后续进度。 + +2. 每轮开始前必须先执行。 + +```bash +git status --short +git log -5 --oneline +tail -n 120 text8.txt +awk '/^[一二三四五六七八九十百]+、/ {print}' text8.txt | sort | uniq -d +``` + +执行规则: + +- 如果 `git status --short` 是 clean,且最新提交已经包含当前建议工作,不要重复追加记录; +- 每轮只追加一个新的中文编号记录;提交前再次检查标题唯一性; +- `text8.txt` 只记录新的后续进度,不复制 `text7.txt` 的长历史; +- 每批完成后,如果要写记录,先写 `text8.txt`,再提交该批代码和记录; +- 如果发现重复记录,先做 dedupe 清理并提交,再继续新功能或新 guard。 + +二、当前项目纪律 + +1. LinuxCNC 仍是唯一 CNC 语义来源。 + +G-code、remap、tool、parameter、planner、kinematics、user-M、tool DB、Python +remap 等语义必须来自 LinuxCNC upstream 或 vendored LinuxCNC C/C++/配置/脚本源码。 + +2. 本项目允许实现的范围仍限于: + +- build; +- source sync; +- runtime shim; +- filesystem staging; +- OPFS; +- WASM/browser boundary; +- 测试胶水; +- 文档; +- 机器可读 gate/artifact。 + +3. 禁止事项继续有效: + +- 不在 JS 中重写 G-code 或 CNC 语义; +- 不修改 vendored LinuxCNC 源文件来让测试通过; +- 不把 full-process/HAL/UI/Python/tool DB 依赖伪装成 standalone pass; +- 不把 expected failure 硬改成 pass,除非已有 LinuxCNC-owned runtime proof,并且 + native、Node、browser gate 都按顺序通过; +- browser 不能依赖目录枚举。 + +三、当前完成情况摘要 + +1. 当前工作树状态。 + +切换到 `text8.txt` 前已确认: + +```text +git status --short: clean +text7.txt duplicate Chinese headings: none +``` + +当前最近提交: + +```text +c35b8bb Guard browser OPFS machine file readback helper +caa6fd9 Guard browser OPFS session wasm map helper +1a339be Guard browser OPFS random session path constants +ded533e Guard browser OPFS ordinary session path constants +06f4316 Guard browser OPFS custom session INI wasm paths +``` + +2. WASM port 基础架构稳定。 + +`wasm-port` 仍按独立移植工作区组织,包含 vendor、runtime/core、runtime/sdk、 +runtime/opfs、runtime/ui、native/wasm/browser tests、docs 和 tools。 + +3. 关键基线保持稳定。 + +- `linuxcnc/nc_files` native Layer 1: + - `total 107` + - `pass 101` + - `expected_fail 6` + - `unexpected_fail 0` +- `linuxcnc/configs/sim` native Layer 2: + - `total 159` + - `pass 151` + - `expected_fail 8` + - `unexpected_fail 0` +- Node sim-config inventory: + - `executed=28` + - `passed=28` + - `skipped=131` + - `unexpected_fail=0` + +4. blocked runtime family 仍未 promotion。 + +仍 blocked,不允许 promotion: + +- `L4-USER-M-PROCESS` +- `L4-TOOL-DB` +- `L4-PYTHON-REMAP` + +当前 host 仍按缺少 LinuxCNC host runtime 处理,不执行任何: + +```bash +ENABLE_MILLTURN_USER_M_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_millturn_user_m_runtime.sh +ENABLE_TOOL_DB_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_tool_db_runtime.sh +ENABLE_PYTHON_REMAP_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_python_remap_runtime.sh +``` + +5. `text7.txt` 最新收敛方向。 + +`text7.txt` 后半段已经把 staged path guard inventory 从 interpreter/fixture staging +推进到 browser OPFS boundary,最近完成的重点包括: + +- custom/ordinary/random OPFS session path constants; +- custom session INI/WASM path helpers; +- OPFS session WASM map helper; +- OPFS saved machine-file readback helper; +- 这些改动均只收敛 browser/OPFS boundary guard,未改变 OPFS bridge behavior、 + file-service、path-model、SDK planner、interpreter 或 LinuxCNC-owned runtime semantics。 + +四、当前必须保持通过的验证入口 + +每批后续改动至少运行: + +```bash +git diff --check +wasm-port/tools/verify_vendor_sync.sh +wasm-port/tools/verify_no_standalone_cnc_semantics.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_interp_browser.sh +wasm-port/tests/host/verify_host_smokes.sh +``` + +涉及 native baseline 或大范围 source/staging 改动时,再运行: + +```bash +wasm-port/tests/native/verify_nc_files.sh +wasm-port/tests/native/verify_sim_configs.sh +wasm-port/tests/native/verify_native_probes.sh +``` + +五、下一步执行计划 + +1. 当前第一候选批次。 + +继续 staged path guard inventory 第四十二轮,优先扫描 OPFS saved parameter/tool-table +readback expected text 是否还存在可安全收敛的 fixture text helper。 + +执行目标: + +- 只处理 `wasm-port/tests/browser/interp_smoke.html` 内的 browser/OPFS test glue; +- 如果 saved parameter/tool-table readback 的 expected text 重复形态明确,则抽出小 helper; +- helper 必须继续通过 `verifyExpectedOutput(...)` 做精确文本校验; +- 保持 custom session 的 direct OPFS readback 语义不变; +- 不改变 OPFS bridge behavior、file-service、path-model、SDK planner、interpreter、 + INI、tool、parameter 或 LinuxCNC-owned runtime semantics。 + +2. 第一候选批次验证。 + +执行: + +```bash +git diff --check +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_interp_browser.sh +wasm-port/tools/verify_vendor_sync.sh +wasm-port/tools/verify_no_standalone_cnc_semantics.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh +wasm-port/tests/host/verify_host_smokes.sh +``` + +如果通过,提交建议: + +```text +Guard browser OPFS saved text helper +``` + +3. 后续候选。 + +如果 saved text helper 收益不明显,转向 OPFS save result +`verifyExpectedOutput(...)` 的重复 result verification 小批收敛。 + +继续只选: + +- 已有 Node/browser coverage; +- 不依赖 HAL/task/tool DB/Python remap/user-M process; +- direct-file、generated-file、OPFS boundary 或 staging helper 已成型; +- 每批小范围收敛; +- 只做 host/filesystem/browser/OPFS boundary guard,不新增 CNC 语义。 + +暂不推进: + +- blocked runtime promotion; +- browser full 159 sim-config inventory; +- full-process/HAL/UI/Python/tool DB 执行; +- upstream intake 大批量扩面。 + +六、下一次开始执行时的第一条命令 + +从这里继续: + +```bash +git status --short && git log -5 --oneline && tail -n 120 text8.txt && awk '/^[一二三四五六七八九十百]+、/ {print}' text8.txt | sort | uniq -d +``` + +七、2026-06-14 继续执行记录:browser OPFS saved text helper guard + +本轮按第一候选批次继续 staged path guard inventory 第四十二轮,范围只触及 +`wasm-port/tests/browser/interp_smoke.html` 的 browser/OPFS test glue。 + +完成内容: + +- 新增 `verifyOpfsSavedText(...)`,统一 saved text readback 的精确文本校验入口; +- `verifyOpfsReadback(...)` 和 `verifyOpfsMachineFileReadback(...)` 均继续通过 + `verifyExpectedOutput(...)` 做精确比对; +- 将 custom INI-named / explicit session 中 saved parameter backup 与 saved + tool-table direct OPFS readback 调用收敛到统一 helper; +- 保持默认 machine-file readback 与 custom direct OPFS readback 的语义边界清晰; +- 未改变 OPFS bridge behavior、file-service、path-model、SDK planner、interpreter、 + INI、tool、parameter 或 LinuxCNC-owned runtime semantics。 + +验证已通过: + +```bash +git diff --check +wasm-port/tools/verify_vendor_sync.sh +wasm-port/tools/verify_no_standalone_cnc_semantics.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh +SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_interp_browser.sh +wasm-port/tests/host/verify_host_smokes.sh +``` + +关键输出: + +```text +vendor sync up to date +standalone CNC semantics guard complete +interp_wasm_node_smoke=ok +sim_configs_wasm_node_inventory_executed=28 +sim_configs_wasm_node_inventory_passed=28 +sim_configs_wasm_node_inventory_skipped=131 +sim_configs_wasm_node_inventory_unexpected_fail=0 +browser_interp_smoke=ok +host_wasm_opfs_browser_smokes=ok +``` + +下一步建议: + +继续小批量推进 OPFS save result 的 `verifyExpectedOutput(...)` 重复 result +verification helper。优先只收敛 `wasm-port/tests/browser/interp_smoke.html` 中 +`saveMachineParametersToOpfs(...)` / `saveMachineToolTableToOpfs(...)` 的 result +校验胶水,不改变 expected text,不触碰 runtime bridge 与 LinuxCNC 语义。 diff --git a/wasm-port/tests/browser/interp_smoke.html b/wasm-port/tests/browser/interp_smoke.html index 184e754..54ea5ac 100644 --- a/wasm-port/tests/browser/interp_smoke.html +++ b/wasm-port/tests/browser/interp_smoke.html @@ -4535,13 +4535,19 @@ ); } + async function verifyOpfsSavedText(label, loadActualText, expectedText) { + verifyExpectedOutput(label, await loadActualText(), expectedText); + } + async function verifyOpfsReadback(label, opfsPath, expectedText) { - verifyExpectedOutput(label, await loadTextFile(opfsPath), expectedText); + await verifyOpfsSavedText(label, () => loadTextFile(opfsPath), expectedText); } async function verifyOpfsMachineFileReadback(label, machineId, fileKey, expectedText) { - const machineFiles = await loadMachineTextFiles(machineId); - verifyExpectedOutput(label, machineFiles[fileKey], expectedText); + await verifyOpfsSavedText(label, async () => { + const machineFiles = await loadMachineTextFiles(machineId); + return machineFiles[fileKey]; + }, expectedText); } async function writeOpfsMachineFile(machineId, filename, text) { @@ -9524,9 +9530,9 @@ "5399\t199.000000", ].join("\n"), ); - await verifyOpfsReadback( + await verifyOpfsSavedText( "opfs_saved_ini_named_parameter_backup_text", - savedIniNamedParameters.backupOpfsPath, + () => loadTextFile(savedIniNamedParameters.backupOpfsPath), [ "5161 31.25", "5162 62.5", @@ -9570,9 +9576,9 @@ "tool_1.pocketno=8", ].join("\n"), ); - await verifyOpfsReadback( + await verifyOpfsSavedText( "opfs_saved_ini_named_tool_table_text", - loadedIniFileSession.toolTable.opfsPath, + () => loadTextFile(loadedIniFileSession.toolTable.opfsPath), [ "T8", "P8", @@ -9700,9 +9706,9 @@ "parameter_5399=202", ].join("\n"), ); - await verifyOpfsReadback( + await verifyOpfsSavedText( "opfs_saved_explicit_parameter_text", - loadedIniOverrideSession.parameters.opfsPath, + () => loadTextFile(loadedIniOverrideSession.parameters.opfsPath), [ "5161\t51.250000", "5162\t102.500000", @@ -9710,9 +9716,9 @@ "5399\t202.000000", ].join("\n"), ); - await verifyOpfsReadback( + await verifyOpfsSavedText( "opfs_saved_explicit_parameter_backup_text", - savedExplicitParameters.backupOpfsPath, + () => loadTextFile(savedExplicitParameters.backupOpfsPath), [ "5161 41.25", "5162 82.5", @@ -9744,9 +9750,9 @@ "tool_1.pocketno=9", ].join("\n"), ); - await verifyOpfsReadback( + await verifyOpfsSavedText( "opfs_saved_explicit_tool_table_text", - loadedIniOverrideSession.toolTable.opfsPath, + () => loadTextFile(loadedIniOverrideSession.toolTable.opfsPath), [ "T9", "P9",