From ea2537e4e323f3f47c458be40039ced8162dd722 Mon Sep 17 00:00:00 2001 From: wangdequan Date: Sat, 13 Jun 2026 19:50:02 +0800 Subject: [PATCH] Guard OPFS bridge path staging --- text7.txt | 70 ++++++++++ .../tests/opfs/node/verify_file_service.mjs | 122 +++++++++++++++++- 2 files changed, 191 insertions(+), 1 deletion(-) diff --git a/text7.txt b/text7.txt index d67e350..fee55c2 100644 --- a/text7.txt +++ b/text7.txt @@ -1752,3 +1752,73 @@ semantics。 ```bash git status --short && git log -5 --oneline && tail -n 120 text7.txt && awk '/^[一二三四五六七八九十百]+、/ {print}' text7.txt | sort | uniq -d ``` + +三十、2026-06-13 继续执行记录:OPFS bridge path staging guard + +1. 本批目标。 + +继续 staged path guard inventory 第二十五轮,处理 OPFS bridge default path helpers: + +```text +restoreMachineParametersFromOpfs(...) +saveMachineParametersToOpfs(...) +loadMachineToolTableFromOpfs(...) +saveMachineToolTableToOpfs(...) +loadMachineSessionFromOpfs(...) +``` + +2. 已完成改动。 + +- Node OPFS smoke 新增 `assertParameterBridgePaths(...)`; +- Node OPFS smoke 新增 `assertToolTableBridgePaths(...)`; +- Node OPFS smoke 新增 `assertSessionBridgePaths(...)`; +- `restoreMachineParametersFromOpfs(...)` 覆盖 custom WASM path 与默认 + `/work/linuxcnc.var` path guard; +- `saveMachineParametersToOpfs(...)` 覆盖 custom WASM path 与默认 + `/work/linuxcnc.var` path guard; +- `loadMachineToolTableFromOpfs(...)` 覆盖 custom WASM path 与默认 `/work/tool.tbl` + path guard; +- `saveMachineToolTableToOpfs(...)` 覆盖 custom WASM path 与默认 `/work/tool.tbl` + path guard; +- `loadMachineSessionFromOpfs(...)` 覆盖 custom WASM path 与默认 + `/work/machine.ini`、`/work/linuxcnc.var`、`/work/tool.tbl` path guard; +- 未修改 OPFS bridge behavior、file-service、path-model 或 runtime semantics。 + +涉及文件: + +```text +wasm-port/tests/opfs/node/verify_file_service.mjs +``` + +3. 已完成验证。 + +```bash +git diff --check +wasm-port/tests/opfs/node/verify_file_service.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 +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 +Guard OPFS bridge path staging +``` + +4. 下一步工作建议。 + +继续 staged path guard inventory 第二十六轮,优先扫描 SDK staging helpers 与 OPFS bridge +之间的边界散点,例如 SDK sim-config staging artifact 中的 path map、machine config +staging helper 或 browser smoke 中仍存在的 inline path strip;仍只加 filesystem/OPFS/ +SDK boundary guard,不改变 LinuxCNC-owned interpreter、INI、tool、parameter 或 runtime +semantics。 + +下一轮第一条命令仍保持: + +```bash +git status --short && git log -5 --oneline && tail -n 120 text7.txt && awk '/^[一二三四五六七八九十百]+、/ {print}' text7.txt | sort | uniq -d +``` diff --git a/wasm-port/tests/opfs/node/verify_file_service.mjs b/wasm-port/tests/opfs/node/verify_file_service.mjs index 095b7a9..eeaa7b9 100644 --- a/wasm-port/tests/opfs/node/verify_file_service.mjs +++ b/wasm-port/tests/opfs/node/verify_file_service.mjs @@ -131,6 +131,62 @@ function assertMachineFileStoragePaths(machineId, paths) { ); } +function assertParameterBridgePaths( + machineId, + result, + wasmPath, + filename = "linuxcnc.var", +) { + assert.equal( + result.opfsPath, + `linuxcnc/machines/${machineId}/${filename}`, + `${machineId}/${filename} parameter bridge OPFS path drift`, + ); + assert.equal( + result.wasmPath, + wasmPath, + `${machineId}/${filename} parameter bridge WASM path drift`, + ); +} + +function assertToolTableBridgePaths( + machineId, + result, + wasmPath, + filename = "tool.tbl", +) { + assert.equal( + result.opfsPath, + `linuxcnc/machines/${machineId}/${filename}`, + `${machineId}/${filename} tool table bridge OPFS path drift`, + ); + assert.equal( + result.wasmPath, + wasmPath, + `${machineId}/${filename} tool table bridge WASM path drift`, + ); +} + +function assertSessionBridgePaths( + machineId, + result, + { + iniWasmPath = "/work/machine.ini", + parameterWasmPath = "/work/linuxcnc.var", + toolTableWasmPath = "/work/tool.tbl", + } = {}, +) { + assert.equal(result.machineId, machineId, `${machineId} session machine id drift`); + assert.equal( + result.ini.opfsPath, + `linuxcnc/machines/${machineId}/machine.ini`, + `${machineId} session INI OPFS path drift`, + ); + assert.equal(result.ini.wasmPath, iniWasmPath, `${machineId} session INI WASM path drift`); + assertParameterBridgePaths(machineId, result.parameters, parameterWasmPath); + assertToolTableBridgePaths(machineId, result.toolTable, toolTableWasmPath); +} + assert.equal(await getOpfsRoot(storage), root); assert.equal(normalizeOpfsPath("linuxcnc/machines/xyzab.ini"), "linuxcnc/machines/xyzab.ini"); @@ -369,6 +425,19 @@ assert.deepEqual(restoredParameters, { result: "restore_parameters=0\nrestore_path=/work/bridge.var\n", }); assert.equal(bridgeFiles.get("/work/bridge.var"), "5161 0.0\n5162 0.0\n"); +assertParameterBridgePaths("xyzab-tdr", restoredParameters, "/work/bridge.var"); + +const restoredDefaultParameters = await restoreMachineParametersFromOpfs( + bridgeInterp, + "xyzab-tdr", + { storage }, +); +assertParameterBridgePaths("xyzab-tdr", restoredDefaultParameters, "/work/linuxcnc.var"); +assert.equal( + restoredDefaultParameters.result, + "restore_parameters=0\nrestore_path=/work/linuxcnc.var\n", +); +assert.equal(bridgeFiles.get("/work/linuxcnc.var"), "5161 0.0\n5162 0.0\n"); const savedParameters = await saveMachineParametersToOpfs( bridgeInterp, @@ -376,7 +445,7 @@ const savedParameters = await saveMachineParametersToOpfs( { 5161: 12.34, 5162: 56.78 }, { storage, wasmPath: "/work/bridge.var" }, ); -assert.equal(savedParameters.opfsPath, "linuxcnc/machines/xyzab-tdr/linuxcnc.var"); +assertParameterBridgePaths("xyzab-tdr", savedParameters, "/work/bridge.var"); assert.equal(savedParameters.backupOpfsPath, "linuxcnc/machines/xyzab-tdr/linuxcnc.var.bak"); assert.equal(savedParameters.result.includes("save_parameters=0"), true); assert.equal( @@ -387,6 +456,18 @@ assert.equal( await loadTextFile("linuxcnc/machines/xyzab-tdr/linuxcnc.var.bak", storage), "5161 0.0\n5162 0.0\n", ); +const savedDefaultParameters = await saveMachineParametersToOpfs( + bridgeInterp, + "xyzab-tdr", + { 5161: 12.34 }, + { storage }, +); +assertParameterBridgePaths("xyzab-tdr", savedDefaultParameters, "/work/linuxcnc.var"); +assert.equal( + savedDefaultParameters.backupOpfsPath, + "linuxcnc/machines/xyzab-tdr/linuxcnc.var.bak", +); +assert.equal(savedDefaultParameters.result.includes("save_path=/work/linuxcnc.var"), true); const loadedToolTable = await loadMachineToolTableFromOpfs( bridgeInterp, @@ -399,6 +480,19 @@ assert.deepEqual(loadedToolTable, { result: "tooldata_load=0\nload_tool_path=/work/bridge-tool.tbl\nrandom_toolchanger=0\n", }); assert.equal(bridgeFiles.get("/work/bridge-tool.tbl"), "T0 P0 ; no tool\nT2 P2 Z1.25 D0.25\n"); +assertToolTableBridgePaths("xyzab-tdr", loadedToolTable, "/work/bridge-tool.tbl"); + +const loadedDefaultToolTable = await loadMachineToolTableFromOpfs( + bridgeInterp, + "xyzab-tdr", + { storage }, +); +assertToolTableBridgePaths("xyzab-tdr", loadedDefaultToolTable, "/work/tool.tbl"); +assert.equal( + loadedDefaultToolTable.result, + "tooldata_load=0\nload_tool_path=/work/tool.tbl\nrandom_toolchanger=0\n", +); +assert.equal(bridgeFiles.get("/work/tool.tbl"), "T0 P0 ; no tool\nT2 P2 Z1.25 D0.25\n"); const loadedRandomToolTable = await loadMachineToolTableFromOpfs( bridgeInterp, @@ -419,11 +513,19 @@ const savedToolTable = await saveMachineToolTableToOpfs( ); assert.equal(savedToolTable.opfsPath, "linuxcnc/machines/xyzab-tdr/tool.tbl"); assert.equal(savedToolTable.wasmPath, "/work/bridge-tool.tbl"); +assertToolTableBridgePaths("xyzab-tdr", savedToolTable, "/work/bridge-tool.tbl"); assert.equal(savedToolTable.result.includes("tooldata_save=0"), true); assert.equal( await loadTextFile("linuxcnc/machines/xyzab-tdr/tool.tbl", storage), "T2 P2 Z+1.250000 D+0.250000 ;loaded by LinuxCNC\n", ); +const savedDefaultToolTable = await saveMachineToolTableToOpfs( + bridgeInterp, + "xyzab-tdr", + { storage }, +); +assertToolTableBridgePaths("xyzab-tdr", savedDefaultToolTable, "/work/tool.tbl"); +assert.equal(savedDefaultToolTable.result.includes("save_tool_path=/work/tool.tbl"), true); const loadedSession = await loadMachineSessionFromOpfs( bridgeInterp, @@ -452,6 +554,11 @@ assert.deepEqual(loadedSession, { result: "tooldata_load=0\nload_tool_path=/work/session-tool.tbl\nrandom_toolchanger=0\n", }, }); +assertSessionBridgePaths("xyzab-tdr", loadedSession, { + iniWasmPath: "/work/session.ini", + parameterWasmPath: "/work/session.var", + toolTableWasmPath: "/work/session-tool.tbl", +}); assert.equal(bridgeFiles.get("/work/session.ini"), "[EMC]\nMACHINE = xyzab-tdr\n"); assert.equal(bridgeFiles.get("/work/session.var"), "5161\t12.340000\n5162\t56.780000\n"); assert.equal( @@ -459,6 +566,19 @@ assert.equal( "T2 P2 Z+1.250000 D+0.250000 ;loaded by LinuxCNC\n", ); +const loadedDefaultSession = await loadMachineSessionFromOpfs( + bridgeInterp, + "xyzab-tdr", + { storage }, +); +assertSessionBridgePaths("xyzab-tdr", loadedDefaultSession); +assert.equal(bridgeFiles.get("/work/machine.ini"), "[EMC]\nMACHINE = xyzab-tdr\n"); +assert.equal(bridgeFiles.get("/work/linuxcnc.var"), "5161\t12.340000\n5162\t56.780000\n"); +assert.equal( + bridgeFiles.get("/work/tool.tbl"), + "T2 P2 Z+1.250000 D+0.250000 ;loaded by LinuxCNC\n", +); + const loadedRandomSession = await loadMachineSessionFromOpfs( bridgeInterp, "xyzab-tdr",