补充 OPFS session persistence release gate 文档

This commit is contained in:
2026-06-15 22:33:16 +08:00
parent f3d8955fd7
commit 98ee77f086
7 changed files with 343 additions and 8 deletions

View File

@@ -9,7 +9,7 @@ turn-by-turn continuation notes and next-batch execution records.
## Current Status ## Current Status
- Active continuation file: `text14.txt` - Active continuation file: `text14.txt`
- Latest completed batch: SDK/API surface exports and smoke - Latest completed batch: OPFS/session persistence release-gate docs
- Latest relevant commit: use `git log -1 --oneline` after each committed batch - Latest relevant commit: use `git log -1 --oneline` after each committed batch
- Working tree at tracker creation: clean - Working tree at tracker creation: clean
- Required policy: LinuxCNC remains the only CNC semantic source - Required policy: LinuxCNC remains the only CNC semantic source
@@ -41,12 +41,12 @@ The project is complete for the current scope when all of the following are true
| Sim config inventory | Stable with skips | `executed=28`, `passed=28`, `skipped=131`, `unexpected_fail=0`. | | Sim config inventory | Stable with skips | `executed=28`, `passed=28`, `skipped=131`, `unexpected_fail=0`. |
| Native nc_files baseline | Stable | Last recorded Layer 1: `total 107`, `pass 101`, `expected_fail 6`, `unexpected_fail 0`. | | Native nc_files baseline | Stable | Last recorded Layer 1: `total 107`, `pass 101`, `expected_fail 6`, `unexpected_fail 0`. |
| Native sim configs baseline | Stable | Last recorded Layer 2: `total 159`, `pass 151`, `expected_fail 8`, `unexpected_fail 0`. | | Native sim configs baseline | Stable | Last recorded Layer 2: `total 159`, `pass 151`, `expected_fail 8`, `unexpected_fail 0`. |
| OPFS/session persistence | In progress | Browser smoke passes and SDK re-exports OPFS/session helpers; final project needs explicit project-level summary/report. | | OPFS/session persistence | In progress | Browser smoke passes, SDK re-exports OPFS/session helpers, and `docs/opfs-session-persistence.md` defines the project-level release gate. |
| SDK/API surface | In progress | SDK re-exports core, OPFS/session, sim-config staging, and INI panel shell/workflow overview helpers with a Node surface smoke. | | SDK/API surface | In progress | SDK re-exports core, OPFS/session, sim-config staging, and INI panel shell/workflow overview helpers with a Node surface smoke. |
| Browser/UI workflow | In progress | Workflow overview embedding mount DOM closure is complete; current focus is SDK/docs/release gate consolidation. | | Browser/UI workflow | In progress | Workflow overview embedding mount DOM closure is complete; current focus is SDK/docs/release gate consolidation. |
| Workflow overview embedding | In progress | Report/display/render, DOM contract/readiness/renderer, mount result/display/render, mount DOM contract/readiness/renderer/wrapper exist. | | Workflow overview embedding | In progress | Report/display/render, DOM contract/readiness/renderer, mount result/display/render, mount DOM contract/readiness/renderer/wrapper exist. |
| Host/runtime boundary proof | In progress | Host smoke passes; runtime families below remain blocked. | | Host/runtime boundary proof | In progress | Host smoke passes; runtime families below remain blocked. |
| Documentation/release gate | In progress | `text14.txt` has roadmap; README/docs final pass still pending. | | Documentation/release gate | In progress | OPFS/session release gate is documented and smoke-tested; sim-config coverage and final README/docs pass still pending. |
## Blocked Runtime Families ## Blocked Runtime Families
@@ -74,7 +74,7 @@ Execute these in order unless a later user request explicitly changes priority.
Current next task: Current next task:
- Add project-level OPFS/session persistence summary and release-gate documentation. - Consolidate sim-config coverage/release-gate docs and machine-readable skip reason handoff.
Then complete the closure: Then complete the closure:
@@ -121,17 +121,19 @@ Completion criteria:
Work items: Work items:
- Add a project-level OPFS/session workflow summary helper or report. - Add a project-level OPFS/session workflow summary helper or report. Done as `docs/opfs-session-persistence.md`.
- Include machine files, session snapshot, readonly control status, and handoff - Include machine files, session snapshot, readonly control status, and handoff
readiness. readiness. Done through linked UI docs plus browser and host gate references.
- Add browser smoke coverage for save -> restore -> readonly status -> shell - Add browser smoke coverage for save -> restore -> readonly status -> shell
handoff. handoff. Existing browser smoke remains the gate for this workflow.
- Document OPFS scope and failure modes. - Document OPFS scope and failure modes. Done.
- Add docs smoke for the project-level handoff. Done via `tests/docs/node/verify_opfs_session_docs.sh`.
Completion criteria: Completion criteria:
- `browser_ini_opfs_smoke=ok` remains stable. - `browser_ini_opfs_smoke=ok` remains stable.
- External callers can inspect persistence readiness and failures. - External callers can inspect persistence readiness and failures.
- `opfs_session_docs_node_smoke=ok` is included in the host aggregate gate.
### 4. Sim Config Coverage Promotion Matrix ### 4. Sim Config Coverage Promotion Matrix

View File

@@ -999,3 +999,125 @@ host_wasm_opfs_browser_smokes=ok
OPFS/session persistence summary 或 release workflow 文档,串联 SDK stable imports、browser OPFS/session persistence summary 或 release workflow 文档,串联 SDK stable imports、browser
OPFS smoke、session snapshot/machine-file helpers、host gate 命令和 blocked runtime family 说明; OPFS smoke、session snapshot/machine-file helpers、host gate 命令和 blocked runtime family 说明;
优先让新接手者能按文档复现支持面与验证入口,不扩大 CNC 语义边界。 优先让新接手者能按文档复现支持面与验证入口,不扩大 CNC 语义边界。
十三、2026-06-15 继续执行记录OPFS/session persistence release-gate docs
本轮按 `text14.txt` 执行,继续推进 OPFS/session persistence 与 release-gate 文档收口。新增
项目级 OPFS/session persistence handoff 文档,串联 SDK stable imports、browser OPFS smoke、
session snapshot/machine-file helpers、host gate 命令和 blocked runtime family 说明。
完成内容:
- 新增 `wasm-port/docs/opfs-session-persistence.md`
- 文档定义项目级 OPFS/session persistence 支持面:
- OPFS text/file helpers
- OPFS path helpers
- session snapshot helpers
- machine file and G-code helpers
- parameter/tool-table OPFS bridge helpers
- `loadMachineSessionFromOpfs()`
- UI/session helper docs 入口;
- 文档记录 persistence workflow
- machine INI/parameter/tool-table OPFS 保存路径;
- optional G-code OPFS 保存路径;
- session snapshot OPFS 保存路径;
- `loadMachineSessionFromOpfs()` 如何使用 LinuxCNC-backed INI SDK 读取
`[RS274NGC]PARAMETER_FILE`、`[EMCIO]TOOL_TABLE` 与
`[EMCIO]RANDOM_TOOLCHANGER`
- parameter/tool-table bridge 如何复制 OPFS text 到 WASM FS 并调用 LinuxCNC-backed
interpreter SDK
- 文档记录 browser OPFS/session smoke
- `browser_ini_opfs_smoke=ok`
- `browser_ini_control_page_smoke=ok`
- `browser_ini_launch_smoke=ok`
- `browser_ini_workflow_overview_smoke=ok`
- `browser_ini_shell_integration_workflow_smoke=ok`
- 文档记录 release gate 命令:
- `git diff --check`
- vendor/source guard
- SDK surface smoke
- OPFS file-service smoke
- UI Node smoke
- interpreter WASM smoke
- sim-config inventory WASM smoke
- browser INI panel smoke
- host aggregate smoke
- 文档记录仍 blocked 的 runtime families
- `L4-USER-M-PROCESS`
- `L4-TOOL-DB`
- `L4-PYTHON-REMAP`
- 文档明确 OPFS/session persistence 不解锁 full LinuxCNC runtime family不执行 opt-in runtime probes
- 文档记录 failure modes
- missing OPFS support
- invalid OPFS paths
- invalid snapshot format/version/session id/payload/machine id
- missing host files
- tool/parameter/remap/planner/kinematics 仍由 LinuxCNC-owned runtime semantics 提供;
- `wasm-port/README.md` 增加 `docs/opfs-session-persistence.md` 项目级入口;
- 新增 `wasm-port/tests/docs/node/verify_opfs_session_docs.mjs`
- 新增 `wasm-port/tests/docs/node/verify_opfs_session_docs.sh`
- docs smoke 覆盖:
- OPFS/session release-gate 文档存在;
- SDK stable entrypoint 记录;
- persistence helpers 记录;
- browser/host gate 输出记录;
- blocked runtime family 记录;
- README、SDK README、host smoke 与 browser smoke 交叉引用;
- `wasm-port/tests/host/verify_host_smokes.sh` 纳入
`wasm-port/tests/docs/node/verify_opfs_session_docs.sh`
- `PROJECT_COMPLETION_TRACKER.md` 同步当前完成批次与下一步 sim-config coverage/release-gate docs
- 未新增控制按钮;
- 未执行 action-plan
- 未解析 G-code
- 未解释 canonical events
- 未新增 JS CNC 语义;
- 未改变 LinuxCNC interpreter、tool、parameter、planner、kinematics 或 LinuxCNC-owned runtime
semantics。
验证已通过:
```bash
git diff --check
wasm-port/tests/docs/node/verify_opfs_session_docs.sh
wasm-port/tests/sdk/node/verify_sdk_surface.sh
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_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
opfs_session_docs_node_smoke=ok
sdk_surface_node_smoke=ok
ini_panel_ui_shell_node_smoke=ok
ini_panel_launch_api_manifest_node_smoke=ok
ini_panel_shell_integration_manifest_node_smoke=ok
ini_panel_entry_docs_node_smoke=ok
ui_node_smokes=ok
browser_ini_opfs_smoke=ok
browser_ini_control_page_smoke=ok
browser_ini_launch_smoke=ok
browser_ini_workflow_overview_smoke=ok
browser_ini_shell_integration_workflow_smoke=ok
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
host_wasm_opfs_browser_smokes=ok
```
下一步工作计划:
继续推进 sim-config coverage/release-gate 文档收口。下一批建议新增或收敛
sim-config coverage handoff 文档/测试,明确 `ASSET_ONLY`、`L4_PYTHON_REMAP`、`L4_TOOL_DB`、
`L4_USER_M_PROCESS`、`NON_MAIN_CLASS`、`UPSTREAM_DEMO` 等 skip reasons 与当前 inventory
输出之间的对应关系,并把 release gate 中的 `sim_configs_wasm_node_inventory_*` 输出作为
机器可审计基线;仍不 promotion blocked runtime family不扩大 CNC 语义边界。

View File

@@ -130,5 +130,8 @@ Directory intent:
- `tests/fixtures/`: stable simulation inputs shared by native and browser tests. - `tests/fixtures/`: stable simulation inputs shared by native and browser tests.
- `build/` and `dist/`: generated outputs only; never hand-edited. - `build/` and `dist/`: generated outputs only; never hand-edited.
Project-level OPFS/session persistence and release-gate handoff is documented in
`docs/opfs-session-persistence.md`.
The presence of this directory means the port is managed independently of the The presence of this directory means the port is managed independently of the
native LinuxCNC tree even though LinuxCNC remains the semantic source of truth. native LinuxCNC tree even though LinuxCNC remains the semantic source of truth.

View File

@@ -0,0 +1,160 @@
# OPFS/session persistence and release gate
This document is the project-level handoff for OPFS/session persistence in the
LinuxCNC WASM/browser port. It links the stable SDK entrypoint, browser smoke,
session snapshot helpers, machine-file helpers, host gate commands, and blocked
runtime family policy in one place.
## Supported surface
Stable external imports come from `runtime/sdk/src/index.js`.
OPFS text/file helpers:
- `getOpfsRoot()`
- `saveTextFile()`
- `loadTextFile()`
- `machineIniPath()`
- `toolTablePath()`
- `parameterFilePath()`
- `gcodeProgramPath()`
- `sessionSnapshotPath()`
- `defaultMachinePaths()`
- `normalizeOpfsPath()`
Session snapshot helpers:
- `createMachineSessionSnapshotPayload()`
- `createSessionSnapshot()`
- `saveSessionSnapshot()`
- `saveMachineSessionSnapshot()`
- `loadSessionSnapshot()`
- `loadMachineSessionSnapshot()`
- `validateSessionSnapshot()`
Machine file and program helpers:
- `machineFilePaths()`
- `saveMachineTextFiles()`
- `loadMachineTextFiles()`
- `saveGcodeProgram()`
- `loadGcodeProgram()`
- `gcodeFilenameFromProgramPath()`
LinuxCNC-backed OPFS bridges:
- `restoreMachineParametersFromOpfs()`
- `saveMachineParametersToOpfs()`
- `loadMachineToolTableFromOpfs()`
- `saveMachineToolTableToOpfs()`
- `loadMachineSessionFromOpfs()`
Browser UI/session helpers are documented in:
- `docs/ui-session-summary-helpers.md`
- `docs/ui-machine-file-helpers.md`
- `docs/ui-run-summary-helpers.md`
- `docs/ui-panel-state-summary.md`
- `docs/panel-entry.md`
## Persistence workflow
The browser/UI persistence workflow is host-side only:
1. The UI saves machine INI, parameter, and tool-table text under
`linuxcnc/machines/<machine-id>/`.
2. Optional G-code programs are saved under `linuxcnc/gcode/`.
3. A session snapshot is saved under `linuxcnc/sessions/<session-id>/`.
4. `loadMachineSessionFromOpfs()` loads the persisted INI text, copies it into
the interpreter WASM filesystem, and uses the LinuxCNC-backed INI SDK to read
`[RS274NGC]PARAMETER_FILE`, `[EMCIO]TOOL_TABLE`, and
`[EMCIO]RANDOM_TOOLCHANGER` when explicit host options do not override them.
5. Parameter and tool-table bridge helpers copy OPFS text into the interpreter
WASM filesystem and then call LinuxCNC-backed interpreter SDK methods such as
`restoreParameters()`, `saveParameters()`, `loadToolTable()`, and
`saveToolTable()`.
This workflow stores host files and stages them into Emscripten FS. It does not
implement G-code, tool-table, parameter-file, planner, remap, or kinematics
semantics in JavaScript.
## Verified browser workflows
The aggregate browser gate is:
```bash
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
```
Required output:
```text
browser_ini_opfs_smoke=ok
browser_ini_control_page_smoke=ok
browser_ini_launch_smoke=ok
browser_ini_workflow_overview_smoke=ok
browser_ini_shell_integration_workflow_smoke=ok
```
`browser_ini_opfs_smoke=ok` covers real browser OPFS/session persistence,
including INI text persistence, session snapshots, machine-file helpers,
G-code program helpers, and the INI panel frame workflow.
## Release gate
Run the project-level gate before claiming a release-ready OPFS/session or SDK
surface:
```bash
git diff --check
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
wasm-port/tests/sdk/node/verify_sdk_surface.sh
wasm-port/tests/opfs/node/verify_file_service.sh
wasm-port/tests/ui/node/verify_ui_node_smokes.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_ini_panel_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
```
The host aggregate must include:
```text
opfs_file_service_node_smoke=ok
sdk_surface_node_smoke=ok
ui_node_smokes=ok
browser_ini_opfs_smoke=ok
browser_ini_shell_integration_workflow_smoke=ok
host_wasm_opfs_browser_smokes=ok
```
## Blocked runtime families
OPFS/session persistence does not unblock full LinuxCNC runtime families. These
remain blocked until a LinuxCNC-owned runtime proof exists and native,
Node/WASM, browser, and host gates all pass in that order:
- `L4-USER-M-PROCESS`
- `L4-TOOL-DB`
- `L4-PYTHON-REMAP`
Do not run the opt-in runtime probes on a host that lacks the required LinuxCNC
runtime processes:
```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
```
## Failure modes
- Missing OPFS support returns an OPFS availability error from `getOpfsRoot()`.
- Invalid OPFS paths are rejected before storage access.
- Invalid snapshot format, version, session id, payload, or machine id is
rejected by snapshot validation helpers.
- Missing INI, parameter, or tool-table OPFS files remain host persistence
errors. JavaScript does not synthesize LinuxCNC machine state.
- Tool, parameter, remap, planner, and kinematics behavior remains owned by
vendored LinuxCNC source and the C/WASM ABI.

View File

@@ -0,0 +1,41 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname, "../../..");
const docText = readFileSync(resolve(root, "docs/opfs-session-persistence.md"), "utf8");
const readmeText = readFileSync(resolve(root, "README.md"), "utf8");
const sdkReadmeText = readFileSync(resolve(root, "runtime/sdk/README.md"), "utf8");
const hostSmokeText = readFileSync(resolve(root, "tests/host/verify_host_smokes.sh"), "utf8");
const browserSmokeText = readFileSync(resolve(root, "tests/browser/verify_ini_panel_browser.sh"), "utf8");
const trackerText = readFileSync(resolve(root, "../PROJECT_COMPLETION_TRACKER.md"), "utf8");
for (const phrase of [
"OPFS/session persistence and release gate",
"runtime/sdk/src/index.js",
"createMachineSessionSnapshotPayload",
"loadMachineSessionFromOpfs",
"restoreMachineParametersFromOpfs",
"loadMachineToolTableFromOpfs",
"browser_ini_opfs_smoke=ok",
"sdk_surface_node_smoke=ok",
"host_wasm_opfs_browser_smokes=ok",
"verify_no_standalone_cnc_semantics.sh",
"L4-USER-M-PROCESS",
"L4-TOOL-DB",
"L4-PYTHON-REMAP",
]) {
assert.match(docText, new RegExp(phrase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));
}
assert.match(readmeText, /docs\/opfs-session-persistence\.md/);
assert.match(sdkReadmeText, /OPFS\/session persistence exports/);
assert.match(hostSmokeText, /verify_sdk_surface\.sh/);
assert.match(hostSmokeText, /verify_file_service\.sh/);
assert.match(browserSmokeText, /browser_ini_opfs_smoke=ok/);
assert.match(trackerText, /OPFS\/session persistence/);
console.log("opfs_session_docs_node_smoke=ok");

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
node "$ROOT_DIR/tests/docs/node/verify_opfs_session_docs.mjs"

View File

@@ -14,6 +14,7 @@ SKIP_INTERP_BUILD=1 "$ROOT_DIR/tests/wasm/node/verify_nc_files_wasm.sh"
SKIP_TP_BUILD=1 "$ROOT_DIR/tests/wasm/node/verify_tp_wasm.sh" SKIP_TP_BUILD=1 "$ROOT_DIR/tests/wasm/node/verify_tp_wasm.sh"
"$ROOT_DIR/tests/opfs/node/verify_file_service.sh" "$ROOT_DIR/tests/opfs/node/verify_file_service.sh"
"$ROOT_DIR/tests/sdk/node/verify_sdk_surface.sh" "$ROOT_DIR/tests/sdk/node/verify_sdk_surface.sh"
"$ROOT_DIR/tests/docs/node/verify_opfs_session_docs.sh"
"$ROOT_DIR/tests/ui/node/verify_ui_node_smokes.sh" "$ROOT_DIR/tests/ui/node/verify_ui_node_smokes.sh"
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 "$ROOT_DIR/tests/browser/verify_ini_panel_browser.sh" SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 "$ROOT_DIR/tests/browser/verify_ini_panel_browser.sh"
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 "$ROOT_DIR/tests/browser/verify_interp_browser.sh" SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 "$ROOT_DIR/tests/browser/verify_interp_browser.sh"