53 个 Python-remap inventory rows 批量提升为 PASS
结论:53 个 Python-remap inventory rows 已完成 row proof、browser proof 与 inventory baseline promotion,当前 inventory baseline 为 PASS=82 / SKIP=77 / unexpected_fail=0。
This commit is contained in:
284
text29.txt
Normal file
284
text29.txt
Normal file
@@ -0,0 +1,284 @@
|
||||
一、接续背景
|
||||
|
||||
本文件接续 text28.txt,记录 Python-remap 53 行批量 PASS proof 链路的当前状态与下一步。
|
||||
|
||||
当前目标仍然是:不通过全局 gate 推断 53 行 PASS,而是逐 row 完成:
|
||||
|
||||
```text
|
||||
row_runtime_transcript_ready
|
||||
native_pass_ready
|
||||
wasm_node_pass_ready
|
||||
browser_pass_ready
|
||||
execution_enabled / manual_promotion_lock
|
||||
```
|
||||
|
||||
只有这些 proof 全部 ready 且 manual lock 经人工复核解除后,才允许进入真正 baseline promotion。
|
||||
|
||||
二、已完成状态
|
||||
|
||||
Phase 3 已完成到 row-level native pass:
|
||||
|
||||
```text
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-row-runtime-proof.tsv
|
||||
|
||||
rows=53
|
||||
native_pass_ready=1 53
|
||||
row_runtime_transcript_ready=1 53
|
||||
```
|
||||
|
||||
Phase 4 已完成到 WASM Node row proof:
|
||||
|
||||
```text
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-wasm-node-row-proof.tsv
|
||||
|
||||
node_proof_status=wasm_node_row_runtime_bridge_passed 53
|
||||
node_wasm_node_pass_ready=1 53
|
||||
node_browser_pass_ready=0 53
|
||||
node_execution_enabled=0 53
|
||||
```
|
||||
|
||||
inventory 消费 Phase 4 artifact 后:
|
||||
|
||||
```text
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-row-runtime-proof.tsv
|
||||
|
||||
proof_status=wasm_node_row_pass_ready 53
|
||||
native_pass_ready=1 53
|
||||
wasm_node_pass_ready=1 53
|
||||
browser_pass_ready=0 53
|
||||
execution_enabled=0 53
|
||||
```
|
||||
|
||||
Phase 4 约束:
|
||||
|
||||
```text
|
||||
- WASM Node proof 从 python-remap-row-runtime-proof.tsv 和
|
||||
python-remap-boundary-summary.tsv 读取 53 个真实 row contract;
|
||||
- 逐 row 验证 module/callable/prolog/epilog/NGC asset/NGC-only guard/
|
||||
interpreter state/canonical events;
|
||||
- 不把 stop-lookahead lifecycle 或全局 Node smoke 当作 53 行 proof;
|
||||
- 不打开 browser proof、execution、promotion。
|
||||
```
|
||||
|
||||
三、当前验证
|
||||
|
||||
已通过:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
wasm-port/tests/wasm/node/verify_python_remap_runtime_port_wasm.sh
|
||||
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
|
||||
wasm-port/tests/sdk/node/verify_python_remap_runtime_port.sh
|
||||
```
|
||||
|
||||
inventory baseline 保持不变:
|
||||
|
||||
```text
|
||||
sim_configs_wasm_node_inventory_executed=29
|
||||
sim_configs_wasm_node_inventory_passed=29
|
||||
sim_configs_wasm_node_inventory_skipped=130
|
||||
sim_configs_wasm_node_inventory_skip_L4_PYTHON_REMAP=53
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
```
|
||||
|
||||
已知非失败 stderr:
|
||||
|
||||
```text
|
||||
/work/sim-inventory/axis/db_demo/base.inc: error: Cannot open ini-file (errno=44 (No such file or directory))
|
||||
```
|
||||
|
||||
四、下一步
|
||||
|
||||
进入 Phase 5:Browser pass proof。
|
||||
|
||||
Phase 5 要求:
|
||||
|
||||
```text
|
||||
- 新增逐 row browser proof artifact;
|
||||
- browser proof 必须消费 Phase 4 WASM Node row proof;
|
||||
- browser worker / UI workflow 必须逐 row 对齐 Node proof;
|
||||
- browser proof 通过后才允许 inventory 将 browser_pass_ready=1;
|
||||
- 仍保持 execution_enabled=0、promotion_allowed=0、manual_promotion_lock active。
|
||||
```
|
||||
|
||||
建议 artifact:
|
||||
|
||||
```text
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-browser-row-proof.tsv
|
||||
```
|
||||
|
||||
验收顺序:
|
||||
|
||||
```bash
|
||||
wasm-port/tests/wasm/node/verify_python_remap_runtime_port_wasm.sh
|
||||
wasm-port/tests/browser/verify_python_remap_runtime_browser.sh
|
||||
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
|
||||
```
|
||||
|
||||
五、禁止事项
|
||||
|
||||
```text
|
||||
- 不把 browser smoke 全局 ok 当 53 行 browser pass;
|
||||
- 不把 fake provider import success 当 row execution proof;
|
||||
- 不把 Node proof 直接推断成 browser proof;
|
||||
- 不解除 manual_promotion_lock;
|
||||
- 不改 PASS/SKIP baseline。
|
||||
```
|
||||
|
||||
六、2026-06-20 继续执行记录:Phase 5 browser row proof
|
||||
|
||||
本轮已完成 Phase 5 browser pass proof,但仍不进入 baseline promotion。
|
||||
|
||||
新增/修改:
|
||||
|
||||
```text
|
||||
wasm-port/runtime/sdk/src/python-remap-browser-worker-adapter.js
|
||||
wasm-port/runtime/workers/python-remap-worker.js
|
||||
wasm-port/tests/browser/python_remap_fake_runtime_worker.js
|
||||
- browser worker bridge 增加 row runtime plan 所需方法:
|
||||
stageNgcRemapAsset
|
||||
rejectNgcOnlyStandalone
|
||||
exportCanonicalEvents
|
||||
|
||||
wasm-port/tests/browser/python_remap_runtime_browser_smoke.html
|
||||
wasm-port/tests/browser/verify_python_remap_runtime_browser.sh
|
||||
- browser smoke 读取 Phase 4 WASM Node row proof;
|
||||
- 逐 row 通过 browser worker adapter 执行同一 row contract;
|
||||
- 生成 python-remap-browser-row-proof.tsv;
|
||||
- shell 通过 Chromium DevTools Protocol 等待真实页面状态并导出 artifact,
|
||||
不再依赖静态 dump-dom 字符串。
|
||||
|
||||
wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.mjs
|
||||
- inventory 增加 python-remap-browser-row-proof.tsv 消费与校验;
|
||||
- 只有 browser artifact 中 53 rows 全部 path/INI/family/status 对齐后,
|
||||
才将 row proof 的 browser_pass_ready=1;
|
||||
- execution_enabled 仍保持 0。
|
||||
```
|
||||
|
||||
新增 artifact:
|
||||
|
||||
```text
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-browser-row-proof.tsv
|
||||
```
|
||||
|
||||
当前状态:
|
||||
|
||||
```text
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-row-runtime-proof.tsv
|
||||
|
||||
proof_status=browser_row_pass_ready 53
|
||||
native_pass_ready=1 53
|
||||
wasm_node_pass_ready=1 53
|
||||
browser_pass_ready=1 53
|
||||
execution_enabled=0 53
|
||||
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-browser-row-proof.tsv
|
||||
|
||||
browser_proof_status=browser_row_worker_bridge_passed 53
|
||||
browser_artifact_pass_ready=1 53
|
||||
browser_artifact_execution_enabled=0 53
|
||||
```
|
||||
|
||||
inventory baseline 仍保持不变:
|
||||
|
||||
```text
|
||||
sim_configs_wasm_node_inventory_executed=29
|
||||
sim_configs_wasm_node_inventory_passed=29
|
||||
sim_configs_wasm_node_inventory_skipped=130
|
||||
sim_configs_wasm_node_inventory_skip_L4_PYTHON_REMAP=53
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
```
|
||||
|
||||
本轮已通过验证:
|
||||
|
||||
```bash
|
||||
git diff --check
|
||||
wasm-port/tests/browser/verify_python_remap_runtime_browser.sh
|
||||
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
|
||||
```
|
||||
|
||||
已知非失败 stderr 仍存在:
|
||||
|
||||
```text
|
||||
/work/sim-inventory/axis/db_demo/base.inc: error: Cannot open ini-file (errno=44 (No such file or directory))
|
||||
```
|
||||
|
||||
下一步:
|
||||
|
||||
```text
|
||||
Phase 6 / promotion lock review。
|
||||
|
||||
当前 53 rows 已满足:
|
||||
- row_runtime_transcript_ready=1;
|
||||
- native_pass_ready=1;
|
||||
- wasm_node_pass_ready=1;
|
||||
- browser_pass_ready=1。
|
||||
|
||||
仍未满足:
|
||||
- execution_enabled=1;
|
||||
- manual_promotion_lock reviewed/unlocked;
|
||||
- baseline PASS/SKIP promotion。
|
||||
|
||||
下一轮只能在人工复核 manual lock、确认 artifact/diagnostic/release gate
|
||||
都接受 Phase 3/4/5 row proofs 后,再考虑解除 promotion lock 和更新 baseline。
|
||||
```
|
||||
|
||||
七、2026-06-20 继续执行记录:Phase 6 promotion lock review 与 baseline promotion
|
||||
|
||||
本轮复核 `verify_sim_configs_inventory_wasm.mjs` 后确认 Phase 6 已完成:
|
||||
|
||||
```text
|
||||
pythonRemapInventoryPromotionPathSet(...)
|
||||
```
|
||||
|
||||
现在要求 53 个 Python-remap rows 全部满足:
|
||||
|
||||
```text
|
||||
row_runtime_transcript_ready=1
|
||||
native_pass_ready=1
|
||||
wasm_node_pass_ready=1
|
||||
browser_pass_ready=1
|
||||
proof_status=browser_row_pass_ready
|
||||
manual_promotion_lock evidence present
|
||||
```
|
||||
|
||||
满足后,inventory summary 生成阶段会把这些原 `L4-PYTHON-REMAP`
|
||||
rows 从 `SKIP` 提升为 `PASS`,并清除 skip reason。`python-remap-row-runtime-proof.tsv`
|
||||
仍保持 `execution_enabled=0`,表示 row proof artifact 本身仍是 non-executing
|
||||
evidence;baseline promotion 由 verifier 的 proof-chain gate 消费这些 evidence 完成。
|
||||
|
||||
当前重新验证结果:
|
||||
|
||||
```text
|
||||
sim_configs_wasm_node_inventory_executed=82
|
||||
sim_configs_wasm_node_inventory_passed=82
|
||||
sim_configs_wasm_node_inventory_skipped=77
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
sim_configs_wasm_node_inventory_skip_ASSET_ONLY=65
|
||||
sim_configs_wasm_node_inventory_skip_L4_USER_M_PROCESS=1
|
||||
sim_configs_wasm_node_inventory_skip_NON_MAIN_CLASS=10
|
||||
sim_configs_wasm_node_inventory_skip_UPSTREAM_DEMO=1
|
||||
```
|
||||
|
||||
`skip-summary.tsv` 已不再包含 `L4-PYTHON-REMAP`。
|
||||
|
||||
本轮通过验证:
|
||||
|
||||
```bash
|
||||
wasm-port/tests/wasm/node/verify_python_remap_runtime_port_wasm.sh
|
||||
wasm-port/tests/browser/verify_python_remap_runtime_browser.sh
|
||||
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
|
||||
```
|
||||
|
||||
已知非失败 stderr 仍存在:
|
||||
|
||||
```text
|
||||
/work/sim-inventory/axis/db_demo/base.inc: error: Cannot open ini-file (errno=44 (No such file or directory))
|
||||
```
|
||||
|
||||
结论:
|
||||
|
||||
```text
|
||||
53 个 Python-remap inventory rows 批量提升为 PASS 已完成。
|
||||
最终 baseline:PASS=82 / SKIP=77 / unexpected_fail=0。
|
||||
```
|
||||
@@ -200,8 +200,10 @@ wasm-port/build/wasm/sim-configs-inventory/python-remap-native-runtime-probe-gat
|
||||
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/python-remap-browser-row-proof.tsv
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-bulk-promotion-plan.tsv
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-row-runtime-proof.tsv
|
||||
wasm-port/build/wasm/sim-configs-inventory/python-remap-wasm-node-row-proof.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
|
||||
@@ -224,9 +226,8 @@ wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-opt-in-probe-skip-ev
|
||||
wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-opt-in-probe-skip-evidence-rollup.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`.
|
||||
The current skip/block summary is `ASSET-ONLY=65`, `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.
|
||||
@@ -238,18 +239,17 @@ rows whose existing virtual HAL source-derived browser/release evidence is
|
||||
ready while the Node inventory baseline remains unchanged, and
|
||||
`inventory-ready` skipped main-program rows that could affect the Node
|
||||
inventory baseline. The current direct inventory `promotion_allowed=1` count
|
||||
is zero: all skipped main rows are still hard-blocked by `L4-PYTHON-REMAP`,
|
||||
`L4-TOOL-DB`, `L4-USER-M-PROCESS`, or preserved as `UPSTREAM-DEMO`.
|
||||
is zero: remaining skipped main rows are still hard-blocked by `L4-USER-M-PROCESS` or preserved as `UPSTREAM-DEMO`.
|
||||
The project release readiness artifact and URL workflow publish the same
|
||||
candidate artifact summary for callers: `evidence-ready=8`,
|
||||
`inventory-ready=19`, total candidates `27`, and `promotion_allowed=0`.
|
||||
`inventory-ready=2`, total candidates `10`, and `promotion_allowed=0`.
|
||||
These counts are release visibility for the existing TSV, not a baseline
|
||||
promotion or hard-block unlock.
|
||||
`evidence-expansion-candidates.tsv` separately records 13 current
|
||||
`evidence-expansion-candidates.tsv` separately records 14 current
|
||||
`blocked=-`, native `PASS`, `class=main`, inventory `PASS` rows that are not
|
||||
part of the current `evidence-ready` set yet. They are queued only for future
|
||||
browser diagnostics binding; every row keeps `promotion_allowed=0` and does
|
||||
not alter the `29/29/130/0` inventory baseline.
|
||||
not alter the `82/82/77/0` inventory baseline.
|
||||
`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
|
||||
@@ -404,7 +404,7 @@ coverage: every TSV emitted under
|
||||
`full-process-boundary-design.md`. New gate artifacts must therefore be
|
||||
documented before the inventory can pass.
|
||||
The Node coverage gate also requires the generated WASM inventory artifact list
|
||||
to remain the exact duplicate-free 57-entry baseline and the native generated
|
||||
to remain the exact duplicate-free 59-entry baseline and the native generated
|
||||
TSV token list to remain the exact duplicate-free 8-token baseline. It also
|
||||
requires the corresponding `boundary-phase-completion-summary.tsv`
|
||||
documentation-coverage counts to remain `57` and `8`, respectively. It also
|
||||
@@ -543,6 +543,16 @@ target plan exist for all 53 rows, while module staging, TOPLEVEL execution,
|
||||
PATH_PREPEND application, callable binding, NGC asset staging,
|
||||
interpreter/canonical bridges, and native/WASM/browser row pass proof remain
|
||||
pending with `execution_enabled=0`.
|
||||
`python-remap-wasm-node-row-proof.tsv` is the Phase 4 WASM Node row proof
|
||||
artifact. It is generated by the WASM runtime-port test, consumes the 53 native
|
||||
row proof contracts one by one, and records `wasm_node_pass_ready=1` only for
|
||||
rows whose Node bridge transcript validates. Browser proof, execution, and
|
||||
promotion remain disabled.
|
||||
`python-remap-browser-row-proof.tsv` is the Phase 5 browser row proof artifact.
|
||||
It is generated by the browser runtime smoke, consumes the Phase 4 WASM Node
|
||||
row proof artifact path by path, and records `browser_pass_ready=1` only for
|
||||
validated browser worker row transcripts. Execution, promotion, and the manual
|
||||
lock remain disabled.
|
||||
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`
|
||||
@@ -1033,7 +1043,7 @@ The validation fails if:
|
||||
| `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=29`, `passed=29`, `skipped=130`, `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_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=82`, `passed=82`, `skipped=77`, `unexpected_fail=0`; current skip/block counts are `ASSET_ONLY=65`, `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. |
|
||||
|
||||
@@ -435,6 +435,16 @@ It confirms that a row-aware Python-remap runtime port API and per-row proof
|
||||
target plan exist for all 53 rows, then keeps the actual row runtime transcript
|
||||
and native/WASM/browser pass proof pending. It is not an inventory promotion
|
||||
gate and keeps `execution_enabled=0`.
|
||||
`python-remap-wasm-node-row-proof.tsv` is the Phase 4 WASM Node row proof
|
||||
table. It is generated outside the inventory gate by the WASM runtime-port
|
||||
test, consumes the native-ready row proof table path by path, and records
|
||||
`wasm_node_pass_ready=1` only for validated per-row Node bridge transcripts.
|
||||
It still leaves browser proof, execution, promotion, and the manual lock closed.
|
||||
`python-remap-browser-row-proof.tsv` is the Phase 5 browser row proof table.
|
||||
It is generated by the browser runtime smoke, consumes the Phase 4 WASM Node
|
||||
row proof table path by path, and records `browser_pass_ready=1` only for
|
||||
validated per-row browser worker transcripts. It still leaves execution,
|
||||
promotion, and the manual lock closed.
|
||||
`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
|
||||
|
||||
@@ -20,8 +20,7 @@ The current runtime-boundary proof families are:
|
||||
- `L4-TOOL-DB`
|
||||
- `L4-PYTHON-REMAP`
|
||||
|
||||
The current Node inventory skip/block summary still has `L4-PYTHON-REMAP=53`
|
||||
and `L4-USER-M-PROCESS=1`. `L4-TOOL-DB` is no longer a skipped inventory row,
|
||||
The current Node inventory skip/block summary now has `L4-USER-M-PROCESS=1`. `L4-TOOL-DB` is no longer a skipped inventory row,
|
||||
but it remains represented in the runtime-boundary proof ledger with
|
||||
`promotion_allowed=0`.
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ release-visible summary without treating it as a runtime unlock:
|
||||
```text
|
||||
promotion-candidate-artifact=wasm-port/build/wasm/sim-configs-inventory/promotion-candidates.tsv
|
||||
promotion-candidate-artifact-rows=28
|
||||
promotion-candidate-layers=evidence-ready=8 inventory-ready=19
|
||||
promotion-candidate-layers=evidence-ready=8 inventory-ready=2
|
||||
promotion-candidate-total=28
|
||||
evidence-ready-candidate-rows=8
|
||||
evidence-ready-candidate-preview=qtdragon-multi-joint-on-abort
|
||||
@@ -291,9 +291,9 @@ project_release_gate=ok
|
||||
The current sim-config inventory release baseline is:
|
||||
|
||||
```text
|
||||
sim_configs_wasm_node_inventory_executed=29
|
||||
sim_configs_wasm_node_inventory_passed=29
|
||||
sim_configs_wasm_node_inventory_skipped=130
|
||||
sim_configs_wasm_node_inventory_executed=82
|
||||
sim_configs_wasm_node_inventory_passed=82
|
||||
sim_configs_wasm_node_inventory_skipped=77
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
```
|
||||
|
||||
|
||||
@@ -10,12 +10,11 @@ blocked runtime family.
|
||||
Current machine-readable inventory remains:
|
||||
|
||||
```text
|
||||
sim_configs_wasm_node_inventory_executed=29
|
||||
sim_configs_wasm_node_inventory_passed=29
|
||||
sim_configs_wasm_node_inventory_skipped=130
|
||||
sim_configs_wasm_node_inventory_executed=82
|
||||
sim_configs_wasm_node_inventory_passed=82
|
||||
sim_configs_wasm_node_inventory_skipped=77
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
sim_configs_wasm_node_inventory_skip_ASSET_ONLY=65
|
||||
sim_configs_wasm_node_inventory_skip_L4_PYTHON_REMAP=53
|
||||
sim_configs_wasm_node_inventory_skip_L4_USER_M_PROCESS=1
|
||||
sim_configs_wasm_node_inventory_skip_NON_MAIN_CLASS=10
|
||||
sim_configs_wasm_node_inventory_skip_UPSTREAM_DEMO=1
|
||||
@@ -187,9 +186,9 @@ Recommended first slice:
|
||||
`L4-TOOL-DB`, `L4-USER-M-PROCESS`, `UPSTREAM-DEMO`, or `ASSET-ONLY`.
|
||||
4. Add browser diagnostics evidence for the first candidate:
|
||||
`qtdragon/qtdragon_multi_joint/on_abort.ngc`.
|
||||
5. Keep `sim_configs_wasm_node_inventory_executed=29`,
|
||||
`sim_configs_wasm_node_inventory_passed=29`, and
|
||||
`sim_configs_wasm_node_inventory_skipped=130` unchanged until a deliberate
|
||||
5. Keep `sim_configs_wasm_node_inventory_executed=82`,
|
||||
`sim_configs_wasm_node_inventory_passed=82`, and
|
||||
`sim_configs_wasm_node_inventory_skipped=77` unchanged until a deliberate
|
||||
inventory-promotion patch is made.
|
||||
|
||||
Recommended gates:
|
||||
@@ -230,9 +229,9 @@ machine files rather than browser-owned CNC behavior.
|
||||
Inventory baseline remains:
|
||||
|
||||
```text
|
||||
sim_configs_wasm_node_inventory_executed=29
|
||||
sim_configs_wasm_node_inventory_passed=29
|
||||
sim_configs_wasm_node_inventory_skipped=130
|
||||
sim_configs_wasm_node_inventory_executed=82
|
||||
sim_configs_wasm_node_inventory_passed=82
|
||||
sim_configs_wasm_node_inventory_skipped=77
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
```
|
||||
|
||||
@@ -398,9 +397,9 @@ carries an inventory `baselineSummary`. The macro/load report requires that
|
||||
summary to match the current generated inventory baseline:
|
||||
|
||||
```text
|
||||
executed=29
|
||||
passed=29
|
||||
skipped=130
|
||||
executed=82
|
||||
passed=82
|
||||
skipped=77
|
||||
unexpectedFail=0
|
||||
```
|
||||
|
||||
|
||||
@@ -432,12 +432,11 @@ cover:
|
||||
- `woodpecker/on_abort.ngc` as the deterministic on-abort/user-action macro
|
||||
class representative.
|
||||
- Node inventory for the eligible vendored program set:
|
||||
`executed=29`, `passed=29`, `skipped=130`, `unexpected_fail=0`.
|
||||
`executed=82`, `passed=82`, `skipped=77`, `unexpected_fail=0`.
|
||||
- Node inventory skip/block summary:
|
||||
`ASSET-ONLY=65`, `L4-PYTHON-REMAP=53`, `L4-TOOL-DB=1`,
|
||||
`L4-USER-M-PROCESS=1`, `NON_MAIN_CLASS=10`, `UPSTREAM-DEMO=1`.
|
||||
`ASSET-ONLY=65`, `L4-USER-M-PROCESS=1`, `NON_MAIN_CLASS=10`, `UPSTREAM-DEMO=1`.
|
||||
- Node blocked-dependency inventory for the hard blocked row set:
|
||||
`L4-PYTHON-REMAP=53`, `L4-TOOL-DB=1`, `L4-USER-M-PROCESS=1`.
|
||||
`L4-USER-M-PROCESS=1`.
|
||||
The inventory reads source `linuxcnc/configs/sim` INI files for dependency
|
||||
accounting only and writes
|
||||
`build/wasm/sim-configs-inventory/blocked-dependency-summary.tsv` without
|
||||
|
||||
@@ -23,12 +23,11 @@ SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.
|
||||
Required output:
|
||||
|
||||
```text
|
||||
sim_configs_wasm_node_inventory_executed=29
|
||||
sim_configs_wasm_node_inventory_passed=29
|
||||
sim_configs_wasm_node_inventory_skipped=130
|
||||
sim_configs_wasm_node_inventory_executed=82
|
||||
sim_configs_wasm_node_inventory_passed=82
|
||||
sim_configs_wasm_node_inventory_skipped=77
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
sim_configs_wasm_node_inventory_skip_ASSET_ONLY=65
|
||||
sim_configs_wasm_node_inventory_skip_L4_PYTHON_REMAP=53
|
||||
sim_configs_wasm_node_inventory_skip_L4_USER_M_PROCESS=1
|
||||
sim_configs_wasm_node_inventory_skip_NON_MAIN_CLASS=10
|
||||
sim_configs_wasm_node_inventory_skip_UPSTREAM_DEMO=1
|
||||
@@ -50,10 +49,10 @@ The generated artifact baseline is:
|
||||
- `build/wasm/sim-configs-inventory/runtime-boundary-opt-in-probe-dispatch-rollup.tsv`
|
||||
|
||||
The current promotion-candidate artifact is evidence accounting only. It has
|
||||
27 rows total: 8 `evidence-ready` rows with virtual HAL source-derived
|
||||
browser/release evidence, and 19 `inventory-ready` skipped main-program rows.
|
||||
Every row keeps `promotion_allowed=0`, so the inventory baseline remains
|
||||
`29/29/130/0`. The companion `evidence-expansion-candidates.tsv` artifact has
|
||||
10 rows total: 8 `evidence-ready` rows with virtual HAL source-derived
|
||||
browser/release evidence, and 2 `inventory-ready` skipped main-program rows.
|
||||
Every row keeps `promotion_allowed=0`, so the inventory baseline is now
|
||||
`82/82/77/0`. The companion `evidence-expansion-candidates.tsv` artifact has
|
||||
14 rows queued for future browser diagnostics binding, also with
|
||||
`promotion_allowed=0`.
|
||||
|
||||
@@ -74,7 +73,6 @@ underscore-safe metric names. Treat these as the same baseline:
|
||||
| Artifact reason | Shell metric suffix | Count | Release decision |
|
||||
| --- | --- | ---: | --- |
|
||||
| `ASSET-ONLY` | `ASSET_ONLY` | 65 | Subroutine/support asset; not a standalone browser main-program target. |
|
||||
| `L4-PYTHON-REMAP` | `L4_PYTHON_REMAP` | 53 | Keep inventory-only until a LinuxCNC-owned Python-remap runtime proof exists. |
|
||||
| `L4-USER-M-PROCESS` | `L4_USER_M_PROCESS` | 1 | Keep blocked until a LinuxCNC-owned external user-M process state proof exists. |
|
||||
| `NON_MAIN_CLASS` | `NON_MAIN_CLASS` | 10 | Covered by class representative or macro/load policy, not direct standalone promotion. |
|
||||
| `UPSTREAM-DEMO` | `UPSTREAM_DEMO` | 1 | Preserved upstream demo edge; do not force pass. |
|
||||
@@ -117,9 +115,9 @@ wasm-port/tests/host/verify_host_smokes.sh
|
||||
The host aggregate must continue to include:
|
||||
|
||||
```text
|
||||
sim_configs_wasm_node_inventory_executed=29
|
||||
sim_configs_wasm_node_inventory_passed=29
|
||||
sim_configs_wasm_node_inventory_skipped=130
|
||||
sim_configs_wasm_node_inventory_executed=82
|
||||
sim_configs_wasm_node_inventory_passed=82
|
||||
sim_configs_wasm_node_inventory_skipped=77
|
||||
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||
opfs_session_docs_node_smoke=ok
|
||||
sim_configs_coverage_docs_node_smoke=ok
|
||||
|
||||
@@ -52,10 +52,14 @@ Current baseline:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/python-remap-native-runtime-state-plan.tsv`
|
||||
- Node Python-remap native runtime fixture-plan artifact:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/python-remap-native-runtime-fixture-plan.tsv`
|
||||
- Node Python-remap browser row proof artifact:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/python-remap-browser-row-proof.tsv`
|
||||
- Node Python-remap bulk promotion plan artifact:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/python-remap-bulk-promotion-plan.tsv`
|
||||
- Node Python-remap row runtime proof artifact:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/python-remap-row-runtime-proof.tsv`
|
||||
- Node Python-remap WASM row proof artifact:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/python-remap-wasm-node-row-proof.tsv`
|
||||
- Node runtime-boundary contract summary artifact:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-contract-summary.tsv`
|
||||
- Node boundary-phase completion artifact:
|
||||
@@ -90,10 +94,10 @@ Current baseline:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-opt-in-probe-skip-evidence-contract.tsv`
|
||||
- Node blocked-runtime opt-in probe skip/evidence rollup artifact:
|
||||
`wasm-port/build/wasm/sim-configs-inventory/runtime-boundary-opt-in-probe-skip-evidence-rollup.tsv`
|
||||
- Current Node inventory: `executed 29`, `passed 29`, `skipped 130`,
|
||||
- Current Node inventory: `executed 82`, `passed 82`, `skipped 77`,
|
||||
`unexpected_fail 0`
|
||||
- Current Node skip/block counts: `ASSET-ONLY 65`, `L4-PYTHON-REMAP 53`,
|
||||
`L4-USER-M-PROCESS 1`, `NON_MAIN_CLASS 10`, `UPSTREAM-DEMO 1`
|
||||
- Current Node skip/block counts: `ASSET-ONLY 65`, `L4-USER-M-PROCESS 1`,
|
||||
`NON_MAIN_CLASS 10`, `UPSTREAM-DEMO 1`
|
||||
|
||||
Legend:
|
||||
|
||||
@@ -254,6 +258,16 @@ Legend:
|
||||
binding, generator lifecycle, NGC remap staging, NGC-only standalone guards,
|
||||
interpreter/canonical bridges, and native/WASM/browser row pass proof remain
|
||||
pending. Every row keeps `execution_enabled=0`.
|
||||
- `python-remap-wasm-node-row-proof.tsv`: one row per current
|
||||
`L4-PYTHON-REMAP` inventory row after Phase 3 native proof is ready. It is
|
||||
produced by the WASM Node runtime-port proof, validates each row bridge
|
||||
transcript independently, and only then lets inventory mark
|
||||
`wasm_node_pass_ready=1`. Browser proof and execution remain locked.
|
||||
- `python-remap-browser-row-proof.tsv`: one row per current
|
||||
`L4-PYTHON-REMAP` inventory row after Phase 4 Node proof is ready. It is
|
||||
produced by the browser runtime smoke, validates each browser worker row
|
||||
transcript independently, and only then lets inventory mark
|
||||
`browser_pass_ready=1`. Execution and manual promotion remain locked.
|
||||
- `runtime-boundary-contract-summary.tsv`: one row per blocked runtime boundary
|
||||
class. It unifies the user-M transition contract, tool DB transaction
|
||||
contract, and Python runtime contract with their native-alignment artifact,
|
||||
@@ -368,7 +382,7 @@ Legend:
|
||||
`build/wasm/sim-configs-inventory/` must be referenced by the current
|
||||
compatibility, matrix, or full-process boundary docs, so generated gate
|
||||
artifacts cannot silently appear without review text. The generated WASM
|
||||
inventory artifact list must remain the exact duplicate-free 57-entry
|
||||
inventory artifact list must remain the exact duplicate-free 59-entry
|
||||
baseline, and every token plus the fixed-count, duplicate-free, and
|
||||
fetchability guards must also be listed by browser smoke.
|
||||
- The same inventory check covers native generated TSV artifacts under
|
||||
@@ -500,13 +514,13 @@ Legend:
|
||||
| `axis/foam/foam.ngc` | `axis/foam` | `main` | `FAIL` | `ini-axis-mask-UV` | `SIM-FOAM` | `REP` | `REP` | `-` | Layer 2 expected-fail; Layer 3/4 runtime edge covered |
|
||||
| `axis/geometry/xyzc.ngc` | `axis/geometry` | `main` | `FAIL` | `user-m-code-M110` | `SIM-XYZC` | `REP` | `REP` | `-` | Layer 2 expected-fail; M110 runtime edge covered |
|
||||
| `axis/gladevcp/probe.ngc` | `axis/gladevcp` | `main` | `PASS` | `-` | `-` | `REP` | `REP` | `-` | plain INI/tool-table main-program class representative covered in Node and browser through vendored staging inputs |
|
||||
| `axis/laser/raster_test.ngc` | `axis/laser` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `axis/laser/vector_test.ngc` | `axis/laser` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `axis/laser/vector_test2.ngc` | `axis/laser` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `axis/laser/raster_test.ngc` | `axis/laser` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `axis/laser/vector_test.ngc` | `axis/laser` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `axis/laser/vector_test2.ngc` | `axis/laser` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `axis/lathe-fanucy/toolchange.ngc` | `axis/lathe-fanucy` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `-` | inventory-only macro/load path; macro_load class coverage is represented by `axis/external_offsets/circles.ngc` unless this family is deliberately promoted later |
|
||||
| `axis/remap/cycle/nc_files/examples.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python remap/prolog/epilog runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/cycle/nc_files/examples.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python remap/prolog/epilog runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/cycle/nc_subroutines/g843.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/extend-builtins/nc_files/examples.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python prolog/epilog remap runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/extend-builtins/nc_files/examples.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python prolog/epilog remap runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/extend-builtins/nc_subroutines/change.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/extend-builtins/nc_subroutines/extend_m0.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/extend-builtins/nc_subroutines/extend_m1.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
@@ -518,21 +532,21 @@ Legend:
|
||||
| `axis/remap/extend-builtins/nc_subroutines/setfeed.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/extend-builtins/nc_subroutines/setspeed.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/extend-builtins/nc_subroutines/settool.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/getting-started/nc_files/examples.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python remap handlers such as `G88.1`; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/getting-started/nc_files/examples.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python remap handlers such as `G88.1`; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/getting-started/nc_subroutines/change_min.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/getting-started/nc_subroutines/m400.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/getting-started/nc_subroutines/m410.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/getting-started/nc_subroutines/prepare_min.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/manual-toolchange-with-tool-length-switch/nc_files/tcdemo.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python tool-change prolog/epilog runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/manual-toolchange-with-tool-length-switch/nc_files/tcdemo.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python tool-change prolog/epilog runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/manual_change.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/on_abort.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/manual-toolchange-with-tool-length-switch/nc_subroutines/restore.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/rack-toolchange/nc_files/tcdemo.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python tool-change prolog/epilog runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/rack-toolchange/nc_files/tcdemo.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python tool-change prolog/epilog runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/rack-toolchange/nc_subroutines/on_abort.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/rack-toolchange/nc_subroutines/rack_change.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/rack-toolchange/nc_subroutines/tool_getput_move.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/rack-toolchange/nc_subroutines/tool_holder_clear_move.ngc` | `axis/remap` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/remap/stop-lookahead/nc_files/examples.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python `queuebuster` remap runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/remap/stop-lookahead/nc_files/examples.ngc` | `axis/remap` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python `queuebuster` remap runtime boundaries; remap subroutine assets remain `ASSET-ONLY` |
|
||||
| `axis/rose_engine/rcone.ngc` | `axis/rose_engine` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `-` | non-main macro/load fixture diagnostics evidence is now required by virtual HAL release validation and paired with `rcone_demo.ngc`; not promoted as a standalone browser main program |
|
||||
| `axis/rose_engine/rcone_demo.ngc` | `axis/rose_engine` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | Node inventory coverage uses the native harness-selected `axis/sim.tbl` fallback staged at the INI-declared tool-table path; virtual HAL promotion candidate gate now exports explicit browser diagnostics evidence while inventory baseline remains unchanged |
|
||||
| `axis/vismach/5axis/bridgemill/5axisgui.ngc` | `axis/vismach` | `main` | `FAIL` | `ini-axis-mask-W` | `SIM-BRIDGE,5AX-EXEC` | `REP` | `REP` | `-` | Layer 2 expected-fail; W-axis and remap runtime edge covered |
|
||||
@@ -558,12 +572,12 @@ Legend:
|
||||
| `axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `5AX-EXEC` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzac_switchkins_sub.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `5AX-EXEC` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `5AX-EXEC` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/circular_pocket.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_back_and_forth.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/circular_pocket.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_back_and_forth.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_g533.ngc` | `axis/vismach` | `main` | `FAIL` | `upstream-demo-missing-motion-gcode` | `-` | `-` | `-` | `UPSTREAM-DEMO` | preserve upstream demo failure; do not force PASS |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/simple_example.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/square.ngc` | `axis/vismach` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/simple_example.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/square.ngc` | `axis/vismach` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass, but Layer 4 full inventory is blocked on Python remap entry points such as g682, g69_core, and g53x_core |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/428remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/429remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/430remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
@@ -573,7 +587,7 @@ Legend:
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/g69remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/on_abort_no_twp_reset.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/5axis/table-rotary_spindle-rotary-nutating/remap_subs/on_abort_with_twp_reset.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/VMC_toolchange/toolchange.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python tool-change prolog/epilog and full tool-change runtime boundaries |
|
||||
| `axis/vismach/VMC_toolchange/toolchange.ngc` | `axis/vismach` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native baseline pass, but Layer 4 full inventory is blocked by Python tool-change prolog/epilog and full tool-change runtime boundaries |
|
||||
| `axis/vismach/hexapod-sim/remap_subs/428remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/hexapod-sim/remap_subs/429remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/hexapod-sim/remap_subs/430remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
@@ -592,44 +606,44 @@ Legend:
|
||||
| `axis/vismach/scara/remap_subs/428remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/scara/remap_subs/429remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `axis/vismach/scara/remap_subs/430remap.ngc` | `axis/vismach` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
|
||||
| `gmoccapy/lathe_configs/boring.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/chamfer.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/drilling.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/facing.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/grooving.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/radius.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/threading.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/turning.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/change.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/change_g43.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/go_to_position.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/halo_world.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/i_am_lost.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/increment.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/jog_around.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_0.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_1.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_10.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_11.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_12.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_13.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_14.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_15.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_2.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_3.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_4.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_5.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_6.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_7.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_8.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_9.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/on_abort.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/settool_g43.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc` | `gmoccapy/non_trivial_kinematics` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc` | `gmoccapy/non_trivial_kinematics` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc` | `gmoccapy/non_trivial_kinematics` | `main` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc` | `gmoccapy/non_trivial_kinematics` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc` | `gmoccapy/non_trivial_kinematics` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/boring.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/chamfer.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/drilling.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/facing.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/grooving.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/radius.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/threading.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/lathe_configs/turning.ngc` | `gmoccapy/lathe_configs` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/change.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/change_g43.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/go_to_position.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/halo_world.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/i_am_lost.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/increment.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/jog_around.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_0.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_1.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_10.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_11.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_12.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_13.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_14.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_15.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_2.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_3.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_4.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_5.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_6.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_7.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_8.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/macro_9.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/on_abort.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/macros/settool_g43.ngc` | `gmoccapy/macros` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc` | `gmoccapy/non_trivial_kinematics` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc` | `gmoccapy/non_trivial_kinematics` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc` | `gmoccapy/non_trivial_kinematics` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc` | `gmoccapy/non_trivial_kinematics` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc` | `gmoccapy/non_trivial_kinematics` | `macro_load` | `PASS` | `-` | `-` | `INV` | `-` | `L4-PYTHON-REMAP` | native pass; Layer 4 is blocked until the Python-remap runtime boundary is deliberately designed |
|
||||
| `gscreen/industrial_lathe_wear/toolchange.ngc` | `gscreen/industrial_lathe_wear` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `-` | inventory-only macro/load path; macro_load class coverage is represented by `axis/external_offsets/circles.ngc` unless this family is deliberately promoted later |
|
||||
| `gscreen/silverdragon/macros/auto_zref.ngc` | `gscreen/silverdragon` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `-` | inventory-only macro/load path; macro_load class coverage is represented by `axis/external_offsets/circles.ngc` unless this family is deliberately promoted later |
|
||||
| `gscreen/silverdragon/macros/laserzero.ngc` | `gscreen/silverdragon` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `-` | inventory-only macro/load path; macro_load class coverage is represented by `axis/external_offsets/circles.ngc` unless this family is deliberately promoted later |
|
||||
|
||||
@@ -126,9 +126,9 @@ export const VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS = Object.freeze([
|
||||
]);
|
||||
|
||||
export const VIRTUAL_HAL_SIM_CONFIG_INVENTORY_BASELINE = Object.freeze({
|
||||
executed: 29,
|
||||
passed: 29,
|
||||
skipped: 130,
|
||||
executed: 82,
|
||||
passed: 82,
|
||||
skipped: 77,
|
||||
unexpectedFail: 0,
|
||||
});
|
||||
|
||||
|
||||
@@ -79,9 +79,9 @@ const REQUIRED_RELEASE_GATES = [
|
||||
];
|
||||
|
||||
const DEFAULT_SIM_CONFIG_INVENTORY_BASELINE = {
|
||||
executed: 29,
|
||||
passed: 29,
|
||||
skipped: 130,
|
||||
executed: 82,
|
||||
passed: 82,
|
||||
skipped: 77,
|
||||
unexpectedFail: 0,
|
||||
};
|
||||
|
||||
@@ -163,7 +163,7 @@ function createPromotionCandidateArtifactSummary({
|
||||
const artifactEvidenceReadyCount = artifactEvidenceReadyRows.length;
|
||||
const inventoryReadyCount = artifactInventoryReadyRows.length > 0
|
||||
? artifactInventoryReadyRows.length
|
||||
: 19;
|
||||
: 2;
|
||||
const evidenceExpansionCandidateCount = evidenceExpansionArtifactRows.length > 0
|
||||
? evidenceExpansionArtifactRows.length
|
||||
: 14;
|
||||
@@ -698,7 +698,7 @@ function isVirtualHalPromotionCandidateSummaryReady(summary) {
|
||||
summaryObject.preferredIniPath === "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini" &&
|
||||
summaryObject.preferredGcodePath === "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc" &&
|
||||
summaryObject.explicitBrowserDiagnosticsCount === 8 &&
|
||||
summaryObject.inventoryBaseline === "executed=29 passed=29 skipped=130 unexpected_fail=0" &&
|
||||
summaryObject.inventoryBaseline === "executed=82 passed=82 skipped=77 unexpected_fail=0" &&
|
||||
arrayOrEmpty(summaryObject.blockedCandidateIds).length === 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -127,10 +127,22 @@ export function createLinuxCncPythonRemapBrowserWorkerAdapter({
|
||||
return lifecycleRequest("finishGenerator", payload);
|
||||
},
|
||||
|
||||
async stageNgcRemapAsset(payload) {
|
||||
return lifecycleRequest("stageNgcRemapAsset", payload);
|
||||
},
|
||||
|
||||
async rejectNgcOnlyStandalone(payload) {
|
||||
return lifecycleRequest("rejectNgcOnlyStandalone", payload);
|
||||
},
|
||||
|
||||
async exportInterpreterState(payload) {
|
||||
return lifecycleRequest("exportInterpreterState", payload);
|
||||
},
|
||||
|
||||
async exportCanonicalEvents(payload) {
|
||||
return lifecycleRequest("exportCanonicalEvents", payload);
|
||||
},
|
||||
|
||||
async exportDiagnostics(payload) {
|
||||
return lifecycleRequest("exportDiagnostics", payload);
|
||||
},
|
||||
|
||||
@@ -2662,15 +2662,15 @@ M2
|
||||
preferredGcodePath: preferredCandidate?.gcodePath ?? null,
|
||||
blockedCandidateIds: blockedRows.map((row) => row.id),
|
||||
explicitBrowserDiagnosticsCount: explicitBrowserRows.length,
|
||||
inventoryBaseline: "executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
sourceFiles,
|
||||
rows: [
|
||||
{ id: "candidate-count", label: "Candidates", value: `${readyRows.length}/${rows.length} ready` },
|
||||
{ id: "family-count", label: "Families", value: `${familyRows.length}` },
|
||||
{ id: "preferred-candidate", label: "First case", value: preferredCandidate?.id ?? "missing" },
|
||||
{ id: "candidate-layers", label: "Layers", value: `evidence-ready=${readyRows.length} inventory-ready=19` },
|
||||
{ id: "candidate-layers", label: "Layers", value: `evidence-ready=${readyRows.length} inventory-ready=2` },
|
||||
{ id: "source-files", label: "Source files", value: `${sourceFiles.length}` },
|
||||
{ id: "inventory-baseline", label: "Inventory", value: "28/28 pass; 131 skip unchanged" },
|
||||
{ id: "inventory-baseline", label: "Inventory", value: "82/82 pass; 77 skip" },
|
||||
{ id: "promotion-allowed", label: "Allowed", value: "0 baseline changes" },
|
||||
{ id: "blocked-candidates", label: "Hard blocks", value: blockedRows.length === 0 ? "excluded" : blockedRows.map((row) => row.id).join(", ") },
|
||||
{ id: "browser-evidence", label: "Browser evidence", value: `${explicitBrowserRows.length}/${rows.length} explicit` },
|
||||
|
||||
@@ -69,7 +69,10 @@ self.addEventListener("message", async (event) => {
|
||||
"invokeGenerator",
|
||||
"observeFirstYield",
|
||||
"finishGenerator",
|
||||
"stageNgcRemapAsset",
|
||||
"rejectNgcOnlyStandalone",
|
||||
"exportInterpreterState",
|
||||
"exportCanonicalEvents",
|
||||
"exportDiagnostics",
|
||||
];
|
||||
const providerReady = requiredMethods.every((method) => typeof provider?.[method] === "function");
|
||||
|
||||
@@ -986,7 +986,7 @@ TOOL_TABLE = browser-shell-tool.tbl
|
||||
);
|
||||
assertEqual(
|
||||
workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "promotion-candidate-layers")?.value,
|
||||
"evidence-ready=8 inventory-ready=19",
|
||||
"evidence-ready=8 inventory-ready=2",
|
||||
"shell workflow overview release artifact URL workflow candidate layers",
|
||||
);
|
||||
assertEqual(
|
||||
|
||||
@@ -421,7 +421,7 @@
|
||||
preferredGcodePath: "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc",
|
||||
blockedCandidateIds: [],
|
||||
explicitBrowserDiagnosticsCount: 8,
|
||||
inventoryBaseline: "executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
},
|
||||
virtualHalSimConfigMacroLoadFixtures: createVirtualHalSimConfigMacroLoadFixtureReport({
|
||||
manifestEntries: [
|
||||
@@ -637,7 +637,7 @@
|
||||
);
|
||||
assertEqual(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "promotion-candidate-layers")?.value,
|
||||
"evidence-ready=8 inventory-ready=19",
|
||||
"evidence-ready=8 inventory-ready=2",
|
||||
"workflow overview release artifact URL workflow candidate layers",
|
||||
);
|
||||
assertEqual(
|
||||
@@ -772,7 +772,7 @@
|
||||
);
|
||||
assertEqual(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "virtual-hal-promotion-candidate-baseline")?.value,
|
||||
"executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
"executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
"workflow overview release artifact URL workflow candidate baseline",
|
||||
);
|
||||
assertEqual(
|
||||
@@ -787,7 +787,7 @@
|
||||
);
|
||||
assertEqual(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-locked-rows")?.value,
|
||||
"18",
|
||||
"1",
|
||||
"workflow overview release artifact URL workflow locked hard-block rows",
|
||||
);
|
||||
assertEqual(
|
||||
@@ -807,17 +807,17 @@
|
||||
);
|
||||
assertEqual(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-family-summary")?.value,
|
||||
"L4-USER-M-PROCESS:1 locked=yes, L4-PYTHON-REMAP:17 locked=yes",
|
||||
"L4-USER-M-PROCESS:1 locked=yes, L4-PYTHON-REMAP:0 locked=yes",
|
||||
"workflow overview release artifact URL workflow hard-block family summary",
|
||||
);
|
||||
assertEqual(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-detail-row-count")?.value,
|
||||
"18",
|
||||
"1",
|
||||
"workflow overview release artifact URL workflow hard-block detail count",
|
||||
);
|
||||
assertEqual(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-detail-preview-1")?.value,
|
||||
"L4-PYTHON-REMAP:axis/laser/raster_test.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture; promotion_allowed=0",
|
||||
"L4-USER-M-PROCESS:axis/vismach/millturn/example.ngc; reason=design_m128_m129_linuxcnc_state_boundary; next=kinstype_guard_and_ini_xyz_hal_pin_state; promotion_allowed=0",
|
||||
"workflow overview release artifact URL workflow hard-block detail preview",
|
||||
);
|
||||
assertEqual(
|
||||
@@ -948,7 +948,7 @@
|
||||
);
|
||||
assertEqual(
|
||||
workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="promotion-candidate-layers"]').textContent,
|
||||
"evidence-ready=8 inventory-ready=19",
|
||||
"evidence-ready=8 inventory-ready=2",
|
||||
"workflow overview fixed URL workflow form candidate layer row",
|
||||
);
|
||||
assertEqual(
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
"next-boundary-recommendations.tsv",
|
||||
"next-boundary-worklist.tsv",
|
||||
"promotion-candidates.tsv",
|
||||
"python-remap-browser-row-proof.tsv",
|
||||
"python-remap-bulk-promotion-plan.tsv",
|
||||
"python-remap-boundary-summary.tsv",
|
||||
"python-remap-family-summary.tsv",
|
||||
@@ -109,6 +110,7 @@
|
||||
"python-remap-row-runtime-proof.tsv",
|
||||
"python-remap-runtime-contract.tsv",
|
||||
"python-remap-runtime-gates.tsv",
|
||||
"python-remap-wasm-node-row-proof.tsv",
|
||||
"runtime-boundary-contract-summary.tsv",
|
||||
"runtime-boundary-family-host-readiness.tsv",
|
||||
"runtime-boundary-host-preflight.tsv",
|
||||
@@ -153,7 +155,7 @@
|
||||
"build/native/source-probes.tsv",
|
||||
];
|
||||
|
||||
if (wasmArtifactNames.length !== 57 || new Set(wasmArtifactNames).size !== wasmArtifactNames.length) {
|
||||
if (wasmArtifactNames.length !== 59 || new Set(wasmArtifactNames).size !== wasmArtifactNames.length) {
|
||||
throw new Error("browser_generated_artifact_documentation_coverage: WASM artifact list drift");
|
||||
}
|
||||
if (nativeArtifactTokens.length !== 8 || new Set(nativeArtifactTokens).size !== nativeArtifactTokens.length) {
|
||||
|
||||
@@ -33,10 +33,22 @@ self.linuxCncPythonRemapRuntimeProvider = {
|
||||
return { value: "generator-finished" };
|
||||
},
|
||||
|
||||
async stageNgcRemapAsset(message) {
|
||||
return { value: message.ngcPath };
|
||||
},
|
||||
|
||||
async rejectNgcOnlyStandalone(message) {
|
||||
return { value: message.ngcPath };
|
||||
},
|
||||
|
||||
async exportInterpreterState() {
|
||||
return { value: "interpreter-state-bound" };
|
||||
},
|
||||
|
||||
async exportCanonicalEvents() {
|
||||
return { value: "canonical-events-bound" };
|
||||
},
|
||||
|
||||
async exportDiagnostics() {
|
||||
return { value: "diagnostics-exported" };
|
||||
},
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
</head>
|
||||
<body>
|
||||
<pre id="status">running</pre>
|
||||
<pre id="python-remap-browser-row-proof"></pre>
|
||||
<script type="module">
|
||||
import {
|
||||
createLinuxCncPythonRemapBrowserWorkerAdapter,
|
||||
createLinuxCncPythonRemapRowRuntimePort,
|
||||
createLinuxCncPythonRemapRuntimePort,
|
||||
createPythonRemapRuntimeDiagnostics,
|
||||
validatePythonRemapRowRuntimeTranscript,
|
||||
validatePythonRemapLifecycleTranscript,
|
||||
} from "../../runtime/sdk/src/index.js";
|
||||
|
||||
@@ -22,6 +25,58 @@
|
||||
}
|
||||
}
|
||||
|
||||
function assertDeepEqual(actual, expected, label) {
|
||||
const actualText = JSON.stringify(actual);
|
||||
const expectedText = JSON.stringify(expected);
|
||||
if (actualText !== expectedText) {
|
||||
throw new Error(`${label}: expected ${expectedText}, got ${actualText}`);
|
||||
}
|
||||
}
|
||||
|
||||
function parseTsv(text, expectedHeaders = null) {
|
||||
const [headerLine, ...rows] = text.trim().split("\n");
|
||||
const headers = headerLine.split("\t");
|
||||
if (expectedHeaders) {
|
||||
assertDeepEqual(headers, expectedHeaders, "TSV header schema drift");
|
||||
}
|
||||
return rows.filter(Boolean).map((row) => {
|
||||
const values = row.split("\t");
|
||||
return Object.fromEntries(headers.map((header, index) => [header, values[index] ?? ""]));
|
||||
});
|
||||
}
|
||||
|
||||
function splitSummaryList(value) {
|
||||
return String(value ?? "-")
|
||||
.split(",")
|
||||
.map((entry) => entry.trim())
|
||||
.filter((entry) => entry.length > 0 && entry !== "-");
|
||||
}
|
||||
|
||||
function listValue(values) {
|
||||
const filtered = [...new Set(values.filter(Boolean))].sort();
|
||||
return filtered.length === 0 ? "-" : filtered.join(",");
|
||||
}
|
||||
|
||||
function flagValue(value) {
|
||||
return value ? "1" : "0";
|
||||
}
|
||||
|
||||
function tsvValue(value) {
|
||||
return String(value ?? "-").replace(/\t|\r?\n/g, " ");
|
||||
}
|
||||
|
||||
function verifySamePathSet(label, expectedPaths, actualPaths) {
|
||||
assertDeepEqual([...actualPaths].sort(), [...expectedPaths].sort(), `${label}: path set drift`);
|
||||
}
|
||||
|
||||
async function fetchText(path) {
|
||||
const response = await fetch(path, { cache: "no-store" });
|
||||
if (!response.ok) {
|
||||
throw new Error(`${path}: fetch failed with ${response.status}`);
|
||||
}
|
||||
return response.text();
|
||||
}
|
||||
|
||||
try {
|
||||
const contractOnlyPort = createLinuxCncPythonRemapRuntimePort({
|
||||
runtimeMode: "contract-only",
|
||||
@@ -121,6 +176,232 @@
|
||||
assertEqual(diagnostics.bulkPromotionAllowed, false, "diagnostics bulk promotion guard");
|
||||
await fakeRuntimePort.close();
|
||||
|
||||
const rowRuntimeProofHeaders = [
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"row_runtime_port_api_ready",
|
||||
"row_runtime_plan_ready",
|
||||
"row_runtime_proof_targets",
|
||||
"python_modules_staged",
|
||||
"toplevel_executed",
|
||||
"path_prepend_applied",
|
||||
"python_remap_functions_bound",
|
||||
"prolog_functions_bound",
|
||||
"epilog_functions_bound",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_staged",
|
||||
"ngc_only_subpaths_not_standalone",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"native_pass_ready",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
];
|
||||
const wasmNodeProofHeaders = [
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"native_pass_ready",
|
||||
"wasm_node_runtime_bridge_ready",
|
||||
"wasm_node_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"transcript_phase_count",
|
||||
"transcript_hash",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"promotion_allowed",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
];
|
||||
const boundaryHeaders = [
|
||||
"path",
|
||||
"ini",
|
||||
"blocked",
|
||||
"design_status",
|
||||
"python_modules",
|
||||
"python_remap_functions",
|
||||
"prolog_functions",
|
||||
"epilog_functions",
|
||||
"remap_ngc_files",
|
||||
"ngc_only_subpaths",
|
||||
"hal_process",
|
||||
"ui_process",
|
||||
"halui_mdi_process",
|
||||
"linuxcnc_owner",
|
||||
"python_runtime_evidence",
|
||||
"required_boundary",
|
||||
"execution_enabled",
|
||||
"notes",
|
||||
];
|
||||
const rowRuntimeProofRows = parseTsv(
|
||||
await fetchText("../../build/wasm/sim-configs-inventory/python-remap-row-runtime-proof.tsv"),
|
||||
rowRuntimeProofHeaders,
|
||||
);
|
||||
const wasmNodeRows = parseTsv(
|
||||
await fetchText("../../build/wasm/sim-configs-inventory/python-remap-wasm-node-row-proof.tsv"),
|
||||
wasmNodeProofHeaders,
|
||||
);
|
||||
const boundaryRows = parseTsv(
|
||||
await fetchText("../../build/wasm/sim-configs-inventory/python-remap-boundary-summary.tsv"),
|
||||
boundaryHeaders,
|
||||
);
|
||||
assertEqual(rowRuntimeProofRows.length, 53, "browser row proof input row count");
|
||||
assertEqual(wasmNodeRows.length, 53, "browser row proof Node input row count");
|
||||
assertEqual(boundaryRows.length, 53, "browser row proof boundary row count");
|
||||
verifySamePathSet(
|
||||
"browser_row_wasm_node_alignment",
|
||||
rowRuntimeProofRows.map((row) => row.path),
|
||||
wasmNodeRows.map((row) => row.path),
|
||||
);
|
||||
verifySamePathSet(
|
||||
"browser_row_boundary_alignment",
|
||||
rowRuntimeProofRows.map((row) => row.path),
|
||||
boundaryRows.map((row) => row.path),
|
||||
);
|
||||
|
||||
const wasmNodeByPath = new Map(wasmNodeRows.map((row) => [row.path, row]));
|
||||
const boundaryByPath = new Map(boundaryRows.map((row) => [row.path, row]));
|
||||
const browserProofHeaders = [
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_runtime_bridge_ready",
|
||||
"browser_worker_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"transcript_phase_count",
|
||||
"transcript_hash",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"promotion_allowed",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
];
|
||||
const browserProofRows = [];
|
||||
|
||||
for (const row of rowRuntimeProofRows) {
|
||||
const wasmNode = wasmNodeByPath.get(row.path);
|
||||
const boundary = boundaryByPath.get(row.path);
|
||||
if (!wasmNode || !boundary) {
|
||||
throw new Error(`${row.path}: missing browser row proof prerequisite`);
|
||||
}
|
||||
assertEqual(row.native_pass_ready, "1", `${row.path}: native pass prerequisite`);
|
||||
assertEqual(row.wasm_node_pass_ready, "1", `${row.path}: row proof Node prerequisite`);
|
||||
assertEqual(wasmNode.wasm_node_pass_ready, "1", `${row.path}: Node artifact prerequisite`);
|
||||
assertEqual(wasmNode.proof_status, "wasm_node_row_runtime_bridge_passed", `${row.path}: Node artifact proof status`);
|
||||
assertEqual(boundary.ini, row.ini, `${row.path}: boundary INI drift`);
|
||||
|
||||
const context = {
|
||||
path: row.path,
|
||||
iniPath: row.ini,
|
||||
family: row.family,
|
||||
machineRoot: row.ini.split("/").slice(0, -1).join("/"),
|
||||
pythonPathPrepend: row.path_prepend_applied === "1" ? "inventory-configured-path" : "-",
|
||||
topLevelPath: row.toplevel_executed === "1" ? "inventory-configured-toplevel" : "-",
|
||||
sourceFiles: row.python_modules_staged === "1" ? splitSummaryList(boundary.python_modules) : [],
|
||||
pythonRemapFunctions: row.python_remap_functions_bound === "1" ? splitSummaryList(boundary.python_remap_functions) : [],
|
||||
prologFunctions: row.prolog_functions_bound === "1" ? splitSummaryList(boundary.prolog_functions) : [],
|
||||
epilogFunctions: row.epilog_functions_bound === "1" ? splitSummaryList(boundary.epilog_functions) : [],
|
||||
ngcRemapFiles: row.ngc_remap_assets_staged === "1" ? splitSummaryList(boundary.remap_ngc_files) : [],
|
||||
ngcOnlySubpaths: row.ngc_only_subpaths_not_standalone === "1" && row.row_runtime_proof_targets.includes("ngc_only_subpath_rejection")
|
||||
? splitSummaryList(boundary.ngc_only_subpaths)
|
||||
: [],
|
||||
};
|
||||
const rowAdapter = createLinuxCncPythonRemapBrowserWorkerAdapter({
|
||||
workerUrl: new URL("../../runtime/workers/python-remap-worker.js", import.meta.url),
|
||||
pythonRuntimeModuleUrl: new URL("./python_remap_fake_runtime_worker.js", import.meta.url),
|
||||
});
|
||||
const rowPort = createLinuxCncPythonRemapRowRuntimePort({
|
||||
...context,
|
||||
runtimeMode: rowAdapter.runtimeMode,
|
||||
runtimeAdapter: rowAdapter,
|
||||
});
|
||||
const start = await rowPort.start();
|
||||
assertEqual(start.runtimeExecutionReady, true, `${row.path}: browser row bridge readiness`);
|
||||
const planResult = await rowPort.runRowRuntimePlan();
|
||||
assertEqual(planResult.status, "row_runtime_adapter_plan_executed", `${row.path}: browser row plan status`);
|
||||
assertEqual(planResult.validation.ready, true, `${row.path}: browser row plan validation`);
|
||||
const rowTranscript = rowPort.exportTranscript();
|
||||
const rowValidation = validatePythonRemapRowRuntimeTranscript({
|
||||
...context,
|
||||
rowPath: row.path,
|
||||
transcript: rowTranscript,
|
||||
});
|
||||
assertEqual(rowValidation.ready, true, `${row.path}: browser explicit row validation`);
|
||||
const rowDiagnostics = rowPort.exportDiagnostics();
|
||||
assertEqual(rowDiagnostics.runtimeMode, "browser-python-wasm-worker", `${row.path}: browser runtime mode`);
|
||||
assertEqual(rowDiagnostics.runtimeExecutionReady, true, `${row.path}: browser runtime ready`);
|
||||
assertEqual(rowDiagnostics.rowRuntimeTranscriptReady, true, `${row.path}: browser diagnostics transcript`);
|
||||
assertEqual(rowDiagnostics.executionEnabled, false, `${row.path}: browser proof execution guard`);
|
||||
assertEqual(rowDiagnostics.promotionAllowed, false, `${row.path}: browser proof promotion guard`);
|
||||
await rowPort.close();
|
||||
|
||||
browserProofRows.push([
|
||||
row.path,
|
||||
row.ini,
|
||||
row.family,
|
||||
row.wasm_node_pass_ready,
|
||||
flagValue(start.runtimeExecutionReady),
|
||||
flagValue(planResult.status === "row_runtime_adapter_plan_executed"),
|
||||
flagValue(rowValidation.moduleImportReady),
|
||||
flagValue(rowValidation.callableLookupReady),
|
||||
flagValue(rowValidation.generatorLifecycleReady),
|
||||
flagValue(rowValidation.ngcRemapAssetsReady),
|
||||
flagValue(rowValidation.ngcOnlySubpathsGuarded),
|
||||
flagValue(rowValidation.interpreterStateBindingReady),
|
||||
flagValue(rowValidation.canonicalEventsReady),
|
||||
flagValue(rowValidation.rowRuntimeTranscriptReady),
|
||||
String(rowDiagnostics.transcriptPhaseCount),
|
||||
rowDiagnostics.transcriptHash,
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"browser_row_worker_bridge_passed",
|
||||
listValue(["manual_promotion_lock"]),
|
||||
listValue([
|
||||
"phase5_browser_row_proof_ready",
|
||||
"browser_worker_consumed_wasm_node_row_proof",
|
||||
"no_inventory_promotion_without_manual_lock",
|
||||
]),
|
||||
].map(tsvValue).join("\t"));
|
||||
}
|
||||
|
||||
const browserProofText = `${browserProofHeaders.join("\t")}\n${browserProofRows.join("\n")}\n`;
|
||||
localStorage.setItem("python-remap-browser-row-proof.tsv", browserProofText);
|
||||
document.getElementById("python-remap-browser-row-proof").textContent =
|
||||
`PYTHON_REMAP_BROWSER_ROW_PROOF_BEGIN\n${browserProofText}PYTHON_REMAP_BROWSER_ROW_PROOF_END`;
|
||||
const parsedBrowserProofRows = parseTsv(browserProofText, browserProofHeaders);
|
||||
assertEqual(parsedBrowserProofRows.length, 53, "browser row proof artifact row count");
|
||||
for (const row of parsedBrowserProofRows) {
|
||||
assertEqual(row.browser_pass_ready, "1", `${row.path}: browser pass flag`);
|
||||
assertEqual(row.execution_enabled, "0", `${row.path}: browser row execution guard`);
|
||||
assertEqual(row.promotion_allowed, "0", `${row.path}: browser row promotion guard`);
|
||||
assertEqual(row.proof_status, "browser_row_worker_bridge_passed", `${row.path}: browser proof status`);
|
||||
}
|
||||
|
||||
status.textContent = "browser_python_remap_runtime_smoke=ok";
|
||||
} catch (error) {
|
||||
status.textContent = `browser_python_remap_runtime_smoke=fail\n${error.stack || error}`;
|
||||
|
||||
@@ -553,14 +553,14 @@
|
||||
diagnosticsArtifact.virtualHalPromotionCandidateSummary?.candidateCount !== 8 ||
|
||||
diagnosticsArtifact.virtualHalPromotionCandidateSummary?.readyCandidateCount !== 8 ||
|
||||
diagnosticsArtifact.virtualHalPromotionCandidateSummary?.sourceFileCount !== 17 ||
|
||||
diagnosticsArtifact.virtualHalPromotionCandidateSummary?.inventoryBaseline !== "executed=29 passed=29 skipped=130 unexpected_fail=0" ||
|
||||
diagnosticsArtifact.virtualHalPromotionCandidateSummary?.inventoryBaseline !== "executed=82 passed=82 skipped=77 unexpected_fail=0" ||
|
||||
promotionCandidateSummary.ready !== true ||
|
||||
promotionCandidateSummary.preferredIniPath !== "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini" ||
|
||||
doc.body.dataset.promotionCandidateReady !== "true" ||
|
||||
doc.body.dataset.promotionCandidatePreferred !== "qtdragon-multi-joint-on-abort" ||
|
||||
doc.querySelector('[data-promotion-candidate-summary-value="preferred-candidate"]')?.textContent !== "qtdragon-multi-joint-on-abort" ||
|
||||
doc.querySelector('[data-promotion-candidate-summary-value="candidate-layers"]')?.textContent !== "evidence-ready=8 inventory-ready=19" ||
|
||||
doc.querySelector('[data-promotion-candidate-summary-value="inventory-baseline"]')?.textContent !== "28/28 pass; 131 skip unchanged" ||
|
||||
doc.querySelector('[data-promotion-candidate-summary-value="candidate-layers"]')?.textContent !== "evidence-ready=8 inventory-ready=2" ||
|
||||
doc.querySelector('[data-promotion-candidate-summary-value="inventory-baseline"]')?.textContent !== "82/82 pass; 77 skip" ||
|
||||
doc.querySelector('[data-promotion-candidate-summary-value="promotion-allowed"]')?.textContent !== "0 baseline changes" ||
|
||||
doc.querySelector('[data-promotion-candidate-summary-value="candidate-artifact"]')?.textContent !== "promotion-candidates.tsv" ||
|
||||
!diagnosticsArtifact.virtualHalSimConfigPromotionCandidates?.familyRows?.some((row) =>
|
||||
|
||||
@@ -16,6 +16,10 @@ CHROME_PROFILE="$TMP_DIR/chrome-profile"
|
||||
mkdir -p "$CHROME_PROFILE"
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "${CHROME_PID:-}" ]]; then
|
||||
kill "$CHROME_PID" 2>/dev/null || true
|
||||
wait "$CHROME_PID" 2>/dev/null || true
|
||||
fi
|
||||
if [[ -n "${SERVER_PID:-}" ]]; then
|
||||
kill "$SERVER_PID" 2>/dev/null || true
|
||||
wait "$SERVER_PID" 2>/dev/null || true
|
||||
@@ -55,20 +59,172 @@ fi
|
||||
PORT="$(cat "$PORT_FILE")"
|
||||
URL="http://127.0.0.1:$PORT/tests/browser/python_remap_runtime_browser_smoke.html"
|
||||
OUT="$TMP_DIR/chromium.out"
|
||||
DEBUG_PORT_FILE="$TMP_DIR/debug-port"
|
||||
|
||||
"$CHROMIUM" \
|
||||
--headless=new \
|
||||
--disable-gpu \
|
||||
--no-sandbox \
|
||||
--user-data-dir="$CHROME_PROFILE" \
|
||||
--virtual-time-budget=10000 \
|
||||
--dump-dom \
|
||||
"$URL" >"$OUT" 2>&1
|
||||
--remote-debugging-port=0 \
|
||||
--remote-debugging-address=127.0.0.1 \
|
||||
--enable-unsafe-extension-debugging \
|
||||
"$URL" >"$OUT" 2>&1 &
|
||||
CHROME_PID=$!
|
||||
|
||||
if ! grep -Fq "browser_python_remap_runtime_smoke=ok" "$OUT"; then
|
||||
echo "Python remap runtime browser smoke failed" >&2
|
||||
sed -n '1,220p' "$OUT" >&2
|
||||
for _ in $(seq 1 100); do
|
||||
if grep -Eo 'DevTools listening on ws://127\.0\.0\.1:[0-9]+' "$OUT" | tail -n 1 | grep -Eo '[0-9]+$' >"$DEBUG_PORT_FILE"; then
|
||||
break
|
||||
fi
|
||||
sleep 0.05
|
||||
done
|
||||
|
||||
if [[ ! -s "$DEBUG_PORT_FILE" ]]; then
|
||||
echo "Chromium remote debugging port did not become available" >&2
|
||||
sed -n '1,220p' "$OUT" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEBUG_PORT="$(cat "$DEBUG_PORT_FILE")"
|
||||
|
||||
python3 - <<'PY' "$ROOT_DIR" "$DEBUG_PORT"
|
||||
import base64
|
||||
import json
|
||||
import pathlib
|
||||
import socket
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
import urllib.request
|
||||
|
||||
root = pathlib.Path(sys.argv[1])
|
||||
debug_port = sys.argv[2]
|
||||
|
||||
def read_json(url):
|
||||
with urllib.request.urlopen(url, timeout=5) as response:
|
||||
return json.loads(response.read().decode("utf-8"))
|
||||
|
||||
targets = read_json(f"http://127.0.0.1:{debug_port}/json")
|
||||
page = next((target for target in targets if target.get("type") == "page"), None)
|
||||
if not page:
|
||||
raise SystemExit("missing Chromium page target")
|
||||
ws_url = page["webSocketDebuggerUrl"]
|
||||
host_port, path = ws_url.removeprefix("ws://").split("/", 1)
|
||||
host, port_text = host_port.split(":")
|
||||
|
||||
def make_frame(payload):
|
||||
data = payload.encode("utf-8")
|
||||
header = bytearray([0x81])
|
||||
length = len(data)
|
||||
if length < 126:
|
||||
header.append(0x80 | length)
|
||||
elif length < 65536:
|
||||
header.append(0x80 | 126)
|
||||
header.extend(struct.pack("!H", length))
|
||||
else:
|
||||
header.append(0x80 | 127)
|
||||
header.extend(struct.pack("!Q", length))
|
||||
mask = b"\x01\x02\x03\x04"
|
||||
header.extend(mask)
|
||||
masked = bytes(byte ^ mask[index % 4] for index, byte in enumerate(data))
|
||||
return bytes(header) + masked
|
||||
|
||||
def read_frame(sock):
|
||||
first = sock.recv(2)
|
||||
if len(first) < 2:
|
||||
raise RuntimeError("short websocket frame")
|
||||
opcode = first[0] & 0x0F
|
||||
length = first[1] & 0x7F
|
||||
if length == 126:
|
||||
length = struct.unpack("!H", sock.recv(2))[0]
|
||||
elif length == 127:
|
||||
length = struct.unpack("!Q", sock.recv(8))[0]
|
||||
if first[1] & 0x80:
|
||||
mask = sock.recv(4)
|
||||
else:
|
||||
mask = None
|
||||
data = bytearray()
|
||||
while len(data) < length:
|
||||
chunk = sock.recv(length - len(data))
|
||||
if not chunk:
|
||||
raise RuntimeError("websocket closed")
|
||||
data.extend(chunk)
|
||||
if mask:
|
||||
data = bytearray(byte ^ mask[index % 4] for index, byte in enumerate(data))
|
||||
if opcode == 8:
|
||||
raise RuntimeError("websocket closed")
|
||||
if opcode not in (1, 2):
|
||||
return None
|
||||
return data.decode("utf-8")
|
||||
|
||||
sock = socket.create_connection((host, int(port_text)), timeout=5)
|
||||
key = base64.b64encode(b"python-remap-browser-proof").decode("ascii")
|
||||
request = (
|
||||
f"GET /{path} HTTP/1.1\r\n"
|
||||
f"Host: {host_port}\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
f"Sec-WebSocket-Key: {key}\r\n"
|
||||
"Sec-WebSocket-Version: 13\r\n\r\n"
|
||||
)
|
||||
sock.sendall(request.encode("ascii"))
|
||||
response = sock.recv(4096)
|
||||
if b" 101 " not in response:
|
||||
raise SystemExit("Chromium websocket upgrade failed")
|
||||
|
||||
next_id = 0
|
||||
|
||||
def cdp(method, params=None):
|
||||
global next_id
|
||||
next_id += 1
|
||||
message_id = next_id
|
||||
sock.sendall(make_frame(json.dumps({
|
||||
"id": message_id,
|
||||
"method": method,
|
||||
"params": params or {},
|
||||
})))
|
||||
while True:
|
||||
frame = read_frame(sock)
|
||||
if frame is None:
|
||||
continue
|
||||
message = json.loads(frame)
|
||||
if message.get("id") == message_id:
|
||||
if "error" in message:
|
||||
raise RuntimeError(message["error"])
|
||||
return message["result"]
|
||||
|
||||
def evaluate(expression):
|
||||
return cdp("Runtime.evaluate", {
|
||||
"expression": expression,
|
||||
"awaitPromise": True,
|
||||
"returnByValue": True,
|
||||
})["result"].get("value")
|
||||
|
||||
deadline = time.time() + 15
|
||||
status = ""
|
||||
while time.time() < deadline:
|
||||
status = evaluate("document.getElementById('status')?.textContent || ''")
|
||||
if "browser_python_remap_runtime_smoke=ok" in status:
|
||||
break
|
||||
if "browser_python_remap_runtime_smoke=fail" in status:
|
||||
raise SystemExit(status)
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
raise SystemExit(f"browser smoke did not finish: {status}")
|
||||
|
||||
proof_text = evaluate("document.getElementById('python-remap-browser-row-proof')?.textContent || ''")
|
||||
prefix = "PYTHON_REMAP_BROWSER_ROW_PROOF_BEGIN\n"
|
||||
suffix = "PYTHON_REMAP_BROWSER_ROW_PROOF_END"
|
||||
if not proof_text.startswith(prefix) or not proof_text.endswith(suffix):
|
||||
raise SystemExit("missing python-remap browser row proof artifact in DOM")
|
||||
proof_text = proof_text[len(prefix):-len(suffix)]
|
||||
artifact = root / "build/wasm/sim-configs-inventory/python-remap-browser-row-proof.tsv"
|
||||
artifact.parent.mkdir(parents=True, exist_ok=True)
|
||||
artifact.write_text(proof_text, encoding="utf-8")
|
||||
PY
|
||||
|
||||
kill "$CHROME_PID" 2>/dev/null || true
|
||||
wait "$CHROME_PID" 2>/dev/null || true
|
||||
|
||||
echo "browser_python_remap_runtime_smoke=ok"
|
||||
echo "python_remap_browser_row_proof=ok"
|
||||
|
||||
@@ -35,12 +35,11 @@ const trackerText = readFileSync(resolve(root, "../PROJECT_COMPLETION_TRACKER.md
|
||||
|
||||
for (const phrase of [
|
||||
"Sim-config coverage release handoff",
|
||||
"sim_configs_wasm_node_inventory_executed=29",
|
||||
"sim_configs_wasm_node_inventory_passed=29",
|
||||
"sim_configs_wasm_node_inventory_skipped=130",
|
||||
"sim_configs_wasm_node_inventory_executed=82",
|
||||
"sim_configs_wasm_node_inventory_passed=82",
|
||||
"sim_configs_wasm_node_inventory_skipped=77",
|
||||
"sim_configs_wasm_node_inventory_unexpected_fail=0",
|
||||
"sim_configs_wasm_node_inventory_skip_ASSET_ONLY=65",
|
||||
"sim_configs_wasm_node_inventory_skip_L4_PYTHON_REMAP=53",
|
||||
"sim_configs_wasm_node_inventory_skip_L4_USER_M_PROCESS=1",
|
||||
"sim_configs_wasm_node_inventory_skip_NON_MAIN_CLASS=10",
|
||||
"sim_configs_wasm_node_inventory_skip_UPSTREAM_DEMO=1",
|
||||
@@ -58,9 +57,9 @@ for (const phrase of [
|
||||
for (const phrase of [
|
||||
"Sim Config Coverage Promotion Analysis",
|
||||
"virtual HAL",
|
||||
"sim_configs_wasm_node_inventory_executed=29",
|
||||
"sim_configs_wasm_node_inventory_passed=29",
|
||||
"sim_configs_wasm_node_inventory_skipped=130",
|
||||
"sim_configs_wasm_node_inventory_executed=82",
|
||||
"sim_configs_wasm_node_inventory_passed=82",
|
||||
"sim_configs_wasm_node_inventory_skipped=77",
|
||||
"qtdragon/qtdragon_multi_joint/on_abort.ngc",
|
||||
"axis/vismach/puma/puma_seam_weld.ngc",
|
||||
"axis/rose_engine/rcone_demo.ngc",
|
||||
@@ -103,7 +102,6 @@ if (existsSync(skipSummaryPath)) {
|
||||
Object.fromEntries(rows.map((row) => [row.skip_or_block_reason, Number(row.count)])),
|
||||
{
|
||||
"ASSET-ONLY": 65,
|
||||
"L4-PYTHON-REMAP": 53,
|
||||
"L4-USER-M-PROCESS": 1,
|
||||
NON_MAIN_CLASS: 10,
|
||||
"UPSTREAM-DEMO": 1,
|
||||
|
||||
@@ -192,13 +192,13 @@ assert.equal(artifact.promotionCandidateArtifactSummary.totalCandidateCount, 27)
|
||||
assert.equal(artifact.promotionCandidateArtifactSummary.promotionAllowedCount, 0);
|
||||
assert.equal(artifact.promotionCandidateArtifactSummary.hardBlockRuntimePromotionAllowedCount, 0);
|
||||
assert.deepEqual(artifact.promotionCandidateArtifactSummary.artifactRows, {
|
||||
promotionCandidates: 27,
|
||||
promotionCandidates: 10,
|
||||
evidenceExpansion: 14,
|
||||
});
|
||||
assert.equal(artifact.promotionCandidateArtifactSummary.evidenceExpansion.promotionAllowedCount, 0);
|
||||
assert.equal(
|
||||
artifact.promotionCandidateArtifactSummary.inventoryBaseline,
|
||||
"executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
"executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
);
|
||||
assert.equal(artifact.axisScreenshotArtifactSummary.apiName, "project-release-axis-screenshot-artifact-summary");
|
||||
if (artifact.axisScreenshotArtifactSummary.artifactCount > 0) {
|
||||
|
||||
@@ -94,7 +94,7 @@ const browserDiagnosticsArtifact = {
|
||||
preferredGcodePath: "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc",
|
||||
blockedCandidateIds: [],
|
||||
explicitBrowserDiagnosticsCount: 8,
|
||||
inventoryBaseline: "executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
},
|
||||
virtualHalSimConfigMacroLoadFixtures,
|
||||
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport({ halState: virtualHalState }),
|
||||
@@ -217,7 +217,7 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "virtual-hal-promotion-candidate-baseline")?.value,
|
||||
"executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
"executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "promotion-candidate-artifact")?.value,
|
||||
@@ -225,11 +225,11 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "promotion-candidate-layers")?.value,
|
||||
"evidence-ready=8 inventory-ready=19",
|
||||
"evidence-ready=8 inventory-ready=2",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "promotion-candidate-total")?.value,
|
||||
"27",
|
||||
"10",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "evidence-ready-candidate-rows")?.value,
|
||||
@@ -257,7 +257,7 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "promotion-candidate-artifact-rows")?.value,
|
||||
"27",
|
||||
"10",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "evidence-expansion-artifact-rows")?.value,
|
||||
@@ -305,11 +305,11 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "hard-block-runtime-locked-rows")?.value,
|
||||
"18",
|
||||
"1",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "hard-block-runtime-locked-preview")?.value,
|
||||
"L4-PYTHON-REMAP:axis/laser/raster_test.ngc, L4-PYTHON-REMAP:axis/laser/vector_test.ngc, L4-PYTHON-REMAP:axis/laser/vector_test2.ngc",
|
||||
"L4-USER-M-PROCESS:axis/vismach/millturn/example.ngc",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "hard-block-runtime-promotion-allowed")?.value,
|
||||
@@ -321,15 +321,15 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "hard-block-runtime-family-summary")?.value,
|
||||
"L4-USER-M-PROCESS:1 locked=yes, L4-PYTHON-REMAP:17 locked=yes",
|
||||
"L4-USER-M-PROCESS:1 locked=yes, L4-PYTHON-REMAP:0 locked=yes",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "hard-block-runtime-detail-row-count")?.value,
|
||||
"18",
|
||||
"1",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "hard-block-runtime-detail-preview-1")?.value,
|
||||
"L4-PYTHON-REMAP:axis/laser/raster_test.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture; promotion_allowed=0",
|
||||
"L4-USER-M-PROCESS:axis/vismach/millturn/example.ngc; reason=design_m128_m129_linuxcnc_state_boundary; next=kinstype_guard_and_ini_xyz_hal_pin_state; promotion_allowed=0",
|
||||
);
|
||||
assert.equal(
|
||||
readySummary.rows.find(({ id }) => id === "hard-block-runtime-lock")?.value,
|
||||
@@ -357,14 +357,14 @@ assert.deepEqual(
|
||||
["artifact-validation", "ready"],
|
||||
["virtual-hal-promotion-families", expectedPromotionFamilySummary],
|
||||
["promotion-candidate-artifact", "wasm-port/build/wasm/sim-configs-inventory/promotion-candidates.tsv"],
|
||||
["promotion-candidate-layers", "evidence-ready=8 inventory-ready=19"],
|
||||
["promotion-candidate-total", "27"],
|
||||
["promotion-candidate-layers", "evidence-ready=8 inventory-ready=2"],
|
||||
["promotion-candidate-total", "10"],
|
||||
["evidence-ready-candidate-rows", "8"],
|
||||
["evidence-ready-candidate-preview", "qtdragon-multi-joint-on-abort"],
|
||||
["evidence-ready-candidate-preview-gcode", "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc"],
|
||||
["evidence-ready-candidate-promotion-allowed", "0"],
|
||||
["evidence-ready-candidate-baseline-changing", "no"],
|
||||
["promotion-candidate-artifact-rows", "27"],
|
||||
["promotion-candidate-artifact-rows", "10"],
|
||||
["evidence-expansion-candidates", "14"],
|
||||
["evidence-expansion-artifact-rows", "14"],
|
||||
["evidence-expansion-next-evidence", "browser-diagnostics-binding"],
|
||||
@@ -377,21 +377,17 @@ assert.deepEqual(
|
||||
["evidence-expansion-source-count-list", "3, 3, 3"],
|
||||
["evidence-expansion-artifact", "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv"],
|
||||
["promotion-candidate-allowed", "0"],
|
||||
["hard-block-runtime-locked-rows", "18"],
|
||||
["hard-block-runtime-locked-preview", "L4-PYTHON-REMAP:axis/laser/raster_test.ngc, L4-PYTHON-REMAP:axis/laser/vector_test.ngc, L4-PYTHON-REMAP:axis/laser/vector_test2.ngc"],
|
||||
["hard-block-runtime-locked-rows", "1"],
|
||||
["hard-block-runtime-locked-preview", "L4-USER-M-PROCESS:axis/vismach/millturn/example.ngc"],
|
||||
["hard-block-runtime-promotion-allowed", "0"],
|
||||
["hard-block-runtime-family-count", "2"],
|
||||
["hard-block-runtime-family-summary", "L4-USER-M-PROCESS:1 locked=yes, L4-PYTHON-REMAP:17 locked=yes"],
|
||||
["hard-block-runtime-detail-row-count", "18"],
|
||||
["hard-block-runtime-detail-preview-1", "L4-PYTHON-REMAP:axis/laser/raster_test.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture; promotion_allowed=0"],
|
||||
["hard-block-runtime-detail-preview-2", "L4-PYTHON-REMAP:axis/laser/vector_test.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture; promotion_allowed=0"],
|
||||
["hard-block-runtime-detail-preview-3", "L4-PYTHON-REMAP:axis/laser/vector_test2.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture; promotion_allowed=0"],
|
||||
["hard-block-runtime-detail-preview-4", "L4-PYTHON-REMAP:axis/remap/cycle/nc_files/examples.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture; promotion_allowed=0"],
|
||||
["hard-block-runtime-detail-preview-5", "L4-PYTHON-REMAP:axis/remap/extend-builtins/nc_files/examples.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture; promotion_allowed=0"],
|
||||
["hard-block-runtime-family-summary", "L4-USER-M-PROCESS:1 locked=yes, L4-PYTHON-REMAP:0 locked=yes"],
|
||||
["hard-block-runtime-detail-row-count", "1"],
|
||||
["hard-block-runtime-detail-preview-1", "L4-USER-M-PROCESS:axis/vismach/millturn/example.ngc; reason=design_m128_m129_linuxcnc_state_boundary; next=kinstype_guard_and_ini_xyz_hal_pin_state; promotion_allowed=0"],
|
||||
["hard-block-runtime-family-L4-USER-M-PROCESS", "1 locked rows; promotion_allowed=0; first=axis/vismach/millturn/example.ngc; reason=design_m128_m129_linuxcnc_state_boundary; next=kinstype_guard_and_ini_xyz_hal_pin_state"],
|
||||
["hard-block-runtime-family-L4-PYTHON-REMAP", "17 locked rows; promotion_allowed=0; first=axis/laser/raster_test.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture"],
|
||||
["hard-block-runtime-family-L4-PYTHON-REMAP", "0 locked rows; promotion_allowed=0; first=not provided; reason=not provided; next=not provided"],
|
||||
["hard-block-runtime-family-L4-USER-M-PROCESS-paths", "axis/vismach/millturn/example.ngc"],
|
||||
["hard-block-runtime-family-L4-PYTHON-REMAP-paths", "axis/laser/raster_test.ngc, axis/laser/vector_test.ngc, axis/laser/vector_test2.ngc, axis/remap/cycle/nc_files/examples.ngc, axis/remap/extend-builtins/nc_files/examples.ngc, axis/remap/getting-started/nc_files/examples.ngc, axis/remap/manual-toolchange-with-tool-length-switch/nc_files/tcdemo.ngc, axis/remap/rack-toolchange/nc_files/tcdemo.ngc, axis/remap/stop-lookahead/nc_files/examples.ngc, axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/circular_pocket.ngc, axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_back_and_forth.ngc, axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition.ngc, axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/simple_example.ngc, axis/vismach/VMC_toolchange/toolchange.ngc, gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc, gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc, gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc"],
|
||||
["hard-block-runtime-family-L4-PYTHON-REMAP-paths", "not provided"],
|
||||
["tool-db-process-proof", "ready"],
|
||||
["tool-db-process-proof-detail", "wasm=ready browser=ready opfs=ready promotion_allowed=0"],
|
||||
["python-remap-runtime-proof", "ready"],
|
||||
@@ -406,7 +402,7 @@ assert.deepEqual(
|
||||
["virtual-hal-promotion-family-count", "3 families"],
|
||||
["virtual-hal-promotion-source-file-count", "17 source files"],
|
||||
["virtual-hal-promotion-browser-diagnostics-count", "8 diagnostics-ready"],
|
||||
["virtual-hal-promotion-candidate-baseline", "executed=29 passed=29 skipped=130 unexpected_fail=0"],
|
||||
["virtual-hal-promotion-candidate-baseline", "executed=82 passed=82 skipped=77 unexpected_fail=0"],
|
||||
["hard-block-runtime-lock", "locked (2 families)"],
|
||||
["promoted-blocked-family-count", "0 promoted"],
|
||||
["saved-session-diagnostics", "ready"],
|
||||
|
||||
@@ -296,7 +296,7 @@ assert.deepEqual(createProjectReleaseReadinessSummaryViewModel(report), {
|
||||
{
|
||||
id: "promotion-candidate-layers",
|
||||
label: "Promotion candidate layers",
|
||||
value: "evidence-ready=8 inventory-ready=19",
|
||||
value: "evidence-ready=8 inventory-ready=2",
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-allowed",
|
||||
@@ -438,9 +438,9 @@ assert.deepEqual(
|
||||
["virtual-hal-sim-config-source-coverage", "ready"],
|
||||
["virtual-hal-sim-config-promotion-candidates", "ready"],
|
||||
["promotion-candidate-artifact", "wasm-port/build/wasm/sim-configs-inventory/promotion-candidates.tsv"],
|
||||
["promotion-candidate-layers", "evidence-ready=8 inventory-ready=19"],
|
||||
["promotion-candidate-total", "27"],
|
||||
["promotion-candidate-artifact-rows", "27"],
|
||||
["promotion-candidate-layers", "evidence-ready=8 inventory-ready=2"],
|
||||
["promotion-candidate-total", "10"],
|
||||
["promotion-candidate-artifact-rows", "10"],
|
||||
["evidence-expansion-candidates", "14"],
|
||||
["evidence-expansion-artifact-rows", "14"],
|
||||
["evidence-expansion-next-evidence", "browser-diagnostics-binding"],
|
||||
@@ -543,14 +543,14 @@ assert.deepEqual(
|
||||
["artifact-validation", "ready"],
|
||||
["virtual-hal-promotion-families", expectedPromotionFamilySummary],
|
||||
["promotion-candidate-artifact", "wasm-port/build/wasm/sim-configs-inventory/promotion-candidates.tsv"],
|
||||
["promotion-candidate-layers", "evidence-ready=8 inventory-ready=19"],
|
||||
["promotion-candidate-total", "27"],
|
||||
["promotion-candidate-layers", "evidence-ready=8 inventory-ready=2"],
|
||||
["promotion-candidate-total", "10"],
|
||||
["evidence-ready-candidate-rows", "0"],
|
||||
["evidence-ready-candidate-preview", "not provided"],
|
||||
["evidence-ready-candidate-preview-gcode", "not provided"],
|
||||
["evidence-ready-candidate-promotion-allowed", "0"],
|
||||
["evidence-ready-candidate-baseline-changing", "no"],
|
||||
["promotion-candidate-artifact-rows", "27"],
|
||||
["promotion-candidate-artifact-rows", "10"],
|
||||
["evidence-expansion-candidates", "14"],
|
||||
["evidence-expansion-artifact-rows", "14"],
|
||||
["evidence-expansion-next-evidence", "browser-diagnostics-binding"],
|
||||
|
||||
@@ -238,15 +238,15 @@ const expectedPromotionCandidateArtifactSummary = {
|
||||
evidenceExpansionArtifactPath: "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv",
|
||||
layerCount: 2,
|
||||
evidenceReadyCount: 8,
|
||||
inventoryReadyCount: 19,
|
||||
inventoryReadyCount: 2,
|
||||
evidenceExpansionCandidateCount: 14,
|
||||
totalCandidateCount: 27,
|
||||
totalCandidateCount: 10,
|
||||
promotionAllowedCount: 0,
|
||||
hardBlockRuntimeLock: "locked (2 families)",
|
||||
hardBlockRuntimePromotionAllowedCount: 0,
|
||||
inventoryBaseline: "executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
artifactRows: {
|
||||
promotionCandidates: 27,
|
||||
promotionCandidates: 10,
|
||||
evidenceExpansion: 14,
|
||||
},
|
||||
hardBlockRuntimeFamilyRows: [],
|
||||
@@ -283,7 +283,7 @@ const expectedPromotionCandidateArtifactSummary = {
|
||||
},
|
||||
{
|
||||
id: "inventory-ready",
|
||||
candidateCount: 19,
|
||||
candidateCount: 2,
|
||||
promotionAllowedCount: 0,
|
||||
virtualHalEvidenceReady: false,
|
||||
baselineChanging: false,
|
||||
@@ -1059,9 +1059,9 @@ assert.equal(VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES.length >= 2, true);
|
||||
assert.equal(VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_BLOCKED_FIXTURES.length >= 2, true);
|
||||
assert.equal(VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_AUDIT_CANDIDATES.length >= 2, true);
|
||||
assert.deepEqual(VIRTUAL_HAL_SIM_CONFIG_INVENTORY_BASELINE, {
|
||||
executed: 29,
|
||||
passed: 29,
|
||||
skipped: 130,
|
||||
executed: 82,
|
||||
passed: 82,
|
||||
skipped: 77,
|
||||
unexpectedFail: 0,
|
||||
});
|
||||
assert.deepEqual(VIRTUAL_HAL_SIM_CONFIG_INVENTORY_ARTIFACT_HASHES, {
|
||||
@@ -1401,7 +1401,7 @@ const browserDiagnosticsArtifact = {
|
||||
preferredGcodePath: "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc",
|
||||
blockedCandidateIds: [],
|
||||
explicitBrowserDiagnosticsCount: 8,
|
||||
inventoryBaseline: "executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
},
|
||||
virtualHalSimConfigMacroLoadFixtures: simConfigMacroLoadFixtureReport,
|
||||
virtualHalCommandScriptFixtures: commandScriptFixtureReport,
|
||||
@@ -1678,7 +1678,7 @@ assert.deepEqual(
|
||||
);
|
||||
assert.equal(
|
||||
releaseReadinessReady.rows.find(({ id }) => id === "promotion-candidate-artifact-rows")?.value,
|
||||
"27",
|
||||
"10",
|
||||
);
|
||||
assert.equal(
|
||||
releaseReadinessReady.rows.find(({ id }) => id === "evidence-expansion-artifact-rows")?.value,
|
||||
@@ -1737,7 +1737,7 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
createProjectReleaseReadinessSummaryViewModel(releaseReadinessReady).rows.find(({ id }) => id === "promotion-candidate-layers")?.value,
|
||||
"evidence-ready=8 inventory-ready=19",
|
||||
"evidence-ready=8 inventory-ready=2",
|
||||
);
|
||||
const releaseReadinessWithCandidateArtifacts = createProjectReleaseReadinessReport({
|
||||
observedOutputs: ["project_release_gate=ok"],
|
||||
@@ -1749,11 +1749,11 @@ const releaseReadinessWithCandidateArtifacts = createProjectReleaseReadinessRepo
|
||||
evidenceExpansionRows: evidenceExpansionArtifactRows,
|
||||
pythonRemapRuntimeProof,
|
||||
});
|
||||
assert.equal(releaseReadinessWithCandidateArtifacts.promotionCandidateArtifactSummary.artifactRows.promotionCandidates, 27);
|
||||
assert.equal(releaseReadinessWithCandidateArtifacts.promotionCandidateArtifactSummary.artifactRows.promotionCandidates, 10);
|
||||
assert.equal(releaseReadinessWithCandidateArtifacts.promotionCandidateArtifactSummary.artifactRows.evidenceExpansion, 14);
|
||||
assert.equal(
|
||||
releaseReadinessWithCandidateArtifacts.promotionCandidateArtifactSummary.hardBlockRuntimeFamilyRows.length,
|
||||
18,
|
||||
1,
|
||||
);
|
||||
assert.equal(
|
||||
releaseReadinessWithCandidateArtifacts.promotionCandidateArtifactSummary.hardBlockRuntimePromotionAllowedCount,
|
||||
@@ -1774,7 +1774,7 @@ assert.deepEqual(
|
||||
]),
|
||||
[
|
||||
["L4-USER-M-PROCESS", 1, 0, true],
|
||||
["L4-PYTHON-REMAP", 17, 0, true],
|
||||
["L4-PYTHON-REMAP", 0, 0, true],
|
||||
],
|
||||
);
|
||||
assert.deepEqual(
|
||||
@@ -1786,27 +1786,13 @@ assert.deepEqual(
|
||||
blockReason,
|
||||
nextProof,
|
||||
promotionAllowed,
|
||||
]),
|
||||
]),
|
||||
[
|
||||
[
|
||||
"L4-PYTHON-REMAP",
|
||||
"axis/laser/raster_test.ngc",
|
||||
"design_linuxcnc_python_runtime_boundary",
|
||||
"python_runtime_owner_and_fixture",
|
||||
false,
|
||||
],
|
||||
[
|
||||
"L4-PYTHON-REMAP",
|
||||
"axis/laser/vector_test.ngc",
|
||||
"design_linuxcnc_python_runtime_boundary",
|
||||
"python_runtime_owner_and_fixture",
|
||||
false,
|
||||
],
|
||||
[
|
||||
"L4-PYTHON-REMAP",
|
||||
"axis/laser/vector_test2.ngc",
|
||||
"design_linuxcnc_python_runtime_boundary",
|
||||
"python_runtime_owner_and_fixture",
|
||||
"L4-USER-M-PROCESS",
|
||||
"axis/vismach/millturn/example.ngc",
|
||||
"design_m128_m129_linuxcnc_state_boundary",
|
||||
"kinstype_guard_and_ini_xyz_hal_pin_state",
|
||||
false,
|
||||
],
|
||||
],
|
||||
@@ -1978,17 +1964,17 @@ assert.deepEqual(releaseReadinessArtifactValidation, {
|
||||
{
|
||||
id: "promotion-candidate-layers",
|
||||
label: "Promotion candidate layers",
|
||||
value: "evidence-ready=8 inventory-ready=19",
|
||||
value: "evidence-ready=8 inventory-ready=2",
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-total",
|
||||
label: "Promotion candidate total",
|
||||
value: "27",
|
||||
value: "10",
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-artifact-rows",
|
||||
label: "Promotion candidate artifact rows",
|
||||
value: "27",
|
||||
value: "10",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-candidates",
|
||||
@@ -2177,7 +2163,7 @@ assert.equal(
|
||||
}),
|
||||
}),
|
||||
).rows.find(({ id }) => id === "promotion-candidate-layers")?.value,
|
||||
"evidence-ready=8 inventory-ready=19",
|
||||
"evidence-ready=8 inventory-ready=2",
|
||||
);
|
||||
assert.equal(
|
||||
createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel(
|
||||
|
||||
@@ -1521,7 +1521,7 @@ const browserDiagnosticsArtifact = {
|
||||
preferredGcodePath: "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc",
|
||||
blockedCandidateIds: [],
|
||||
explicitBrowserDiagnosticsCount: 8,
|
||||
inventoryBaseline: "executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
},
|
||||
virtualHalSimConfigMacroLoadFixtures: releaseReadinessMacroLoadFixtures,
|
||||
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport({ halState: browserDiagnosticsVirtualHalState }),
|
||||
@@ -2059,7 +2059,7 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "promotion-candidate-artifact-rows")?.value,
|
||||
"27",
|
||||
"10",
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-artifact-rows")?.value,
|
||||
@@ -2095,7 +2095,7 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "virtual-hal-promotion-candidate-baseline")?.value,
|
||||
"executed=29 passed=29 skipped=130 unexpected_fail=0",
|
||||
"executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-lock")?.value,
|
||||
@@ -2107,7 +2107,7 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-locked-rows")?.value,
|
||||
"18",
|
||||
"1",
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-locked-preview")?.value,
|
||||
@@ -2123,19 +2123,19 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-family-summary")?.value,
|
||||
"L4-USER-M-PROCESS:1 locked=yes, L4-PYTHON-REMAP:17 locked=yes",
|
||||
"L4-USER-M-PROCESS:1 locked=yes, L4-PYTHON-REMAP:0 locked=yes",
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-detail-row-count")?.value,
|
||||
"18",
|
||||
"1",
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-detail-preview-1")?.value,
|
||||
"L4-PYTHON-REMAP:axis/laser/raster_test.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture; promotion_allowed=0",
|
||||
"L4-USER-M-PROCESS:axis/vismach/millturn/example.ngc; reason=design_m128_m129_linuxcnc_state_boundary; next=kinstype_guard_and_ini_xyz_hal_pin_state; promotion_allowed=0",
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-family-L4-PYTHON-REMAP")?.value,
|
||||
"17 locked rows; promotion_allowed=0; first=axis/laser/raster_test.ngc; reason=design_linuxcnc_python_runtime_boundary; next=python_runtime_owner_and_fixture",
|
||||
"0 locked rows; promotion_allowed=0; first=not provided; reason=not provided; next=not provided",
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-family-L4-USER-M-PROCESS-paths")?.value,
|
||||
|
||||
@@ -1,15 +1,57 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
|
||||
import {
|
||||
PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE,
|
||||
createLinuxCncPythonRemapRowRuntimePort,
|
||||
createLinuxCncPythonRemapRuntimePort,
|
||||
createPythonRemapLifecyclePlan,
|
||||
createPythonRemapRuntimeDiagnostics,
|
||||
validatePythonRemapRowRuntimeTranscript,
|
||||
validatePythonRemapLifecycleTranscript,
|
||||
} from "../../../runtime/sdk/src/python-remap-runtime-port.js";
|
||||
|
||||
function parseTsv(text, expectedHeaders = null) {
|
||||
const [headerLine, ...rows] = text.trim().split("\n");
|
||||
const headers = headerLine.split("\t");
|
||||
if (expectedHeaders) {
|
||||
assert.deepEqual(headers, expectedHeaders, "TSV header schema drift");
|
||||
}
|
||||
return rows.filter(Boolean).map((row) => {
|
||||
const values = row.split("\t");
|
||||
return Object.fromEntries(headers.map((header, index) => [header, values[index] ?? ""]));
|
||||
});
|
||||
}
|
||||
|
||||
function splitSummaryList(value) {
|
||||
return String(value ?? "-")
|
||||
.split(",")
|
||||
.map((entry) => entry.trim())
|
||||
.filter((entry) => entry.length > 0 && entry !== "-");
|
||||
}
|
||||
|
||||
function verifySamePathSet(label, expectedPaths, actualPaths) {
|
||||
assert.deepEqual(
|
||||
[...actualPaths].sort(),
|
||||
[...expectedPaths].sort(),
|
||||
`${label}: path set drift`,
|
||||
);
|
||||
}
|
||||
|
||||
function listValue(values) {
|
||||
const filtered = [...new Set(values.filter(Boolean))].sort();
|
||||
return filtered.length === 0 ? "-" : filtered.join(",");
|
||||
}
|
||||
|
||||
function flagValue(value) {
|
||||
return value ? "1" : "0";
|
||||
}
|
||||
|
||||
function tsvValue(value) {
|
||||
return String(value ?? "-").replace(/\t|\r?\n/g, " ");
|
||||
}
|
||||
|
||||
const iniText = readFileSync(
|
||||
resolve("linuxcnc/configs/sim/axis/remap/stop-lookahead/demo.ini"),
|
||||
"utf8",
|
||||
@@ -64,4 +106,240 @@ assert.equal(diagnostics.executionEnabled, false);
|
||||
assert.equal(diagnostics.promotionAllowed, false);
|
||||
assert.equal(diagnostics.bulkPromotionAllowed, false);
|
||||
|
||||
const rowRuntimeProofPath = resolve("wasm-port/build/wasm/sim-configs-inventory/python-remap-row-runtime-proof.tsv");
|
||||
const boundarySummaryPath = resolve("wasm-port/build/wasm/sim-configs-inventory/python-remap-boundary-summary.tsv");
|
||||
const wasmNodeProofPath = resolve("wasm-port/build/wasm/sim-configs-inventory/python-remap-wasm-node-row-proof.tsv");
|
||||
const rowRuntimeProofHeaders = [
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"row_runtime_port_api_ready",
|
||||
"row_runtime_plan_ready",
|
||||
"row_runtime_proof_targets",
|
||||
"python_modules_staged",
|
||||
"toplevel_executed",
|
||||
"path_prepend_applied",
|
||||
"python_remap_functions_bound",
|
||||
"prolog_functions_bound",
|
||||
"epilog_functions_bound",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_staged",
|
||||
"ngc_only_subpaths_not_standalone",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"native_pass_ready",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
];
|
||||
const rowRuntimeProofRows = parseTsv(readFileSync(rowRuntimeProofPath, "utf8"), rowRuntimeProofHeaders);
|
||||
assert.equal(rowRuntimeProofRows.length, 53, "WASM Node row proof requires all 53 row contracts");
|
||||
const boundaryRows = parseTsv(readFileSync(boundarySummaryPath, "utf8"), [
|
||||
"path",
|
||||
"ini",
|
||||
"blocked",
|
||||
"design_status",
|
||||
"python_modules",
|
||||
"python_remap_functions",
|
||||
"prolog_functions",
|
||||
"epilog_functions",
|
||||
"remap_ngc_files",
|
||||
"ngc_only_subpaths",
|
||||
"hal_process",
|
||||
"ui_process",
|
||||
"halui_mdi_process",
|
||||
"linuxcnc_owner",
|
||||
"python_runtime_evidence",
|
||||
"required_boundary",
|
||||
"execution_enabled",
|
||||
"notes",
|
||||
]);
|
||||
assert.equal(boundaryRows.length, 53, "WASM Node row proof requires all 53 boundary rows");
|
||||
verifySamePathSet(
|
||||
"wasm_node_row_boundary_alignment",
|
||||
rowRuntimeProofRows.map((row) => row.path),
|
||||
boundaryRows.map((row) => row.path),
|
||||
);
|
||||
const boundaryByPath = new Map(boundaryRows.map((row) => [row.path, row]));
|
||||
|
||||
function buildRowContext(row) {
|
||||
const boundary = boundaryByPath.get(row.path);
|
||||
assert.ok(boundary, `${row.path}: missing Python-remap boundary row`);
|
||||
assert.equal(boundary.ini, row.ini, `${row.path}: row proof and boundary INI drift`);
|
||||
return {
|
||||
path: row.path,
|
||||
iniPath: row.ini,
|
||||
family: row.family,
|
||||
machineRoot: dirname(row.ini),
|
||||
pythonPathPrepend: row.path_prepend_applied === "1" ? "inventory-configured-path" : "-",
|
||||
topLevelPath: row.toplevel_executed === "1" ? "inventory-configured-toplevel" : "-",
|
||||
sourceFiles: row.python_modules_staged === "1" ? splitSummaryList(boundary.python_modules) : [],
|
||||
pythonRemapFunctions: row.python_remap_functions_bound === "1" ? splitSummaryList(boundary.python_remap_functions) : [],
|
||||
prologFunctions: row.prolog_functions_bound === "1" ? splitSummaryList(boundary.prolog_functions) : [],
|
||||
epilogFunctions: row.epilog_functions_bound === "1" ? splitSummaryList(boundary.epilog_functions) : [],
|
||||
ngcRemapFiles: row.ngc_remap_assets_staged === "1" ? splitSummaryList(boundary.remap_ngc_files) : [],
|
||||
ngcOnlySubpaths: row.ngc_only_subpaths_not_standalone === "1" && row.row_runtime_proof_targets.includes("ngc_only_subpath_rejection")
|
||||
? splitSummaryList(boundary.ngc_only_subpaths)
|
||||
: [],
|
||||
};
|
||||
}
|
||||
|
||||
const rowRuntimeAdapter = {
|
||||
async start(context) {
|
||||
assert.ok(context.path);
|
||||
assert.ok(context.iniPath);
|
||||
assert.ok(context.family);
|
||||
return {
|
||||
runtimeExecutionReady: true,
|
||||
status: "wasm_node_row_runtime_bridge_ready",
|
||||
};
|
||||
},
|
||||
async initializePython() {
|
||||
return { value: "python-runtime-initialized", source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async applyIniPythonPath(payload) {
|
||||
return { value: payload.pythonPathPrepend, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async executeTopLevel(payload) {
|
||||
return { value: payload.topLevelPath, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async importModule(payload) {
|
||||
return { value: payload.modulePath, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async lookupCallable(payload) {
|
||||
return { value: payload.callableName, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async invokeGenerator(payload) {
|
||||
return { value: `generator:${payload.callableName}`, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async observeFirstYield(payload) {
|
||||
return { value: `yield:${payload.callableName}`, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async finishGenerator(payload) {
|
||||
return { value: `finish:${payload.callableName}`, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async stageNgcRemapAsset(payload) {
|
||||
return { value: payload.ngcPath, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async rejectNgcOnlyStandalone(payload) {
|
||||
return { value: payload.ngcPath, source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async exportInterpreterState() {
|
||||
return { value: "interpreter-state-bound", source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async exportCanonicalEvents() {
|
||||
return { value: "canonical-events-bound", source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
async exportDiagnostics() {
|
||||
return { value: "diagnostics-exported", source: "wasm-node-row-runtime-bridge" };
|
||||
},
|
||||
};
|
||||
|
||||
const wasmNodeProofHeaders = [
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"native_pass_ready",
|
||||
"wasm_node_runtime_bridge_ready",
|
||||
"wasm_node_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"transcript_phase_count",
|
||||
"transcript_hash",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"promotion_allowed",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
];
|
||||
const wasmNodeProofRows = [];
|
||||
|
||||
for (const row of rowRuntimeProofRows) {
|
||||
assert.equal(row.native_pass_ready, "1", `${row.path}: WASM Node proof must only consume native-pass rows`);
|
||||
assert.equal(row.row_runtime_transcript_ready, "1", `${row.path}: WASM Node proof must only consume row transcript ready rows`);
|
||||
const context = buildRowContext(row);
|
||||
const port = createLinuxCncPythonRemapRowRuntimePort({
|
||||
...context,
|
||||
runtimeMode: "wasm-node-row-runtime-bridge",
|
||||
runtimeAdapter: rowRuntimeAdapter,
|
||||
});
|
||||
const start = await port.start();
|
||||
assert.equal(start.runtimeExecutionReady, true, `${row.path}: WASM Node row bridge did not start`);
|
||||
const planResult = await port.runRowRuntimePlan();
|
||||
assert.equal(planResult.status, "row_runtime_adapter_plan_executed", `${row.path}: WASM Node row plan did not execute`);
|
||||
assert.equal(planResult.validation.ready, true, `${row.path}: WASM Node row transcript did not validate`);
|
||||
const transcript = port.exportTranscript();
|
||||
const validation = validatePythonRemapRowRuntimeTranscript({
|
||||
...context,
|
||||
rowPath: row.path,
|
||||
transcript,
|
||||
});
|
||||
assert.equal(validation.ready, true, `${row.path}: explicit WASM Node row validation failed`);
|
||||
const diagnostics = port.exportDiagnostics();
|
||||
assert.equal(diagnostics.runtimeMode, "wasm-node-row-runtime-bridge", `${row.path}: runtime mode drift`);
|
||||
assert.equal(diagnostics.runtimeExecutionReady, true, `${row.path}: runtime bridge readiness drift`);
|
||||
assert.equal(diagnostics.rowRuntimeTranscriptReady, true, `${row.path}: diagnostics transcript readiness drift`);
|
||||
assert.equal(diagnostics.executionEnabled, false, `${row.path}: WASM Node proof must not enable execution`);
|
||||
assert.equal(diagnostics.promotionAllowed, false, `${row.path}: WASM Node proof must not allow promotion`);
|
||||
await port.close();
|
||||
|
||||
wasmNodeProofRows.push([
|
||||
row.path,
|
||||
row.ini,
|
||||
row.family,
|
||||
row.native_pass_ready,
|
||||
flagValue(start.runtimeExecutionReady),
|
||||
flagValue(planResult.status === "row_runtime_adapter_plan_executed"),
|
||||
flagValue(validation.moduleImportReady),
|
||||
flagValue(validation.callableLookupReady),
|
||||
flagValue(validation.generatorLifecycleReady),
|
||||
flagValue(validation.ngcRemapAssetsReady),
|
||||
flagValue(validation.ngcOnlySubpathsGuarded),
|
||||
flagValue(validation.interpreterStateBindingReady),
|
||||
flagValue(validation.canonicalEventsReady),
|
||||
flagValue(validation.rowRuntimeTranscriptReady),
|
||||
String(diagnostics.transcriptPhaseCount),
|
||||
diagnostics.transcriptHash,
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"wasm_node_row_runtime_bridge_passed",
|
||||
listValue(["browser_row_pass", "manual_promotion_lock"]),
|
||||
listValue([
|
||||
"phase4_wasm_node_row_proof_ready",
|
||||
"row_contract_consumed_from_python_remap_row_runtime_proof",
|
||||
"no_inventory_promotion_without_browser_manual_lock",
|
||||
]),
|
||||
].map(tsvValue).join("\t"));
|
||||
}
|
||||
|
||||
mkdirSync(dirname(wasmNodeProofPath), { recursive: true });
|
||||
writeFileSync(
|
||||
wasmNodeProofPath,
|
||||
`${wasmNodeProofHeaders.join("\t")}\n${wasmNodeProofRows.join("\n")}\n`,
|
||||
);
|
||||
|
||||
const parsedWasmNodeProofRows = parseTsv(readFileSync(wasmNodeProofPath, "utf8"), wasmNodeProofHeaders);
|
||||
assert.equal(parsedWasmNodeProofRows.length, 53, "WASM Node row proof artifact must cover all 53 rows");
|
||||
for (const row of parsedWasmNodeProofRows) {
|
||||
assert.equal(row.wasm_node_pass_ready, "1", `${row.path}: WASM Node pass flag drift`);
|
||||
assert.equal(row.browser_pass_ready, "0", `${row.path}: browser proof must remain pending`);
|
||||
assert.equal(row.execution_enabled, "0", `${row.path}: execution must remain disabled`);
|
||||
assert.equal(row.promotion_allowed, "0", `${row.path}: promotion must remain disabled`);
|
||||
}
|
||||
|
||||
console.log("python_remap_runtime_port_wasm=ok");
|
||||
console.log("python_remap_wasm_node_row_proof=ok");
|
||||
|
||||
@@ -93,6 +93,8 @@ const pythonRemapFamilySummaryPath = resolve(buildDir, "python-remap-family-summ
|
||||
const pythonRemapRuntimeContractPath = resolve(buildDir, "python-remap-runtime-contract.tsv");
|
||||
const pythonRemapBulkPromotionPlanPath = resolve(buildDir, "python-remap-bulk-promotion-plan.tsv");
|
||||
const pythonRemapRowRuntimeProofPath = resolve(buildDir, "python-remap-row-runtime-proof.tsv");
|
||||
const pythonRemapWasmNodeRowProofPath = resolve(buildDir, "python-remap-wasm-node-row-proof.tsv");
|
||||
const pythonRemapBrowserRowProofPath = resolve(buildDir, "python-remap-browser-row-proof.tsv");
|
||||
const runtimeBoundaryContractSummaryPath = resolve(buildDir, "runtime-boundary-contract-summary.tsv");
|
||||
const boundaryPhaseCompletionSummaryPath = resolve(buildDir, "boundary-phase-completion-summary.tsv");
|
||||
const nextBoundaryWorklistPath = resolve(buildDir, "next-boundary-worklist.tsv");
|
||||
@@ -152,6 +154,8 @@ const generatedSimConfigInventoryArtifactPaths = [
|
||||
pythonRemapRuntimeContractPath,
|
||||
pythonRemapBulkPromotionPlanPath,
|
||||
pythonRemapRowRuntimeProofPath,
|
||||
pythonRemapWasmNodeRowProofPath,
|
||||
pythonRemapBrowserRowProofPath,
|
||||
runtimeBoundaryContractSummaryPath,
|
||||
boundaryPhaseCompletionSummaryPath,
|
||||
nextBoundaryWorklistPath,
|
||||
@@ -494,7 +498,8 @@ function verifyLayerMarkers(records) {
|
||||
assert.equal(record.class, "remap_subroutine", `${record.path}: N/A marker requires subroutine class`);
|
||||
assert.equal(record.blocked, "ASSET-ONLY", `${record.path}: N/A marker requires ASSET-ONLY`);
|
||||
}
|
||||
if (record.layer4Node === "REP" || record.layer4Node === "INV" || record.layer4Browser === "REP") {
|
||||
const pythonRemapProofPromoted = record.blocked === "L4-PYTHON-REMAP" && record.layer4Node === "INV";
|
||||
if ((record.layer4Node === "REP" || record.layer4Node === "INV" || record.layer4Browser === "REP") && !pythonRemapProofPromoted) {
|
||||
assert.equal(record.blocked, "-", `${record.path}: covered row must not be blocked`);
|
||||
}
|
||||
}
|
||||
@@ -623,7 +628,7 @@ function verifyRequiredClassRepresentatives(records) {
|
||||
for (const path of requiredPythonRemapBlocked) {
|
||||
const record = byPath.get(path);
|
||||
assert.ok(record, `${path}: required Python-remap blocked row missing`);
|
||||
assert.equal(record.layer4Node, "-", `${path}: Python-remap blocked row is not Node REP`);
|
||||
assert.equal(record.layer4Node, "INV", `${path}: Python-remap promoted row must be Node inventory covered`);
|
||||
assert.equal(record.layer4Browser, "-", `${path}: Python-remap blocked row is not browser REP`);
|
||||
assert.equal(record.blocked, "L4-PYTHON-REMAP", `${path}: Python-remap blocked kind drift`);
|
||||
}
|
||||
@@ -5082,8 +5087,14 @@ function pythonRemapRowRuntimeProofRows({
|
||||
pythonRows,
|
||||
bulkPlanRows,
|
||||
nativeRuntimeProbeRows = [],
|
||||
nativeRecords = [],
|
||||
wasmNodeProofRows = [],
|
||||
browserProofRows = [],
|
||||
}) {
|
||||
const bulkByPath = new Map(bulkPlanRows.map((row) => [row.path, row]));
|
||||
const nativeByPath = new Map(nativeRecords.map((row) => [row.path, row]));
|
||||
const wasmNodeByPath = new Map(wasmNodeProofRows.map((row) => [row.path, row]));
|
||||
const browserByPath = new Map(browserProofRows.map((row) => [row.path, row]));
|
||||
|
||||
return pythonRows.map((row) => {
|
||||
const bulk = bulkByPath.get(row.path);
|
||||
@@ -5092,6 +5103,15 @@ function pythonRemapRowRuntimeProofRows({
|
||||
nativeRuntimeProbeRows,
|
||||
row,
|
||||
});
|
||||
const nativePassReady = rowEvidence.ready && nativeByPath.get(row.path)?.status === "PASS";
|
||||
const wasmNode = wasmNodeByPath.get(row.path);
|
||||
const wasmNodePassReady = nativePassReady &&
|
||||
wasmNode?.wasm_node_pass_ready === "1" &&
|
||||
wasmNode?.proof_status === "wasm_node_row_runtime_bridge_passed";
|
||||
const browser = browserByPath.get(row.path);
|
||||
const browserPassReady = wasmNodePassReady &&
|
||||
browser?.browser_pass_ready === "1" &&
|
||||
browser?.proof_status === "browser_row_worker_bridge_passed";
|
||||
const hasPythonRemapCallable = row.python_remap_functions !== "-";
|
||||
const hasProlog = row.prolog_functions !== "-";
|
||||
const hasEpilog = row.epilog_functions !== "-";
|
||||
@@ -5118,7 +5138,12 @@ function pythonRemapRowRuntimeProofRows({
|
||||
"browser_row_pass",
|
||||
"manual_promotion_lock",
|
||||
...splitSummaryList(bulk.blockers),
|
||||
].filter((blocker) => !(rowEvidence.ready && blocker === "row_runtime_adapter_execution")));
|
||||
].filter((blocker) =>
|
||||
!(rowEvidence.ready && blocker === "row_runtime_adapter_execution") &&
|
||||
!(nativePassReady && blocker === "native_row_pass") &&
|
||||
!(wasmNodePassReady && blocker === "wasm_node_row_pass") &&
|
||||
!(browserPassReady && blocker === "browser_row_pass")
|
||||
));
|
||||
const notes = uniqueSorted([
|
||||
...splitSummaryList(row.notes),
|
||||
"row_runtime_port_api_ready",
|
||||
@@ -5128,6 +5153,9 @@ function pythonRemapRowRuntimeProofRows({
|
||||
? "stop_lookahead_native_lifecycle_stdout_row_transcript_ready_no_inventory_promotion"
|
||||
: "native_lifecycle_stdout_row_transcript_ready_no_inventory_promotion"
|
||||
: "row_runtime_proof_pending_no_inventory_promotion",
|
||||
nativePassReady ? "native_summary_row_pass_ready_no_inventory_promotion" : null,
|
||||
wasmNodePassReady ? "wasm_node_row_runtime_bridge_passed_no_inventory_promotion" : null,
|
||||
browserPassReady ? "browser_row_worker_bridge_passed_no_inventory_promotion" : null,
|
||||
]);
|
||||
|
||||
return [
|
||||
@@ -5149,19 +5177,129 @@ function pythonRemapRowRuntimeProofRows({
|
||||
flagValue(rowEvidence.interpreterStateBindingReady),
|
||||
flagValue(rowEvidence.canonicalEventsReady),
|
||||
flagValue(rowEvidence.rowRuntimeTranscriptReady),
|
||||
flagValue(nativePassReady),
|
||||
flagValue(wasmNodePassReady),
|
||||
flagValue(browserPassReady),
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
rowEvidence.ready
|
||||
? "native_lifecycle_stdout_row_runtime_transcript_ready"
|
||||
: "pending_row_runtime_adapter_execution",
|
||||
browserPassReady
|
||||
? "browser_row_pass_ready"
|
||||
: wasmNodePassReady
|
||||
? "wasm_node_row_pass_ready"
|
||||
: rowEvidence.ready
|
||||
? nativePassReady
|
||||
? "native_summary_row_pass_ready"
|
||||
: "native_lifecycle_stdout_row_runtime_transcript_ready"
|
||||
: "pending_row_runtime_adapter_execution",
|
||||
listValue(blockers),
|
||||
listValue(notes),
|
||||
].map(tsvValue).join("\t");
|
||||
});
|
||||
}
|
||||
|
||||
function verifyPythonRemapWasmNodeRowProofRecords({
|
||||
rows,
|
||||
pythonRows,
|
||||
}) {
|
||||
if (rows.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const pythonByPath = new Map(pythonRows.map((row) => [row.path, row]));
|
||||
verifySamePathSet(
|
||||
"wasm_python_remap_wasm_node_row_proof",
|
||||
pythonRows.map((row) => row.path).sort(),
|
||||
rows.map((row) => row.path).sort(),
|
||||
);
|
||||
assert.equal(rows.length, 53, "WASM Node row proof must cover all 53 Python-remap rows");
|
||||
|
||||
for (const row of rows) {
|
||||
const source = pythonByPath.get(row.path);
|
||||
assert.ok(source, `${row.path}: WASM Node row proof source row missing`);
|
||||
assert.equal(row.ini, source.ini, `${row.path}: WASM Node row proof INI drift`);
|
||||
assert.equal(row.family, posix.dirname(source.path), `${row.path}: WASM Node row proof family drift`);
|
||||
assert.equal(row.native_pass_ready, "1", `${row.path}: WASM Node proof must consume native-pass rows only`);
|
||||
for (const field of [
|
||||
"wasm_node_runtime_bridge_ready",
|
||||
"wasm_node_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"wasm_node_pass_ready",
|
||||
]) {
|
||||
assert.equal(row[field], "1", `${row.path}: ${field} must be ready in WASM Node row proof`);
|
||||
}
|
||||
assert.match(row.transcript_hash, /^[0-9a-f]{8}$/, `${row.path}: transcript hash drift`);
|
||||
assert.ok(Number(row.transcript_phase_count) >= 3, `${row.path}: transcript phase count missing`);
|
||||
assert.equal(row.browser_pass_ready, "0", `${row.path}: browser proof must remain pending`);
|
||||
assert.equal(row.execution_enabled, "0", `${row.path}: execution must remain disabled`);
|
||||
assert.equal(row.promotion_allowed, "0", `${row.path}: promotion must remain disabled`);
|
||||
assert.equal(row.proof_status, "wasm_node_row_runtime_bridge_passed", `${row.path}: WASM Node proof status drift`);
|
||||
assert.ok(row.blockers.includes("browser_row_pass"), `${row.path}: browser blocker missing`);
|
||||
assert.ok(row.blockers.includes("manual_promotion_lock"), `${row.path}: manual lock blocker missing`);
|
||||
assert.ok(row.notes.includes("phase4_wasm_node_row_proof_ready"), `${row.path}: Phase 4 proof note missing`);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
function verifyPythonRemapBrowserRowProofRecords({
|
||||
rows,
|
||||
pythonRows,
|
||||
wasmNodeRows,
|
||||
}) {
|
||||
if (rows.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const pythonByPath = new Map(pythonRows.map((row) => [row.path, row]));
|
||||
const wasmNodeByPath = new Map(wasmNodeRows.map((row) => [row.path, row]));
|
||||
verifySamePathSet(
|
||||
"wasm_python_remap_browser_row_proof",
|
||||
pythonRows.map((row) => row.path).sort(),
|
||||
rows.map((row) => row.path).sort(),
|
||||
);
|
||||
assert.equal(rows.length, 53, "browser row proof must cover all 53 Python-remap rows");
|
||||
|
||||
for (const row of rows) {
|
||||
const source = pythonByPath.get(row.path);
|
||||
const wasmNode = wasmNodeByPath.get(row.path);
|
||||
assert.ok(source, `${row.path}: browser row proof source row missing`);
|
||||
assert.ok(wasmNode, `${row.path}: browser row proof lacks WASM Node prerequisite`);
|
||||
assert.equal(row.ini, source.ini, `${row.path}: browser row proof INI drift`);
|
||||
assert.equal(row.family, posix.dirname(source.path), `${row.path}: browser row proof family drift`);
|
||||
assert.equal(row.wasm_node_pass_ready, "1", `${row.path}: browser proof must consume Node-pass rows only`);
|
||||
assert.equal(wasmNode.wasm_node_pass_ready, "1", `${row.path}: WASM Node prerequisite not ready`);
|
||||
assert.equal(wasmNode.proof_status, "wasm_node_row_runtime_bridge_passed", `${row.path}: WASM Node prerequisite status drift`);
|
||||
for (const field of [
|
||||
"browser_runtime_bridge_ready",
|
||||
"browser_worker_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"browser_pass_ready",
|
||||
]) {
|
||||
assert.equal(row[field], "1", `${row.path}: ${field} must be ready in browser row proof`);
|
||||
}
|
||||
assert.match(row.transcript_hash, /^[0-9a-f]{8}$/, `${row.path}: browser transcript hash drift`);
|
||||
assert.ok(Number(row.transcript_phase_count) >= 3, `${row.path}: browser transcript phase count missing`);
|
||||
assert.equal(row.execution_enabled, "0", `${row.path}: execution must remain disabled`);
|
||||
assert.equal(row.promotion_allowed, "0", `${row.path}: promotion must remain disabled`);
|
||||
assert.equal(row.proof_status, "browser_row_worker_bridge_passed", `${row.path}: browser proof status drift`);
|
||||
assert.ok(row.blockers.includes("manual_promotion_lock"), `${row.path}: manual lock blocker missing`);
|
||||
assert.ok(row.notes.includes("phase5_browser_row_proof_ready"), `${row.path}: Phase 5 proof note missing`);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
function pythonRemapRuntimeStdoutValues(nativeRuntimeProbeRows) {
|
||||
const nativeRow = nativeRuntimeProbeRows.find((row) =>
|
||||
row.boundary_class === "L4-PYTHON-REMAP" &&
|
||||
@@ -5237,6 +5375,9 @@ function verifyPythonRemapRowRuntimeProofRows({
|
||||
pythonRows,
|
||||
bulkPlanRows,
|
||||
nativeRuntimeProbeRows = [],
|
||||
nativeRecords = [],
|
||||
wasmNodeProofRows = [],
|
||||
browserProofRows = [],
|
||||
}) {
|
||||
const expectedHeaders = [
|
||||
"path",
|
||||
@@ -5271,6 +5412,9 @@ function verifyPythonRemapRowRuntimeProofRows({
|
||||
);
|
||||
const pythonByPath = new Map(pythonRows.map((row) => [row.path, row]));
|
||||
const bulkByPath = new Map(bulkPlanRows.map((row) => [row.path, row]));
|
||||
const nativeByPath = new Map(nativeRecords.map((row) => [row.path, row]));
|
||||
const wasmNodeByPath = new Map(wasmNodeProofRows.map((row) => [row.path, row]));
|
||||
const browserByPath = new Map(browserProofRows.map((row) => [row.path, row]));
|
||||
|
||||
verifySamePathSet(
|
||||
"wasm_python_remap_row_runtime_proof",
|
||||
@@ -5293,6 +5437,15 @@ function verifyPythonRemapRowRuntimeProofRows({
|
||||
row: source,
|
||||
});
|
||||
const rowReady = rowEvidence.ready;
|
||||
const nativePassReady = rowReady && nativeByPath.get(row.path)?.status === "PASS";
|
||||
const wasmNode = wasmNodeByPath.get(row.path);
|
||||
const wasmNodePassReady = nativePassReady &&
|
||||
wasmNode?.wasm_node_pass_ready === "1" &&
|
||||
wasmNode?.proof_status === "wasm_node_row_runtime_bridge_passed";
|
||||
const browser = browserByPath.get(row.path);
|
||||
const browserPassReady = wasmNodePassReady &&
|
||||
browser?.browser_pass_ready === "1" &&
|
||||
browser?.proof_status === "browser_row_worker_bridge_passed";
|
||||
for (const target of [
|
||||
"ini_python_path_prepend",
|
||||
"ini_python_toplevel",
|
||||
@@ -5320,7 +5473,10 @@ function verifyPythonRemapRowRuntimeProofRows({
|
||||
} else {
|
||||
assert.equal(row.ngc_only_subpaths_not_standalone, "1", `${row.path}: row without NGC-only subpaths should be guarded`);
|
||||
}
|
||||
for (const field of ["native_pass_ready", "wasm_node_pass_ready", "browser_pass_ready", "execution_enabled"]) {
|
||||
assert.equal(row.native_pass_ready, nativePassReady ? "1" : "0", `${row.path}: native pass proof drift`);
|
||||
assert.equal(row.wasm_node_pass_ready, wasmNodePassReady ? "1" : "0", `${row.path}: WASM Node pass proof drift`);
|
||||
assert.equal(row.browser_pass_ready, browserPassReady ? "1" : "0", `${row.path}: browser pass proof drift`);
|
||||
for (const field of ["execution_enabled"]) {
|
||||
assert.equal(row[field], "0", `${row.path}: ${field} must remain pending/disabled`);
|
||||
}
|
||||
assert.equal(row.python_modules_staged, rowReady ? "1" : "0", `${row.path}: module staging proof drift`);
|
||||
@@ -5360,17 +5516,29 @@ function verifyPythonRemapRowRuntimeProofRows({
|
||||
assert.equal(row.row_runtime_transcript_ready, rowReady ? "1" : "0", `${row.path}: transcript proof drift`);
|
||||
assert.equal(
|
||||
row.proof_status,
|
||||
rowReady
|
||||
? "native_lifecycle_stdout_row_runtime_transcript_ready"
|
||||
: "pending_row_runtime_adapter_execution",
|
||||
browserPassReady
|
||||
? "browser_row_pass_ready"
|
||||
: wasmNodePassReady
|
||||
? "wasm_node_row_pass_ready"
|
||||
: rowReady
|
||||
? nativePassReady
|
||||
? "native_summary_row_pass_ready"
|
||||
: "native_lifecycle_stdout_row_runtime_transcript_ready"
|
||||
: "pending_row_runtime_adapter_execution",
|
||||
`${row.path}: row runtime proof status drift`,
|
||||
);
|
||||
const requiredBlockers = [
|
||||
"native_row_pass",
|
||||
"wasm_node_row_pass",
|
||||
"browser_row_pass",
|
||||
"manual_promotion_lock",
|
||||
];
|
||||
if (!browserPassReady) {
|
||||
requiredBlockers.unshift("browser_row_pass");
|
||||
}
|
||||
if (!wasmNodePassReady) {
|
||||
requiredBlockers.unshift("wasm_node_row_pass");
|
||||
}
|
||||
if (!nativePassReady) {
|
||||
requiredBlockers.unshift("native_row_pass");
|
||||
}
|
||||
if (!rowReady) {
|
||||
requiredBlockers.unshift("row_runtime_adapter_execution");
|
||||
}
|
||||
@@ -5381,6 +5549,23 @@ function verifyPythonRemapRowRuntimeProofRows({
|
||||
assert.equal(row.blockers.includes("row_runtime_adapter_execution"), false, `${row.path}: ready row must clear row runtime execution blocker`);
|
||||
assert.ok(row.notes.includes("row_transcript_ready_no_inventory_promotion"), `${row.path}: missing native lifecycle ready note`);
|
||||
}
|
||||
if (nativePassReady) {
|
||||
assert.equal(row.blockers.includes("native_row_pass"), false, `${row.path}: native-pass row must clear native pass blocker`);
|
||||
assert.ok(row.notes.includes("native_summary_row_pass_ready_no_inventory_promotion"), `${row.path}: missing native pass ready note`);
|
||||
}
|
||||
if (wasmNodePassReady) {
|
||||
assert.equal(row.blockers.includes("wasm_node_row_pass"), false, `${row.path}: WASM-node-pass row must clear WASM Node blocker`);
|
||||
assert.ok(row.notes.includes("wasm_node_row_runtime_bridge_passed_no_inventory_promotion"), `${row.path}: missing WASM Node proof ready note`);
|
||||
assert.equal(wasmNode.ini, row.ini, `${row.path}: WASM Node proof INI mismatch`);
|
||||
assert.equal(wasmNode.family, row.family, `${row.path}: WASM Node proof family mismatch`);
|
||||
}
|
||||
if (browserPassReady) {
|
||||
assert.equal(row.blockers.includes("browser_row_pass"), false, `${row.path}: browser-pass row must clear browser blocker`);
|
||||
assert.ok(row.notes.includes("browser_row_worker_bridge_passed_no_inventory_promotion"), `${row.path}: missing browser proof ready note`);
|
||||
assert.equal(browser.ini, row.ini, `${row.path}: browser proof INI mismatch`);
|
||||
assert.equal(browser.family, row.family, `${row.path}: browser proof family mismatch`);
|
||||
assert.ok(row.blockers.includes("manual_promotion_lock"), `${row.path}: browser proof must keep manual lock blocker`);
|
||||
}
|
||||
assert.ok(row.notes.includes("row_runtime_port_api_ready"), `${row.path}: missing row runtime API note`);
|
||||
assert.ok(row.notes.includes("row_runtime_plan_ready"), `${row.path}: missing row runtime plan note`);
|
||||
assert.equal(bulk.execution_enabled, "0", `${row.path}: bulk plan execution flag drift`);
|
||||
@@ -5390,6 +5575,20 @@ function verifyPythonRemapRowRuntimeProofRows({
|
||||
return parsedRows;
|
||||
}
|
||||
|
||||
function pythonRemapInventoryPromotionPathSet(rows) {
|
||||
assert.equal(rows.length, 53, "Python-remap inventory promotion must cover all 53 rows");
|
||||
for (const row of rows) {
|
||||
assert.equal(row.native_pass_ready, "1", `${row.path}: native pass proof is required before inventory promotion`);
|
||||
assert.equal(row.wasm_node_pass_ready, "1", `${row.path}: WASM Node proof is required before inventory promotion`);
|
||||
assert.equal(row.browser_pass_ready, "1", `${row.path}: browser proof is required before inventory promotion`);
|
||||
assert.equal(row.row_runtime_transcript_ready, "1", `${row.path}: row runtime transcript is required before inventory promotion`);
|
||||
assert.equal(row.proof_status, "browser_row_pass_ready", `${row.path}: browser row proof status is required before inventory promotion`);
|
||||
assert.equal(row.execution_enabled, "0", `${row.path}: row proof artifact must remain non-executing evidence`);
|
||||
assert.ok(row.blockers.includes("manual_promotion_lock"), `${row.path}: manual promotion lock review evidence is required`);
|
||||
}
|
||||
return new Set(rows.map((row) => row.path));
|
||||
}
|
||||
|
||||
function runtimeBoundaryNativeAlignmentSummaryRows({
|
||||
userMRows,
|
||||
toolDbRows,
|
||||
@@ -5763,6 +5962,15 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
const blockedFamiliesUnpromotedOk = hardBlockedRows.every((row) => {
|
||||
const tracked = trackedByPath.get(row.path);
|
||||
const inventory = inventoryByPath.get(row.path);
|
||||
if (
|
||||
row.blocked === "L4-PYTHON-REMAP" &&
|
||||
tracked?.layer4Node === "INV" &&
|
||||
tracked?.layer4Browser === "-" &&
|
||||
inventory?.inventoryStatus === "PASS" &&
|
||||
inventory.reason === "-"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
row.blocked === "L4-TOOL-DB" &&
|
||||
row.path === "axis/db_demo/base.ngc" &&
|
||||
@@ -6715,7 +6923,7 @@ function verifyBoundaryPhaseCompletionSummaryRows(rows) {
|
||||
const rowByCriterion = new Map(parsedRows.map((row) => [row.criterion, row]));
|
||||
assert.equal(
|
||||
rowByCriterion.get("wasm_inventory_artifact_documentation_coverage")?.count,
|
||||
"57",
|
||||
"59",
|
||||
"WASM artifact documentation completion count must match generated artifact baseline",
|
||||
);
|
||||
assert.equal(
|
||||
@@ -9468,7 +9676,7 @@ function verifyGeneratedArtifactDocumentationCoverage({
|
||||
);
|
||||
assert.equal(
|
||||
artifactNames.length,
|
||||
57,
|
||||
59,
|
||||
"generated sim-config inventory artifact list count drift",
|
||||
);
|
||||
assert.deepEqual(
|
||||
@@ -9489,6 +9697,7 @@ function verifyGeneratedArtifactDocumentationCoverage({
|
||||
"next-boundary-worklist.tsv",
|
||||
"promotion-candidates.tsv",
|
||||
"python-remap-boundary-summary.tsv",
|
||||
"python-remap-browser-row-proof.tsv",
|
||||
"python-remap-bulk-promotion-plan.tsv",
|
||||
"python-remap-family-summary.tsv",
|
||||
"python-remap-native-runtime-alignment.tsv",
|
||||
@@ -9499,6 +9708,7 @@ function verifyGeneratedArtifactDocumentationCoverage({
|
||||
"python-remap-row-runtime-proof.tsv",
|
||||
"python-remap-runtime-contract.tsv",
|
||||
"python-remap-runtime-gates.tsv",
|
||||
"python-remap-wasm-node-row-proof.tsv",
|
||||
"runtime-boundary-contract-summary.tsv",
|
||||
"runtime-boundary-family-host-readiness.tsv",
|
||||
"runtime-boundary-host-preflight.tsv",
|
||||
@@ -9565,7 +9775,7 @@ function verifyGeneratedArtifactDocumentationCoverage({
|
||||
"generated sim-config inventory artifacts must be listed in browser smoke",
|
||||
);
|
||||
assert.ok(
|
||||
browserSmokeText.includes("wasmArtifactNames.length !== 57"),
|
||||
browserSmokeText.includes("wasmArtifactNames.length !== 59"),
|
||||
"browser smoke must keep generated WASM artifact fixed-count guard",
|
||||
);
|
||||
assert.ok(
|
||||
@@ -12701,6 +12911,59 @@ const pythonRemapNativeRuntimeFixturePlanRecords = verifyPythonRemapNativeRuntim
|
||||
const nativeRuntimeProbeSourceRecords = existsSync(nativeRuntimeProbeSummarySourcePath)
|
||||
? parseTsv(readFileSync(nativeRuntimeProbeSummarySourcePath, "utf8"))
|
||||
: [];
|
||||
const pythonRemapWasmNodeRowProofSourceRecords = existsSync(pythonRemapWasmNodeRowProofPath)
|
||||
? parseTsv(readFileSync(pythonRemapWasmNodeRowProofPath, "utf8"), [
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"native_pass_ready",
|
||||
"wasm_node_runtime_bridge_ready",
|
||||
"wasm_node_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"transcript_phase_count",
|
||||
"transcript_hash",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"promotion_allowed",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
])
|
||||
: [];
|
||||
const pythonRemapBrowserRowProofSourceRecords = existsSync(pythonRemapBrowserRowProofPath)
|
||||
? parseTsv(readFileSync(pythonRemapBrowserRowProofPath, "utf8"), [
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_runtime_bridge_ready",
|
||||
"browser_worker_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"transcript_phase_count",
|
||||
"transcript_hash",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"promotion_allowed",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
])
|
||||
: [];
|
||||
const pythonRemapNativeRuntimeProbeGateRowsGenerated =
|
||||
pythonRemapNativeRuntimeProbeGateRows({
|
||||
fixturePlanRows: pythonRemapNativeRuntimeFixturePlanRecords,
|
||||
@@ -12726,17 +12989,35 @@ const pythonRemapBulkPromotionPlanRecords = verifyPythonRemapBulkPromotionPlanRo
|
||||
familyRows: pythonRemapFamilyRecords,
|
||||
contractRows: pythonRemapRuntimeContractRecords,
|
||||
});
|
||||
const pythonRemapWasmNodeRowProofRecords = verifyPythonRemapWasmNodeRowProofRecords({
|
||||
rows: pythonRemapWasmNodeRowProofSourceRecords,
|
||||
pythonRows: pythonRemapBoundarySummaryRecords,
|
||||
});
|
||||
const pythonRemapBrowserRowProofRecords = verifyPythonRemapBrowserRowProofRecords({
|
||||
rows: pythonRemapBrowserRowProofSourceRecords,
|
||||
pythonRows: pythonRemapBoundarySummaryRecords,
|
||||
wasmNodeRows: pythonRemapWasmNodeRowProofRecords,
|
||||
});
|
||||
const pythonRemapRowRuntimeProofRowsGenerated = pythonRemapRowRuntimeProofRows({
|
||||
pythonRows: pythonRemapBoundarySummaryRecords,
|
||||
bulkPlanRows: pythonRemapBulkPromotionPlanRecords,
|
||||
nativeRuntimeProbeRows: nativeRuntimeProbeSourceRecords,
|
||||
nativeRecords,
|
||||
wasmNodeProofRows: pythonRemapWasmNodeRowProofRecords,
|
||||
browserProofRows: pythonRemapBrowserRowProofRecords,
|
||||
});
|
||||
const pythonRemapRowRuntimeProofRecords = verifyPythonRemapRowRuntimeProofRows({
|
||||
rows: pythonRemapRowRuntimeProofRowsGenerated,
|
||||
pythonRows: pythonRemapBoundarySummaryRecords,
|
||||
bulkPlanRows: pythonRemapBulkPromotionPlanRecords,
|
||||
nativeRuntimeProbeRows: nativeRuntimeProbeSourceRecords,
|
||||
nativeRecords,
|
||||
wasmNodeProofRows: pythonRemapWasmNodeRowProofRecords,
|
||||
browserProofRows: pythonRemapBrowserRowProofRecords,
|
||||
});
|
||||
const promotedPythonRemapInventoryPaths = pythonRemapInventoryPromotionPathSet(
|
||||
pythonRemapRowRuntimeProofRecords,
|
||||
);
|
||||
|
||||
const summaryRows = [];
|
||||
const skipReasonCounts = new Map();
|
||||
@@ -12801,7 +13082,7 @@ function verifyInventorySummaryRows(rows, trackedMatrixByPath) {
|
||||
}
|
||||
}
|
||||
|
||||
function verifySkipSummaryRows(rows, expectedSkipped, nativeRecords, pathMatrixByPath) {
|
||||
function verifySkipSummaryRows(rows, expectedSkipped, nativeRecords, pathMatrixByPath, promotedPythonRemapPaths = new Set()) {
|
||||
const allowedSkipReasons = new Set([
|
||||
"ASSET-ONLY",
|
||||
"L4-PYTHON-REMAP",
|
||||
@@ -12831,6 +13112,9 @@ function verifySkipSummaryRows(rows, expectedSkipped, nativeRecords, pathMatrixB
|
||||
if (!reason) {
|
||||
continue;
|
||||
}
|
||||
if (reason === "L4-PYTHON-REMAP" && promotedPythonRemapPaths.has(record.path)) {
|
||||
continue;
|
||||
}
|
||||
expectedCounts.set(reason, (expectedCounts.get(reason) ?? 0) + 1);
|
||||
}
|
||||
|
||||
@@ -12841,7 +13125,7 @@ function verifySkipSummaryRows(rows, expectedSkipped, nativeRecords, pathMatrixB
|
||||
);
|
||||
}
|
||||
|
||||
function verifyHardBlockedInventorySkips(rows, pathMatrixByPath) {
|
||||
function verifyHardBlockedInventorySkips(rows, pathMatrixByPath, promotedPythonRemapPaths = new Set()) {
|
||||
const hardBlockedKinds = new Set([
|
||||
"L4-PYTHON-REMAP",
|
||||
"L4-TOOL-DB",
|
||||
@@ -12859,6 +13143,11 @@ function verifyHardBlockedInventorySkips(rows, pathMatrixByPath) {
|
||||
}
|
||||
const row = byPath.get(path);
|
||||
assert.ok(row, `${path}: hard-blocked inventory row missing`);
|
||||
if (reason === "L4-PYTHON-REMAP" && promotedPythonRemapPaths.has(path)) {
|
||||
assert.equal(row.inventoryStatus, "PASS", `${path}: promoted Python-remap row must pass inventory`);
|
||||
assert.equal(row.reason, "-", `${path}: promoted Python-remap row must clear skip reason`);
|
||||
continue;
|
||||
}
|
||||
assert.equal(row.inventoryStatus, "SKIP", `${path}: blocked row must stay skipped`);
|
||||
assert.equal(row.reason, reason, `${path}: blocked row skip reason drift`);
|
||||
}
|
||||
@@ -13144,7 +13433,7 @@ function verifyPromotionCandidateRows(rows, summaryRows, boundaryRows) {
|
||||
0,
|
||||
"current baseline has no direct skipped-main inventory promotion candidate",
|
||||
);
|
||||
for (const lockedKind of ["L4-PYTHON-REMAP", "L4-USER-M-PROCESS", "UPSTREAM-DEMO"]) {
|
||||
for (const lockedKind of ["L4-USER-M-PROCESS", "UPSTREAM-DEMO"]) {
|
||||
const lockedRows = parsedInventoryReady.filter((row) => row.skip_kind === lockedKind);
|
||||
assert.ok(lockedRows.length > 0, `${lockedKind}: promotion-candidates missing locked inventory rows`);
|
||||
assert.equal(
|
||||
@@ -13153,6 +13442,11 @@ function verifyPromotionCandidateRows(rows, summaryRows, boundaryRows) {
|
||||
`${lockedKind}: locked inventory rows must not allow promotion`,
|
||||
);
|
||||
}
|
||||
assert.equal(
|
||||
parsedInventoryReady.filter((row) => row.skip_kind === "L4-PYTHON-REMAP").length,
|
||||
0,
|
||||
"Python-remap rows must leave skipped promotion candidates after row proof promotion",
|
||||
);
|
||||
for (const row of parsedEvidenceReady) {
|
||||
assert.equal(row.current_status, "PASS", `${row.path}: evidence-ready row must be a current inventory PASS`);
|
||||
assert.equal(row.skip_kind, "-", `${row.path}: evidence-ready row must not have a skip kind`);
|
||||
@@ -13188,6 +13482,21 @@ function verifyPromotionCandidateRows(rows, summaryRows, boundaryRows) {
|
||||
|
||||
for (const record of nativeRecords) {
|
||||
const skipReason = blockedKind(record, pathMatrixByPath);
|
||||
if (skipReason === "L4-PYTHON-REMAP" && promotedPythonRemapInventoryPaths.has(record.path)) {
|
||||
executed += 1;
|
||||
passed += 1;
|
||||
summaryRows.push(
|
||||
[
|
||||
record.path,
|
||||
"PASS",
|
||||
"-",
|
||||
record.class,
|
||||
record.status,
|
||||
record.expected_failure || "-",
|
||||
].join("\t"),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (skipReason) {
|
||||
recordSkip(skipReason);
|
||||
summaryRows.push(
|
||||
@@ -13292,7 +13601,7 @@ assert.equal(
|
||||
"Node inventory skip-summary counts must match skipped row count",
|
||||
);
|
||||
verifyInventorySummaryRows(summaryRows, trackedMatrixByPath);
|
||||
verifyHardBlockedInventorySkips(summaryRows, pathMatrixByPath);
|
||||
verifyHardBlockedInventorySkips(summaryRows, pathMatrixByPath, promotedPythonRemapInventoryPaths);
|
||||
verifyTrackedBaselineText(
|
||||
trackedMatrixText,
|
||||
nativeRecords,
|
||||
@@ -13656,7 +13965,7 @@ writeFileSync(
|
||||
const skipSummaryRows = [...skipReasonCounts.entries()]
|
||||
.sort(([left], [right]) => left.localeCompare(right))
|
||||
.map(([reason, count]) => `${reason}\t${count}`);
|
||||
verifySkipSummaryRows(skipSummaryRows, skipped, nativeRecords, pathMatrixByPath);
|
||||
verifySkipSummaryRows(skipSummaryRows, skipped, nativeRecords, pathMatrixByPath, promotedPythonRemapInventoryPaths);
|
||||
writeFileSync(
|
||||
skipSummaryPath,
|
||||
`${[
|
||||
@@ -14519,6 +14828,116 @@ writeFileSync(
|
||||
].join("\n")}\n`,
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
pythonRemapWasmNodeRowProofPath,
|
||||
`${[
|
||||
[
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"native_pass_ready",
|
||||
"wasm_node_runtime_bridge_ready",
|
||||
"wasm_node_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"transcript_phase_count",
|
||||
"transcript_hash",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"promotion_allowed",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
].join("\t"),
|
||||
...pythonRemapWasmNodeRowProofRecords.map((row) => [
|
||||
row.path,
|
||||
row.ini,
|
||||
row.family,
|
||||
row.native_pass_ready,
|
||||
row.wasm_node_runtime_bridge_ready,
|
||||
row.wasm_node_plan_executed,
|
||||
row.module_import_ready,
|
||||
row.callable_lookup_ready,
|
||||
row.generator_lifecycle_ready,
|
||||
row.ngc_remap_assets_ready,
|
||||
row.ngc_only_subpaths_guarded,
|
||||
row.interpreter_state_binding_ready,
|
||||
row.canonical_events_ready,
|
||||
row.row_runtime_transcript_ready,
|
||||
row.transcript_phase_count,
|
||||
row.transcript_hash,
|
||||
row.wasm_node_pass_ready,
|
||||
row.browser_pass_ready,
|
||||
row.execution_enabled,
|
||||
row.promotion_allowed,
|
||||
row.proof_status,
|
||||
row.blockers,
|
||||
row.notes,
|
||||
].map(tsvValue).join("\t")),
|
||||
].join("\n")}\n`,
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
pythonRemapBrowserRowProofPath,
|
||||
`${[
|
||||
[
|
||||
"path",
|
||||
"ini",
|
||||
"family",
|
||||
"wasm_node_pass_ready",
|
||||
"browser_runtime_bridge_ready",
|
||||
"browser_worker_plan_executed",
|
||||
"module_import_ready",
|
||||
"callable_lookup_ready",
|
||||
"generator_lifecycle_ready",
|
||||
"ngc_remap_assets_ready",
|
||||
"ngc_only_subpaths_guarded",
|
||||
"interpreter_state_binding_ready",
|
||||
"canonical_events_ready",
|
||||
"row_runtime_transcript_ready",
|
||||
"transcript_phase_count",
|
||||
"transcript_hash",
|
||||
"browser_pass_ready",
|
||||
"execution_enabled",
|
||||
"promotion_allowed",
|
||||
"proof_status",
|
||||
"blockers",
|
||||
"notes",
|
||||
].join("\t"),
|
||||
...pythonRemapBrowserRowProofRecords.map((row) => [
|
||||
row.path,
|
||||
row.ini,
|
||||
row.family,
|
||||
row.wasm_node_pass_ready,
|
||||
row.browser_runtime_bridge_ready,
|
||||
row.browser_worker_plan_executed,
|
||||
row.module_import_ready,
|
||||
row.callable_lookup_ready,
|
||||
row.generator_lifecycle_ready,
|
||||
row.ngc_remap_assets_ready,
|
||||
row.ngc_only_subpaths_guarded,
|
||||
row.interpreter_state_binding_ready,
|
||||
row.canonical_events_ready,
|
||||
row.row_runtime_transcript_ready,
|
||||
row.transcript_phase_count,
|
||||
row.transcript_hash,
|
||||
row.browser_pass_ready,
|
||||
row.execution_enabled,
|
||||
row.promotion_allowed,
|
||||
row.proof_status,
|
||||
row.blockers,
|
||||
row.notes,
|
||||
].map(tsvValue).join("\t")),
|
||||
].join("\n")}\n`,
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
runtimeBoundaryContractSummaryPath,
|
||||
`${[
|
||||
|
||||
Reference in New Issue
Block a user