Files
cnc_wams/wasm-port/docs/source-reuse-map.md
2026-06-09 06:13:28 +08:00

125 lines
24 KiB
Markdown

# Source Reuse Map
## Purpose
This map records which LinuxCNC source files are currently vendored into the
standalone WASM port, why they are present, which standalone boundary they
touch, and how the port verifies that they still come directly from upstream
LinuxCNC.
The authoritative extraction list is `tools/source-manifest.txt`. The upstream
baseline is recorded in `tools/upstream-baseline.txt` and
`docs/scope-and-baseline.md`.
## Validation Contract
Current validation is intentionally mechanical:
- `tools/verify_upstream_baseline.sh` checks that `../linuxcnc` is at the
recorded upstream commit.
- `tools/verify_vendor_sync.sh` checks that every manifest file exists in
`vendor/linuxcnc/`, that no extra vendored file exists, and that each
vendored file is byte-identical to the matching upstream file.
- `tools/build_native_probes.sh` builds source-level native compile probes for
every `.c` and `.cc` file in the manifest.
- `tests/native/verify_native_probes.sh` checks that every manifest `.c` and
`.cc` file has a matching source probe in `build/native/source-probes.tsv`.
- `tools/verify_no_standalone_cnc_semantics.sh` rejects standalone
`Interp::...` member definitions outside `vendor/linuxcnc/`, except for the
documented Python/remap runtime-edge stubs in
`runtime/core/linuxcnc_wrap/linuxcnc_interp_edge_stubs.cpp`.
## Reuse Matrix
| Capability | LinuxCNC source files | Port classification | Standalone boundary | Current validation |
| --- | --- | --- | --- | --- |
| INI parsing | `src/emc/ini/inifile.cc`, `inifile.h`, `inifile.hh` | Copy unchanged | Native file IO remains LinuxCNC-style in the vendored parser; browser OPFS integration remains outside this layer; `runtime/sdk/src/index.js` exports the INI SDK wrapper around the generated WASM C ABI, including LinuxCNC `iniFindBool()` for machine-session flags and LinuxCNC string lookup for INI-declared `[RS274NGC]PARAMETER_FILE` and `[EMCIO]TOOL_TABLE` machine file names | Vendor byte sync, `linuxcnc_ini_probe`, `linuxcnc_inifile_source_probe`, `tests/wasm/node/verify_ini_wasm.sh` boolean plus file-name lookup assertions, `tests/browser/verify_ini_panel_browser.sh`, `tests/host/verify_host_smokes.sh` |
| RTAPI compatibility headers | `src/rtapi/rtapi_*.h` in the manifest | Copy unchanged plus standalone shim include path | `runtime/core/shims/rtapi.h` supplies the minimal standalone RTAPI surface needed by vendored code | Vendor byte sync, compile coverage through dependent source probes |
| Canon/NML-facing interpreter types | `src/emc/nml_intf/canon*.hh`, `emctool.h`, `interp_return.hh`, `motion_types.h`, `emcpose.*`, `emcpos.h`, `debugflags.h`, `src/emc/linuxcnc.h` | Copy unchanged plus narrow standalone status shim | NML transport is not ported; `runtime/core/shims/nml_intf/emc.hh` exposes only the `emcStatus` machine-units status edge currently needed by vendored interpreter conversion and initialization code | Vendor byte sync, dependent source probes, `linuxcnc_emc_status_probe`, `linuxcnc_tp_api_probe`, interpreter harnesses, `tests/wasm/node/verify_interp_wasm.sh` and `tests/browser/verify_interp_browser.sh` `Interp::init()` machine-unit assertions |
| Motion state headers | `src/emc/motion/state_tag.h`, `emcmotcfg.h`, `simple_tp.h`, `motion.h`, `mot_priv.h`, `axis.h` | Copy unchanged | Realtime motion process is not ported; standalone probes seed the small motion status/config state required by TP calls | Vendor byte sync, `linuxcnc_tp_api_probe`, `tests/wasm/node/verify_tp_wasm.sh` |
| Identity/trivial kinematics | `src/emc/kinematics/kinematics.h`, `cubic.h`, `kins_util.c`, `trivkins.c` | Copy unchanged | HAL component lifecycle and RTAPI module metadata are replaced by standalone shims; forward/inverse mapping behavior remains LinuxCNC source | Vendor byte sync, per-file source probes, `linuxcnc_kinematics_probe` |
| Switchable 5-axis bridge kinematics | `src/emc/kinematics/5axiskins.c`, `switchkins.c`, `switchkins.h`, `userkfuncs.c`, plus `src/rtapi/rtapi_ctype.h` | Copy unchanged | HAL pin allocation, HAL component lifecycle, and RTAPI module metadata are standalone runtime edges; switchable 5-axis forward/inverse behavior remains LinuxCNC source | Vendor byte sync, per-file source probes, `linuxcnc_5axis_kinematics_probe` |
| TRT table-rotary kinematics | `src/emc/kinematics/trtfuncs.c`, `xyzac-trt-kins.c`, `xyzbc-trt-kins.c` | Copy unchanged | HAL pin allocation and switchkins lifecycle stay runtime boundaries; XYZAC/XYZBC TRT forward/inverse behavior remains LinuxCNC source | Vendor byte sync, per-file source probes, `linuxcnc_xyzac_trt_kinematics_probe`, `linuxcnc_xyzbc_trt_kinematics_probe` |
| Five-axis switchkins machine configs and M428/M429/M430 remaps | `configs/sim/axis/vismach/5axis/bridgemill/*`, `table-dual-rotary/*`, and `table-rotary-tilting/*` selected INI, HAL, tool-table, XML, demo, and `remap_subs/*.ngc` files plus `src/emc/rs274ngc/interp_remap.cc` | Copy unchanged | `M428`, `M429`, and `M430` remain LinuxCNC `REMAP` entries that call LinuxCNC NGC subroutines using `M68`, `M66`, `_hal[motion.switchkins-type]`, and the INI/HAL `motion.analog-out-03 => motion.switchkins-type` link; standalone remap descriptor parsing routes through vendored `Interp::parse_remap()` and `find_ngc_file()`, and NGC remap/file execution routes through vendored LinuxCNC O-word and `open()`/`read()`/`execute()` paths while HAL synchronization stays a runtime adapter boundary | Vendor byte sync, `linuxcnc_5axis_remap_asset_probe`, `linuxcnc_remap_parse_harness`, `linuxcnc_remap_hal_sync_harness`, `linuxcnc_5axis_remap_execute_harness`, `tests/wasm/node/verify_interp_wasm.sh`, `tests/wasm/node/verify_sim_configs_wasm.sh`, `tests/browser/verify_interp_browser.sh`, `tests/browser/verify_ini_panel_browser.sh` |
| Representative sim-config machine programs | `configs/sim/axis/foam/*`, `configs/sim/axis/geometry/M110`, `xyzc.ini`, `xyzc.ngc`, `configs/sim/axis/external_offsets/M111`, `dyn_demo.ngc`, `dynamic_offsets.ini`, `eoffset.tbl`, and `configs/sim/axis/sim.tbl` | Copy unchanged | The `foam`, `xyzc`, and dynamic external-offset sample programs remain LinuxCNC sim-config assets. The standalone boundary only copies INI, tool table, G-code, and executable user-M files into the native or WASM filesystem, then calls vendored LinuxCNC INI parsing and `Interp::open()`/`read()`/`execute()` through the existing machine-config adapter. The JS SDK `runSimConfigProgram()` is only the host file-staging helper for this boundary: it writes caller-provided text files to the Emscripten filesystem, applies executable bits, and forwards to LinuxCNC-backed C ABI entry points. `M110`/`M111` process execution stays a runtime boundary represented by deterministic `USER_M_COMMAND` canonical events | Vendor byte sync, `tests/native/verify_sim_configs.sh`, `tests/wasm/node/verify_sim_configs_wasm.sh`, `tests/browser/verify_interp_browser.sh` |
| Representative `nc_files` examples | `nc_files/arcspiral.ngc`, `nc_files/factorial.ngc`, `nc_files/hole-circle.ngc`, `nc_files/m6demo.ngc` | Copy unchanged | These upstream `linuxcnc/nc_files` examples are copied byte-for-byte into the WASM vendor tree after the native `nc_files` harness classifies the broader directory. Node and browser tests only stage the original `.ngc` text in the Emscripten filesystem and call the LinuxCNC-backed `Interp::open()`, `read()`, and `execute()` path through the existing SDK; no G-code, O-word, tool-change, or M-code behavior is implemented in JavaScript | Vendor byte sync, `tests/native/verify_nc_files.sh`, `tests/wasm/node/verify_nc_files_wasm.sh`, `tests/browser/verify_interp_browser.sh`, `tests/host/verify_host_smokes.sh` |
| LinuxCNC remap regression fixtures | `tests/remap/duplicate-o-word/*`, `tests/remap/fail/args.0/*`, `tests/remap/fail/args.1/*`, `tests/remap/fail/args.2/*`, `tests/remap/fail/body-ngc/*`, `tests/remap/m30-interaction/*`, `tests/remap/nested-remaps-oword/*`, `tests/remap/posargs.0/*`, `tests/remap/sequencing/*`, selected NGC-only `tests/remap/remap-io/test-ngc.ini` plus `io_*.ngc`, and `src/emc/rs274ngc/interp_remap.cc` plus `interp_o_word.cc` | Copy unchanged | The upstream duplicate O-word, NGC-only remap failure, M30/remap-level interaction, nested O-word remap, positional-argument remap, G/M remap sequencing, and remap-IO NGC subroutine regressions remain LinuxCNC REMAP/O-word/file or MDI execution tests. The standalone boundary only copies the upstream test files into native or WASM filesystems, reads LinuxCNC INI `SUBROUTINE_PATH`, `REMAP`, and `OWORD_NARGS` entries, and calls vendored `Interp::parse_remap()`, `open()`, `read()`, and `execute()` or feeds the upstream remap-IO MDI sequence into vendored `Interp::execute()`; the continue-on-error runner path only mirrors LinuxCNC `rs274 -n 0` test execution and does not implement duplicate-label, O-word, nested remap, M30, positional-argument, failure, sequencing, M62-M68, M66 input, or remap semantics | Vendor byte sync, `linuxcnc_duplicate_oword_remap_harness`, `tests/wasm/node/verify_interp_wasm.sh`, `tests/browser/verify_interp_browser.sh` |
| LinuxCNC interpreter regression fixtures | `tests/interp/do-while-break/*`, `tests/interp/oword-bug315/*`, `tests/interp/oword-bug315-p2/*`, `tests/interp/exists/*`, `tests/interp/return-value/*`, `tests/interp/subs-follow-main/*`, `tests/interp/fractional-linenumbers/*`, `tests/interp/namedparam-bug424/*`, selected `tests/interp/rotation/*` pure interpreter cases, `tests/interp/iniparam/*`, `tests/interp/iniparam-failassign/*`, `tests/interp/m19/*`, `tests/interp/magic_comments/param_format_printing/*`, selected `tests/interp/m98m99/*` pure interpreter cases, `tests/interp/sub-call-from-sub/*`, `tests/interp/sequence-number/*`, `tests/interp/nested-sub-error/*`, `tests/interp/nested-sub-in-file-error/*`, `tests/interp/abort-hot-comment/*`, plus vendored interpreter/O-word sources including `interp_o_word.cc`, `interp_read.cc`, `interp_execute.cc`, `interp_find.cc`, `interp_namedparams.cc`, and `rs274ngc_pre.cc` | Copy unchanged | The upstream do/while/break, O-word bug315, `EXISTS[]`, subroutine return-value, subs-after-main, fractional line-number, named-parameter, selected rotation/G53/G28 absolute-position and endpoint, INI named-parameter lookup/read-only protection, M19 spindle-orient offset/timeout handling, magic-comment parameter formatting, selected Fanuc `M98/M99` and O-expression call regressions, external-subroutine-call, external-subroutine line-number, nested-subroutine-definition rejection, blocked forward-seek-to-later-numbered-sub, and `(ABORT,...)` hot-comment parameter-expansion regressions remain LinuxCNC interpreter file-execution tests. The standalone boundary only vendors the original upstream assets, copies `*.ngc`, `test.ini`, `test.tbl`, `subs/*.ngc`, and referenced external subroutine `.ngc` files into native or WASM filesystems where applicable, sets the LinuxCNC `INI_FILE_NAME` runtime edge for `_ini[...]`, applies LinuxCNC INI machine settings such as `[RS274NGC]ORIENT_OFFSET`, reads LinuxCNC INI `SUBROUTINE_PATH`, captures LinuxCNC `(PRINT,...)` output through the existing stdout/Emscripten `print` boundary, and calls vendored `Interp::open()`, `read()`, and `execute()`; it does not implement O-word loop, break, subroutine, dynamic call, `M98/M99`, `EXISTS[]`, named-parameter, absolute-position named-parameter, G28/G53 endpoint, INI-variable, read-only parameter, line-number, spindle-speed, spindle-orient, magic-comment formatting, subroutine lookup, ABORT hot-comment, error, or branch semantics | Vendor byte sync, `linuxcnc_interp_minimal_harness`, `tests/wasm/node/verify_interp_wasm.sh`, `tests/browser/verify_interp_browser.sh` |
| Additional non-switchable kinematics | `src/emc/kinematics/corexykins.c`, `rotatekins.c`, `rosekins.c`, `maxkins.c`, `lineardeltakins.c`, `lineardeltakins-common.h`, `rotarydeltakins.c`, `rotarydeltakins-common.h`, `scorbot-kins.c`, `tripodkins.c`, `scarakins.c`, `pumakins.c`, `pumakins.h`, `genhexkins.c`, `genhexkins.h`, `genserfuncs.c`, `genserkins.c`, `genserkins.h`, `ugenserkins.c`, `pentakins.c`, `pentakins.h`, `cubic.c` | Copy unchanged | HAL pin allocation, HAL parameter allocation, HAL component lifecycle, RTAPI module metadata, Go math C/C++ linkage, switchkins iterative-forward warmup, and userspace test-program process entry remain standalone runtime edges; forward/inverse behavior remains LinuxCNC source where the module exposes it | Vendor byte sync, per-file source probes, `linuxcnc_corexy_kinematics_probe`, `linuxcnc_rotate_kinematics_probe`, `linuxcnc_rose_kinematics_probe`, `linuxcnc_max_kinematics_probe`, `linuxcnc_lineardelta_kinematics_probe`, `linuxcnc_rotarydelta_kinematics_probe`, `linuxcnc_scorbot_kinematics_probe`, `linuxcnc_tripod_kinematics_probe`, `linuxcnc_scara_kinematics_probe`, `linuxcnc_puma_kinematics_probe`, `linuxcnc_genser_kinematics_probe`, `linuxcnc_genhex_kinematics_probe`, `linuxcnc_pentakins_kinematics_probe` |
| Trajectory planner | `src/emc/tp/tp.c`, `tc.c`, `tcq.c`, `spherical_arc.c`, `blendmath.c`, `sp_scurve.c`, `ruckig_wrapper.c`, plus matching `*.h` files | Copy unchanged | Native realtime scheduling and motion process state are replaced by standalone probe setup; the WASM TP probe uses the same deterministic status/config boundary and calls vendored TP APIs through a narrow C ABI | Vendor byte sync, per-file source probes, `linuxcnc_tp_api_probe`, `tests/wasm/node/verify_tp_wasm.sh` |
| Ruckig C planner support | Selected `src/emc/tp/cruckig/*.c` and `*.h` files in the manifest | Copy unchanged | Used as LinuxCNC planner support code through vendored TP sources | Vendor byte sync, per-file source probes, `tests/wasm/node/verify_tp_wasm.sh` |
| Posemath | `src/libnml/posemath/posemath.cc`, `_posemath.c`, `gomath.c`, `sincos.c`, and matching headers | Copy unchanged | `gomath.c` is compiled as C; `rtapi.h` shim is C/C++ compatible for this boundary | Vendor byte sync, per-file source probes, TP native and WASM probes |
| RS274 interpreter state and parser | `src/emc/rs274ngc/modal_state.*`, `interp_internal.*`, `interp_read.cc`, `interp_check.cc`, `interp_execute.cc`, `interp_find.cc`, `interp_array.cc`, `interp_queue.*`, `rs274ngc*`, `units.h` | Copy unchanged | Python/remap/runtime edges are isolated in standalone wrappers and shims; parser and execution logic remain LinuxCNC source | Vendor byte sync, per-file source probes, interpreter harness fixtures |
| RS274 conversion semantics | `src/emc/rs274ngc/interp_convert.cc`, `interp_arc.cc`, `interp_inverse.cc`, `interp_cycles.cc`, `interp_g7x.cc`, `interp_o_word.cc`, `interp_write.cc` | Copy unchanged | Canonical calls are captured by standalone event sink functions; conversion behavior stays in vendored LinuxCNC files; feed-rate state is read back through the canonical runtime boundary during length-unit conversion; single-axis rotary indexer lock/unlock dispatch remains vendored LinuxCNC `issue_straight_index()` behavior | Vendor byte sync, per-file source probes, canonical fixture suite, no standalone `Interp::convert_g()` guard, `linuxcnc_indexer_harness`, `tests/wasm/node/verify_interp_wasm.sh` and `tests/browser/verify_interp_browser.sh` rotary-indexer assertions |
| User M-code registration boundary | `src/emc/task/emctask.cc`, `src/emc/rs274ngc/interp_convert.cc`, `src/emc/rs274ngc/interp_queue.cc` | Runtime-edge adapter | Vendored interpreter conversion still checks LinuxCNC `USER_DEFINED_FUNCTION` before accepting `M100..M199` and queues through vendored `enqueue_M_USER_COMMAND()`. The standalone machine-config adapter mirrors LinuxCNC task search order for `[DISPLAY]PROGRAM_PREFIX` and `[RS274NGC]USER_M_PATH`, registers executable M-code files in `USER_DEFINED_FUNCTION`, calls the canonical `FINISH()` boundary, and records deterministic `USER_M_COMMAND` events instead of spawning host processes in WASM/browser. | `linuxcnc_interp_minimal_harness` sim `M110`/`M111` probes, `tests/wasm/node/verify_interp_wasm.sh` minimal `M110`/`M111` fixtures |
| Named parameters and tool slot status | `src/emc/rs274ngc/interp_namedparams.cc`, related interpreter headers | Copy unchanged | `_ini[...]` and `_hal[...]` resolve through standalone INI/HAL adapters while lookup order stays LinuxCNC-derived; current/selected tool slot reads for vendored `Interp::synch()` come from the standalone tool adapter | Vendor byte sync, source probe, `linuxcnc_namedparam_harness`, `linuxcnc_interp_init_harness`, `tests/wasm/node/verify_interp_wasm.sh` and `tests/browser/verify_interp_browser.sh` `Interp::synch()` tool-slot assertions plus `Interp::init_named_parameters()`/`find_named_param()` named-parameter lookup assertions |
| Tool table parsing and formatting | `src/emc/tooldata/tooldata_common.cc` | Copy unchanged plus standalone storage callbacks | Native file parsing/formatting stays in vendored LinuxCNC source; the standalone tool adapter supplies `tooldata_get()`/`tooldata_put()` storage and index lookup, the WASM boundary only selects the LinuxCNC non-random or random-toolchanger branch via `tooldata_init()`, and OPFS remains a host-side persistence boundary | Vendor byte sync, `linuxcnc_tooldata_common_source_probe`, `tests/wasm/node/verify_interp_wasm.sh` non-random/random load/save tool-table assertions |
| Dynamic interpreter base | `src/emc/rs274ngc/interp_base.*` | Copy unchanged | `interp_base.cc` source probe uses standalone `EMC2_HOME` compile-time path boundary for LinuxCNC dynamic interpreter lookup | Vendor byte sync, `linuxcnc_interp_base_source_probe` |
## Dependency Matrix
| Dependency | LinuxCNC files that expose it | Standalone treatment |
| --- | --- | --- |
| Native file IO | `inifile.cc`, `rs274ngc_pre.cc`, `tooldata_common.cc`, parameter file paths, tool table paths | Allowed in native probes; the interpreter WASM C ABI validates parameter-file restore/save by calling vendored `Interp::restore_parameters()` and `Interp::save_parameters()`, including missing required numeric parameter defaulting, and tool-table load/save by calling vendored `tooldata_load()` and `tooldata_save()` against Emscripten filesystem paths; browser OPFS remains a host-side adapter under `runtime/opfs/`, with path ownership in `runtime/opfs/path-model.js`, generic snapshot persistence in `runtime/opfs/snapshot-store.js`, pure-text machine-file persistence in `runtime/opfs/machine-file-store.js`, OPFS-to-WASM parameter-file copying in `runtime/opfs/linuxcnc-parameter-bridge.js`, OPFS-to-WASM tool-table copying in `runtime/opfs/linuxcnc-tool-table-bridge.js`, and grouped INI/parameter/tool-table session loading in `runtime/opfs/linuxcnc-machine-session-bridge.js`, including INI-derived `[RS274NGC]PARAMETER_FILE` and `[EMCIO]TOOL_TABLE` OPFS filename selection through the LinuxCNC-backed INI SDK; explicit host session file-name options take precedence over INI-derived names, missing INI file-name values fall back to host default `linuxcnc.var` and `tool.tbl` paths, and OPFS path validation rejects traversal and nested segments before host storage access |
| RTAPI | `rtapi_*.h`, TP, posemath, motion headers | Minimal standalone shim in `runtime/core/shims/rtapi.h` |
| NML transport | `emc.hh`, motion/NML type headers | Transport is not ported; only the status/type edges needed by vendored compute code are exposed through standalone shims and probes |
| HAL runtime | named parameter lookup, kinematics component lifecycle, and runtime status edges | Standalone HAL adapter under `runtime/core/linuxcnc_wrap/` |
| User M-code process execution | `emctask.cc`, `interp_convert.cc`, `interp_queue.cc` | Search and registration are mirrored at the standalone machine-config boundary; native/WASM tests record deterministic `USER_M_COMMAND` events and do not spawn host processes |
| Python/remap | `rs274ngc_pre.cc`, `interp_o_word.cc`, `interp_remap.cc`, remap hooks, selected LinuxCNC `configs/sim/axis/vismach/5axis/*/remap_subs/*.ngc` files, `tests/remap/duplicate-o-word/*`, `tests/remap/fail/args.0/*`, `tests/remap/fail/args.1/*`, `tests/remap/fail/args.2/*`, `tests/remap/fail/body-ngc/*`, `tests/remap/m30-interaction/*`, `tests/remap/nested-remaps-oword/*`, `tests/remap/posargs.0/*`, `tests/remap/sequencing/*`, and NGC-only `tests/remap/remap-io/test-ngc.ini` plus `io_*.ngc` | Python calls remain stubbed at the runtime boundary today; five-axis M428/M429/M430 source assets and the upstream NGC remap regression files are vendored unchanged. NGC remap descriptor paths parse through vendored LinuxCNC code, native/WASM/browser validation executes the NGC remap files through vendored LinuxCNC O-word and file execution paths, and the remap-IO NGC-only branch feeds the upstream MDI sequence into vendored LinuxCNC `Interp::execute()` while external M66 input values and `_hal[...]` synchronization remain standalone runtime adapter boundaries |
| Canonical machine actions | `interp_convert.cc`, `interp_execute.cc`, `interp_queue.cc`, selected `tests/interp/*` regression assets | Captured by standalone canonical event sink functions for regression fixtures; vendored upstream interpreter test assets remain unchanged and are executed through LinuxCNC file execution |
| Realtime scheduling | TP and motion headers | Not ported; native TP probes seed deterministic status/config state |
| GUI | None used as implementation | Native LinuxCNC GUI remains reference-only |
## Known Gaps
- Additional non-trivial kinematics implementation files are now extracted at
source-probe level. Serial `genserkins`, hexapod `genhexkins`, and pentapod
`pentakins` have native runtime baselines; full runtime machine baselines for
userspace genser flows are not yet established.
- Five-axis M428/M429/M430 source assets are now vendored for bridge-mill,
dual-rotary, and table-rotary-tilting LinuxCNC sample machines. NGC remap
descriptors for the TRT, TDR, and bridge-mill sample machines are parsed
through vendored `Interp::parse_remap()` and `find_ngc_file()` by
`linuxcnc_remap_parse_harness`; native, WASM Node, browser interpreter, and
INI panel UI validation execute the selected switchkins demo files through
vendored LinuxCNC O-word remap dispatch, file `open()`/`read()`/`execute()`,
and the standalone HAL adapter boundary for `M68`/`M66` plus
`_hal[motion.switchkins-type]` readback.
- Cutter compensation positive motion and negative interpreter paths are
fixture-covered through vendored `interp_convert.cc` and `interp_queue.cc`.
- Browser/WASM C ABI and JS SDK layers are now present for the INI parser, the
current interpreter-core smoke scope, and a trajectory-planner TP probe. The interpreter SDK is a thin
allocation, filesystem, and C ABI wrapper over vendored LinuxCNC execution
paths, including parameter-file restore/save through vendored
`rs274ngc_pre.cc` and non-random/random tool-table load/save through
vendored `tooldata_common.cc`; it does not define G-code, parameter, or
tool-table semantics. The TP WASM probe calls vendored LinuxCNC planner APIs
directly and does not expose a browser planner SDK yet; full planner/session
SDK coverage remains future work.
- OPFS persistence is connected to the INI panel through the host-side
`runtime/opfs/file-service.js` adapter. `runtime/opfs/path-model.js` now
defines paths for INI, tool table, parameter file, G-code program,
preview-cache, and session-snapshot targets. `runtime/opfs/snapshot-store.js`
adds a generic JSON session snapshot envelope, supports custom snapshot
filenames under the session directory, and validates its format, version,
session id, metadata, payload shape, and filename boundary.
`runtime/opfs/machine-file-store.js` adds pure-text storage for INI, tool
table, parameter file, and G-code program content, with G-code program
filenames constrained by `runtime/opfs/path-model.js`.
`runtime/opfs/linuxcnc-parameter-bridge.js` copies OPFS-backed parameter
files into the interpreter SDK filesystem and writes back the LinuxCNC-saved
parameter file plus backup. `runtime/opfs/linuxcnc-tool-table-bridge.js`
copies OPFS-backed tool tables into the interpreter SDK filesystem and writes
back the LinuxCNC-saved tool table.
`runtime/opfs/linuxcnc-machine-session-bridge.js` groups INI, parameter, and
tool-table loading into one host-side session load boundary and can derive
the random-toolchanger tooldata mode from `[EMCIO]RANDOM_TOOLCHANGER` plus
parameter/tool-table OPFS file names from `[RS274NGC]PARAMETER_FILE` and
`[EMCIO]TOOL_TABLE` through the LinuxCNC-backed INI SDK. Explicit host
session file-name options take precedence over those INI-derived names,
missing INI file-name values fall back to the default host path model, and
invalid traversal or nested file names are rejected by
`runtime/opfs/path-model.js`. Full machine-state restoration remains future
work.
- Native LinuxCNC GUI code remains out of scope for implementation.