# LinuxCNC Sim Config Completion Plan

This plan tracks the work needed to run the LinuxCNC programs under
`linuxcnc/configs/sim` through the standalone native/WASM simulation runtime.
LinuxCNC source remains the semantic source of truth. Port code must live under
`wasm-port/`; do not edit `linuxcnc/` in place.

## Current Baseline

The latest strict harness run used `linuxcnc/configs/sim` as the program source,
selected the nearest INI/tool table for each `.ngc` unless an explicit sim
mapping is required, and ran `rs274` from the INI directory so relative
`SUBROUTINE_PATH` and `REMAP` entries resolve like a real sim config.

Result file:

```text
wasm-port/build/native/sim-configs/summary.tsv
wasm-port/build/native/sim-configs/class-summary.tsv
wasm-port/build/native/sim-configs/path-matrix.tsv
```

Baseline:

```text
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0

main:             PASS 40, FAIL 8
macro_load:       PASS 46, FAIL 0
remap_subroutine: PASS 65, FAIL 0
```

Remaining failures are explicit LinuxCNC-native baseline edges:

- `axis/external_offsets/*`: 4 failures from sim-only user M-codes `M111`.
  The native harness now resolves the corresponding INI by
  `[DISPLAY]OPEN_FILE`, so `eoffsets.ngc`, `jwp_z.ngc`, and `opa_demo.ngc`
  are no longer judged through `dynamic_offsets.ini`.
- `axis/geometry/xyzc.ngc`: 1 failure from sim-only user M-code `M110`.
- `axis/foam/foam.ngc`: 1 failure from missing `U/V` axis support in the
  LinuxCNC `bin/rs274` entry point.
- `axis/vismach/5axis/bridgemill/5axisgui.ngc`: 1 failure from missing `W`
  axis support in the LinuxCNC `bin/rs274` entry point.
- `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_g533.ngc`:
  1 failure from an upstream demo line that uses bare `X/Y/Z` words after
  `G53.6` without an explicit motion G-code.

## Target

The first target is not a browser UI feature and not a requirement that every
`linuxcnc/configs/sim` `.ngc` program pass through standalone `bin/rs274`.
It is a repeatable native and WASM inventory that classifies every
`configs/sim` program, runs the entries that are meaningful in standalone
native/WASM/browser contexts, and records blocked dependencies for the entries
that require full LinuxCNC task, HAL, UI, Python-remap, or external process
runtime.

Acceptance criteria:

- The native sim-config harness reports `unexpected_fail: 0` and writes
  `summary.tsv`, `class-summary.tsv`, and `path-matrix.tsv`.
- Macro/remap files are validated by the correct entry point: direct execution
  only for real programs, load/parse or remap-call validation for subroutines.
- Node WASM inventory executes only entries with a defined standalone/WASM
  runtime path and reports `unexpected_fail: 0`.
- Browser coverage remains focused on representative runtime classes rather
  than blind full-directory execution.
- Any remaining unsupported files are explicitly classified by dependency, not
  by accident.

## Definition Of Done For Full configs/sim Coverage

Full coverage for this project means:

- Inventory complete: every `summary.tsv` `.ngc` entry appears in
  `docs/sim-configs-coverage-matrix.md` and generated `path-matrix.tsv`.
- Classification complete: every entry has `main`, `macro_load`, or
  `remap_subroutine` class.
- Blocked table complete: full-process, HAL, UI, linuxcncrsh, external
  userspace component, Python binding/remap, tool-database, and process user-M
  dependencies are recorded explicitly.
- Native source-of-truth complete: `verify_sim_configs.sh` remains the Layer 2
  source for per-path status and expected-failure reason.
- Node inventory complete: `verify_sim_configs_inventory_wasm.sh` checks the
  native/generated/tracked path sets, runs eligible vendored programs, and
  emits stable WASM inventory and skip/block summaries.
  Any eligible row with missing vendored machine context is an inventory
  failure, not an expected skip.
- Browser class coverage complete: each promoted browser class has a
  representative sample and no browser test relies on directory enumeration.
- Expected failures justified: the current eight Layer 2 expected failures are
  tied to runtime boundaries or the preserved upstream demo edge.
- No accidental standalone semantic ownership: tests must not pass by changing
  G-code semantics, JS interpreter behavior, or project-owned
  `Interp::...` implementations.

## Phase 1: Make The Harness A First-Class Test

Status: complete. The tracked script exists and is wired into the native
validation entry point.

1. Add a tracked script:

   ```text
   wasm-port/tests/native/verify_sim_configs.sh
   ```

2. Move the ad hoc test logic into the script:

   - scan only `linuxcnc/configs/sim`;
   - identify `.ngc`, nearest `.ini`, nearest `.tbl`;
   - run from the INI directory;
   - write `summary.tsv`, `class-summary.tsv`, `path-matrix.tsv`, stdout,
     stderr, and interpreter output under
     `wasm-port/build/native/sim-configs/`;
   - classify programs as `main`, `macro_load`, `remap_subroutine`, or
     `unsupported_runtime_edge`;
   - fail the script only on unexpected failures.

3. Add deterministic classification rules:

   - files under `remap_subs/` and `nc_subroutines/` are not standalone main
     programs;
   - files with no `M2`, `M30`, or `%` are load/parse fixtures unless the INI
     references them through `REMAP`;
   - user M-code files are tested through `USER_M_PATH` resolution, not by
     pretending LinuxCNC native process services exist.

4. Wire the script into existing validation:

   ```text
   wasm-port/tests/native/verify_native_probes.sh
   ```

5. Completion check:

   ```bash
   wasm-port/tests/native/verify_sim_configs.sh
   ```

   Latest result:

   ```text
   total: 159
   pass: 151
   fail: 8
   timeout: 0
   expected_fail: 8
   unexpected_fail: 0
   skipped: 0
   ```

## Phase 2: Load Machine Axes From INI

Status: partially complete for the port runtime. The standalone native/WASM
runtime now parses `[TRAJ] COORDINATES`, updates the standalone external axis
mask used by LinuxCNC `GET_EXTERNAL_AXIS_MASK()`, and applies the same
`Interp::_readers` filtering that upstream `rs274ngc_pre.cc` uses. Native
regression coverage verifies that `axis_foam.ini` enables `U/V` readers and
`bridgemill/5axis.ini` enables the `W` reader.

The `verify_sim_configs.sh` baseline still records the LinuxCNC `bin/rs274`
entry-point failures as expected failures. That harness is intentionally kept
as a LinuxCNC-native baseline while the port runtime coverage tracks this
phase's standalone behavior.

Current failures:

- `axis/foam/foam.ngc`: `Bad character 'u' used`
- `axis/vismach/5axis/bridgemill/5axisgui.ngc`: `Bad character 'w' used`

Root cause:

The current standalone interpreter initialization does not configure the active
axis mask from `[TRAJ] COORDINATES` / `[KINS] KINEMATICS`. Native LinuxCNC
accepts `U/V/W` only when the machine config declares those axes.

Implementation steps:

1. Add a machine-config loader in `runtime/core/linuxcnc_wrap/`, for example:

   ```text
   linuxcnc_machine_config.hh
   linuxcnc_machine_config.cpp
   ```

2. Reuse vendored `inifile.cc` to parse:

   - `[TRAJ] COORDINATES`
   - `[KINS] KINEMATICS`
   - `[DISPLAY] GEOMETRY`
   - `[RS274NGC] PARAMETER_FILE`
   - `[RS274NGC] SUBROUTINE_PATH`
   - `[RS274NGC] USER_M_PATH`
   - `[EMCIO] TOOL_TABLE`

3. Extend `initialize_minimal_interp()` / the runtime equivalent to set the
   interpreter setup fields from the parsed machine config instead of hardcoded
   `XYZ`.

4. Add focused native fixtures:

   - `axis_foam.ini` + `foam.ngc` accepts `U/V`.
   - `bridgemill/5axis.ini` + `5axisgui.ngc` accepts `W`.

5. Add the same coverage to the WASM SDK once native is green.

Completion check:

```bash
wasm-port/tests/native/verify_sim_configs.sh --only axis/foam/foam.ngc
wasm-port/tests/native/verify_sim_configs.sh --only axis/vismach/5axis/bridgemill/5axisgui.ngc
```

## Phase 3: Implement Standalone User M-Code Dispatch

Status: complete for the standalone native/WASM runtime boundary. The port now
reads `[DISPLAY] PROGRAM_PREFIX` and `[RS274NGC] USER_M_PATH`, searches
executable `M100` through `M199` files using the same order as LinuxCNC task
initialization, registers them in LinuxCNC's `USER_DEFINED_FUNCTION` table, and
records `USER_M_COMMAND` canonical boundary events instead of spawning host
processes. Native probes cover `axis/geometry` `M110` and
`axis/external_offsets` `M111`; Node WASM covers minimal `M110` and `M111`
fixtures through the Emscripten filesystem.

The `verify_sim_configs.sh` baseline still records these files as expected
failures because it intentionally runs LinuxCNC `bin/rs274`, not the standalone
task/runtime adapter.

Current failures:

- `axis/external_offsets/*.ngc`: unknown `M111`
- `axis/geometry/xyzc.ngc`: unknown `M110`

Root cause:

Native LinuxCNC resolves user M-codes through `[DISPLAY] PROGRAM_PREFIX` and
`[RS274NGC] USER_M_PATH` during task initialization, registers matching
executable `M100..M199` handlers with the interpreter, and later runs external
scripts through the task process boundary. The standalone runtime must register
the same interpreter boundary without running host processes in WASM/browser.

Implementation steps:

1. Locate the upstream M-code dispatch path in LinuxCNC and vendor the minimum
   source needed to preserve semantics, or add a narrow runtime-edge adapter if
   the upstream path is process-bound. Done: the adapter mirrors
   `src/emc/task/emctask.cc` search/registration behavior and keeps process
   execution outside CNC semantics.

2. Add `USER_M_PATH` parsing to the machine-config loader. Done.

3. For native standalone tests. Done:

   - resolve `M100` through `M199` against configured search paths;
   - register only executable files;
   - emit deterministic `USER_M_COMMAND` boundary events.

4. For WASM/browser. Done for Node WASM:

   - do not spawn host processes;
   - use a host-boundary user-M adapter that registers deterministic
     message-emitting handlers for sim-only notification M-codes;
   - document this as a runtime edge, not CNC semantics.

5. Add tests. Done:

   - `M110` from `axis/geometry`;
   - `M111` from `axis/external_offsets`;
   - minimal WASM `M110` and `M111` fixtures.

Completion check:

```bash
wasm-port/tests/native/verify_sim_configs.sh --only axis/external_offsets
wasm-port/tests/native/verify_sim_configs.sh --only axis/geometry/xyzc.ngc
```

Standalone runtime checks:

```bash
wasm-port/tests/native/verify_native_probes.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
```

## Phase 4: Classify Python Remap Runtime Edges

Status: complete for the native sim-config harness and blocked for Layer 4
full inventory. Current native checks:

```text
gmoccapy:   total 38, pass 38, fail 0
axis/laser: total 3,  pass 3,  fail 0
axis/remap main demos: total 6, pass 6, fail 0
VMC_toolchange: total 1, pass 1, fail 0
```

Boundary:

The configs use LinuxCNC Python remap modules. Native LinuxCNC `rs274` can
resolve and execute these configs under the current baseline, but Node/browser
Layer 4 full inventory is intentionally blocked until a Python-remap runtime
boundary is deliberately designed. Do not make these pass in browser by
translating Python remap behavior into JavaScript or by adding project-owned
CNC semantics.

Recorded dependency:

- `configs/sim/gmoccapy/python/toplevel.py`
- `configs/sim/gmoccapy/python/remap.py`
- `configs/sim/gmoccapy/python/stdglue.py`
- `configs/sim/axis/laser/python/toplevel.py`
- `configs/sim/axis/laser/python/remap.py`
- `configs/sim/axis/remap/*/python/*.py` for Python remap, prolog, epilog,
  queue, and tool-change callbacks.
- `configs/sim/axis/vismach/VMC_toolchange/remap.py` and `toplevel.py` for
  Python tool-change prolog/epilog handling.

Current policy:

- Keep native inventory as source-of-truth.
- Mark `gmoccapy/*`, `axis/laser/*`, `axis/remap/*/nc_files/*.ngc`, and
  `axis/vismach/VMC_toolchange/toolchange.ngc` rows as `L4-PYTHON-REMAP` in
  `docs/sim-configs-coverage-matrix.md`.
- Revisit Layer 4 only after the runtime boundary is designed from LinuxCNC
  source ownership, not as a browser smoke expansion.

Completion check:

```bash
wasm-port/tests/native/verify_sim_configs.sh --only gmoccapy
wasm-port/tests/native/verify_sim_configs.sh --only axis/laser
wasm-port/tests/native/verify_sim_configs.sh --only axis/remap
wasm-port/tests/native/verify_sim_configs.sh --only VMC_toolchange
```

## Phase 5: Classify TWP Remaps Including G69

Status: native mapping complete and Layer 4 blocked on Python-remap runtime
ownership. The harness now maps
`axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/*` through the
explicit `xyzacb-trsrn_twp/xyzacb-trsrn.ini` machine config instead of falling
back to `axis/axis.ini`. That loads the TWP `G69` remap declarations correctly,
and 14 of the 15 TWP demo/remap programs now pass.

Current failures:

- `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_g533.ngc`
  fails in the LinuxCNC `rs274` baseline because line 10 uses bare
  `x50y50z150` after `G53.6`; same-directory demos use explicit `G0` motion
  words at this point.

Boundary:

The demo programs rely on table/spindle rotary TWP remaps. The original test
mapping fell back to `axis/axis.ini` for these demo files because the actual
INI is in a child directory:

```text
axis/vismach/5axis/table-rotary_spindle-rotary-nutating/
  xyzacb-trsrn_twp/xyzacb-trsrn.ini
  xyzbca-trsrn_twp/xyzbca-trsrn.ini
```

Current policy:

- Keep native mapping and expected-failure classification in
  `verify_sim_configs.sh`.
- Keep `incremental_repetition_g533.ngc` as `UPSTREAM-DEMO`; do not edit the
  upstream G-code or add standalone semantics to force a pass.
- Keep TWP demo Layer 4 rows as `L4-PYTHON-REMAP` until Python remap entry
  points such as `g682`, `g69_core`, and `g53x_core` have an intentional
  runtime boundary.

Latest result:

```text
total: 15
pass: 14
fail: 1
timeout: 0
expected_fail: 1
unexpected_fail: 0
skipped: 0
```

Completion check:

```bash
wasm-port/tests/native/verify_sim_configs.sh --only table-rotary_spindle-rotary-nutating
```

## Phase 6: Promote Eligible Native Coverage To WASM

Status: complete for the current representative Node/browser class coverage
and the Node inventory layer. Dedicated Node and browser smokes now pass a
representative vendored `configs/sim` subset through the SDK
`runSimConfigProgram()` host boundary, which copies files into the Emscripten
filesystem and forwards execution to existing LinuxCNC-backed C ABI paths. They
cover:

- `axis/foam/foam.ngc` with `axis_foam.ini`, verifying INI-driven `U/V` axis
  mask handling in WASM.
- `axis/vismach/5axis/bridgemill/5axisgui.ngc` with `5axis.ini`, verifying
  INI-driven `W` axis mask handling and bridge-mill NGC remap execution in
  WASM.
- `axis/geometry/xyzc.ngc` with `xyzc.ini` and real executable `M110`, verifying
  `USER_M_PATH` registration in WASM.
- `axis/external_offsets/dyn_demo.ngc`, `eoffsets.ngc`, `jwp_z.ngc`, and
  `opa_demo.ngc` with their corresponding INI files, real executable `M111`,
  shared `eoffset.tbl`, and `opa_demo.ngc`'s `circles.ngc` subroutine,
  verifying the same user-M and `SUBROUTINE_PATH` boundaries against upstream
  sim programs.
  The Node inventory guard keeps these deterministic `M110`/`M111` rows
  unblocked, requires a vendored user-M file, and includes the `opa_demo.ngc`
  `circles.ngc` subroutine text in boundary analysis so the reached `M111`
  call is accounted for instead of being mistaken for an external user-M
  process gap.
- `axis/gladevcp/probe.ngc` as a plain INI/tool-table main-program sample.
- `axis/external_offsets/circles.ngc` as the macro-load class representative,
  wrapped only with an added `M2` for load/parse style execution.
- `axis/vismach/5axis/table-dual-rotary/demos/xyzab-tdr-demo.ngc` and
  `axis/vismach/5axis/table-rotary-tilting/demos/*` through the existing
  five-axis remap execution C ABI.
- `axis/vismach/melfa-sim/example.ngc` and `axis/vismach/puma/puma_cube.ngc`
  as additional remap/kinematics machine representatives.
- `woodpecker/on_abort.ngc` as the deterministic on-abort/user-action macro
  class representative.
- Node inventory for the eligible vendored program set:
  `executed=82`, `passed=82`, `skipped=77`, `unexpected_fail=0`.
- Node inventory skip/block summary:
  `ASSET-ONLY=65`, `L4-USER-M-PROCESS=1`, `NON_MAIN_CLASS=10`, `UPSTREAM-DEMO=1`.
- Node blocked-dependency inventory for the hard blocked row set:
  `L4-USER-M-PROCESS=1`.
  The inventory reads source `linuxcnc/configs/sim` INI files for dependency
  accounting only and writes
  `build/wasm/sim-configs-inventory/blocked-dependency-summary.tsv` without
  vendoring or executing those blocked families. The blocked summary includes
  source-derived `user_m_process_effects` for `millturn`,
  `tool_db_protocol_evidence` for `db_demo`, and Python module/remap/prolog/
  epilog dependency ownership for Python-remap families. Python-remap rows are
  also projected into
  `build/wasm/sim-configs-inventory/python-remap-boundary-summary.tsv`, which
  keeps all 53 `L4-PYTHON-REMAP` rows inventory-only with
  `python_runtime_evidence` and `execution_enabled=0`.

Boundary decisions for the current hard blocks:

- `axis/vismach/millturn/example.ngc` remains `L4-USER-M-PROCESS`. The
  source INI declares HAL, HALUI MDI, and UI process dependencies, and the
  remap chain enters `remap_subs/428remap.ngc` and `429remap.ngc`, which call
  external user-M process codes `M128` and `M129`. Those process scripts live
  at `configs/sim/axis/vismach/millturn/mcodes/M128` and `M129`; they use Tcl
  LinuxCNC/HAL packages, `emc_init`, `parse_ini`, `hal getp`, and `hal setp`
  to change INI axis limit HAL pins after the kinematics switch. The current
  LinuxCNC owner is therefore task user-M process dispatch plus HALUI/MDI and
  the config-owned Tcl process scripts, not the standalone interpreter. Do not
  promote this row until the native runtime probe can run in an exclusive
  LinuxCNC process graph and report `runtime_state_probe_passed`. The current
  Web/virtual HAL simulation proof is complete for `M429 -> M129` turn and
  `M428 -> M128` mill state transitions, and the real browser simulation page
  smoke verifies the switchkins guard pins plus `ini.[xz].*` limit pins through
  `linuxCncRealSimulationState.millturnUserMProcess`. That proof is simulation
  evidence only: it keeps `processExecutionReady=false`, `executionEnabled=0`,
  and `promotion_allowed=0`. The latest opt-in native probe on this workstation
  reports `blocked_existing_linuxcnc_runtime` with
  `exclusive_linuxcnc_runtime` because an existing `linuxcncsvr`/`rtapi_app`
  runtime is already active. The Node inventory guard requires this row to stay
  non-`REP` in Node and browser while it remains `L4-USER-M-PROCESS`, and the
  generated inventory summary must keep it as `SKIP` with that reason.
- `axis/db_demo/base.ngc` remains `L4-TOOL-DB`. The source INI declares
  `[EMCIO]DB_PROGRAM = ./db_nonran.py`, so standalone interpreter execution
  would miss LinuxCNC tool-database process startup and protocol/state
  behavior. The LinuxCNC owner is `src/emc/task/taskclass.cc` for DB_PROGRAM
  activation, `src/emc/tooldata/tooldata_db.cc` for DB process startup and
  command/reply protocol, `src/emc/tooldata/tooldata_common.cc` for DB-backed
  tooldata behavior, and the config program `configs/sim/axis/db_demo/db.py`.
  Do not promote until the boundary design in
  `docs/full-process-boundary-design.md` has a LinuxCNC-owned tool database
  boundary that proves lookup/update behavior across native and WASM. The Node
  inventory guard requires this row to stay non-`REP` in Node and browser while
  it remains `L4-TOOL-DB`, and the generated inventory summary must keep it as
  `SKIP` with that reason.
- Python-remap/full-process families remain `L4-PYTHON-REMAP`. The blocked
  dependency inventory records Python modules, remap/prolog/epilog function
  ownership, NGC remap subpaths, and HAL/UI/HALUI declarations for gmoccapy,
  axis/laser, axis/remap demos, TWP nutating demos, and VMC tool-change
  rows. The Python-specific boundary summary records the same row set as
  inventory-only and requires a LinuxCNC-owned Python runtime boundary before
  any promotion. Every `L4-PYTHON-REMAP` row must also remain `SKIP` with
  `L4-PYTHON-REMAP` in the generated inventory summary. This is an inventory
  artifact, not a Layer 4 execution path.

Completion checks:

```bash
wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
wasm-port/tests/browser/verify_interp_browser.sh
```

Current Layer 4 non-goals:

- Do not run all 159 programs in browser.
- Do not promote Python remap/full-process/HAL/UI-only families into
  Emscripten without LinuxCNC-owned runtime support.
- Do not add JS-owned G-code, remap, tool, kinematics, parameter, or planner
  semantics.

Browser inventory decision record:

- Promoted after Node inventory: plain INI/tool-table execution
  (`axis/gladevcp/probe.ngc`), deterministic macro/load execution
  (`axis/external_offsets/circles.ngc`), deterministic on-abort/user-action
  execution (`woodpecker/on_abort.ngc`), TDR/TRT five-axis remap execution,
  bridge-mill W-axis remap execution, `melfa-sim`, and PUMA.
  The Node inventory guard requires process-declaring representatives such as
  `axis/gladevcp/probe.ngc`, `woodpecker/on_abort.ngc`,
  `axis/vismach/melfa-sim/example.ngc`, and
  `axis/vismach/puma/puma_cube.ngc` to keep their dependency rows in
  `boundary-summary.tsv`, match the expected HAL/UI/HALUI/Python process flag
  combinations, remain Node/browser `REP` rows, and avoid hard-block promotion
  unless the classifier finds a real hard runtime dependency.
- Kept as blocked: TWP `table-rotary_spindle-rotary-nutating`, `gmoccapy`,
  `axis/laser`, `axis/remap/*/nc_files`, and VMC tool-change Python remap
  families. These are not missing browser staging work; they depend on
  Python-remap, prolog/epilog, or full runtime process boundaries that have not
  been intentionally exposed in Layer 4.
- Kept out of browser full inventory: remap subroutine assets and macro-only
  non-representatives. They remain covered by native inventory, native remap
  parse/execute probes, Node inventory where eligible, or a class
  representative in browser.

## Phase 7: Documentation And Drift Control

Status: complete for the current full `configs/sim` coverage definition. The
documentation and manifest now record native inventory, generated class/path
artifacts, blocked policy, Node inventory, browser class coverage, source
reuse, and vendor-sync state.

1. Update `docs/compatibility-validation.md` with the sim-config matrix,
   blocked policy, and validation commands. Done.

2. Add `docs/sim-configs-coverage-matrix.md` as the tracked review surface for
   all 159 current native inventory rows. Done.

3. Update `docs/source-reuse-map.md` for newly vendored source files. Done.

4. Update `tools/source-manifest.txt` and `tools/verify_vendor_sync.sh` if new
   LinuxCNC files are copied into `wasm-port/vendor/linuxcnc`. Done for the
   current representative and inventory-backed sim-config files; no
   `verify_vendor_sync.sh` logic change was needed.

5. Preserve the latest result summary as a machine-readable artifact, but do
   not commit generated logs unless they are intentionally used as fixtures.
   Done: `summary.tsv` remains the source row set, and `class-summary.tsv` plus
   `path-matrix.tsv` are generated artifacts under `build/native/sim-configs/`.
   Node inventory also writes `build/wasm/sim-configs-inventory/summary.tsv`
   `build/wasm/sim-configs-inventory/skip-summary.tsv`, and
   `build/wasm/sim-configs-inventory/boundary-summary.tsv` plus
   `build/wasm/sim-configs-inventory/ini-boundary-summary.tsv` for Layer 4
   execution, skip/block accounting, and runtime-boundary dependency reporting.
   The same inventory now writes the full blocked-boundary handoff artifacts:
   `blocked-dependency-summary.tsv`, `full-process-boundary-summary.tsv`,
   `user-m-process-boundary-summary.tsv`, `user-m-process-state-targets.tsv`,
   `tool-db-process-boundary-summary.tsv`,
   `tool-db-process-protocol-gates.tsv`,
   `python-remap-boundary-summary.tsv`, `python-remap-family-summary.tsv`,
   `boundary-phase-completion-summary.tsv`,
   `native-proof-alignment-summary.tsv`, `next-boundary-worklist.tsv`, and
   `boundary-proof-gates.tsv`. These remain accounting/proof-gate artifacts;
   they do not enable blocked execution or promotion.
   The inventory guard checks `skip-summary.tsv` against skip reasons derived
   from `path-matrix.tsv`, so aggregate skip counts drift when any blocked or
   class policy changes without updating the tracked matrix and inventory.
   The inventory guard requires every vendored INI row to have an available
   SDK runtime-boundary classifier report; `UNAVAILABLE` is reserved for rows
   whose boundary summary records a missing vendored INI.
   Hard blocked rows are additionally recorded in
  `build/wasm/sim-configs-inventory/blocked-dependency-summary.tsv` without
  promotion into standalone/WASM execution. That artifact includes source
  owner fields and runtime proof fields such as `user_m_process_files`,
  `user_m_process_effects`, `tool_db_protocol_evidence`, and `linuxcnc_owner`,
  so `millturn` and `db_demo` remain blocked for dependency-backed reasons
  rather than path-only classification. The follow-up boundary design and
  required proof for those two blocked rows are tracked in
  `docs/full-process-boundary-design.md`. Node inventory also writes
  `build/wasm/sim-configs-inventory/full-process-boundary-summary.tsv` for
  the designed-but-blocked non-Python full-process rows, including their
  `runtime_owner_evidence`, and
  `build/wasm/sim-configs-inventory/python-remap-boundary-summary.tsv` for
  the Python remap inventory-only row set. The Python boundary and family
  summaries include `python_runtime_evidence`. All blocked boundary artifacts
  require `execution_enabled=0`.

## Layer 2 Expected-Failure Policy

The current Layer 2 baseline remains:

```text
total: 159
pass: 151
fail: 8
timeout: 0
expected_fail: 8
unexpected_fail: 0
```

Do not reduce the eight expected failures by changing upstream G-code, JS
interpreter behavior, or project-owned standalone interpreter semantics. Reducing
this count is only valid if a new LinuxCNC-owned native/runtime entry point can
legitimately supply the missing task/user-M/axis/TWP context while preserving the
strict native baseline as a separately documented source of truth.

## Recommended Next Work

1. Keep `verify_sim_configs.sh`, `path-matrix.tsv`, and
   `docs/sim-configs-coverage-matrix.md` in sync whenever the source manifest or
   vendored sim-config set changes.
2. Add new Node/browser representatives only when they cover a new runtime class
   with a LinuxCNC-owned execution path.
3. Treat Python remap, full-process HAL/UI, tool database, and external
   userspace process families as blocked until their runtime boundary is
   intentionally designed and the proof criteria in
   `docs/full-process-boundary-design.md` are met where applicable.
4. Re-evaluate Layer 2 expected failures only after a new legitimate
   LinuxCNC-owned entry point exists.

## Non-Goals

- Do not implement a new JavaScript or project-authored G-code interpreter.
- Do not edit `linuxcnc/configs/sim` or any upstream `linuxcnc/` file to make
  tests pass.
- Do not fake path, modal, kinematic, tool, or parameter semantics in the SDK.
- Do not treat gmoccapy native GUI code as browser UI implementation. Only its
  simulation/remap behavior is relevant to this runtime.
