diff --git a/docs/linuxcnc-source-policy.md b/docs/linuxcnc-source-policy.md index 4c44ead..0c7784d 100644 --- a/docs/linuxcnc-source-policy.md +++ b/docs/linuxcnc-source-policy.md @@ -16,6 +16,10 @@ Hard rules: LinuxCNC source before implementation. - Browser-side wasm filesystem behavior must use OPFS-backed storage. Do not add browser filesystem paths that bypass OPFS. +- Browser app and wasm bridge code must not persist CNC programs, LinuxCNC + parameter files, or mirrored workspace files through non-OPFS browser storage + APIs such as Local Storage, IndexedDB, File Picker writes, WebKit filesystem + APIs, or FileReader-backed import paths. Allowed project code: @@ -61,6 +65,8 @@ Efficiency rules: permission to expand the pass into another workstream. - Do not add a smoke-only behavior path when the LinuxCNC-backed route already exists; add coverage to the source-backed route instead. +- Keep browser filesystem guardrails negative as well as positive: require the + OPFS bridge and reject browser app/wasm storage APIs that could bypass it. - Smoke tests are verification guardrails. They must not be expanded with new functional CNC behavior unless that behavior is directly routed to, copied from, or checked against the relevant LinuxCNC source in the same narrow diff --git a/test-all-native.sh b/test-all-native.sh index ff895ee..5e255f7 100755 --- a/test-all-native.sh +++ b/test-all-native.sh @@ -504,6 +504,9 @@ grep -F 'cached `nm --defined-only` symbol export signatures' docs/linuxcnc-sour grep -F 'Cache wasm blocker analyzer output' docs/linuxcnc-source-policy.md >/dev/null grep -F 'signature must include the blocker wrapper script, analyzer script' docs/linuxcnc-source-policy.md >/dev/null grep -F 'sha256sum test-linuxcnc-wasm-blockers.sh' test-linuxcnc-wasm-blockers.sh >/dev/null +grep -F 'browser app/wasm code must not add filesystem persistence outside OPFS' test-native.sh >/dev/null +grep -F 'browser app/wasm code must not add filesystem persistence outside OPFS' test-linuxcnc-wasm-cmake-safe-probe.sh >/dev/null +grep -F 'reject browser app/wasm storage APIs that could bypass it' docs/linuxcnc-source-policy.md >/dev/null grep -F 'Persistent native, source-link, source-syntax, and wasm-safe CMake probe' docs/linuxcnc-source-policy.md >/dev/null grep -F 'copies and byte-compares `cnc_sim.js` and `cnc_sim.wasm` under' docs/linuxcnc-source-policy.md >/dev/null grep -F '`CNC_SIM_BUILD_JOBS` must be a positive integer and defaults to `8`.' docs/linuxcnc-source-policy.md >/dev/null diff --git a/test-linuxcnc-wasm-cmake-safe-probe.sh b/test-linuxcnc-wasm-cmake-safe-probe.sh index 4242203..3383358 100755 --- a/test-linuxcnc-wasm-cmake-safe-probe.sh +++ b/test-linuxcnc-wasm-cmake-safe-probe.sh @@ -753,6 +753,10 @@ grep -F -- './test-web-wasm-node-smoke.sh' build-wasm.sh >/dev/null grep -F -- './test-web-wasm-browser-smoke.sh' build-wasm.sh >/dev/null grep -F 'const opfsOptions = options.opfs ?? (isOpfsAvailable() ? {} : false)' web/src/wasm-core.js >/dev/null grep -F 'OPFS cannot be disabled in browser contexts with OPFS support' web/src/wasm-core.js >/dev/null +if grep -R -n -E 'localStorage|sessionStorage|indexedDB|showOpenFilePicker|showSaveFilePicker|webkitRequestFileSystem|FileReader' web/src; then + echo "browser app/wasm code must not add filesystem persistence outside OPFS" >&2 + exit 1 +fi grep -F 'async function opfsEntryExists(workspacePath, relativePath)' web/src/wasm-core.js >/dev/null grep -F 'async function statOpfsEntry(workspacePath, relativePath)' web/src/wasm-core.js >/dev/null grep -F 'async function readOpfsDirectoryTree(workspacePath, relativePath, relativeRoot = "")' web/src/wasm-core.js >/dev/null diff --git a/test-native.sh b/test-native.sh index d4fc6f0..f642e6e 100755 --- a/test-native.sh +++ b/test-native.sh @@ -227,6 +227,10 @@ grep -F '"parameters/rs274ngc.var"' web/test-browser-wasm-smoke-opfs-parameter-s grep -F '"parameters/rs274ngc.var.bak"' web/test-browser-wasm-smoke-opfs-parameter-sections.js >/dev/null grep -F 'const opfsOptions = options.opfs ?? (isOpfsAvailable() ? {} : false)' web/src/wasm-core.js >/dev/null grep -F 'OPFS cannot be disabled in browser contexts with OPFS support' web/src/wasm-core.js >/dev/null +if grep -R -n -E 'localStorage|sessionStorage|indexedDB|showOpenFilePicker|showSaveFilePicker|webkitRequestFileSystem|FileReader' web/src; then + echo "browser app/wasm code must not add filesystem persistence outside OPFS" >&2 + exit 1 +fi grep -F 'LinuxCNC source basis: rs274ngc_pre.cc restore_parameters() reads the' web/src/wasm-core.js >/dev/null grep -F 'before replacing the main file and managing filename + ".bak".' web/src/wasm-core.js >/dev/null grep -F 'await removeOpfsEntry(workspacePath, `${path}.new`, false);' web/src/wasm-core.js >/dev/null