# Full-Process Runtime Boundary Design

Generated: 2026-06-10 CST

This document records the first design pass for `configs/sim` rows that are
already classified by the Node inventory, but must remain blocked until a
LinuxCNC-owned runtime boundary exists. It is a design and accounting artifact,
not an execution path.

## Scope

- `axis/vismach/millturn/example.ngc`, currently `L4-USER-M-PROCESS`.
- `axis/db_demo/base.ngc`, currently `L4-TOOL-DB`.
- Python-remap and broader full-process families remain inventoried in
  `build/wasm/sim-configs-inventory/blocked-dependency-summary.tsv`; they are
  not promoted here.

## Non-Goals

- Do not implement HAL, task, HALUI, Tcl, Python, tool-database, or external
  process semantics in JavaScript.
- Do not make blocked rows pass by editing upstream G-code, Tcl, Python, INI,
  or tool-table files.
- Do not treat native GUI code or config helper scripts as browser UI
  implementation code.
- Do not mark a row unblocked until native, Node, and browser validation prove
  the boundary where that layer is applicable.

## External User-M Process Boundary

### Current Block

`axis/vismach/millturn/example.ngc` is blocked because
`millturn.ini` declares:

- `[RS274NGC]USER_M_PATH = ./mcodes`;
- `REMAP = M428 ... ngc=428remap`;
- `REMAP = M429 ... ngc=429remap`;
- `[HAL]HALUI = halui`, `HALFILE`, `HALCMD`, and `POSTGUI_HALFILE`;
- `[HALUI]MDI_COMMAND = M128` and `M129`;
- `[DISPLAY]PYVCP = millturn.xml`.

The promoted execution chain reaches `remap_subs/428remap.ngc` and
`remap_subs/429remap.ngc`. Those LinuxCNC NGC remaps execute `M68`/`M66`
switchkins synchronization and then call external user-M process codes
`M128` or `M129`.

### LinuxCNC Owner Set

- `configs/sim/axis/vismach/millturn/millturn.ini` owns the machine
  declarations and search paths.
- `configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc` and
  `429remap.ngc` own the NGC remap call sequence around `M128` and `M129`.
- `configs/sim/axis/vismach/millturn/mcodes/M128` and
  `configs/sim/axis/vismach/millturn/mcodes/M129` own the config side effects.
- `src/emc/task/emctask.cc` owns `USER_M_PATH` search, executable detection,
  `USER_DEFINED_FUNCTION_ADD()`, and queuing `EMC_SYSTEM_CMD`.
- `src/emc/task/emctaskmain.cc` owns `emcSystemCmd()` process spawning and
  completion tracking for queued system commands.
- `src/emc/usr_intf/halui.cc` owns HALUI MDI command queue behavior.
- The HAL runtime owns `hal getp`/`hal setp` state, including the `ini.*`
  soft-limit pins used by the scripts.

### Native Behavior To Preserve

`M128` is a Tcl process script that:

- requires the LinuxCNC and HAL Tcl packages;
- calls `emc_init -quick`;
- calls `parse_ini $::env(INI_FILE_NAME)`;
- checks `hal getp kinstype.is-0`;
- writes mill limits from `[AXIS_X]`, `[AXIS_Y]`, and `[AXIS_Z]` into
  `ini.x.*`, `ini.y.*`, and `ini.z.*` HAL pins.

`M129` follows the same process path, but checks `kinstype.is-1` and writes the
`MIN_LIMIT_TURN` / `MAX_LIMIT_TURN` values for X, Y, and Z. Both scripts also
restore `MAX_VELOCITY` and `MAX_ACCELERATION`.

The NGC remap files own the surrounding interpreter-visible work:

- set `motion.analog-out-03` through `M68`;
- force synchronization with `M66`;
- set G5x offsets with `G10 L2 P7` or `G10 L2 P8`;
- activate `G59.1` or `G59.2`;
- verify `_hal[motion.switchkins-type]` after the switch.

### Boundary Decision

This is not the same boundary as the existing deterministic `M110`/`M111`
registration adapter. `M110` and `M111` can currently be represented as
deterministic `USER_M_COMMAND` canonical events because the promoted tests only
need the interpreter to accept and queue the user-M command. `M128` and `M129`
must also prove HAL pin state updates that affect soft limits after a
kinematics switch.

The row therefore remains `L4-USER-M-PROCESS`.

### Current Machine-Readable Artifact

`user-m-process-boundary-summary.tsv` records the current designed-but-blocked
state target set for this boundary. It maps `M128` to
`remap_subs/428remap.ngc` and `M129` to `remap_subs/429remap.ngc`, records the
`kinstype.is-0` and `kinstype.is-1` guards, and expands the source-traceable
`ini.[xyz].min_limit`, `ini.[xyz].max_limit`, `ini.[xyz].min_velocity`, and
`ini.[xyz].max_acceleration` target pins from `millturn.ini`.
`user-m-process-state-targets.tsv` is the normalized companion table for that
same evidence. It has one pending proof row per `M128`/`M129` target pin,
including the config script source file, remap caller, mill/turn state mode,
guard pin, source INI section/field, and expected value. The current table has
24 target rows plus a header and keeps `proof_status=pending`,
`execution_enabled=0`, and `promotion_allowed=0`.
`user-m-process-transition-plan.tsv` records the next non-executing contract
for this boundary. It binds `M428` to `M128` and `M429` to `M129`, records the
`motion.analog-out-03` switchkins output, target kinstype values `0` and `1`,
the active `G59.1`/`G59.2` work offsets, `P7`/`P8` offset pockets, guard pins,
and the 12 expected `ini.[xyz].*` state outputs for each user-M code. This is
still a pending transition contract only; it does not execute Tcl, start HAL,
or permit standalone/browser promotion.
`user-m-process-native-state-alignment.tsv` aligns those 24 generated target
rows with the native source probe stdout keys, such as
`M128_X_AXIS_X.MIN_LIMIT_ok` and `M129_Z_AXIS_Z.MAX_LIMIT_TURN_ok`. This table
proves the generated pin targets still match the native LinuxCNC source/state
probe output, but it also remains `proof_status=pending`,
`execution_enabled=0`, and `promotion_allowed=0`.
`user-m-process-native-transition-alignment.tsv` aligns the two generated
transition-plan rows with native source probe stdout for `M428` and `M429`.
It verifies the source-owned `motion.analog-out-03` switchkins output, target
kinstype values `0` and `1`, active `G59.1`/`G59.2` offsets, `P7`/`P8`
offset pockets, and `M428 -> M128` / `M429 -> M129` process calls. This is
still source-transition alignment only; it does not execute the Tcl user-M
processes, start HAL, or allow promotion.
`user-m-process-native-runtime-state-plan.tsv` is the next native runnable
probe contract. It records the required LinuxCNC task/HAL/Tcl user-M runtime,
the required environment (`INI_FILE_NAME`, `motion.switchkins-type`,
`kinstype.is-0`, `kinstype.is-1`, and `ini.[xyz].*` pins), the two transition
steps, and the exact expected `ini.[xyz].*` values after each user-M process.
It requires the source transition/state alignment artifacts to be complete, but
keeps `native_runtime_status=pending_native_hal_tcl_process_probe`,
`proof_status=pending`, `execution_enabled=0`, and `promotion_allowed=0`.
`user-m-process-native-runtime-readiness.tsv` records whether the host has the
runtime commands needed to attempt that native probe. It currently checks
`tclsh`, `halrun`, `halcmd`, and `linuxcnc`, records PATH evidence where a
command exists, and keeps the boundary blocked with `proof_status=pending`,
`execution_enabled=0`, and `promotion_allowed=0` even if the commands become
available.
`user-m-process-native-runtime-probe-gate.tsv` is the generated execution gate
for the future runtime probe. It combines source proof readiness with host
runtime readiness for `M428/M128` and `M429/M129`, records missing runtime
commands, and keeps `proof_status=pending`, `execution_enabled=0`, and
`promotion_allowed=0`.
`tests/native/probe_millturn_user_m_runtime.sh` is wired into
`build_native_probes.sh` as `linuxcnc_millturn_user_m_runtime_probe`. On hosts
without `halrun`, `halcmd`, or `linuxcnc`, it exits successfully but reports
`millturn_user_m_runtime_probe_status=skipped_missing_host_runtime`; on a host
with the full LinuxCNC runtime it remains disabled by default. If explicitly
enabled with `ENABLE_MILLTURN_USER_M_RUNTIME_PROBE=1`, it starts the vendored
`millturn.ini`, runs the LinuxCNC-owned Tcl `M128`/`M129` scripts, and verifies
the resulting `ini.[xyz].*` HAL state targets before reporting
`runtime_state_probe_passed`.

The artifact keeps `execution_enabled=0` and `promotion_allowed=0`. It is not
a standalone Tcl/HAL executor and does not make `millturn` a Node/browser
representative.

`linuxcnc_millturn_user_m_boundary_probe` is the current native guard for this
evidence. It reads the LinuxCNC source `millturn.ini`, `mcodes/M128`,
`mcodes/M129`, and the `428remap`/`429remap` callers, then verifies the
source-derived guard pins, `M428`/`M429` switchkins transition fields, and
`ini.[xyz].*` target values recorded in the machine-readable tables. This is a
source/state-target and source-transition proof only: it does not execute Tcl,
start HAL, spawn the external user-M process, or permit promotion.

### Candidate Boundary

A valid future boundary would have to be LinuxCNC-owned and state based:

1. Reuse LinuxCNC task user-M search and registration behavior for discovering
   `M128` and `M129`.
2. Reuse a LinuxCNC-owned HAL/INI state boundary for the `ini.x.*`,
   `ini.y.*`, `ini.z.*`, `kinstype.is-*`, and `motion.switchkins-type` pins.
3. Execute or faithfully host the config-owned side-effect source without
   translating it into JavaScript CNC semantics. If the Tcl scripts cannot be
   executed in the target layer, the boundary must be narrowed to a documented
   LinuxCNC-owned state transition with source-traceable inputs and outputs.
4. Keep browser execution blocked unless the same state transition can be
   proven without spawning arbitrary host processes.

### Required Proof Before Promotion

Native proof:

- The existing `linuxcnc_millturn_user_m_boundary_probe` source/state guard
  must continue to prove that the pending M128/M129 state targets come from
  LinuxCNC config files rather than project-owned behavior.
- A LinuxCNC or standalone-native probe runs the `M428 -> M129 -> M429 -> M128`
  relevant switch path and records the `ini.[xyz].min_limit`,
  `ini.[xyz].max_limit`, `ini.[xyz].min_velocity`, and
  `ini.[xyz].max_acceleration` pin values before and after each user-M call.
- The same probe records the kinstype guard result and the active G5x offset.

Node WASM proof:

- The SDK stages the same INI, remap, and script assets for dependency
  accounting.
- The WASM runtime proves the same state output through a LinuxCNC-owned
  boundary. A `USER_M_COMMAND` event alone is not sufficient.

Browser proof:

- The browser smoke calls the already validated SDK/WASM boundary.
- The test labels the row as a millturn process-boundary representative only
  after the state proof exists. It must not claim full LinuxCNC HAL/task/UI
  process coverage.

## Tool Database Boundary

### Current Block

`axis/db_demo/base.ngc` is blocked because `db_nonran.ini` declares:

```text
[EMCIO]
RANDOM_TOOLCHANGER = 0
DB_PROGRAM = ./db_nonran.py
```

The INI explicitly notes that `TOOL_TABLE` is not used with `DB_PROGRAM`.
Standalone interpreter file execution would therefore bypass the tool database
startup, command/reply protocol, and persistent database state.

### LinuxCNC Owner Set

- `configs/sim/axis/db_demo/db_nonran.ini` owns the DB program declaration.
- `configs/sim/axis/db_demo/db.py` owns the demo database behavior.
- `src/emc/task/taskclass.cc` owns reading `[EMCIO]DB_PROGRAM`, enabling DB
  mode, calling `tooldata_db_init()`, loading tooldata, and notifying DB state
  changes during tool load/unload paths.
- `src/emc/tooldata/tooldata_db.cc` owns child process startup, pipe setup,
  version handshake, `g` get-all requests, and `l`/`u`/`p` notifications.
- `src/emc/tooldata/tooldata_common.cc` owns common tooldata storage and DB
  refresh behavior.

### Native Behavior To Preserve

`tooldata_db_init()` splits `DB_PROGRAM` into argv, verifies that the program is
executable, forks it, connects stdin/stdout pipes, and waits for the version
reply `v2.1`. `tooldata_db_getall()` sends `g`, resets local tooldata, reads
tool lines until `FINI`, and calls `tooldata_read_entry()` for each line.

`tooldata_db_notify()` sends:

- `l ...` for `SPINDLE_LOAD`;
- `u ...` for `SPINDLE_UNLOAD`;
- `p ...` for `TOOL_OFFSET`.

The demo `db.py` uses LinuxCNC's `tooldb` module with callbacks for:

- `user_get_tool`;
- `user_put_tool`;
- `user_load_spindle_nonran_tc` or `user_load_spindle_ran_tc`;
- `user_unload_spindle_nonran_tc` or `user_unload_spindle_ran_tc`.

It maintains a persistent flat-file database, updates tool usage minutes, and
can call `linuxcnc.command().load_tool_table` to synchronize changes back to
LinuxCNC. Those details are DB process behavior, not interpreter file
execution behavior.

### Boundary Decision

This row remains `L4-TOOL-DB`. A standalone adapter that merely loads a
fallback `.tbl` file would be wrong for this config because DB mode explicitly
replaces the tool table file path.

### Current Machine-Readable Artifact

`tool-db-process-boundary-summary.tsv` records the current designed-but-blocked
protocol and state target set for this boundary. It records `DB_PROGRAM =
./db_nonran.py`, the LinuxCNC tooldata protocol messages `v2.1`, `g`, `l`, `u`,
and `p`, the demo DB callbacks `user_get_tool`, `user_put_tool`,
`user_load_spindle_nonran_tc`, and `user_unload_spindle_nonran_tc`, and the
nonrandom database state targets such as `T10..T19`, `/tmp/db_nonran_file`,
`tno+100` startup pockets, and pocket-0 spindle load/unload behavior.
`tool-db-process-protocol-gates.tsv` is the normalized companion table for
that evidence. It splits the blocked DB boundary into pending protocol-message,
DB-program-callback, and state-target gates, including the `v2.1` startup
reply, `g` get-all through `FINI`, `l`/`u`/`p` notifications, demo callback
registration, ignored `TOOL_TABLE`, startup tools, nonrandom pocket mapping,
and persistence/sync targets. The current table keeps `proof_status=pending`,
`execution_enabled=0`, and `promotion_allowed=0`.
`tool-db-process-transaction-plan.tsv` records the next non-executing contract
for this boundary. It orders the pending DB protocol into startup handshake,
initial get-all, spindle load notify, tool offset notify, and spindle unload
notify steps. Each step binds one LinuxCNC protocol message to the expected
`db.py` callback, required native/Node/browser proof, and source-traceable
state targets. This is still a transaction contract only; it does not start
`DB_PROGRAM`, run Python, mutate `/tmp/db_nonran_file`, fall back to a tool
table, or permit standalone/browser promotion.
`tool-db-process-native-protocol-alignment.tsv` aligns those generated gates
with the native source probe stdout keys, such as `tool_db_v2_1_handshake`,
`tool_db_getall_g_until_fini`, `tool_db_notify_l_u_p_protocol`, and
`tool_db_program_nonran_state_targets`. This table proves the generated gates
still match LinuxCNC-owned task/tooldata/config evidence, but it also remains
`proof_status=pending`, `execution_enabled=0`, and `promotion_allowed=0`.
`tool-db-process-native-runtime-readiness.tsv` records whether the host has
the runtime pieces needed to attempt a DB process protocol probe. It checks
`python3`, `linuxcnc`, `milltask`, `halcmd`, the configured
`axis/db_demo/db_nonran.py` program, and the LinuxCNC Python `linuxcnc.so` and
`tooldb.py` modules. It records PATH/source evidence where available and keeps
the DB boundary blocked with `proof_status=pending`, `execution_enabled=0`,
and `promotion_allowed=0`.
`tests/native/probe_tool_db_runtime.sh` is wired into `build_native_probes.sh`
as `linuxcnc_tool_db_runtime_probe`. On hosts without the required DB runtime
commands it exits successfully with `tool_db_runtime_probe_status =
skipped_missing_host_runtime`; on a ready host it remains disabled by default.
If explicitly enabled with `ENABLE_TOOL_DB_RUNTIME_PROBE=1`, it starts the
vendored `DB_PROGRAM`, drives the LinuxCNC `tooldb.py` `v2.1`/`g`/`p`/`l`/`u`
protocol over stdin/stdout, verifies nonrandom `T10..T19` startup state, tool
update, spindle load/unload, and flat-file persistence, then reports
`runtime_protocol_probe_passed`.

The artifact keeps `execution_enabled=0` and `promotion_allowed=0`. It is not
a standalone tool database executor, does not replace `DB_PROGRAM` with a
fallback `.tbl`, and does not make `axis/db_demo/base.ngc` a Node/browser
representative.

`linuxcnc_tool_db_boundary_probe` is the current native guard for this
evidence. It reads the LinuxCNC source `db_nonran.ini`, `db.py`,
`src/emc/task/taskclass.cc`, and `src/emc/tooldata/tooldata_db.cc`, then
verifies the DB mode owner path, child-process protocol, `v2.1` startup
handshake, `g`/`FINI` get-all path, `l`/`u`/`p` notifications, demo DB
callbacks, and nonrandom state targets. This is a source/protocol-target proof
only: it does not start `DB_PROGRAM`, run the Python tooldb loop, mutate the
flat-file database, or permit promotion.

### Candidate Boundary

A valid future boundary should be a narrow tool-database host adapter:

1. Reuse `tooldata_db.cc` and `tooldata_common.cc` for DB mode behavior.
2. Isolate the process-spawn edge behind a host abstraction so native can spawn
   the configured DB program, while WASM/browser use an explicitly designed
   equivalent only if it preserves the LinuxCNC protocol.
3. Preserve the `v2.1`, `g`, `l`, `u`, and `p` command/reply protocol rather
   than parsing or inventing tool semantics in JavaScript.
4. Treat `db.py` as a config-owned process dependency. If it is not executable
   in a target layer, that layer remains blocked.

### Required Proof Before Promotion

Native proof:

- The existing `linuxcnc_tool_db_boundary_probe` source/protocol guard must
  continue to prove that the pending DB gates come from LinuxCNC task/tooldata
  and demo DB sources rather than project-owned behavior.
- A probe starts `db_nonran.py` through the LinuxCNC DB path and verifies the
  `v2.1` handshake.
- A get-all request returns the expected nonrandom startup tools.
- A load/unload or update path changes DB state through `l`, `u`, or `p` and
  is reflected by a subsequent get-all.

Node WASM proof:

- The same protocol is visible through the SDK boundary.
- Tool lookup/update behavior matches the native proof without staging a fake
  `.tbl` replacement.

Browser proof:

- Browser validation calls the Node-proven SDK/WASM boundary.
- OPFS may store DB files only as host persistence. It must not implement DB
  command semantics.

## Python-Remap Inventory Boundary

Python-remap rows remain inventory-only. The current
`blocked-dependency-summary.tsv` records Python modules, remap/prolog/epilog
functions, NGC-only subpaths, and HAL/UI/HALUI declarations.
`python-remap-boundary-summary.tsv` preserves the same evidence per blocked
path and records LinuxCNC Python runtime owner evidence from
`src/emc/rs274ngc/interp_python.cc` and
`src/emc/pythonplugin/python_plugin.cc`. `python-remap-family-summary.tsv`
aggregates it by runtime family so mixed Python/NGC-only subpaths remain
visible without promoting execution. No Python-remap row should be promoted
until a separate LinuxCNC-owned Python runtime boundary exists and has native
plus Node/browser proof appropriate to the target layer.
`python-remap-runtime-gates.tsv` expands each blocked path into Python module,
remap/prolog/epilog callable, NGC-only subpath, process-assumption, and
runtime-owner gates. `python-remap-native-runtime-alignment.tsv` aligns those
generated gates with the current native source probe stdout. Runtime owner
gates map to exact LinuxCNC runtime proof keys such as
`python_runtime_pycall_dispatch` and `python_plugin_callable_invoke`; dependency
inventory gates map to representative family inventory proof or the aggregate
`python_remap_native_source_inventory_proof`. Both tables remain
`proof_status=pending`, `execution_enabled=0`, and `promotion_allowed=0`.
`python-remap-runtime-contract.tsv` records the next non-executing family-level
contract. It keeps one row per blocked Python-remap family, records the
LinuxCNC-owned Python runtime phases (`initialize_python`,
`apply_ini_python_path`, `execute_toplevel`, callable lookup/invoke,
remap-phase dispatch, generator finish, execute-string/file, and reload),
aggregates Python modules/callables/NGC-only subpaths, carries HAL/UI/HALUI
process assumptions, and binds each family to native, Node, and browser proof
requirements. It is a runtime contract only: it does not initialize Python,
import modules, execute callbacks, or permit promotion.
`python-remap-native-runtime-readiness.tsv` records the current host/source
readiness for future native Python-remap runtime probes. It checks `python3`,
`linuxcnc`, the LinuxCNC interpreter/plugin owner source files, and each
configured Python module by blocked runtime family. The artifact remains a
gate only: every row stays `proof_status=pending`, `execution_enabled=0`, and
`promotion_allowed=0`.
`python-remap-native-runtime-state-plan.tsv` records the non-executing runtime
state plan for those future probes. It binds each blocked Python-remap family
to the required LinuxCNC Python phases, configured modules, callables,
NGC-only subpaths, process assumptions, readiness counts, source-alignment
artifacts, and future native proof targets. It does not initialize Python,
import modules, execute callbacks, or permit promotion.
`python-remap-native-runtime-fixture-plan.tsv` selects the first native runtime
fixture target, `axis/remap/stop-lookahead/nc_files`. That family is the
smallest current Python runtime lifecycle candidate because it needs the
LinuxCNC Python initialization/path/toplevel/runtime phases and configured
modules but avoids Python callable and NGC-only subpath complexity. The
fixture plan is still non-executing: it records the proof target only and
keeps `proof_status=pending`, `execution_enabled=0`, and
`promotion_allowed=0`.
`tests/native/probe_python_remap_runtime.sh` is wired into
`build_native_probes.sh` as `linuxcnc_python_remap_runtime_probe`. It records
the stop-lookahead fixture identity, configured Python modules, required
LinuxCNC Python runtime phases, host command readiness, and source/module
availability. On hosts without `linuxcnc`, it exits successfully but reports
`python_remap_runtime_probe_status=skipped_missing_host_runtime`; on hosts with
the runtime available it remains disabled by default. If explicitly enabled
with `ENABLE_PYTHON_REMAP_RUNTIME_PROBE=1`, it follows the `demo.ini`
`[PYTHON]` path/toplevel declarations, imports the vendored stop-lookahead
modules, verifies `queuebuster` callable lookup, confirms the callable returns
a generator, and checks that the first yield is the LinuxCNC
`INTERP_EXECUTE_FINISH` value from `interp_return.hh` before reporting
`runtime_lifecycle_probe_passed`.

`linuxcnc_python_remap_boundary_probe` is the current native guard for this
inventory. It reads the LinuxCNC Python runtime owners and representative
config families (`axis/laser`, `axis/remap/cycle`, TWP nutating, and
`gmoccapy` stdglue), then verifies the runtime dispatch/phase/callable owner
evidence plus representative Python modules, remap callables, prolog/epilog
callables, and Python path declarations. This is source inventory only: it
does not initialize Python, import modules, execute remap callbacks, or permit
promotion.

## Next Boundary Worklist

`next-boundary-worklist.tsv` is the machine-readable handoff for the next
runtime-boundary design phase. It is a planning artifact only: every row keeps
`execution_enabled=0` and `promotion_allowed=0`, records the LinuxCNC owner set,
records runtime owner evidence, records required native, Node, and browser
proof, and names the next boundary-design action before promotion.

`boundary-proof-gates.tsv` is the machine-readable proof checklist derived from
that worklist. It expands every target into native, Node, and browser proof
rows and keeps each row at `proof_status=pending`, `execution_enabled=0`, and
`promotion_allowed=0`. It must fail validation if a future edit tries to
promote a target without first replacing the pending gate with LinuxCNC-owned
proof for that layer. For the current blockers, event-only `USER_M_COMMAND`
coverage is insufficient for `millturn`, `.tbl` fallback coverage is
insufficient for `db_demo`, and JavaScript-owned behavior is insufficient for
Python runtime families.

`native-proof-alignment-summary.tsv` records whether the native source proof
summary, when present, is consumed by generated worklist and native proof-gate
rows. It currently aligns the `millturn` user-M source-state proof, `db_demo`
tool database protocol source proof, and Python runtime source-inventory proof
without enabling execution or promotion.
`runtime-boundary-native-alignment-summary.tsv` is the aggregate guard for the
detailed native alignment artifacts. It requires every user-M, tool DB, and
Python alignment row to have native stdout evidence, `alignment_ok=1`,
`proof_status=pending`, `execution_enabled=0`, and `promotion_allowed=0`.
`build/native/native-runtime-probe-summary.tsv` is the native companion for the
disabled runtime probe entry points. It summarizes the current runtime
readiness for `millturn` user-M, `db_demo` tool DB, and the Python
stop-lookahead fixture, records the missing host runtime requirements, points
back to each probe stdout log, and keeps every row at `execution_enabled=0` and
`promotion_allowed=0`.
`runtime-boundary-contract-summary.tsv` is the aggregate guard for the
non-executing runtime contracts. It ties the `millturn` user-M transition
contract, `db_demo` tool DB transaction contract, and Python-remap family
runtime contract to their native-alignment artifacts, and requires every
contract row to remain pending with execution and promotion disabled.
`blocked-runtime-promotion-lock.tsv` is the final machine-readable lock for
this phase. It combines the worklist, native/Node/browser proof gates, and
runtime alignment summary so every blocked target has `lock_active=1` until a
LinuxCNC-owned runtime boundary replaces the pending gates.

## Host Preflight Runbook

The blocked runtime probes are manual opt-in probes. They must not be run just
because the probe script exists. A future host must first pass the generated
preflight and dispatch checks for the specific blocked family.

Before attempting any opt-in probe, inspect:

```bash
wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
cat wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-host-preflight.tsv
cat wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-family-host-readiness.tsv
cat wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-host-readiness-rollup.tsv
cat wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-opt-in-probe-dispatch-plan.tsv
cat wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-opt-in-probe-dispatch-rollup.tsv
cat wasm-port/build/wasm/sim-configs-inventory/native-runtime-probe-execution-plan.tsv
cat wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-native-evidence-acceptance-gate.tsv
cat wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-promotion-blockers.tsv
```

The current host is not ready for any blocked runtime opt-in probe. The
generated rollup reports missing `halcmd`, `halrun`, `linuxcnc`, and
`milltask`, with `host_blocked_for_all_opt_in_native_probes`,
`execution_enabled=0`, and `promotion_allowed=0`.

The opt-in commands remain forbidden while their dispatch rows have
`dispatch_allowed=0`:

```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
```

A probe may be attempted only when all of these are true for that family:

- the corresponding runtime probe gate reports `runtime_ready=1`;
- `runtime-boundary-family-host-readiness.tsv` reports the family ready;
- `runtime-boundary-opt-in-probe-dispatch-plan.tsv` reports
  `dispatch_allowed=1`;
- `runtime-boundary-opt-in-probe-dispatch-rollup.tsv` does not block that
  command;
- the probe is run manually with its explicit `ENABLE_*_RUNTIME_PROBE=1`
  environment variable.

Passing a native opt-in probe is not promotion. After a native pass, the row
must still satisfy:

- `native-runtime-probe-pass-evidence-contract.tsv`;
- `runtime-probe-gate-alignment.tsv`;
- `runtime-boundary-promotion-readiness.tsv`;
- `runtime-boundary-post-native-pass-gates.tsv`;
- `runtime-boundary-native-evidence-acceptance-gate.tsv`;
- `runtime-boundary-promotion-blockers.tsv`;
- Node inventory proof;
- browser smoke proof where applicable;
- manual update of `blocked-runtime-promotion-lock.tsv`;
- documentation updates in this file, `compatibility-validation.md`, and
  `sim-configs-coverage-matrix.md`.

While the skip/evidence artifacts report
`skip_valid_until_host_requirements_available` and
`no_native_pass_evidence_accepted_while_host_blocked`, skipped probes provide
no native pass evidence. They only prove that the current host is correctly
blocked.

`native-runtime-probe-execution-plan.tsv` and
`next-boundary-recommendations.tsv` are planning handoffs, not permission to
run probes. They name the next recommended boundary work and exact opt-in
commands, but the host preflight and dispatch rows still decide whether those
commands are allowed on the current machine.

The first two priorities are the current designed-but-disabled full-process
blocks:

1. `external_user_m_process` for `axis/vismach/millturn/example.ngc`;
2. `tool_database_process` for `axis/db_demo/base.ngc`.

Python runtime family rows follow as inventory-only targets. They must remain
behind a LinuxCNC-owned Python runtime boundary and must not be used to vendor
or execute `gmoccapy`, `axis/laser`, TWP nutating, or other Python-remap
families by path alone.

## Current Validation

These commands must continue to pass after any change to this document or to
the inventory code:

```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
wasm-port/tests/host/verify_host_smokes.sh
wasm-port/tools/verify_vendor_sync.sh
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
```
