82 KiB
Compatibility Validation
Purpose
This document records how the standalone LinuxCNC WASM port currently proves that migrated behavior remains tied to LinuxCNC source code and fixture semantics.
The primary native validation command is:
wasm-port/tests/native/verify_native_probes.sh
The native LinuxCNC nc_files basic/example validation command is:
wasm-port/tests/native/verify_nc_files.sh
The current WASM smoke validation command is:
wasm-port/tests/wasm/node/verify_ini_wasm.sh
The current WASM interpreter-core smoke validation command is:
wasm-port/tests/wasm/node/verify_interp_wasm.sh
The current WASM sim-config smoke validation command is:
wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
The current WASM sim-config inventory validation command is:
wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
The current WASM nc_files smoke validation command is:
wasm-port/tests/wasm/node/verify_nc_files_wasm.sh
The current WASM trajectory-planner smoke validation command is:
wasm-port/tests/wasm/node/verify_tp_wasm.sh
The current OPFS host-boundary validation command is:
wasm-port/tests/opfs/node/verify_file_service.sh
The current browser smoke validation command is:
wasm-port/tests/browser/verify_ini_panel_browser.sh
The current browser interpreter smoke validation command is:
wasm-port/tests/browser/verify_interp_browser.sh
The current aggregate host/WASM/browser smoke command is:
wasm-port/tests/host/verify_host_smokes.sh
Validation Layers
Use these layers when deciding where a LinuxCNC asset belongs. Do not widen a later layer until the narrower layer has either passed or recorded an explicit expected boundary.
| Layer | Scope | Entry command | Current result | Expected boundary |
|---|---|---|---|---|
| 1 | linuxcnc/nc_files basic G-code smoke |
wasm-port/tests/native/verify_nc_files.sh |
total: 107, pass: 101, expected_fail: 6, unexpected_fail: 0 |
LinuxCNC-native entry-point/context edges only: W-axis machine context, lathe tool/cutter-comp context, upstream O-word syntax edge, and probe runtime context. |
| 2 | linuxcnc/configs/sim native strict harness |
wasm-port/tests/native/verify_sim_configs.sh |
total: 159, pass: 151, expected_fail: 8, unexpected_fail: 0 |
Native bin/rs274 cannot provide task/user-M process execution or some INI axis-mask/runtime context. The upstream incremental_repetition_g533.ngc demo remains an expected upstream demo edge and must not be made pass by changing G-code semantics. |
| 3 | Standalone native runtime probes | wasm-port/tests/native/verify_native_probes.sh |
Passes with native probes complete after source sync, no-standalone-semantics, fixture baseline, sim-config, and nc_files checks |
Runtime adapters may cover filesystem, HAL/user-M, remap, parameter, tool, kinematics, TP, and WASM/browser boundary behavior, but CNC semantics must still come from vendored LinuxCNC source. |
| 4 | WASM Node/browser representative smoke | wasm-port/tests/host/verify_host_smokes.sh plus targeted Node/browser commands below |
Current targeted checks pass with sim_configs_wasm_node_smoke=ok, nc_files_wasm_node_smoke=ok, browser_interp_smoke=ok, browser_ini_opfs_smoke=ok, and aggregate host_wasm_opfs_browser_smokes=ok |
JS/browser code may stage files, apply executable bits, persist OPFS text, and forward paths to C ABI calls. It must not implement G-code, remap, tool-table, parameter, planner, kinematics, or user-M semantics. |
Layer 4 is made of focused smoke commands so failures can be isolated before running the aggregate host check:
wasm-port/tests/wasm/node/verify_ini_wasm.sh
wasm-port/tests/wasm/node/verify_interp_wasm.sh
wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh
wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
wasm-port/tests/wasm/node/verify_nc_files_wasm.sh
wasm-port/tests/wasm/node/verify_tp_wasm.sh
wasm-port/tests/opfs/node/verify_file_service.sh
wasm-port/tests/browser/verify_ini_panel_browser.sh
wasm-port/tests/browser/verify_interp_browser.sh
wasm-port/tests/host/verify_host_smokes.sh
Layer 4 INI-context staging uses planIniFileContextStaging() to collect
INI-declared [DISPLAY]OPEN_FILE, [EMCIO]TOOL_TABLE,
[RS274NGC]PARAMETER_FILE, [RS274NGC]SUBROUTINE_PATH,
[RS274NGC]USER_M_PATH, and remap-NGC files from the vendored source
manifest without browser directory enumeration. planSimConfigStaging() is the
configs/sim wrapper around that generic planner. These planners are host
filesystem helpers only; execution still goes through vendored LinuxCNC
interpreter/remap/tool/parameter code.
Layer responsibilities are intentionally narrow:
| Layer | LinuxCNC-owned behavior | Host/WASM adapter allowance | Expected-failure policy |
|---|---|---|---|
| 1 | nc_files parsing and execution through upstream rs274 |
Generate only the native harness INI/tool-table context needed to classify upstream examples | Expected failures document missing machine/task context or known upstream example edges; they must not be made pass by changing G-code semantics. |
| 2 | configs/sim file execution through upstream rs274 with sim INI context |
Locate the corresponding INI/tool table and classify main programs, macros, and remap subroutines | Expected failures document upstream standalone rs274 limits such as task/user-M process edges and the preserved incremental_repetition_g533.ngc demo edge. |
| 3 | Vendored LinuxCNC interpreter, remap, tool, parameter, kinematics, and planner code | Provide deterministic runtime shims for filesystem, HAL/user-M boundaries, machine status, and build/source-probe coverage | A standalone pass may cover a runtime edge that Layer 1/2 cannot provide, but it must still call vendored LinuxCNC source for CNC behavior. |
| 4 | Vendored LinuxCNC C ABI behavior from generated WASM modules | Stage files, apply executable bits, persist OPFS text, generate manifest-based staging plans, and forward paths/results between JS/browser and C ABI | A WASM/browser pass proves the host boundary can reproduce the staged LinuxCNC context; it does not replace native source validation or justify JS-owned CNC semantics. |
Layer 2 Expected Failures
The current wasm-port/tests/native/verify_sim_configs.sh run reports
total: 159, pass: 151, expected_fail: 8, and unexpected_fail: 0.
The eight expected failures are listed in the table below.
The tracked per-program inventory for this layer now lives in
wasm-port/docs/sim-configs-coverage-matrix.md. That matrix maps all 159
current summary.tsv records to program class, native result, current
Layer 3/4 coverage, and the first-pass blocked or follow-up note used for
future configs/sim coverage work.
The native harness also emits machine-readable derived artifacts without
changing the summary.tsv schema:
wasm-port/build/native/sim-configs/class-summary.tsv
wasm-port/build/native/sim-configs/path-matrix.tsv
class-summary.tsv aggregates class/status/expected-failure counts.
path-matrix.tsv records each path, class, native status, expected-failure
reason, INI, tool table, runtime family, and blocked kind for CI and Node
inventory reconciliation.
The Node inventory layer writes its own machine-readable artifacts:
wasm-port/build/wasm/sim-configs-inventory/summary.tsv
wasm-port/build/wasm/sim-configs-inventory/skip-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/boundary-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/ini-boundary-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/blocked-dependency-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/full-process-boundary-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/user-m-process-state-targets.tsv
wasm-port/build/wasm/sim-configs-inventory/user-m-process-native-state-alignment.tsv
wasm-port/build/wasm/sim-configs-inventory/tool-db-process-protocol-gates.tsv
wasm-port/build/wasm/sim-configs-inventory/tool-db-process-native-protocol-alignment.tsv
wasm-port/build/wasm/sim-configs-inventory/python-remap-boundary-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/python-remap-runtime-gates.tsv
wasm-port/build/wasm/sim-configs-inventory/python-remap-native-runtime-alignment.tsv
wasm-port/build/wasm/sim-configs-inventory/python-remap-native-runtime-readiness.tsv
wasm-port/build/wasm/sim-configs-inventory/python-remap-native-runtime-state-plan.tsv
wasm-port/build/wasm/sim-configs-inventory/python-remap-native-runtime-fixture-plan.tsv
wasm-port/build/wasm/sim-configs-inventory/python-remap-family-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/boundary-phase-completion-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/native-proof-alignment-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-native-alignment-summary.tsv
wasm-port/build/wasm/sim-configs-inventory/blocked-runtime-promotion-lock.tsv
wasm-port/build/wasm/sim-configs-inventory/next-boundary-worklist.tsv
wasm-port/build/wasm/sim-configs-inventory/boundary-proof-gates.tsv
The current skip/block summary is ASSET-ONLY=65, L4-PYTHON-REMAP=53,
L4-TOOL-DB=1, L4-USER-M-PROCESS=1, NON_MAIN_CLASS=10, and
UPSTREAM-DEMO=1.
skip-summary.tsv is checked against the skip reasons derived from
path-matrix.tsv, so both the per-row inventory status and the aggregate
skip counts fail on blocked-policy drift.
For eligible rows, missing vendored machine context is an inventory failure,
not an expected skip; blocked rows must be classified by runtime dependency
before the Node inventory filter runs.
boundary-summary.tsv records one row per native inventory path with the
matrix blocked kind, SDK classifier recommendation, declared HAL/UI/HALUI/Python
process dependencies, [EMCIO]DB_PROGRAM, user-M execution codes, and the
subset of execution user-M codes that are not staged by vendored
USER_M_PATH files. It also separates Python UI/DB process dependencies from
Python remap runtime dependencies. For vendored INI rows, the SDK classifier
report must be available and L4-TOOL-DB / L4-USER-M-PROCESS hard blocks
must match the classifier recommendation. recommended_blocked=UNAVAILABLE is
only allowed when the boundary row records a missing vendored INI. Non-vendored
Python-remap families remain unavailable until their dependency inventory batch
vendors the required INI context.
ini-boundary-summary.tsv aggregates those path-level reports by INI, giving
vendored sim-config INIs a direct report_available=1 coverage check and
recording hard-block recommendation alignment at INI granularity.
The inventory also guards safe representative rows such as
axis/gladevcp/probe.ngc, woodpecker/on_abort.ngc,
axis/vismach/puma/puma_cube.ngc, and
axis/vismach/melfa-sim/example.ngc: they must keep their declared process
dependencies in boundary-summary.tsv, remain Node/browser representatives,
match the expected HAL/UI/HALUI/Python process flags, and avoid hard-block
promotion unless a real hard runtime dependency appears.
Deterministic M110/M111 representatives are also guarded: the inventory
must see the execution-chain user-M code, a vendored user-M file, and no hard
L4-USER-M-PROCESS recommendation. opa_demo.ngc includes its vendored
circles.ngc subroutine text in the boundary analysis so the M111 call is
accounted for even though it is reached through SUBROUTINE_PATH.
blocked-dependency-summary.tsv records the hard blocked rows without
promoting them: 53 Python-remap rows, one tool-database row, and one external
user-M process row. It reads the source linuxcnc/configs/sim INI files for
dependency accounting only and records Python modules, remap/prolog/epilog
function ownership, NGC remap subpaths, HAL/UI/HALUI process declarations,
DB_PROGRAM, tool database protocol evidence, external user-M execution
codes, user-M process script files, user-M process side-effect evidence, and
the LinuxCNC source/config files that own the blocked behavior. The user-M
evidence is source-derived from the M128/M129 Tcl scripts and records their
Tcl/HAL runtime use, kinstype guard, and ini.[xyz] HAL pin updates. The tool
database evidence is source-derived from taskclass.cc, tooldata_db.cc, and
axis/db_demo/db.py, including the v2.1 handshake, g/FINI get-all, and
l/u/p notification protocol.
The final Node inventory summary.tsv also guards every hard-blocked row:
L4-TOOL-DB, L4-USER-M-PROCESS, and L4-PYTHON-REMAP paths must remain
SKIP with their matching blocked reason, not only carry a matrix-level
blocked label.
The detailed boundary design for the current non-Python hard blocks is tracked
in wasm-port/docs/full-process-boundary-design.md. That document records the
LinuxCNC owner sets and proof required before axis/vismach/millturn/example.ngc
or axis/db_demo/base.ngc can move out of L4-USER-M-PROCESS or
L4-TOOL-DB. It is not an execution artifact and does not change the current
Layer 4 blocked counts.
full-process-boundary-summary.tsv is the machine-readable companion for that
design record. It has one designed-but-blocked row for millturn and one for
db_demo, records the LinuxCNC runtime owner evidence from the corresponding
blocked dependency row, records the required native/Node/browser proof, and
keeps execution_enabled=0 until the corresponding LinuxCNC-owned runtime
boundary exists. The tracked matrix and inventory guard also require those two
rows to remain non-representative in Node/browser until that proof exists.
user-m-process-state-targets.tsv expands the millturn M128/M129 process
boundary into per-pin proof targets: two user-M codes, three axes, and four
ini.[xyz] HAL pins per axis. Each row records the source Tcl file, remap
caller, kinstype guard, INI source section/field, expected value,
proof_status=pending, execution_enabled=0, and promotion_allowed=0.
user-m-process-native-state-alignment.tsv then aligns each generated pin
target with the native source probe stdout key/value pair, for example
M128_X_AXIS_X.MIN_LIMIT_ok=1. This catches drift between generated target
rows and the LinuxCNC-owned native source proof without executing Tcl/HAL or
allowing promotion.
user-m-process-native-transition-alignment.tsv performs the same source
alignment for the M428/M429 transition plan. It checks the native probe
stdout for motion.analog-out-03, kinstype targets 0 and 1,
G59.1/G59.2, P7/P8, and the M428 -> M128 / M429 -> M129 calls.
Those rows also remain proof_status=pending, execution_enabled=0, and
promotion_allowed=0.
user-m-process-native-runtime-state-plan.tsv is the runnable native probe
contract that follows those source-alignment tables. It names the required
LinuxCNC task/HAL/Tcl user-M process runtime, the required HAL/INI
environment, and the exact ini.[xyz].* state values that a future native
runtime probe must record after M428 and M429. It remains a plan only with
native_runtime_status=pending_native_hal_tcl_process_probe,
execution_enabled=0, and promotion_allowed=0.
user-m-process-native-runtime-readiness.tsv is the host capability gate for
that future probe. It records availability of tclsh, halrun, halcmd, and
linuxcnc, captures PATH evidence for available commands, and leaves
proof_status=pending, execution_enabled=0, and promotion_allowed=0.
user-m-process-native-runtime-probe-gate.tsv combines that readiness with the
source/state proof for M428/M128 and M429/M129. The native
probe_millturn_user_m_runtime.sh entry point is wired through
build_native_probes.sh; without the full LinuxCNC HAL/Tcl command set it
reports skipped_missing_host_runtime, and with the runtime present it remains
disabled by default. When explicitly enabled with
ENABLE_MILLTURN_USER_M_RUNTIME_PROBE=1, it starts the vendored millturn.ini,
runs the LinuxCNC-owned Tcl M128/M129 scripts, verifies the expected
ini.[xyz].* HAL pin state, and reports runtime_state_probe_passed without
enabling promotion.
tool-db-process-protocol-gates.tsv expands the db_demo tool-database
boundary into pending protocol, callback, and state gates. It records the
LinuxCNC v2.1, g, l, u, and p protocol requirements, the demo DB
callbacks, DB mode state targets such as ignored TOOL_TABLE, T10..T19,
tno+100 pockets, and OPFS/host persistence boundaries, while keeping
proof_status=pending, execution_enabled=0, and promotion_allowed=0.
tool-db-process-native-protocol-alignment.tsv aligns each generated DB gate
with the native source probe stdout proof keys, including the protocol
handshake, get-all, notifications, callback registration, and nonrandom state
targets. This is still dependency/proof accounting only: it does not spawn
DB_PROGRAM, emulate the tool database protocol in JavaScript, or fall back to
a .tbl file.
tool-db-process-native-runtime-readiness.tsv records the host prerequisites
for the guarded DB process protocol probe: python3, linuxcnc, milltask,
halcmd, the configured db_nonran.py executable, and LinuxCNC's Python
linuxcnc.so / tooldb.py modules. It captures availability evidence while
keeping proof_status=pending, execution_enabled=0, and
promotion_allowed=0. When explicitly enabled with
ENABLE_TOOL_DB_RUNTIME_PROBE=1, probe_tool_db_runtime.sh starts the
vendored DB_PROGRAM, drives the LinuxCNC tooldb.py v2.1/g/p/l/u
protocol, verifies nonrandom startup/update/load/unload state and persistence,
and reports runtime_protocol_probe_passed without enabling promotion.
python-remap-boundary-summary.tsv is the machine-readable companion for the
Python remap inventory batch. It has one inventory-only row for each
L4-PYTHON-REMAP path, records Python modules, remap/prolog/epilog functions,
NGC-only subpaths, HAL/UI/HALUI assumptions, LinuxCNC Python runtime owner
evidence from interp_python.cc and python_plugin.cc, and keeps
execution_enabled=0 until a LinuxCNC-owned Python runtime boundary exists.
python-remap-runtime-gates.tsv expands those rows into Python module,
remap/prolog/epilog callable, NGC-only subpath, process-assumption, and
runtime-owner gates, all with proof_status=pending,
execution_enabled=0, and promotion_allowed=0.
python-remap-native-runtime-alignment.tsv aligns every generated Python gate
with native source proof: exact runtime owner gates use keys such as
python_runtime_pycall_dispatch, while dependency gates use representative
family inventory proof or the aggregate
python_remap_native_source_inventory_proof. It does not initialize Python,
import modules, execute callbacks, or promote browser/Node coverage.
python-remap-native-runtime-readiness.tsv records the native runtime
prerequisites for guarded probes by family: python3, linuxcnc,
LinuxCNC's interp_python.cc / python_plugin.cc owner source files, and the
configured Python modules. It is a readiness gate only and keeps every row
proof_status=pending, execution_enabled=0, and promotion_allowed=0.
python-remap-native-runtime-state-plan.tsv records the next native runtime
probe target set by family: LinuxCNC Python phases, configured modules,
callables, NGC-only subpaths, process assumptions, readiness counts, and
source-alignment artifacts. It remains a plan only and does not initialize
Python, import modules, execute callbacks, or permit promotion.
python-remap-native-runtime-fixture-plan.tsv selects the first minimal
Python runtime lifecycle fixture, axis/remap/stop-lookahead/nc_files, because
it exercises Python runtime phases and configured modules without Python
callable or NGC-only subpath complexity. It is still a fixture plan only:
proof_status=pending, execution_enabled=0, and promotion_allowed=0.
When explicitly enabled with ENABLE_PYTHON_REMAP_RUNTIME_PROBE=1,
probe_python_remap_runtime.sh follows the fixture demo.ini Python path and
toplevel declarations, imports the vendored modules, verifies queuebuster
callable lookup, generator return, and first INTERP_EXECUTE_FINISH yield, and
reports runtime_lifecycle_probe_passed without promoting Python-remap
execution.
python-remap-family-summary.tsv aggregates the same blocked rows by runtime
family, preserving row and INI counts plus family-level Python module,
remap/prolog/epilog, NGC-only subpath, Python runtime owner evidence,
HAL/UI/HALUI, and execution_enabled=0 evidence. It is dependency inventory
only and must not be used to promote Python-remap execution.
boundary-phase-completion-summary.tsv records the current boundary-phase
completion criteria as machine-readable checks: vendored INI boundary report
coverage, hard-block dependency evidence, safe HAL/UI representative coverage,
proof that blocked families remain skipped/non-representative with execution
disabled, and proof that blocked runtime families carry LinuxCNC-owned user-M,
tool DB, and Python runtime evidence fields. It also records native source
proof alignment when the native proof summary is available, plus the aggregate
native stdout alignment summary for user-M, tool DB, and Python runtime gates.
native-proof-alignment-summary.tsv aligns native source proof rows with the
generated worklist and native proof gates for user-M, tool DB, and Python
runtime blockers. It is proof-consumption accounting only and keeps execution
and promotion disabled.
runtime-boundary-native-alignment-summary.tsv summarizes the three detailed
native alignment artifacts. It requires every alignment row to have native
stdout evidence, alignment_ok=1, proof_status=pending,
execution_enabled=0, and promotion_allowed=0.
blocked-runtime-promotion-lock.tsv combines the next-boundary worklist,
native/Node/browser proof gates, and runtime native alignment summary into one
promotion lock per blocked runtime target. A lock row is active only while
every proof layer is still pending, execution and promotion remain disabled,
and the matching runtime alignment artifact is complete.
next-boundary-worklist.tsv records the next blocked runtime-boundary design
targets in priority order. It starts with the designed-but-disabled
millturn external user-M process and db_demo tool database process
boundaries, then lists Python runtime families from the inventory. Every row
keeps execution_enabled=0 and promotion_allowed=0, records the LinuxCNC
owner set and runtime owner evidence, records required native, Node, and
browser proof, and names the next boundary-design action before promotion.
boundary-proof-gates.tsv expands that worklist into one pending native,
Node, and browser proof gate per target. It is a promotion guard only: current
rows keep proof_status=pending, execution_enabled=0, and
promotion_allowed=0; user-M gates must require HAL pin state rather than
event-only proof, tool-DB gates must require protocol proof rather than a
.tbl fallback, and Python gates must require a LinuxCNC-owned Python runtime
boundary rather than JavaScript semantics.
The browser interpreter smoke reads the browser-layer rows from this artifact
before running safe representatives, so millturn, db_demo, and Python
runtime families cannot be accidentally treated as browser/full-process
coverage while their proof gates remain pending.
Current configs/sim class taxonomy:
| Class | Meaning | Current policy |
|---|---|---|
main |
A complete standalone-executable sim-config program. | Eligible for native inventory; promote to Layer 3/4 when the required runtime boundary exists. |
macro_load |
A macro or load/parse asset that is not the primary machine program entry point. | Keep in native inventory, but do not treat it as a browser main-program target by default. Add class-level load/parse representatives instead of widening browser execution blindly. |
remap_subroutine |
A remap or subroutine asset under remap_subs/ or similar directories. |
Validate through remap parse/execute paths, not by pretending it is a standalone browser main program. |
Current configs/sim blocked policy:
| Blocked kind | Meaning | Current examples |
|---|---|---|
ASSET-ONLY |
The file is a macro/remap asset or subroutine and is not a standalone browser main-program target. | configs/sim/*/remap_subs/*.ngc entries in the matrix. |
L4-TOOL-DB |
Native LinuxCNC rs274 coverage exists, but Node/browser inventory is blocked by LinuxCNC tool-database process boundaries such as [EMCIO]DB_PROGRAM. |
configs/sim/axis/db_demo/*. |
L4-USER-M-PROCESS |
Native LinuxCNC rs274 coverage exists, but Node/browser inventory is blocked because the config depends on external USER_M_PATH process execution rather than the deterministic M110/M111 boundary already modeled by the standalone runtime. |
configs/sim/axis/vismach/millturn/*. |
L4-PYTHON-REMAP |
Native LinuxCNC rs274 coverage exists, but full Node/browser inventory is blocked until an intentional Python-remap runtime boundary is exposed for Layer 4. |
configs/sim/gmoccapy/*, configs/sim/axis/laser/*, configs/sim/axis/remap/*/nc_files/*.ngc, configs/sim/axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/*, and configs/sim/axis/vismach/VMC_toolchange/toolchange.ngc. |
UPSTREAM-DEMO |
A preserved upstream demo edge that should remain an expected failure instead of being forced through standalone semantics. | axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_g533.ngc. |
| Program | Layer 2 classification | Current Layer 3/4 coverage or boundary |
|---|---|---|
axis/foam/foam.ngc |
ini-axis-mask-UV; native upstream bin/rs274 rejects U/V words before the standalone runtime applies the INI machine axis mask. |
Covered by wasm-port/tests/native/verify_native_probes.sh, wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh, and wasm-port/tests/browser/verify_interp_browser.sh, which run the vendored file with axis_foam.ini and verify U/V axis acceptance through LinuxCNC-backed file execution. |
axis/vismach/5axis/bridgemill/5axisgui.ngc |
ini-axis-mask-W; native upstream bin/rs274 rejects the W word outside the bridge-mill runtime context. |
Covered by wasm-port/tests/native/verify_native_probes.sh, wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh, and wasm-port/tests/browser/verify_interp_browser.sh, which stage 5axis.ini, the tool table, and remap subroutines, then execute through the vendored LinuxCNC remap/file path. |
axis/geometry/xyzc.ngc |
user-m-code-M110; native upstream bin/rs274 does not register or execute the sim-config USER_M_PATH handler. |
Covered by wasm-port/tests/native/verify_native_probes.sh, wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh, and wasm-port/tests/browser/verify_interp_browser.sh; the smoke assertions require canon_event=USER_M_COMMAND code=M110 and reject Unknown m code used: M110. |
axis/external_offsets/dyn_demo.ngc |
user-m-code-M111; native upstream bin/rs274 does not register or execute the sim-config USER_M_PATH handler. |
Covered by wasm-port/tests/native/verify_native_probes.sh, wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh, and wasm-port/tests/browser/verify_interp_browser.sh; the smoke assertions require canon_event=USER_M_COMMAND code=M111 and reject Unknown m code used: M111. |
axis/external_offsets/eoffsets.ngc |
user-m-code-M111; same standalone task/user-M boundary as dyn_demo.ngc. |
Covered by wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh and wasm-port/tests/browser/verify_interp_browser.sh with the vendored executable M111 and eoffset.tbl staged from the manifest. |
axis/external_offsets/jwp_z.ngc |
user-m-code-M111; same standalone task/user-M boundary as dyn_demo.ngc. |
Covered by wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh and wasm-port/tests/browser/verify_interp_browser.sh with the vendored executable M111 and eoffset.tbl staged from the manifest. |
axis/external_offsets/opa_demo.ngc |
user-m-code-M111; same standalone task/user-M boundary as dyn_demo.ngc, plus a subroutine dependency. |
Covered by wasm-port/tests/wasm/node/verify_sim_configs_wasm.sh and wasm-port/tests/browser/verify_interp_browser.sh, which stage M111, eoffset.tbl, and the SUBROUTINE_PATH dependency circles.ngc. |
axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_g533.ngc |
upstream-demo-missing-motion-gcode; upstream standalone rs274 reports Cannot use axis values without a g code that uses them. |
Preserved as an upstream demo expected failure. Do not make this pass by editing the G-code, changing JS interpreter behavior, or adding standalone semantics. |
Validation Chain
The native validation script runs these checks in order:
tools/verify_upstream_baseline.shConfirms../linuxcncis at the recorded upstream commit intools/upstream-baseline.txt.tools/verify_vendor_sync.shConfirms every manifest file is present invendor/linuxcnc/, no extra vendored file exists, and every vendored file is byte-identical to upstream.tools/verify_no_standalone_cnc_semantics.shConfirms standalone code has not introduced project-ownedInterp::...member definitions outside the documented Python/remap runtime-edge stubs.tools/verify_native_linuxcnc_fixture_baseline.shRuns a side-by-side fixture baseline through upstream../linuxcnc/bin/rs274and compares normalized canonical events for fixtures that do not require standalone-only runtime adapters.tools/build_native_probes.shBuilds native source probes and standalone harnesses from vendored LinuxCNC source plus narrow runtime wrappers.tests/native/verify_sim_configs.shRuns LinuxCNCconfigs/sim.ngcprograms through the upstream../linuxcnc/bin/rs274standalone entry point, using nearest or explicit sim INI/tool-table mappings and classifying main programs, macro-load checks, and remap subroutines separately.tests/native/verify_nc_files.shRuns the basic/example subset of upstreamlinuxcnc/nc_filesthrough../linuxcnc/bin/rs274, with complete programs executed strictly and macro/library files wrapped only for load/parse validation.tests/native/verify_native_probes.shChecks probe exit codes, source-probe coverage, harness stdout, canonical fixture events, and expected error behavior.
Current nc_files basic-suite baseline:
total: 107
pass: 101
fail: 6
timeout: 0
expected_fail: 6
unexpected_fail: 0
The six expected failures are LinuxCNC-native entry-point/context edges:
cone.ngc needs a W-axis 5-axis machine context; g76.ngc and
lathe-g76.ngc need lathe cutter-compensation/tool context;
lathe_g70_71_demo.ngc needs lathe profile/tool context; nestedcall.ngc
uses an upstream O-word callsub syntax edge; and tool-length-probe.ngc
needs probe runtime context.
The same runner also supports exploratory full-directory inventory:
wasm-port/tests/native/verify_nc_files.sh --all
Current full-directory nc_files inventory:
total: 247
pass: 219
fail: 28
timeout: 0
expected_fail: 28
unexpected_fail: 0
The additional expected failures are probe/plasmac runtime-context files and
one NURBS sample using G2.2, which the current upstream bin/rs274
standalone entry point reports as Unknown g code used.
The WASM INI smoke script builds runtime/ui/ini-panel/linuxcnc_ini.js and
linuxcnc_ini.wasm from vendored LinuxCNC inifile.cc, then loads that
module through runtime/sdk/src/index.js in Node and verifies INI string and
boolean queries against a file written to the Emscripten filesystem. Boolean
conversion is validated through vendored LinuxCNC iniFindBool(), and
machine-session file-name lookup is validated through LinuxCNC string queries
for [RS274NGC]PARAMETER_FILE and [EMCIO]TOOL_TABLE.
The WASM interpreter-core smoke script builds
build/wasm/core/linuxcnc_interp.js and linuxcnc_interp.wasm from the same
vendored LinuxCNC interpreter source set used by the native minimal
interpreter harness. It loads the module in Node through
runtime/sdk/src/index.js, runs the first WASM interpreter fixture
group through Interp::execute(), and compares emitted canonical events plus
required LinuxCNC _setup state readback with the matching files in
tests/fixtures/canon/. It also calls vendored Interp::init() and
Interp::synch() through the WASM C ABI to validate the initialization
canonical boundary, metric/inch machine-unit status edge, and current/selected
tool slot status synchronization already covered by the native init harness.
It also calls the vendored single-axis rotary indexer path through
Interp::execute() to validate the UNLOCK_ROTARY/LOCK_ROTARY canonical
runtime boundary already covered by the native indexer harness.
It also calls vendored Interp::init_named_parameters() and
Interp::find_named_param() through the WASM C ABI to validate the native
named-parameter harness path for LinuxCNC built-in, INI-backed, HAL-backed,
and missing named-parameter lookup.
It also writes selected G-code fixtures and vendored tests/interp/g10
regressions into the Emscripten filesystem through the SDK and runs them
through LinuxCNC Interp::open(), Interp::read(), and Interp::execute()
to validate the file execution path, including G10 tool-table updates,
tool-length offset application timing, active G5X offset changes, G92
interaction, XY-rotation behavior, G52/G92 shared-offset transitions, and
G92 startup parameter-file persistence through vendored
ini_load()/Interp::init()/restore_parameters(), including
DISABLE_G92_PERSISTENCE clearing parameters 5210-5219. It also writes the vendored LinuxCNC xyzac-trt and
xyzbc-trt table-rotary-tilting sample machine INI, remap_subs/*.ngc, and
xyzac_switchkins.ngc/xyzbc_switchkins.ngc,
xyzac_switchkins_test_1.ngc, xyzac_switchkins_test_2.ngc,
xyzac_switchkins_test_3.ngc, boat-xyzac.ngc, boat-xyzbc.ngc, and
impeller-7bl-xyzac.ngc demo files into the Emscripten
filesystem. It also writes the vendored LinuxCNC xyzab-tdr table-dual-rotary
INI, tool table, remap_subs/*.ngc, and xyzab-tdr-demo.ngc into the
Emscripten filesystem. It also writes the vendored LinuxCNC bridge-mill
5axis.ini, tool table, remap_subs/*.ngc, and 5axisgui.ngc into the
Emscripten filesystem. These checks validate the WASM C ABI/SDK path for
vendored LinuxCNC REMAP parsing, vendored LinuxCNC tool-table loading from
the machine INI, O-word remap execution, M68/M66 HAL synchronization, and
file open()/read()/execute() completion without JavaScript M-code or
kinematics semantics. The same Node smoke writes the vendored LinuxCNC
tests/remap/duplicate-o-word, NGC-only 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, and
tests/remap/sequencing INI, program, and remap subroutines into the
Emscripten filesystem and validates those
upstream NGC remap regressions through the generic runRemapFile() C ABI/SDK
path, which only reads LinuxCNC INI SUBROUTINE_PATH, REMAP, and
OWORD_NARGS entries and calls vendored Interp::parse_remap(), open(),
read(), and execute(). The NGC-only failure cases that match upstream
rs274 -n 0 flow use the sibling runRemapFileContinueOnError() C ABI/SDK
path, which records LinuxCNC error text and continues the same vendored
open()/read()/execute() loop without implementing failure semantics in
JavaScript. The same Node smoke also writes the NGC-only LinuxCNC
tests/remap/remap-io/test-ngc.ini and io_*.ngc subroutines into the
Emscripten filesystem, then calls runRemapIoMdiSequence() to feed the
upstream test-driver MDI sequence into vendored Interp::execute(). The SDK
does not implement M62-M68, M66 input, or REMAP semantics; the standalone
boundary only pre-seeds deterministic external input values and captures
LinuxCNC canonical events. The same WASM interpreter smoke also writes minimal M110 and
M111 fixtures into the Emscripten filesystem, marks the M1xx files
executable, and validates that the standalone machine-config boundary mirrors
LinuxCNC task-layer [DISPLAY]PROGRAM_PREFIX plus [RS274NGC]USER_M_PATH
lookup by registering USER_DEFINED_FUNCTION entries and recording
deterministic USER_M_COMMAND events instead of spawning host processes. The
same Node smoke writes the vendored LinuxCNC
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/cam-nisley with its
upstream test.tbl, tests/interp/namedparam-bug424,
selected tests/interp/rotation pure interpreter cases, tests/interp/iniparam,
tests/interp/iniparam-failassign,
tests/interp/sub-call-from-sub, tests/interp/sequence-number, and
tests/interp/nested-sub-error, tests/interp/nested-sub-in-file-error, and
tests/interp/abort-hot-comment
files into the Emscripten filesystem and validates those upstream interpreter
regressions through runFile() or
runFileWithIni(), which only reads LinuxCNC INI SUBROUTINE_PATH where
needed and calls vendored LinuxCNC Interp::open(), read(), and execute().
The iniparam fixtures validate vendored LinuxCNC _ini[...] lookup, missing
INI-parameter error text, and read-only named-parameter assignment rejection
through the INI_FILE_NAME runtime edge. It checks LinuxCNC canonical messages,
canonical motion/events, and final interpreter state without JavaScript O-word,
subroutine lookup, INI-variable, or read-only-parameter semantics. The
same Node smoke writes
LinuxCNC-format parameter files into the Emscripten filesystem and validates
vendored Interp::restore_parameters() and Interp::save_parameters(),
including the saved parameter values, missing required numeric parameter
defaulting, and the .bak backup file boundary. It also writes the
negative G-code fixtures into the Emscripten filesystem and verifies their
LinuxCNC-produced error text through the Interp::open()/read()/execute()
file path.
The WASM trajectory-planner smoke script builds
build/wasm/tp/linuxcnc_tp.js and linuxcnc_tp.wasm from vendored LinuxCNC
TP, TC, TC queue, spherical-arc, blendmath, S-curve, Ruckig-wrapper, C Ruckig
support, emcpose, and posemath source files. It loads the module in Node and
calls the exported TP probe C ABI to validate the same LinuxCNC linear, arc,
and queued-line planner calls covered by the native linuxcnc_tp_api_probe.
The OPFS host-boundary script validates the JavaScript file-service adapter with a Node mock of the browser File System Access handles. It covers nested directory creation, text save/load, missing file behavior, invalid relative paths, unavailable OPFS storage, and the host-side OPFS path model for INI, tool table, parameter, G-code, preview-cache, and session-snapshot storage targets. It also validates the host-side session snapshot JSON envelope and round-trip store, including unsupported format/version, session-id mismatch, non-object metadata/payload rejection, custom snapshot filenames, and invalid snapshot filename rejection, plus pure-text machine file and G-code stores, including G-code program filename rejection for traversal or nested paths, without defining CNC machine-state or file-format semantics. It now also validates the OPFS-to-WASM parameter-file bridge with a mock interpreter SDK to ensure the host boundary copies text into and out of the WASM filesystem without defining parameter semantics, and that INI-derived machine file names are still rejected by the OPFS path model when they contain traversal or nested path segments. The same Node smoke also validates that explicit session file-name options take precedence over INI-derived parameter and tool-table file names, and that missing INI file-name values fall back to the host path model defaults, keeping host override policy outside CNC semantics.
The browser INI/OPFS smoke script serves wasm-port/ over localhost and runs
Chromium headless against a test page that imports the JS SDK, loads the INI
WASM module, queries vendored LinuxCNC INI parsing through the SDK, including
machine-session parameter/tool-table file-name strings, and performs an OPFS
text-file, generic session snapshot, custom snapshot filename, invalid
snapshot filename/envelope, machine file, G-code text round trip, and G-code
filename path-model rejection. It also verifies that the INI panel UI exposes
LinuxCNC-backed [RS274NGC]PARAMETER_FILE and [EMCIO]TOOL_TABLE query
results, plus the default OPFS parameter-file and tool-table mappings used
when a machine session is copied into the interpreter WASM filesystem. It also
clicks the INI panel's 5-axis remap demo action and verifies that the UI
copies vendored LinuxCNC xyzac-trt machine/remap/demo files into the
interpreter WASM filesystem, calls the LinuxCNC-backed SDK remap execution
path for the vendored impeller-7bl-xyzac.ngc demo, and displays the
resulting fiveaxis_* status lines without JavaScript M-code or kinematics
semantics.
The browser interpreter smoke script serves wasm-port/ over localhost and
runs Chromium headless against a test page that loads the interpreter-core
WASM module through runtime/sdk/src/index.js, writes no CNC
behavior in JavaScript, and verifies existing canonical fixtures through the
exported C ABI backed by vendored LinuxCNC Interp::execute() and
Interp::open()/read()/execute() paths, including the INI-aware
named-parameter file path and negative interpreter fixtures with expected
error text plus absent canonical motion output. It also validates vendored
Interp::init() and Interp::synch() through the same SDK/C ABI path,
including initialization canonical events, metric/inch machine units, and tool
slot readback, and checks the vendored rotary-indexer G0 A... execution path
for UNLOCK_ROTARY/LOCK_ROTARY boundary events. It also validates
Interp::init_named_parameters() and Interp::find_named_param() through the
same browser SDK/C ABI path for built-in, INI-backed, HAL-backed, and missing
named-parameter lookup. It also directly checks browser SDK parameter-file
restore/save through vendored Interp::restore_parameters() and
Interp::save_parameters(), including the LinuxCNC-saved text and .bak
backup, and directly checks browser SDK non-random/random tool-table
load/save through vendored tooldata_common.cc. The same browser smoke uses
real browser OPFS storage plus the interpreter SDK to restore/save LinuxCNC
parameter files, directly checks missing-file success plus out-of-order
parameter-file rejection through the same LinuxCNC restore_parameters() C
ABI, and checks the random-toolchanger tooldata_save() result before OPFS
text writeback,
to reject invalid INI-derived parameter/tool-table file names through the OPFS
path model after the names are parsed by the LinuxCNC-backed INI WASM SDK. It
also verifies that explicit session parameter/tool-table file-name options
override INI-derived names before OPFS text is copied into the LinuxCNC-backed
WASM filesystem, and that absent INI file-name values use the default OPFS
parameter/tool-table paths in a real browser session. It also writes vendored
LinuxCNC xyzac-trt/xyzbc-trt INI, remap subroutines, and switchkins demo
files, including xyzac_switchkins_test_1.ngc,
xyzac_switchkins_test_2.ngc, xyzac_switchkins_test_3.ngc, and the larger
boat-xyzac.ngc, boat-xyzbc.ngc, and impeller-7bl-xyzac.ngc demos, into
the browser WASM filesystem. It also
writes vendored LinuxCNC xyzab-tdr machine files and xyzab-tdr-demo.ngc
into the browser WASM filesystem. It also writes vendored LinuxCNC bridge-mill
machine files and 5axisgui.ngc into the browser WASM filesystem. The browser
smoke verifies runFiveAxisRemapFile() for the table-rotary-tilting,
table-dual-rotary, and bridge-mill sample machines through the exported
LinuxCNC remap/tool-table/file execution path. It also verifies the vendored
LinuxCNC configs/sim/axis/foam/foam.ngc, axis/geometry/xyzc.ngc, and
axis/external_offsets/dyn_demo.ngc programs through runSimConfigProgram(),
which writes the browser WASM filesystem files and forwards to
runFileWithIni(). It also verifies the bridge-mill
axis/vismach/5axis/bridgemill/5axisgui.ngc program through
runSimConfigProgram() with executionMode: "fiveAxisRemap", which forwards
to runFiveAxisRemapFile(). These paths use the real vendored executable
M110 and M111 files for USER_M_PATH registration without spawning host
processes. It
also verifies the vendored
LinuxCNC tests/remap/duplicate-o-word, NGC-only 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, and
tests/remap/sequencing regressions through runRemapFile() or
runRemapFileContinueOnError(), using the browser WASM filesystem and
vendored LinuxCNC REMAP/O-word/file execution path without JavaScript remap
semantics. It also writes the NGC-only vendored LinuxCNC
tests/remap/remap-io/test-ngc.ini and io_*.ngc subroutines into the
browser WASM filesystem and validates runRemapIoMdiSequence() through
vendored LinuxCNC REMAP parsing and MDI execution without JavaScript M-code or
I/O semantics. It also writes vendored LinuxCNC 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/cam-nisley, tests/interp/namedparam-bug424,
tests/interp/inside-corners,
tests/interp/inverse-time-with-comp, and selected tests/interp/rotation
.ngc files plus
tests/interp/sub-call-from-sub test.ini, test.ngc, and subs/*.ngc
files and tests/interp/sequence-number test.ini, test.ngc, and
rm400.ngc plus tests/interp/nested-sub-error test.ini, test.ngc, and
subs/nested.ngc and tests/interp/nested-sub-in-file-error test.ini,
test.ngc, and subs/sequential.ngc, plus tests/interp/abort-hot-comment
test.ini and test.ngc, plus tests/interp/m19 test.ini and test.ngc,
plus tests/interp/magic_comments/param_format_printing test.ngc,
plus selected pure-interpreter tests/interp/m98m99 cases covering
Fanuc-style M98/M99, missing-P-word, missing-subprogram, mixed
Fanuc/RS274NGC sub-style, and DISABLE_FANUC_STYLE_SUB INI-gated errors,
main-program O-word termination rules, parameter scope, loop counts including
L0, nested numbered subprograms, subprograms after main program text,
leading-zero O-word lookup, named and numbered main programs, and
expression-based O-sub/M98 calls,
into the browser WASM filesystem and
validates those upstream
interpreter regressions through runFile() or runFileWithIni(), without
JavaScript O-word, parameter, line-number, spindle-speed, spindle-orient,
magic-comment formatting, M98/M99, subroutine lookup, or branch semantics.
The aggregate host smoke script builds the INI, interpreter-core, and trajectory-planner WASM artifacts once, then runs the Node WASM smokes, the Node OPFS mock smoke, and the Chromium browser smokes.
Source Coverage
Every .c and .cc entry in tools/source-manifest.txt must have a
corresponding *_source_probe entry in build/native/source-probes.tsv.
The validation fails if:
- a manifest source file lacks a source probe;
- a source probe references a file not listed in the manifest;
- a manifest file is duplicated;
- vendored files drift byte-for-byte from upstream LinuxCNC.
Current Native Harnesses
| Harness | Purpose |
|---|---|
linuxcnc_ini_probe |
Validates vendored LinuxCNC INI parsing can be used standalone. |
linuxcnc_interp_state_probe |
Validates interpreter state constants and structs compile under the standalone boundary. |
linuxcnc_rs274_compile_probe |
Validates the upstream tests/interp/compile class remains a source/compile boundary rather than being misclassified as a runtime .ngc interpreter fixture. |
linuxcnc_emc_status_probe |
Validates the standalone emcStatus machine-units status boundary used by vendored interpreter conversion and initialization code. |
linuxcnc_namedparam_harness |
Validates LinuxCNC named parameter behavior, _ini[...], and _hal[...] adapter resolution. |
linuxcnc_interp_minimal_harness |
Runs G-code fixtures through vendored LinuxCNC parser/execution/conversion code, captures canonical events, and validates feed-rate state readback across length-unit changes. |
linuxcnc_parameter_file_harness |
Validates LinuxCNC parameter file restore/save behavior and required/read-only parameter handling. |
linuxcnc_interp_init_harness |
Validates vendored LinuxCNC Interp::init() emits canonical initialization boundaries, reads metric/inch machine units, and synchronizes current/selected tool slots through standalone status adapters. |
linuxcnc_indexer_harness |
Validates vendored LinuxCNC single-axis rotary indexer dispatch emits lock/unlock and motion boundaries through the standalone event sink. |
linuxcnc_remap_hal_sync_harness |
Validates vendored LinuxCNC M68/M66 execution can drive the standalone HAL adapter boundary used by 5-axis switchkins remap files, including _hal[motion.switchkins-type] readback. |
linuxcnc_5axis_remap_execute_harness |
Validates vendored LinuxCNC REMAP parsing plus NGC remap execution for the 5-axis M429 -> M428 -> M430 -> M429 switchkins path in the xyzac-trt and xyzbc-trt sample machines, the two-remap M429 -> M428 -> M429 path in the xyzab-tdr sample machine, and the bridge-mill M429 -> M428 -> M430 -> M429 path where M428 selects the default bridge-mill kinematics. It loads vendored machine tool tables through LinuxCNC tooldata_load(), then runs vendored xyzac_switchkins.ngc, xyzbc_switchkins.ngc, xyzac_switchkins_test_1.ngc, xyzac_switchkins_test_2.ngc, xyzac_switchkins_test_3.ngc, boat-xyzac.ngc, boat-xyzbc.ngc, impeller-7bl-xyzac.ngc, xyzab-tdr-demo.ngc, and 5axisgui.ngc through the LinuxCNC file open/read/execute path. |
linuxcnc_duplicate_oword_remap_harness |
Validates vendored LinuxCNC upstream tests/remap/duplicate-o-word, NGC-only 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 the NGC-only tests/remap/remap-io/test-ngc.ini branch through LinuxCNC REMAP parsing, O-word remap dispatch, OWORD_NARGS, error-text reporting, G/M remap sequencing, remapped M62-M68/M66 MDI execution, and file open/read/execute. The standalone harness only supplies INI/file path setup, deterministic external input values, and canonical-event capture; it can continue after LinuxCNC errors for upstream rs274 -n 0 style tests and does not implement duplicate-label, O-word, M30, positional-argument, failure, sequencing, M62-M68, M66 input, or remap semantics. |
linuxcnc_tp_api_probe |
Validates vendored LinuxCNC trajectory planner calls for linear, arc, and queued motion paths. |
linuxcnc_kinematics_probe |
Validates vendored LinuxCNC trivkins.c plus kins_util.c initialize and perform identity forward/inverse mapping through the standalone HAL/RTAPI boundary. |
linuxcnc_5axis_kinematics_probe |
Validates vendored LinuxCNC 5axiskins.c through switchkins.c, including 5-axis forward/inverse round-trip behavior and switching to identity kinematics. |
linuxcnc_xyzac_trt_kinematics_probe |
Validates vendored LinuxCNC XYZAC TRT kinematics through switchkins.c, including forward/inverse round-trip behavior and switching to identity kinematics. |
linuxcnc_xyzbc_trt_kinematics_probe |
Validates vendored LinuxCNC XYZBC TRT kinematics through switchkins.c, including forward/inverse round-trip behavior and switching to identity kinematics. |
linuxcnc_corexy_kinematics_probe |
Validates vendored LinuxCNC CoreXY forward/inverse behavior through the standalone HAL/RTAPI boundary. |
linuxcnc_rotate_kinematics_probe |
Validates vendored LinuxCNC rotated-axis forward/inverse behavior. |
linuxcnc_rose_kinematics_probe |
Validates vendored LinuxCNC rose kinematics forward/inverse behavior. |
linuxcnc_max_kinematics_probe |
Validates vendored LinuxCNC max kinematics forward/inverse behavior. |
linuxcnc_lineardelta_kinematics_probe |
Validates vendored LinuxCNC linear-delta inverse/forward pose round-trip behavior. |
linuxcnc_rotarydelta_kinematics_probe |
Validates vendored LinuxCNC rotary-delta inverse/forward pose round-trip behavior. |
linuxcnc_scorbot_kinematics_probe |
Validates vendored LinuxCNC Scorbot forward/inverse behavior and pose round-trip behavior. |
linuxcnc_tripod_kinematics_probe |
Validates vendored LinuxCNC tripod inverse/forward behavior, including below-platform flag behavior. |
linuxcnc_scara_kinematics_probe |
Validates vendored LinuxCNC SCARA forward/inverse behavior and switching to identity kinematics. |
linuxcnc_puma_kinematics_probe |
Validates vendored LinuxCNC PUMA forward/inverse behavior, pose round-trip behavior, and switching to identity kinematics. |
linuxcnc_genser_kinematics_probe |
Validates vendored LinuxCNC generic serial kinematics forward/inverse behavior and switching to identity kinematics. |
linuxcnc_genhex_kinematics_probe |
Validates vendored LinuxCNC generic hexapod inverse/forward behavior, including the switchkins iterative-forward warmup path. |
linuxcnc_pentakins_kinematics_probe |
Validates vendored LinuxCNC pentapod inverse/forward pose round-trip behavior. |
Current WASM Harnesses
| Harness | Purpose |
|---|---|
tests/wasm/node/verify_ini_wasm.sh |
Validates the browser-facing INI WASM module can be built from vendored LinuxCNC inifile.cc, loaded through the JS SDK in Node, and queried through the exported C ABI, including LinuxCNC-backed boolean conversion and machine-session file-name string lookup. |
tests/wasm/node/verify_interp_wasm.sh |
Validates the interpreter-core WASM module can be built from vendored LinuxCNC interpreter/remap source, loaded through the interpreter JS SDK, run the first fixture group through Interp::execute() and selected file fixtures plus vendored upstream tests/interp regression files through Interp::open()/read()/execute(), match the native canonical event plus required state readback fixtures, emit run_step execution-status records with LinuxCNC line number, encoded source statement, return code, and interpreter axis positions for file execution, cover vendored tests/interp/flowsnake recursive O-word file execution, tests/interp/g6164 path-control and naive-cam tolerance execution, tests/interp/oword-unwind continue-on-error stack unwind behavior through planner-staged INI context, selected tests/interp/bad file-error paths, and tests/interp/g33.1 rigid-tap file execution, run vendored xyzac-trt/xyzbc-trt table-rotary-tilting and xyzab-tdr table-dual-rotary switchkins remap demo files through the WASM C ABI/SDK path, and run parameter-file restore/save through vendored LinuxCNC Interp::restore_parameters() and Interp::save_parameters(). |
tests/wasm/node/verify_sim_configs_wasm.sh |
Validates representative vendored LinuxCNC configs/sim programs in Node WASM through planSimConfigStaging() plus runSimConfigProgram(). The generic planIniFileContextStaging() planner and its sim-config wrapper use INI text and tools/source-manifest.txt to collect the program, INI, tool table, parameter file when vendored, SUBROUTINE_PATH files, USER_M_PATH files, and remap-NGC files before forwarding to runFileWithIni() or runFiveAxisRemapFile(). This covers INI-driven U/V/W axis mask handling, real USER_M_PATH registration for executable M110/M111, all four current external-offset M111 expected-failure programs, deterministic woodpecker/on_abort.ngc file execution, plain INI/tool-table execution through axis/gladevcp/probe.ngc, SUBROUTINE_PATH staging for opa_demo.ngc -> circles.ngc, bridge-mill remap-subroutine staging, vendored LinuxCNC bridge-mill and melfa-sim NGC remap execution, and PUMA machine-context execution without spawning host processes. The same smoke includes synthetic staging-plan assertions for generic TOOL_TABLE, PARAMETER_FILE, multi-directory SUBROUTINE_PATH, USER_M_PATH, and REMAP ... ngc=... file collection. |
tests/wasm/node/verify_sim_configs_inventory_wasm.sh |
Validates the first machine-readable Node inventory layer for configs/sim. It ensures native build/native/sim-configs/summary.tsv, generated class-summary.tsv, and generated path-matrix.tsv exist; verifies that generated path-matrix.tsv and tracked docs/sim-configs-coverage-matrix.md contain the same 159 paths as native summary.tsv; checks tracked matrix fields for class, native status, expected-failure reason, and blocked kind drift against generated path-matrix.tsv; and checks that generated class-summary.tsv matches class/status/expected-failure counts derived from summary.tsv. It then executes only entries that are currently vendored and have a defined standalone/WASM runtime path, and writes the sim-config inventory TSV artifacts. The boundary summary records one row per native inventory path with the matrix block, SDK classifier recommendation, declared HAL/UI/HALUI/Python process dependencies, [EMCIO]DB_PROGRAM, and execution-chain user-M codes; vendored INI rows must have an available classifier report, vendored hard blocks fail on classifier/matrix drift, safe process-declaring representatives must remain Node/browser REP rows with the expected process flag combinations rather than full-process promotions, and the designed full-process blocked rows must remain non-REP until their proof criteria are met. The generated inventory summary also requires all hard-blocked rows to remain SKIP with matching reasons, and skip-summary.tsv must match the matrix-derived skip counts. The blocked-dependency and boundary summaries record hard blocked Python-remap, tool-database, and external user-M rows from source linuxcnc/configs/sim INI files for dependency accounting only, including LinuxCNC source/config ownership fields, user-M script side effects, tool DB protocol evidence, Python runtime owner evidence, and completion criteria that all remain non-executing. Current gate: executed=28, passed=28, skipped=131, unexpected_fail=0; current skip/block counts are ASSET_ONLY=65, L4_PYTHON_REMAP=53, L4_TOOL_DB=1, L4_USER_M_PROCESS=1, NON_MAIN_CLASS=10, and UPSTREAM_DEMO=1. The executed set now includes the deterministic woodpecker plus qtdragon / qtdragon_hd / qtvcp_screens on_abort.ngc family, axis/gladevcp/probe.ngc, axis/rose_engine/rcone_demo.ngc, axis/vismach/melfa-sim/example.ngc, and the axis/vismach/puma sample programs after vendoring the required machine INI, tool-table, and remap-subroutine inputs. When an upstream INI declares a missing local tool table but the native harness resolved a valid fallback table, the Node inventory stages that native-selected table at the INI-declared path so WASM execution uses the same machine context. The skip reasons are explicit: NON_MAIN_CLASS, L4-TOOL-DB, L4-USER-M-PROCESS, L4-PYTHON-REMAP, and UPSTREAM-DEMO; an eligible row that lacks vendored machine context is reported as an inventory failure. This runner is an inventory source-of-truth for Node WASM and is intentionally narrower than a browser full inventory. |
tests/wasm/node/verify_nc_files_wasm.sh |
Validates representative vendored LinuxCNC nc_files examples in Node WASM by copying 3D_Chips.ngc, arcspiral.ngc, hole-circle.ngc, factorial.ngc, and m6demo.ngc into the Emscripten filesystem and forwarding to the LinuxCNC-backed Interp::open()/read()/execute() path. 3D_Chips.ngc is staged with a minimal INI-declared tool.tbl because the upstream program contains T1 M6; JavaScript only stages files and checks LinuxCNC output, including run_step status records, and does not implement G-code, O-word, tool-change, or M-code behavior. |
tests/wasm/node/verify_tp_wasm.sh |
Validates a standalone trajectory-planner WASM module can be built from vendored LinuxCNC TP/TC/Ruckig support source, loaded in Node, and run the same linear, arc, and queued-line planner probe paths covered by the native TP harness. |
tests/opfs/node/verify_file_service.sh |
Validates the host-owned OPFS text-file adapter, path model, session snapshot store including custom filenames and envelope/path rejection paths, machine file store, G-code text store including filename rejection paths, OPFS-to-WASM parameter/tool-table bridges, and grouped machine-session loading without moving file persistence, parameter semantics, or tool-table semantics into the WASM core. |
tests/browser/verify_ini_panel_browser.sh |
Validates the INI SDK, INI/interpreter WASM module loading, LinuxCNC-backed INI machine-session file-name string lookup, OPFS text-file round trip, generic session snapshot round trip plus custom filename and envelope/path rejection paths, machine file text round trip, G-code text round trip plus filename rejection paths, and the INI panel UI's machine-session load with default OPFS parameter/tool-table file mapping, G-code run, run_step-backed progress/line/statement/axis display, canonical-event display paths, and 5-axis remap demo action in a real browser runtime. |
tests/browser/verify_interp_browser.sh |
Validates the interpreter-core WASM module loads through the interpreter JS SDK in a real browser runtime and runs selected positive and negative canonical fixtures plus vendored upstream tests/interp regression files through vendored LinuxCNC Interp::execute() and Interp::open()/read()/execute() via the exported C ABI, including direct browser SDK and OPFS-backed parameter-file restore/save, non-random/random tool-table load/save through vendored LinuxCNC source, vendored xyzac-trt/xyzbc-trt table-rotary-tilting and xyzab-tdr table-dual-rotary switchkins remap demo execution, representative vendored configs/sim foam, geometry, external_offsets, axis/gladevcp/probe.ngc, deterministic woodpecker/on_abort.ngc, bridge-mill, melfa-sim, and puma_cube.ngc programs through runSimConfigProgram(), representative vendored nc_files examples through runFile() or runFileWithIni() when the upstream file requires INI/tool-table context, and a synthetic browser assertion that planIniFileContextStaging() can collect INI, program, tool-table, parameter, multi-directory subroutine, executable user-M, and remap-NGC files using only manifest text. |
tests/host/verify_host_smokes.sh |
Runs the current host-side Node, WASM interpreter-core, sim-config representative smoke, sim-config Node inventory, WASM trajectory-planner, OPFS, and browser smoke validation with shared WASM builds. |
Fixture Coverage
Positive G-code fixtures currently cover:
- linear traverse/feed
- arc semantics
- modal absolute/incremental motion
- position parameters
- canned cycles
- coordinate offsets
- G53 machine-coordinate motion
- feed and motion control modes
- probing
- threading and rigid tap
- NURBS G5/G6
- spindle orient
- tool semantics
- tool table setup
- tool-data reload boundary
- interpreter state-tag boundary
- percent-delimited file
FINISHboundary - file-open
ON_RESETboundary - comment logging canonical calls
- local, INI-backed named parameters and numbered parameters
- O-word subroutines
- continue-on-error O-word unwind
- program-end modal reset
- canonical runtime edge calls
Negative fixtures currently cover:
- zero-feed
G1 - arc radius mismatch
- zero-radius arc
- G53 incremental-mode rejection
- read-only named parameter writes
- read-only numbered parameter writes
- missing tool
- missing tool length offset
The negative fixture expectations are also checked against upstream
rs274 -g: the baseline requires LinuxCNC to reject each program, to emit the
expected error text, and to omit the canonical event lines marked as absent in
tests/fixtures/canon_errors/.
Validation Boundaries
Current full-core validation is native-only. WASM/SDK validation covers the
INI parser smoke harness and an initial interpreter-core canonical event smoke
for minimal_linear, arc_semantics, length_units, modal_incremental,
plane_selection, coordinate_offsets, g53_machine_coordinates,
feed_control_modes, position_params, probe_semantics, spindle_orient,
comment_logging, numbered_params, tool_semantics, tool_table_setup,
tool_reload, canned_cycles, cutter_comp_motion, threading_sync,
nurbs_g5_semantics, nurbs_g6_semantics, state_tag_motion,
canon_runtime_edges, program_end_modal_reset, namedparam_ini_semantics,
and namedparam_semantics through both Node WASM and browser INI-aware
program ABI smoke coverage,
plus the g1_zero_feed, arc_radius_mismatch, arc_zero_radius,
cutter_comp_plane_change, g53_incremental, namedparam_readonly,
numbered_param_readonly, tool_not_found, and
tool_length_offset_not_found negative fixtures. The WASM interpreter file
path additionally covers the same canonical-event fixture group, plus
namedparam_ini_semantics and namedparam_semantics through the INI-aware
file execution ABI,
file_open_reset, percent_file_finish, oword_subroutine,
g6164, and oword_unwind.
position_params uses a dedicated file-path expectation under
tests/fixtures/canon_file/ because LinuxCNC file execution advances the
post-execute position parameters differently than the line-by-line MDI smoke;
both expectations now also pin post-execute modal, override, spindle, mist,
and flood _setup state readback.
coordinate_offsets also uses a dedicated file-path expectation because
LinuxCNC file execution leaves the post-execute position parameters at the
file-path reset state while the line-by-line MDI path exposes the active G55
offset values; both paths pin the post-execute modal, override, spindle, mist,
and flood _setup state.
tool_semantics also pins the post-execute position-parameter and modal,
override, spindle, mist, and flood _setup state after T/M6/G43/G49/M61
tool behavior.
feed_control_modes pins the post-execute feed and motion-control modal state
plus the same position-parameter, override, spindle, mist, and flood _setup
state readback after G93/G94/G95 and G61/G61.1/G64 transitions.
The same Node WASM and browser file-path smokes also cover the negative fixture
group and check the LinuxCNC file-execution error text plus absent canonical
motion constraints where applicable.
canon_runtime_edges also pins the vendored interpreter's post-program
modal, override, spindle, mist, and flood _setup state readback after the
canonical runtime-edge calls complete.
The Node WASM and browser interpreter smokes also cover LinuxCNC parameter-file
restore/save behavior through the exported C ABI, including out-of-order file
rejection, missing-file success, missing required numeric parameter defaulting,
required numeric parameter writeback, removal of named-parameter-only lines
from saved output, and the .bak backup produced by vendored
save_parameters(), including direct browser SDK readback from the
Emscripten filesystem, browser OPFS readback of the backup text after the host
bridge writes it to persistent storage, plus INI-derived custom and explicit
host override parameter-file paths saved back to OPFS with their
LinuxCNC-produced backup text. It also covers LinuxCNC tool-table load/save
behavior through vendored tooldata_common.cc, including the non-random and
random-toolchanger tooldata_init() branches, with the SDK only copying text
into the Emscripten filesystem and calling the exported C ABI; the browser
smoke directly reads back both non-random and random saved tool-table text
from the Emscripten filesystem, checks the random-toolchanger
tooldata_save() C ABI result before OPFS persistence writes the saved table
text back, and verifies that INI-derived custom and explicit host override
tool-table OPFS paths can be saved and read back after the table is loaded
through vendored LinuxCNC. The same
Node WASM and browser interpreter smokes now validate the exported
Interp::init()/Interp::synch() probe for initialization canonical events,
metric/inch emcStatus machine-unit conversion, and current/selected tool
slot synchronization. They also validate the exported rotary-indexer probe for
vendored LinuxCNC UNLOCK_ROTARY/LOCK_ROTARY dispatch around a single-axis
G0 A... move, plus the exported named-parameter probe for direct LinuxCNC
init_named_parameters() and find_named_param() lookup of built-in,
INI-backed, HAL-backed, and missing named parameters.
OPFS validation covers the JavaScript host-boundary adapter, the INI browser
smoke harness, the INI panel UI's machine-session load and G-code run buttons,
the raw canonical-event display fed directly by LinuxCNC interpreter WASM
output, the Node parameter/tool-table bridges that copy OPFS text through the
SDK into vendored LinuxCNC file APIs, the Node machine-session bridge that
groups INI, parameter, and tool-table loading, the random-toolchanger flag
derived from vendored LinuxCNC INI boolean parsing, INI-derived
[RS274NGC]PARAMETER_FILE and [EMCIO]TOOL_TABLE file names mapped to OPFS
machine files, OPFS path-model rejection of invalid INI-derived file names,
explicit host session file-name overrides taking precedence over INI-derived
names, default host path fallback when INI file-name values are absent,
session snapshot custom filename handling plus envelope/path rejection
for unsupported format/version, wrong session id, and invalid snapshot
filenames, and a browser interpreter smoke that uses the same session bridge
with real LinuxCNC INI WASM parsing before saving OPFS-backed parameter and
tool-table text through vendored LinuxCNC file APIs, including default OPFS
path fallback when INI file-name values are absent.
Full browser coverage, full SDK coverage, and richer machine-state validation
remain future work.
WASM/Browser Fixture Matrix
The executable fixture lists for Node WASM and browser interpreter smoke tests
are centralized in tests/fixtures/interp-fixture-matrix.mjs. Additions to the
matrix must continue to route execution through the SDK and exported C ABI
backed by vendored LinuxCNC interpreter code; the matrix is only a test
coverage list, not a CNC behavior implementation.
Node WASM Interp::execute() coverage currently includes:
minimal_lineararc_semanticslength_unitsmodal_incrementalplane_selectioncoordinate_offsetsg53_machine_coordinatesfeed_control_modesposition_paramsprobe_semanticsspindle_orientcomment_loggingnumbered_paramstool_semanticstool_table_setuptool_reloadcanned_cyclescutter_comp_motionthreading_syncnurbs_g5_semanticsnurbs_g6_semanticsstate_tag_motioncanon_runtime_edgesprogram_end_modal_resetnamedparam_ini_semanticsthrough the INI-aware program ABInamedparam_semanticsthrough the INI-aware program ABI
Node WASM file-path coverage currently includes:
minimal_lineararc_semanticslength_unitsmodal_incrementalplane_selectiong53_machine_coordinatesfeed_control_modesprobe_semanticsspindle_orientcomment_loggingnumbered_paramstool_semanticstool_table_setuptool_reloadcanned_cyclescutter_comp_motionthreading_syncnurbs_g5_semanticsnurbs_g6_semanticsstate_tag_motioncanon_runtime_edgesprogram_end_modal_resetfile_open_resetpercent_file_finishoword_subroutinecoordinate_offsetsthrough the dedicatedcanon_file/expectationposition_paramsthrough the dedicatedcanon_file/expectationnamedparam_ini_semanticsthrough the INI-aware file ABInamedparam_semanticsthrough the INI-aware file ABI
Node WASM file-path negative coverage currently includes every fixture under
tests/fixtures/gcode_errors/:
g1_zero_feedarc_radius_mismatcharc_zero_radiuscutter_comp_plane_changeg53_incrementalnamedparam_readonlynumbered_param_readonlytool_length_offset_not_foundtool_not_found
Browser interpreter file-path negative coverage currently includes the same
negative fixture list through Interp::open()/read()/execute():
g1_zero_feedarc_radius_mismatcharc_zero_radiuscutter_comp_plane_changeg53_incrementalnamedparam_readonlynumbered_param_readonlytool_length_offset_not_foundtool_not_found
Browser interpreter Interp::execute() coverage currently includes:
minimal_lineararc_semanticslength_unitsmodal_incrementalplane_selectioncoordinate_offsetsg53_machine_coordinatesfeed_control_modesposition_paramscanned_cyclesnumbered_paramscomment_loggingtool_semanticstool_table_setupprobe_semanticsspindle_orientcutter_comp_motionthreading_syncnurbs_g5_semanticsnurbs_g6_semanticsstate_tag_motioncanon_runtime_edgestool_reloadprogram_end_modal_resetnamedparam_ini_semanticsthrough the INI-aware program ABInamedparam_semanticsthrough the INI-aware program ABI
Browser interpreter negative coverage currently includes every fixture under
tests/fixtures/gcode_errors/:
g1_zero_feedarc_radius_mismatcharc_zero_radiusg53_incrementalcutter_comp_plane_changenamedparam_readonlynumbered_param_readonlytool_length_offset_not_foundtool_not_found
Browser interpreter file-path coverage currently includes the same
INTERP_FILE_FIXTURES list as the Node WASM smoke:
minimal_lineararc_semanticslength_unitsmodal_incrementalplane_selectiong53_machine_coordinatesfeed_control_modesprobe_semanticsspindle_orientcomment_loggingnumbered_paramstool_semanticstool_table_setuptool_reloadcanned_cyclescutter_comp_motionthreading_syncnurbs_g5_semanticsnurbs_g6_semanticsstate_tag_motioncanon_runtime_edgesprogram_end_modal_resetfile_open_resetpercent_file_finishoword_subroutinecoordinate_offsetsthrough the dedicatedcanon_file/expectationposition_paramsthrough the dedicatedcanon_file/expectationnamedparam_ini_semanticsthrough the INI-aware file ABInamedparam_semanticsthrough the INI-aware file ABI
All current positive G-code fixtures have browser interpreter smoke coverage
through either Interp::execute(), the file-path ABI, or the INI-aware
file-path ABI.
The current fixture expectations validate standalone behavior against both the
vendored LinuxCNC source path and an upstream rs274 side-by-side baseline for
parser/conversion, arc geometry, offsets, feed-control and feed-state
readback, comment/logging,
numbered-parameter, local named-parameter plus _ini[...] lookup through
rs274 -i, probing, spindle-orient, file-open reset, file-finish,
tool-reload, tool select/change/length-offset, M61 current-tool-number update,
canned-cycle, state-tag motion, tool-table setup, and O-word subroutine
fixtures, plus vendored tests/interp/flowsnake recursive O-word toolpath,
tests/interp/cam-nisley storm-door latch cam execution with upstream
tool-table context and a bare-run missing-tool negative check,
tests/interp/inside-corners cutter-compensation concave/convex/tangent
geometry across XY and ZX planes,
tests/interp/inverse-time-with-comp inverse-time feed and cutter-compensation
interaction,
selected upstream tests/interp/bad file-error paths including canned-cycle
A-axis rejection, center-format arc radius mismatch rejection, and
selected upstream tests/interp/good center-format arc tolerance acceptance,
selected tests/interp/g72-* lathe facing canned-cycle iteration regressions,
selected tests/interp/g71-* lathe roughing/finish canned-cycle regressions,
tests/interp/g76 lathe threading with upstream tool-table context,
cutter-compensation rejection, selected standalone tests/ccomp
cutter-compensation file execution with upstream tool tables, threading/rigid tap,
vendored tests/interp/g33.1 rigid-tap file execution, NURBS dispatch
boundaries, and the
comparable canonical runtime edge and program-end cleanup calls. The
standalone vendored-source harness, Node WASM smoke, and browser smoke also
pin coordinate_offsets MDI/file-path, feed_control_modes, run_step
file-execution status output for line number, URI-encoded source statement,
return code, and current interpreter axis positions, the
position_params MDI/file-path, tool_semantics, and canon_runtime_edges
post-program modal, override, spindle, mist, and flood _setup state. Native
and WASM standalone checks also cover the user M-code registration boundary for
INI-declared M110/M111 handlers while keeping process execution outside the
browser/WASM runtime. Node and browser WASM sim-config coverage now run the real
vendored axis/geometry/xyzc.ngc and the
axis/external_offsets/dyn_demo.ngc, eoffsets.ngc, jwp_z.ngc, and
opa_demo.ngc programs with their executable M110/M111 files,
opa_demo.ngc's SUBROUTINE_PATH dependency on circles.ngc,
axis/foam/foam.ngc with its U/V machine configuration and shared
axis/sim.tbl tool table staged beside the INI, and
bridge-mill 5axisgui.ngc with its W machine coordinates. The same upstream baseline also
validates the current negative fixture error text and absent canonical-event
constraints. Fixtures that depend on standalone-only runtime
adapters, HAL state, upstream rs274 output gaps such as
WAIT or hidden NURBS control-point detail, or richer machine session state
still need dedicated native LinuxCNC baselines.
Remaining positive fixtures that are not in the upstream rs274 side-by-side
baseline are intentionally held out until they get a dedicated native LinuxCNC
baseline: namedparam_semantics still depends on the standalone HAL adapter,
while namedparam_ini_semantics now covers the local named-parameter and
LinuxCNC _ini[...] subset against upstream rs274 -i. state_tag_motion
now compares its motion events with upstream rs274, while UPDATE_TAG
events remain a standalone state-tag capture boundary. tool_semantics now
compares T/M6/G43/G49 and M61 canonical/current-pocket readback with upstream
rs274 -t -i; Interp::synch() current/selected tool slot reads are covered
by the native init harness.
The kinematics probes currently cover LinuxCNC identity/trivial kinematics, the
switchable 5axiskins XYZBCW bridge-mill model, TRT xyzac/xyzbc
table-rotary models, CoreXY, rotated-axis, rose, max, linear-delta,
rotary-delta, Scorbot, tripod, SCARA, PUMA, generic serial, generic hexapod,
and pentapod models.
linuxcnc_5axis_remap_asset_probe pins the LinuxCNC sample-machine assets
that define five-axis switchkins M428, M429, and M430: bridge-mill,
dual-rotary, and table-rotary-tilting INI files, remap_subs/*.ngc, HAL
switchkins links, tool tables, and demo programs. It verifies that these
commands remain LinuxCNC REMAP entries backed by LinuxCNC NGC subroutines
using M68, M66, and _hal[motion.switchkins-type]; it does not implement
the remap execution path.
linuxcnc_remap_parse_harness links vendored interp_remap.cc for the
standalone remap descriptor path. It reads the vendored xyzac-trt,
xyzbc-trt, xyzab-tdr, and bridge-mill INI REMAP entries, resolves their
remap_subs/*.ngc files through LinuxCNC find_ngc_file(), and validates the
resulting _setup.m_remapped descriptors for each machine's LinuxCNC-defined
M428/M429/M430 set. Python callbacks remain runtime boundaries. Native
and WASM validation now execute the NGC remap/file paths through vendored
LinuxCNC O-word dispatch and the standalone HAL adapter boundary.
linuxcnc_duplicate_oword_remap_harness vendors LinuxCNC's upstream
tests/remap/duplicate-o-word and tests/remap/m30-interaction files
unchanged and runs each test.ngc with its test.ini through vendored
Interp::parse_remap(), open(), read(), and execute(). Native, Node
WASM, and browser interpreter validation assert the same successful LinuxCNC
regression paths, including the remapped M207/M208 messages and final
FINISH() event for duplicate O-word, and the M400 M30 remap-level
interaction with PROGRAM_END.
linuxcnc_interp_minimal_harness now also runs selected vendored LinuxCNC
upstream tests/interp/*/test.ngc files through vendored Interp::open(),
read(), and execute(), using LinuxCNC INI SUBROUTINE_PATH for
tests/interp/sub-call-from-sub, tests/interp/sequence-number, and
tests/interp/nested-sub-error, tests/interp/nested-sub-in-file-error, and
tests/interp/abort-hot-comment, plus LinuxCNC [RS274NGC]ORIENT_OFFSET for
tests/interp/m19.
Native, Node WASM, and browser interpreter validation assert the LinuxCNC
canonical messages, canonical events, error texts, and interpreter state for
O-word loop/break/subroutine paths, dynamic O-word calls, EXISTS[],
subroutine return values, subroutines after main programs, fractional line
numbers, named-parameter parsing, M19 spindle-orient offset and wait timeout
canonical events, magic-comment parameter formatting, valid external subroutine calls from another
external subroutine, external-subroutine #<_line> reporting,
nested-subroutine-definition rejection, and blocked forward seek to a later
numbered subroutine in the same external file, selected tests/interp/rotation
absolute-position #<_abs_x>, #<_abs_y>, and #<_abs_z> reporting under
G54, G92, XY rotation, and unit changes plus rotated-coordinate G28 and
G53 endpoint behavior, selected tests/interp/m98m99
Fanuc-style M98/M99 subprogram calls, missing-P-word, missing-subprogram,
mixed Fanuc/RS274NGC sub-style, and DISABLE_FANUC_STYLE_SUB INI-gated
errors, main-program O-word termination rules, parameter-scope differences,
loop counts including L0, nested numbered subprograms, subprograms after main
program text, leading-zero O-word lookup, named/numbered main programs, and
O-expression calls, plus
(ABORT,...) hot-comment numbered, named, and INI-parameter
expansion, with skipped branch/subroutine messages and post-abort program end
asserted absent where applicable. The same native, Node WASM, and browser
interpreter validation also stages an INI-declared variable file to verify
LinuxCNC G92 startup persistence and the DISABLE_G92_PERSISTENCE startup
clear path through vendored interpreter initialization.