# 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()`
- `readMachineSessionReadiness()`

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()`.

External callers can run `readMachineSessionReadiness()` before step 4 to get a
structured `ready`/`blocked` report for persisted INI, parameter, tool-table,
optional G-code, and optional session snapshot files. This helper only checks
host file availability and snapshot envelope validity.

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.
- `readMachineSessionReadiness()` reports missing files or invalid snapshots as
  structured blocked checks before callers load a session into WASM.
- 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.
