按text32继续推进evidence expansion过滤预设

结论:已完成 evidence expansion family/source filter 的 summary/action-plan、query/hash 预选、UI/API/SDK/浏览器验证覆盖,并保持 sim-config inventory baseline=82/82/77/0。
This commit is contained in:
2026-06-20 12:18:08 +08:00
parent 8a1c4699b1
commit a6eda3fbff
18 changed files with 2144 additions and 51 deletions

View File

@@ -9,7 +9,7 @@ turn-by-turn continuation notes and next-batch execution records.
## Current Status ## Current Status
- Active continuation file: `text32.txt` - Active continuation file: `text32.txt`
- Latest completed batch: evidence expansion UI surface - Latest completed batch: evidence expansion filter query/hash preset
- Latest relevant commit: use `git log -1 --oneline` after each committed batch - Latest relevant commit: use `git log -1 --oneline` after each committed batch
- Working tree at tracker creation: clean - Working tree at tracker creation: clean
- Required policy: LinuxCNC remains the only CNC semantic source - Required policy: LinuxCNC remains the only CNC semantic source
@@ -45,7 +45,7 @@ The project is complete for the current scope when all of the following are true
| Simulation test program library | Active | Built-in browser simulation programs live in `wasm-port/runtime/ui/simulation/programs/`, one module per program, exported through `programs/index.js`; `verify_real_simulation_programs.sh` checks directory-backed inventory, IDs, defaults, and playback contracts. | | Simulation test program library | Active | Built-in browser simulation programs live in `wasm-port/runtime/ui/simulation/programs/`, one module per program, exported through `programs/index.js`; `verify_real_simulation_programs.sh` checks directory-backed inventory, IDs, defaults, and playback contracts. |
| Vendor/source guard | Stable | `verify_vendor_sync.sh` and standalone semantic guard are required every batch. | | Vendor/source guard | Stable | `verify_vendor_sync.sh` and standalone semantic guard are required every batch. |
| Interpreter WASM smoke | Stable | `interp_wasm_node_smoke=ok`. | | Interpreter WASM smoke | Stable | `interp_wasm_node_smoke=ok`. |
| Sim config inventory | Stable with skips | `executed=82`, `passed=82`, `skipped=77`, `unexpected_fail=0`; `docs/sim-configs-coverage-handoff.md` records the release-gate baseline. The 2026-06-20 remaining-skip audit found 2 skipped main-program rows and 0 rows with `promotion_allowed=1`, so the baseline must not change without new LinuxCNC-owned native/Node/browser proof. Browser diagnostics evidence expansion now includes five ready source-derived REP candidates: `woodpecker-on-abort`, `puma-cube`, `melfa-example`, `trt-boat-xyzac`, and `trt-xyzac-switchkins`, all with `promotionAllowed=false`; the real simulation diagnostics panel and release URL workflow summaries expose the five-row full candidate/G-code lists. | | Sim config inventory | Stable with skips | `executed=82`, `passed=82`, `skipped=77`, `unexpected_fail=0`; `docs/sim-configs-coverage-handoff.md` records the release-gate baseline. The 2026-06-20 remaining-skip audit found 2 skipped main-program rows and 0 rows with `promotion_allowed=1`, so the baseline must not change without new LinuxCNC-owned native/Node/browser proof. Browser diagnostics evidence expansion now includes eleven ready source-derived REP candidates, including the full current TRT table-rotary-tilting batch, all with `promotionAllowed=false`; the real simulation diagnostics panel and release URL workflow summaries expose the eleven-row full candidate/G-code lists plus three-family/source-count drilldown, and the INI workflow overview now has a separate evidence-expansion family/source filter with summary/action-plan helpers plus query/hash UI-state presets for external shell reads. |
| Native nc_files baseline | Stable | Last recorded Layer 1: `total 107`, `pass 101`, `expected_fail 6`, `unexpected_fail 0`. | | Native nc_files baseline | Stable | Last recorded Layer 1: `total 107`, `pass 101`, `expected_fail 6`, `unexpected_fail 0`. |
| Native sim configs baseline | Stable | Last recorded Layer 2: `total 159`, `pass 151`, `expected_fail 8`, `unexpected_fail 0`. | | Native sim configs baseline | Stable | Last recorded Layer 2: `total 159`, `pass 151`, `expected_fail 8`, `unexpected_fail 0`. |
| OPFS/session persistence | Stable for current scope | Browser smoke passes, SDK re-exports OPFS/session helpers including `readMachineSessionReadiness()` and `createMachineSessionPersistenceSummary()`, the UI exposes `getMachineSessionPersistenceSummary()`, and `docs/opfs-session-persistence.md` defines the project-level release gate. | | OPFS/session persistence | Stable for current scope | Browser smoke passes, SDK re-exports OPFS/session helpers including `readMachineSessionReadiness()` and `createMachineSessionPersistenceSummary()`, the UI exposes `getMachineSessionPersistenceSummary()`, and `docs/opfs-session-persistence.md` defines the project-level release gate. |

View File

@@ -181,8 +181,8 @@ trt-xyzac-switchkins
当前 evidence expansion report 当前 evidence expansion report
```text ```text
candidateCount=5 candidateCount=11
readyCandidateCount=5 readyCandidateCount=11
inventoryBaselineUnchanged=true inventoryBaselineUnchanged=true
promotionAllowed=false promotionAllowed=false
``` ```
@@ -288,7 +288,7 @@ standalone CNC semantics guard complete
```text ```text
1. real simulation diagnostics panel 显示 evidence expansion ready count 1. real simulation diagnostics panel 显示 evidence expansion ready count
2. real simulation diagnostics panel 显示完整 5 个 ready candidates 2. real simulation diagnostics panel 显示完整 ready candidates
3. release artifact URL workflow summary 暴露完整 candidate / G-code list 3. release artifact URL workflow summary 暴露完整 candidate / G-code list
4. INI workflow overview URL summary 暴露完整 candidate / G-code list 4. INI workflow overview URL summary 暴露完整 candidate / G-code list
5. 保留原有 preview 的前三项,兼容既有 UI 和测试。 5. 保留原有 preview 的前三项,兼容既有 UI 和测试。
@@ -298,9 +298,9 @@ standalone CNC semantics guard complete
```text ```text
real-browser-simulation-evidence-expansion-summary real-browser-simulation-evidence-expansion-summary
data-evidence-expansion-summary-value="candidate-count" => 5/5 ready data-evidence-expansion-summary-value="candidate-count" => 11/11 ready
data-evidence-expansion-summary-value="candidate-list" => data-evidence-expansion-summary-value="candidate-list" =>
woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins
evidence-expansion-full-candidate-list evidence-expansion-full-candidate-list
evidence-expansion-full-gcode-list evidence-expansion-full-gcode-list
``` ```
@@ -340,18 +340,412 @@ browser_release_artifact_url_workflow_smoke=ok
九、下一步工作计划 九、下一步工作计划
继续扩展五轴 TRT family 的 browser diagnostics evidence,不改变 本轮已把计划中的六个五轴 TRT row 加入 browser diagnostics evidence
`82/82/77/0` baseline。建议下一批新增 expansion当前完整 ready candidates 为
```text ```text
axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc woodpecker-on-abort
axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc puma-cube
axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc melfa-example
axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc trt-boat-xyzac
axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc trt-xyzac-switchkins
axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc trt-boat-xyzbc
trt-impeller-7bl-xyzac
trt-xyzac-switchkins-test-1
trt-xyzac-switchkins-test-2
trt-xyzac-switchkins-test-3
trt-xyzbc-switchkins
``` ```
每批仍只做 browser diagnostics / release evidence expansion,不能改 下一步建议不要继续堆同一 TRT family改为做“evidence expansion
`promotionAllowed=false`,不能把 SKIP 或 REP 伪装为 inventory baseline source drilldown / family grouping”让 UI 按 family 或 source kind 查看
promotion。 11 个 candidates
```text
1. 在 real simulation diagnostics panel 增加 evidence-expansion family rows
2. 在 release URL / INI workflow summary 增加 source-count 或 family-count
drilldown
3. 保持 preview 三项兼容;
4. inventory baseline 仍保持 82/82/77/0
5. promotionAllowed 仍保持 false。
```
十、本轮接续推进evidence expansion family/source drilldown
执行时间2026-06-20 CST
已完成第九节建议的 family/source drilldown不改变
`82/82/77/0` inventory baseline也不允许 evidence expansion 触发
inventory promotion。
新增/确认的 diagnostics/API/UI 字段:
```text
virtualHalSimConfigEvidenceExpansion.familyRows
evidence-expansion-family-count
evidence-expansion-family-summary
evidence-expansion-family-source-count-list
evidence-expansion-family-woodpecker
evidence-expansion-family-vismach-remap-sims
evidence-expansion-family-five-axis-trt
data-evidence-expansion-summary-value="family-count"
data-evidence-expansion-summary-value="family-summary"
data-evidence-expansion-summary-value="family-source-count-list"
```
当前 family drilldown
```text
woodpecker: 1/1 ready; sources=3
vismach-remap-sims: 2/2 ready; sources=6
five-axis-trt: 8/8 ready; sources=12
```
边界仍保持:
```text
candidateCount=11
readyCandidateCount=11
inventoryBaselineUnchanged=true
promotionAllowed=false
inventory baseline=82/82/77/0
```
本轮已运行验证:
```text
wasm-port/tests/sdk/node/verify_sdk_surface.sh
wasm-port/tests/sdk/node/verify_project_release_gate_manifest.sh
wasm-port/tests/sdk/node/verify_project_release_artifact_url_workflow.sh
wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_release_artifact_url_workflow_browser.sh
```
结果:
```text
sdk_surface_node_smoke=ok
project_release_gate_manifest_node_smoke=ok
project_release_artifact_url_workflow_node_smoke=ok
project_batch_acceptance_workflow_node_smoke=ok
project_batch_acceptance_artifact_node_smoke=ok
ini_panel_ui_shell_node_smoke=ok
browser_real_simulation_page_smoke=ok
browser_ini_workflow_overview_smoke=ok
browser_ini_shell_integration_workflow_smoke=ok
browser_release_artifact_url_workflow_smoke=ok
```
十一、下一步工作计划
不要继续扩大同一个 TRT evidence expansion 列表,也不要改 inventory
baseline。下一批建议转向“drilldown 可用性/过滤”:
```text
1. 在 INI workflow overview 增加 evidence-expansion family/source filter
render-state类似现有 promotion family source filter
2. 支持按 family 查看 candidateIds / gcodePaths / sourceFiles
3. real simulation diagnostics panel 保持 summary 简洁,只暴露 family rows
4. release URL workflow summary 保留 preview 三项和 full list 兼容;
5. 继续保持 promotionAllowed=false、baseline=82/82/77/0。
```
十二、本轮接续推进evidence expansion family/source filter
执行时间2026-06-20 CST
已完成第十一节建议的 evidence-expansion family/source filter。该 filter
独立于 promotion family source filter避免把 promotion candidates 与
evidence expansion diagnostics rows 混在同一 API/DOM contract 中。
新增 API / DOM surface
```text
getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState
getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel
getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract
getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness
getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan
handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange
bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls
renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState
mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState
data-workflow-overview-evidence-expansion-family-source-filter
data-workflow-overview-evidence-expansion-family-source-filter-controls
data-workflow-overview-evidence-expansion-family-source-filter-rows
```
当前 filter 覆盖:
```text
families=3
sourceFiles=21
candidates=11
sourceKinds=ini/gcode/remap-subroutine/source
evidence-expansion-family-five-axis-trt + gcode => 8 source files / 8 candidates
```
边界仍保持:
```text
promotionAllowed=false
inventoryBaselineUnchanged=true
inventory baseline=82/82/77/0
```
本轮已运行验证:
```text
wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh
wasm-port/tests/sdk/node/verify_sdk_surface.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
```
结果:
```text
ini_panel_ui_shell_node_smoke=ok
sdk_surface_node_smoke=ok
project_release_gate_manifest_node_smoke=ok
project_release_artifact_url_workflow_node_smoke=ok
project_batch_acceptance_workflow_node_smoke=ok
project_batch_acceptance_artifact_node_smoke=ok
browser_ini_workflow_overview_smoke=ok
browser_ini_shell_integration_workflow_smoke=ok
```
十三、下一步工作计划
不要改 inventory baseline也不要扩大同一 TRT family。下一批建议做
filter 状态的可复用输出/深链:
```text
1. 为 evidence-expansion family/source filter 增加 summary/action-plan
helper输出 selectedFamilyId / selectedSourceKind / filtered counts
2. 在 workflow overview URL workflow result 中保留当前 filter selection
的 structured summary方便外部 shell 读取;
3. 可选:支持 query/hash 参数预选 family/sourceKind
4. 继续保持 promotionAllowed=false、baseline=82/82/77/0
5. 验证仍以 Node UI smoke、INI browser smoke、SDK surface、docs smoke 为主。
```
十四、本轮接续推进evidence expansion filter summary/action-plan
执行时间2026-06-20 CST
已完成第十三节建议中的可复用输出层,不改变 inventory baseline也不扩大
TRT family 候选集合。
新增 API / SDK / 页面 surface
```text
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan
getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary
getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan
```
当前 structured summary/action-plan 覆盖:
```text
selectedFamilyId
selectedSourceKind
filteredSourceFileCount
scopedSourceFileCount
totalSourceFileCount
filteredCandidateCount
totalCandidateCount
familyIds
sourceKinds
candidateIds
gcodePaths
sourceFiles
promotionAllowed=false
baselineChanging=false
```
页面侧 `workflow-overview.html` 现在会在 fixed release artifact URL workflow
执行后保留当前 evidence-expansion filter selection 的 structured summary
和 action-plan并通过 workflow overview API 暴露给外部 shell。默认状态
```text
all / all => 21/21 source files selected
five-axis-trt / gcode => 8/21 source files selected, 8 candidates
```
边界仍保持:
```text
promotionAllowed=false
baselineChanging=false
inventoryBaselineUnchanged=true
inventory baseline=82/82/77/0
```
本轮已运行验证:
```text
git diff --check
wasm-port/tests/sdk/node/verify_sdk_surface.sh
wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_release_artifact_url_workflow_browser.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh
wasm-port/tests/docs/node/verify_sim_configs_coverage_docs.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
```
结果:
```text
sdk_surface_node_smoke=ok
project_release_gate_manifest_node_smoke=ok
project_release_artifact_url_workflow_node_smoke=ok
project_batch_acceptance_workflow_node_smoke=ok
project_batch_acceptance_artifact_node_smoke=ok
ini_panel_ui_shell_node_smoke=ok
browser_ini_opfs_smoke=ok
browser_ini_control_page_smoke=ok
browser_ini_launch_smoke=ok
browser_ini_workflow_overview_smoke=ok
browser_ini_shell_integration_workflow_smoke=ok
browser_release_artifact_url_workflow_smoke=ok
browser_real_simulation_page_smoke=ok
sim_configs_coverage_docs_node_smoke=ok
sim_configs_wasm_node_inventory=ok
standalone CNC semantics guard complete
```
inventory 验证结果仍为:
```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
```
十五、下一步工作计划
继续不要改 inventory baseline也不要继续扩大同一个 TRT evidence list。
下一批建议做可选的 filter 深链预选,但要保持为 UI 状态恢复能力,不影响
release evidence 或 promotion 结论:
```text
1. 支持 workflow overview 的 query/hash 参数预选:
- evidenceExpansionFamily=evidence-expansion-family-five-axis-trt
- evidenceExpansionSourceKind=gcode
2. 预选只驱动 filter view-model 初始状态,不写入 inventory/report artifact
3. browser smoke 覆盖预选后 body dataset / DOM selectedFamilyId /
selectedSourceKind / filtered count
4. SDK summary/action-plan 保持 promotionAllowed=false、baselineChanging=false
5. baseline 继续保持 82/82/77/0。
```
十六、本轮接续推进evidence expansion filter query/hash 预选
执行时间2026-06-20 CST
已完成第十五节建议的 workflow overview filter 深链预选。该能力只影响
`workflow-overview.html` 中 evidence-expansion family/source filter 的初始
UI 状态,不写入 release artifact、不写入 diagnostics artifact、不改变
inventory/report 结论。
新增行为:
```text
workflow-overview.html?evidenceExpansionFamily=evidence-expansion-family-five-axis-trt&evidenceExpansionSourceKind=gcode
workflow-overview.html#evidenceExpansionFamily=evidence-expansion-family-five-axis-trt&evidenceExpansionSourceKind=gcode
```
当前预选结果:
```text
selectedFamilyId=evidence-expansion-family-five-axis-trt
selectedSourceKind=gcode
filteredSourceFileCount=8
filteredCandidateCount=8
baselineChanging=false
promotionAllowed=false
```
实现边界:
```text
1. 预选只通过 URL query/hash 读取;
2. 只传入 createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel
3. 不改 SDK helper 的纯函数输入/输出;
4. 不改 diagnostics artifact 或 release readiness artifact
5. 不改 inventory baseline。
```
本轮已运行验证:
```text
git diff --check
wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh
wasm-port/tests/sdk/node/verify_sdk_surface.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_release_artifact_url_workflow_browser.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh
wasm-port/tests/docs/node/verify_sim_configs_coverage_docs.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
```
结果:
```text
ini_panel_ui_shell_node_smoke=ok
sdk_surface_node_smoke=ok
project_release_gate_manifest_node_smoke=ok
project_release_artifact_url_workflow_node_smoke=ok
project_batch_acceptance_workflow_node_smoke=ok
project_batch_acceptance_artifact_node_smoke=ok
browser_ini_opfs_smoke=ok
browser_ini_control_page_smoke=ok
browser_ini_launch_smoke=ok
browser_ini_workflow_overview_smoke=ok
browser_ini_shell_integration_workflow_smoke=ok
browser_release_artifact_url_workflow_smoke=ok
browser_real_simulation_page_smoke=ok
sim_configs_coverage_docs_node_smoke=ok
sim_configs_wasm_node_inventory=ok
standalone CNC semantics guard complete
```
inventory 验证结果仍为:
```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
```
十七、下一步工作计划
不要改 inventory baseline也不要把 evidence-expansion filter 状态写入
artifact。下一批建议转向真实浏览器模拟页面的 operator-facing 可用性:
```text
1. 在 real simulation page diagnostics 区增加 evidence-expansion family
drilldown 的紧凑 operator view
2. 只展示 family/count/source-kind summary不新增 CNC 语义;
3. 保持 release artifact URL workflow 和 INI workflow overview 现有 API 兼容;
4. browser smoke 覆盖 real simulation page 的 family drilldown 可见状态;
5. baseline 继续保持 82/82/77/0。
```

View File

@@ -709,6 +709,24 @@ linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ng
trt-xyzac-switchkins trt-xyzac-switchkins
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc
trt-boat-xyzbc
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc
trt-impeller-7bl-xyzac
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc
trt-xyzac-switchkins-test-1
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc
trt-xyzac-switchkins-test-2
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc
trt-xyzac-switchkins-test-3
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc
trt-xyzbc-switchkins
linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc
``` ```
Both rows use the LinuxCNC-owned `xyzac-trt.ini` machine context and the Both rows use the LinuxCNC-owned `xyzac-trt.ini` machine context and the
@@ -724,8 +742,8 @@ inventoryBaselineUnchanged=true
``` ```
The real browser simulation diagnostics artifact now validates that the The real browser simulation diagnostics artifact now validates that the
evidence expansion report has `candidateCount=5` and `readyCandidateCount=5`, evidence expansion report has `candidateCount=11` and `readyCandidateCount=11`,
including the two TRT rows above. The inventory baseline remains including the TRT rows above. The inventory baseline remains
`executed=82 passed=82 skipped=77 unexpected_fail=0`. `executed=82 passed=82 skipped=77 unexpected_fail=0`.
## 2026-06-20 Evidence Expansion UI Surface ## 2026-06-20 Evidence Expansion UI Surface
@@ -736,14 +754,56 @@ The evidence expansion data is now visible outside the raw diagnostics JSON:
real-browser-simulation-evidence-expansion-summary real-browser-simulation-evidence-expansion-summary
evidence-expansion-full-candidate-list evidence-expansion-full-candidate-list
evidence-expansion-full-gcode-list evidence-expansion-full-gcode-list
evidence-expansion-family-count
evidence-expansion-family-summary
evidence-expansion-family-source-count-list
``` ```
The real simulation diagnostics panel renders `5/5 ready`, the full five-row The real simulation diagnostics panel renders `11/11 ready`, the full eleven-row
candidate list, source-file count, promotion lock state, and unchanged candidate list, source-file count, promotion lock state, and unchanged
inventory state. The project release URL workflow summary and INI workflow inventory state. The project release URL workflow summary and INI workflow
overview keep their existing three-row preview fields for compatibility, and overview keep their existing three-row preview fields for compatibility, and
also expose the full candidate and G-code lists so shell callers can inspect also expose the full candidate and G-code lists so shell callers can inspect
all five ready evidence-expansion rows without opening the raw artifact. all eleven ready evidence-expansion rows without opening the raw artifact.
The same diagnostics and release URL summaries now group the eleven
evidence-expansion rows into three browser diagnostics families:
```text
woodpecker: 1/1 ready; sources=3
vismach-remap-sims: 2/2 ready; sources=6
five-axis-trt: 8/8 ready; sources=12
```
This family drilldown is source/evidence visibility only. It does not alter the
separate promotion candidate summary of 8 diagnostics-ready candidates across
3 families and 17 source files, and it does not change the inventory baseline.
## 2026-06-20 Evidence Expansion Source Filter
The INI workflow overview now exposes a separate evidence-expansion family
source filter, distinct from the promotion-family source filter:
```text
getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState
getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel
renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState
mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState
```
The filter supports selecting `all`, `ini`, `gcode`, `remap-subroutine`, or
`source` rows within the evidence-expansion families, and it keeps candidate
rows separate from source rows. The current ready filter surface covers:
```text
21 source files
11 evidence-expansion candidate rows
evidence-expansion-family-five-axis-trt / gcode => 8 source files, 8 candidates
```
All rows remain diagnostics evidence only: `promotionAllowed=false`,
`inventoryBaselineUnchanged=true`, and the inventory baseline remains
`82/82/77/0`.
## Boundary Statement ## Boundary Statement

View File

@@ -61,6 +61,17 @@ import {
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness,
@@ -707,6 +718,20 @@ for external browser shells:
`renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState()`, `renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState()`,
and `mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState()` and `mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState()`
let callers render the URL workflow status into their own DOM. let callers render the URL workflow status into their own DOM.
`createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState()`,
`createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel()`,
`createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary()`,
and `createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan()`
expose the current evidence-expansion family/source selection for external
shells without enabling inventory promotion.
`createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract()`,
`createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness()`,
`createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan()`,
`handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange()`,
`bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls()`,
`renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState()`,
and `mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState()`
let callers render and bind that evidence-expansion filter in caller-owned DOM.
`createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan()` `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan()`
exposes the direct artifact-validation next-command plan when callers already exposes the direct artifact-validation next-command plan when callers already
have parsed or validated artifact JSON. have parsed or validated artifact JSON.

View File

@@ -234,6 +234,17 @@ export {
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState, createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel, createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract, createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract,

View File

@@ -513,6 +513,132 @@ export const VIRTUAL_HAL_SIM_CONFIG_EVIDENCE_EXPANSION_CANDIDATES = Object.freez
blockedKind: "-", blockedKind: "-",
evidence: "The LinuxCNC table-rotary-tilting XYZAC switchkins demo is already a browser representative row; this evidence expansion binds it into release diagnostics only.", evidence: "The LinuxCNC table-rotary-tilting XYZAC switchkins demo is already a browser representative row; this evidence expansion binds it into release diagnostics only.",
}), }),
Object.freeze({
id: "trt-boat-xyzbc",
label: "TRT boat XYZBC",
simConfigTarget: "five-axis-trt",
sourceFiles: Object.freeze([
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
]),
iniPath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
gcodePath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc",
currentNodeInventoryStatus: "PASS",
currentMatrixBrowserStatus: "REP",
dependencyClass: "hal_process,halui_mdi_process,ui_process",
targetBrowserEvidence: "browser-diagnostics-expansion",
promotionAllowed: false,
blockedKind: "-",
evidence: "The LinuxCNC table-rotary-tilting boat XYZBC demo is already a five-axis representative row and is added as browser diagnostics evidence only.",
}),
Object.freeze({
id: "trt-impeller-7bl-xyzac",
label: "TRT impeller 7 blade XYZAC",
simConfigTarget: "five-axis-trt",
sourceFiles: Object.freeze([
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
]),
iniPath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
gcodePath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
currentNodeInventoryStatus: "PASS",
currentMatrixBrowserStatus: "REP",
dependencyClass: "hal_process,halui_mdi_process,ui_process",
targetBrowserEvidence: "browser-diagnostics-expansion",
promotionAllowed: false,
blockedKind: "-",
evidence: "The LinuxCNC table-rotary-tilting impeller demo expands the TRT representative diagnostics set without changing inventory promotion state.",
}),
Object.freeze({
id: "trt-xyzac-switchkins-test-1",
label: "TRT XYZAC switchkins test 1",
simConfigTarget: "five-axis-trt",
sourceFiles: Object.freeze([
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
]),
iniPath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
gcodePath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc",
currentNodeInventoryStatus: "PASS",
currentMatrixBrowserStatus: "REP",
dependencyClass: "hal_process,halui_mdi_process,ui_process",
targetBrowserEvidence: "browser-diagnostics-expansion",
promotionAllowed: false,
blockedKind: "-",
evidence: "The LinuxCNC XYZAC switchkins test 1 row is already representative coverage and is exposed as browser diagnostics evidence only.",
}),
Object.freeze({
id: "trt-xyzac-switchkins-test-2",
label: "TRT XYZAC switchkins test 2",
simConfigTarget: "five-axis-trt",
sourceFiles: Object.freeze([
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
]),
iniPath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
gcodePath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc",
currentNodeInventoryStatus: "PASS",
currentMatrixBrowserStatus: "REP",
dependencyClass: "hal_process,halui_mdi_process,ui_process",
targetBrowserEvidence: "browser-diagnostics-expansion",
promotionAllowed: false,
blockedKind: "-",
evidence: "The LinuxCNC XYZAC switchkins test 2 row is already representative coverage and is exposed as browser diagnostics evidence only.",
}),
Object.freeze({
id: "trt-xyzac-switchkins-test-3",
label: "TRT XYZAC switchkins test 3",
simConfigTarget: "five-axis-trt",
sourceFiles: Object.freeze([
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
]),
iniPath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
gcodePath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc",
currentNodeInventoryStatus: "PASS",
currentMatrixBrowserStatus: "REP",
dependencyClass: "hal_process,halui_mdi_process,ui_process",
targetBrowserEvidence: "browser-diagnostics-expansion",
promotionAllowed: false,
blockedKind: "-",
evidence: "The LinuxCNC XYZAC switchkins test 3 row is already representative coverage and is exposed as browser diagnostics evidence only.",
}),
Object.freeze({
id: "trt-xyzbc-switchkins",
label: "TRT XYZBC switchkins",
simConfigTarget: "five-axis-trt",
sourceFiles: Object.freeze([
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
]),
iniPath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
gcodePath: "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc",
currentNodeInventoryStatus: "PASS",
currentMatrixBrowserStatus: "REP",
dependencyClass: "hal_process,halui_mdi_process,ui_process",
targetBrowserEvidence: "browser-diagnostics-expansion",
promotionAllowed: false,
blockedKind: "-",
evidence: "The LinuxCNC XYZBC switchkins demo completes the current TRT representative diagnostics batch without changing inventory promotion state.",
}),
]); ]);
export const VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES = Object.freeze([ export const VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES = Object.freeze([
@@ -3371,6 +3497,30 @@ export function createVirtualHalSimConfigEvidenceExpansionReport(options = {}) {
const blockedCandidateIds = rows.filter((row) => row.blockedKind !== "-").map((row) => row.id); const blockedCandidateIds = rows.filter((row) => row.blockedKind !== "-").map((row) => row.id);
const missingManifestFiles = [...new Set(rows.flatMap((row) => row.missingManifestFiles))]; const missingManifestFiles = [...new Set(rows.flatMap((row) => row.missingManifestFiles))];
const missingRequiredReports = [...new Set(rows.flatMap((row) => row.missingRequiredReports))]; const missingRequiredReports = [...new Set(rows.flatMap((row) => row.missingRequiredReports))];
const familyRows = [...new Set(rows.map((row) => row.simConfigTarget ?? row.id))].map((familyId) => {
const familyCandidates = rows.filter((row) => (row.simConfigTarget ?? row.id) === familyId);
const completeCount = familyCandidates.filter((row) => row.complete).length;
const readyBrowserDiagnosticsCount = familyCandidates
.filter((row) => row.targetBrowserEvidence === "browser-diagnostics-expansion").length;
const promotionAllowedCount = familyCandidates.filter((row) => row.promotionAllowed).length;
const sourceFiles = [...new Set(familyCandidates.flatMap((row) => row.sourceFiles))];
const gcodePaths = [...new Set(familyCandidates.map((row) => row.gcodePath).filter(Boolean))];
const iniPaths = [...new Set(familyCandidates.map((row) => row.iniPath).filter(Boolean))];
return {
id: familyId,
candidateIds: familyCandidates.map((row) => row.id),
candidateCount: familyCandidates.length,
completeCount,
readyBrowserDiagnosticsCount,
browserDiagnosticsExpansionReady: readyBrowserDiagnosticsCount === familyCandidates.length,
promotionAllowedCount,
complete: completeCount === familyCandidates.length,
sourceFiles,
sourceFileCount: sourceFiles.length,
gcodePaths,
iniPaths,
};
});
const complete = rows.length > 0 && const complete = rows.length > 0 &&
missingCandidates.length === 0 && missingCandidates.length === 0 &&
promotionAllowedViolations.length === 0 && promotionAllowedViolations.length === 0 &&
@@ -3397,10 +3547,12 @@ export function createVirtualHalSimConfigEvidenceExpansionReport(options = {}) {
blockedCandidateIds, blockedCandidateIds,
missingManifestFiles, missingManifestFiles,
missingRequiredReports, missingRequiredReports,
familyRows,
rows, rows,
summaryRows: [ summaryRows: [
{ id: "candidates", label: "Expansion candidates", value: `${rows.length}` }, { id: "candidates", label: "Expansion candidates", value: `${rows.length}` },
{ id: "ready-candidates", label: "Ready candidates", value: `${rows.filter((row) => row.complete).length}` }, { id: "ready-candidates", label: "Ready candidates", value: `${rows.filter((row) => row.complete).length}` },
{ id: "families", label: "Expansion families", value: `${familyRows.length}` },
{ id: "promotion-allowed", label: "Promotion allowed", value: "0" }, { id: "promotion-allowed", label: "Promotion allowed", value: "0" },
{ id: "inventory-baseline", label: "Inventory baseline", value: "unchanged" }, { id: "inventory-baseline", label: "Inventory baseline", value: "unchanged" },
], ],

View File

@@ -138,6 +138,35 @@ function createPromotionFamilySummaryRows(candidateReport = {}) {
}); });
} }
function createEvidenceExpansionFamilySummaryRows(evidenceExpansionReport = {}) {
return arrayOrEmpty(objectOrEmpty(evidenceExpansionReport).familyRows).map((family) => {
const candidateCount = family.candidateCount ?? 0;
const completeCount = family.completeCount ?? 0;
const sourceFileCount = family.sourceFileCount ?? arrayOrEmpty(family.sourceFiles).length;
const ready = family.complete === true && family.browserDiagnosticsExpansionReady === true;
return {
id: family.id ?? "unknown",
label: family.id ?? "Unknown evidence expansion family",
value: `${completeCount}/${candidateCount} ready; sources=${sourceFileCount}; diagnostics=${ready ? "ready" : "blocked"}`,
candidateIds: arrayOrEmpty(family.candidateIds),
sourceFiles: arrayOrEmpty(family.sourceFiles),
gcodePaths: arrayOrEmpty(family.gcodePaths),
iniPaths: arrayOrEmpty(family.iniPaths),
candidateCount,
completeCount,
sourceFileCount,
ready,
};
});
}
function createEvidenceExpansionFamilySummaryText(evidenceExpansionReport = {}) {
const rows = createEvidenceExpansionFamilySummaryRows(evidenceExpansionReport);
return rows.length > 0
? rows.map((row) => `${row.id}: ${row.completeCount}/${row.candidateCount} ${row.ready ? "ready" : "blocked"}`).join("; ")
: "not provided";
}
function createPromotionCandidateArtifactSummary({ function createPromotionCandidateArtifactSummary({
candidateReport = {}, candidateReport = {},
evidenceExpansionReport = {}, evidenceExpansionReport = {},
@@ -161,6 +190,8 @@ function createPromotionCandidateArtifactSummary({
const artifactInventoryReadyRows = candidateArtifactRows const artifactInventoryReadyRows = candidateArtifactRows
.filter((row) => row.candidate_kind === "inventory-ready"); .filter((row) => row.candidate_kind === "inventory-ready");
const artifactEvidenceReadyCount = artifactEvidenceReadyRows.length; const artifactEvidenceReadyCount = artifactEvidenceReadyRows.length;
const evidenceExpansionFamilyRows = createEvidenceExpansionFamilySummaryRows(evidenceExpansionReport);
const evidenceExpansionFamilySummary = createEvidenceExpansionFamilySummaryText(evidenceExpansionReport);
const inventoryReadyCount = artifactInventoryReadyRows.length > 0 const inventoryReadyCount = artifactInventoryReadyRows.length > 0
? artifactInventoryReadyRows.length ? artifactInventoryReadyRows.length
: 2; : 2;
@@ -269,6 +300,9 @@ function createPromotionCandidateArtifactSummary({
promotionAllowedCount: 0, promotionAllowedCount: 0,
baselineChanging: false, baselineChanging: false,
nextEvidence: "browser-diagnostics-binding", nextEvidence: "browser-diagnostics-binding",
familyCount: evidenceExpansionFamilyRows.length,
familySummary: evidenceExpansionFamilySummary,
familyRows: evidenceExpansionFamilyRows,
}, },
}; };
} }
@@ -482,6 +516,66 @@ const REQUIRED_EVIDENCE_EXPANSION_CANDIDATES = [
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
], ],
}, },
{
id: "trt-boat-xyzbc",
sourceFiles: [
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
],
},
{
id: "trt-impeller-7bl-xyzac",
sourceFiles: [
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
],
},
{
id: "trt-xyzac-switchkins-test-1",
sourceFiles: [
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
],
},
{
id: "trt-xyzac-switchkins-test-2",
sourceFiles: [
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
],
},
{
id: "trt-xyzac-switchkins-test-3",
sourceFiles: [
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
],
},
{
id: "trt-xyzbc-switchkins",
sourceFiles: [
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc",
"linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc",
],
},
]; ];
const REQUIRED_MACRO_LOAD_FIXTURES = [ const REQUIRED_MACRO_LOAD_FIXTURES = [
@@ -3223,6 +3317,10 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
const evidenceExpansionRows = arrayOrEmpty( const evidenceExpansionRows = arrayOrEmpty(
workflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.rows, workflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.rows,
); );
const evidenceExpansionFamilyRows = arrayOrEmpty(
promotionCandidateArtifactSummary.evidenceExpansion?.familyRows
?? workflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.familyRows,
);
const preferredEvidenceExpansion = evidenceExpansionRows[0] ?? {}; const preferredEvidenceExpansion = evidenceExpansionRows[0] ?? {};
const evidenceExpansionPreviewRows = evidenceExpansionRows.slice(0, 3); const evidenceExpansionPreviewRows = evidenceExpansionRows.slice(0, 3);
const evidenceExpansionFullRows = evidenceExpansionRows; const evidenceExpansionFullRows = evidenceExpansionRows;
@@ -3401,6 +3499,34 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
? evidenceExpansionFullRows.map((row) => row.gcodePath).join(", ") ? evidenceExpansionFullRows.map((row) => row.gcodePath).join(", ")
: "not provided", : "not provided",
}, },
{
id: "evidence-expansion-family-count",
label: "Evidence expansion family count",
value: evidenceExpansionFamilyRows.length > 0
? `${evidenceExpansionFamilyRows.length} families`
: "not provided",
},
{
id: "evidence-expansion-family-summary",
label: "Evidence expansion family summary",
value: promotionCandidateArtifactSummary.evidenceExpansion?.familySummary
?? createEvidenceExpansionFamilySummaryText(workflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion),
},
{
id: "evidence-expansion-family-source-count-list",
label: "Evidence expansion family source counts",
value: evidenceExpansionFamilyRows.length > 0
? evidenceExpansionFamilyRows.map((row) => `${row.id}:${row.sourceFileCount ?? arrayOrEmpty(row.sourceFiles).length}`).join(", ")
: "not provided",
},
...evidenceExpansionFamilyRows.map((row) => ({
id: `evidence-expansion-family-${row.id}`,
label: `Evidence expansion family ${row.label ?? row.id}`,
value: row.value ?? `${row.completeCount ?? 0}/${row.candidateCount ?? 0} ready; sources=${row.sourceFileCount ?? arrayOrEmpty(row.sourceFiles).length}`,
candidateIds: arrayOrEmpty(row.candidateIds),
sourceFiles: arrayOrEmpty(row.sourceFiles),
gcodePaths: arrayOrEmpty(row.gcodePaths),
})),
{ {
id: "evidence-expansion-artifact", id: "evidence-expansion-artifact",
label: "Evidence expansion artifact", label: "Evidence expansion artifact",

View File

@@ -219,6 +219,17 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan", "getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState", "getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState",
"getWorkflowOverviewPromotionFamilyRowsRenderState", "getWorkflowOverviewPromotionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan",
"handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange",
"bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls",
"renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"getWorkflowOverviewPromotionFamilySourceFilterViewModel", "getWorkflowOverviewPromotionFamilySourceFilterViewModel",
"getWorkflowOverviewPromotionFamilySourceFilterDomContract", "getWorkflowOverviewPromotionFamilySourceFilterDomContract",
"getWorkflowOverviewPromotionFamilySourceFilterDomReadiness", "getWorkflowOverviewPromotionFamilySourceFilterDomReadiness",
@@ -1942,6 +1953,17 @@ export function createIniPanelShellWorkflowOverviewContract() {
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan", "getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState", "getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState",
"getWorkflowOverviewPromotionFamilyRowsRenderState", "getWorkflowOverviewPromotionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan",
"handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange",
"bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls",
"renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"getWorkflowOverviewPromotionFamilySourceFilterViewModel", "getWorkflowOverviewPromotionFamilySourceFilterViewModel",
"getWorkflowOverviewPromotionFamilySourceFilterDomContract", "getWorkflowOverviewPromotionFamilySourceFilterDomContract",
"getWorkflowOverviewPromotionFamilySourceFilterDomReadiness", "getWorkflowOverviewPromotionFamilySourceFilterDomReadiness",
@@ -2600,6 +2622,12 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
?? workflow?.urlWorkflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.rows ?? workflow?.urlWorkflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.rows
?? [] ?? []
); );
const evidenceExpansionFamilyRows = (
promotionCandidateArtifactSummary.evidenceExpansion?.familyRows
?? workflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.familyRows
?? workflow?.urlWorkflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.familyRows
?? []
);
const preferredEvidenceExpansion = Array.isArray(evidenceExpansionRows) const preferredEvidenceExpansion = Array.isArray(evidenceExpansionRows)
? (evidenceExpansionRows[0] ?? {}) ? (evidenceExpansionRows[0] ?? {})
: {}; : {};
@@ -2817,6 +2845,40 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
? evidenceExpansionFullRows.map((row) => row.gcodePath).join(", ") ? evidenceExpansionFullRows.map((row) => row.gcodePath).join(", ")
: "not provided", : "not provided",
}, },
{
id: "evidence-expansion-family-count",
label: "Evidence expansion family count",
value: Array.isArray(evidenceExpansionFamilyRows) && evidenceExpansionFamilyRows.length > 0
? `${evidenceExpansionFamilyRows.length} families`
: "not provided",
},
{
id: "evidence-expansion-family-summary",
label: "Evidence expansion family summary",
value: evidenceExpansion.familySummary ?? (Array.isArray(evidenceExpansionFamilyRows) && evidenceExpansionFamilyRows.length > 0
? evidenceExpansionFamilyRows.map((row) => {
const ready = row.ready === true || (row.complete === true && row.browserDiagnosticsExpansionReady === true);
return `${row.id}: ${row.completeCount ?? 0}/${row.candidateCount ?? 0} ${ready ? "ready" : "blocked"}`;
}).join("; ")
: "not provided"),
},
{
id: "evidence-expansion-family-source-count-list",
label: "Evidence expansion family source counts",
value: Array.isArray(evidenceExpansionFamilyRows) && evidenceExpansionFamilyRows.length > 0
? evidenceExpansionFamilyRows.map((row) =>
`${row.id}:${row.sourceFileCount ?? (Array.isArray(row.sourceFiles) ? row.sourceFiles.length : 0)}`
).join(", ")
: "not provided",
},
...(Array.isArray(evidenceExpansionFamilyRows) ? evidenceExpansionFamilyRows.map((row) => ({
id: `evidence-expansion-family-${row.id}`,
label: `Evidence expansion family ${row.label ?? row.id}`,
value: row.value ?? `${row.completeCount ?? 0}/${row.candidateCount ?? 0} ready; sources=${row.sourceFileCount ?? (Array.isArray(row.sourceFiles) ? row.sourceFiles.length : 0)}`,
candidateIds: Array.isArray(row.candidateIds) ? row.candidateIds : [],
sourceFiles: Array.isArray(row.sourceFiles) ? row.sourceFiles : [],
gcodePaths: Array.isArray(row.gcodePaths) ? row.gcodePaths : [],
})) : []),
{ {
id: "hard-block-runtime-lock", id: "hard-block-runtime-lock",
label: "Hard-block runtime lock", label: "Hard-block runtime lock",
@@ -3360,6 +3422,77 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderStat
}; };
} }
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(
summaryViewModel = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(),
) {
const summaryRows = Array.isArray(summaryViewModel?.rows) ? summaryViewModel.rows : [];
const rows = summaryRows
.filter(({ id }) => String(id).startsWith("evidence-expansion-family-"))
.filter(({ sourceFiles, gcodePaths }) => Array.isArray(sourceFiles) && Array.isArray(gcodePaths))
.map(({ id, label, value, sourceFiles, gcodePaths, candidateIds }) => {
const familySourceFiles = Array.isArray(sourceFiles) ? sourceFiles : [];
const familyGcodePaths = Array.isArray(gcodePaths) ? gcodePaths : [];
const familyCandidateIds = Array.isArray(candidateIds) ? candidateIds : [];
const sourceKindCounts = countPromotionFamilySourceKinds(familySourceFiles);
const sourceKindSummary = formatPromotionFamilySourceKindCounts(sourceKindCounts);
return {
id,
label,
value: value == null ? "" : String(value),
sourceFiles: familySourceFiles,
gcodePaths: familyGcodePaths,
candidateIds: familyCandidateIds,
sourceKindCounts,
sourceKindSummary,
};
});
const sourceRows = rows.flatMap((row) =>
row.sourceFiles.map((sourceFile, index) => ({
id: `${row.id}-source-${index + 1}`,
familyId: row.id,
label: `Source ${index + 1}`,
value: sourceFile,
sourceKind: classifyPromotionFamilySource(sourceFile),
manifestBacked: true,
status: "evidence-expansion-source",
}))
);
const candidateRows = rows.flatMap((row) =>
row.gcodePaths.map((gcodePath, index) => ({
id: `${row.id}-candidate-${index + 1}`,
familyId: row.id,
label: row.candidateIds[index] ?? `Candidate ${index + 1}`,
value: gcodePath,
candidateStatus: "evidence-expansion-ready",
promotionAllowed: false,
baselineChanging: false,
sourceKind: "gcode",
manifestBacked: true,
}))
);
const ready = rows.length > 0 && rows.every(({ value }) => String(value).includes("diagnostics=ready"));
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-rows-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: "Evidence expansion family diagnostics",
statusText: ready ? "Ready" : "Blocked",
detailText: ready ? `${rows.length} evidence expansion families ready` : "evidence expansion family rows missing",
statusLine: `${ready ? "Ready" : "Blocked"}: ${ready ? `${rows.length} evidence expansion families ready` : "evidence expansion family rows missing"}`,
rows,
sourceRows,
candidateRows,
sourceFileCount: sourceRows.length,
candidateCount: candidateRows.length,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-evidence-expansion-family-rows",
},
};
}
export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel( export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(
renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(), renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(),
{ sourceKind = "all", familyId = "all" } = {}, { sourceKind = "all", familyId = "all" } = {},
@@ -3454,6 +3587,88 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterVi
}; };
} }
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(
renderState = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(),
{ sourceKind = "all", familyId = "all" } = {},
) {
const viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(
renderState,
{ sourceKind, familyId },
);
return {
...viewModel,
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-view-model",
detailText: viewModel.ready
? `${viewModel.filteredSourceFileCount}/${viewModel.totalSourceFileCount} source files selected`
: "evidence expansion source rows missing",
statusLine: `${viewModel.ready ? "Ready" : "Blocked"}: ${viewModel.ready ? `${viewModel.filteredSourceFileCount}/${viewModel.totalSourceFileCount} source files selected` : "evidence expansion source rows missing"}`,
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(),
) {
const familyRows = Array.isArray(viewModel?.familyRows) ? viewModel.familyRows : [];
const sourceRows = Array.isArray(viewModel?.sourceRows) ? viewModel.sourceRows : [];
const candidateRows = Array.isArray(viewModel?.candidateRows) ? viewModel.candidateRows : [];
const selectedFamilyId = viewModel?.selectedFamilyId ?? "all";
const selectedSourceKind = viewModel?.selectedSourceKind ?? "all";
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-summary",
summaryVersion: 1,
phase: viewModel?.ready === true ? "ready" : "blocked",
ready: viewModel?.ready === true,
selectedFamilyId,
selectedSourceKind,
filteredSourceFileCount: viewModel?.filteredSourceFileCount ?? sourceRows.length,
scopedSourceFileCount: viewModel?.scopedSourceFileCount ?? sourceRows.length,
totalSourceFileCount: viewModel?.totalSourceFileCount ?? sourceRows.length,
filteredCandidateCount: viewModel?.filteredCandidateCount ?? candidateRows.length,
totalCandidateCount: viewModel?.totalCandidateCount ?? candidateRows.length,
familyCount: familyRows.length,
sourceKinds: [...new Set(sourceRows.map((row) => row.sourceKind).filter(Boolean))],
familyIds: familyRows.map((row) => row.id),
candidateIds: candidateRows.map((row) => row.label ?? row.id),
gcodePaths: candidateRows.map((row) => row.value).filter(Boolean),
sourceFiles: sourceRows.map((row) => row.value).filter(Boolean),
statusLine: viewModel?.ready === true
? `Ready: ${selectedFamilyId} / ${selectedSourceKind} selects ${viewModel?.filteredSourceFileCount ?? sourceRows.length}/${viewModel?.totalSourceFileCount ?? sourceRows.length} source files`
: "Blocked: evidence expansion source filter summary missing",
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan(
summary = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(),
) {
const ready = summary?.ready === true;
const selectedFamilyId = summary?.selectedFamilyId ?? "all";
const selectedSourceKind = summary?.selectedSourceKind ?? "all";
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-action-plan",
actionPlanVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
selectedFamilyId,
selectedSourceKind,
filteredSourceFileCount: summary?.filteredSourceFileCount ?? 0,
filteredCandidateCount: summary?.filteredCandidateCount ?? 0,
promotionAllowed: false,
baselineChanging: false,
nextCommand: ready ? null : "mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
nextSteps: ready
? []
: [
"Load a release readiness artifact URL workflow summary.",
"Create evidence expansion family rows render state.",
"Mount the evidence expansion family/source filter DOM.",
],
statusLine: ready
? `Ready: evidence expansion filter ${selectedFamilyId} / ${selectedSourceKind} is externally readable`
: "Blocked: evidence expansion filter summary is not ready",
summary,
};
}
export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract({ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract({
rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter", rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter",
selectors = {}, selectors = {},
@@ -3496,6 +3711,21 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDo
}; };
} }
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
selectors = {},
} = {}) {
return createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract({
rowDatasetPrefix,
selectors: {
mount: selectors.mount ?? "[data-workflow-overview-evidence-expansion-family-source-filter]",
status: selectors.status ?? "[data-workflow-overview-evidence-expansion-family-source-filter-status]",
controls: selectors.controls ?? "[data-workflow-overview-evidence-expansion-family-source-filter-controls]",
rows: selectors.rows ?? "[data-workflow-overview-evidence-expansion-family-source-filter-rows]",
},
});
}
export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomReadiness({ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomReadiness({
rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter", rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract({ rowDatasetPrefix }), contract = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract({ rowDatasetPrefix }),
@@ -3528,6 +3758,30 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDo
}; };
} }
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness({
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const readiness = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomReadiness({
rowDatasetPrefix,
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
return {
...readiness,
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-dom-readiness",
};
}
function readPromotionFamilySourceFilterControlValue( function readPromotionFamilySourceFilterControlValue(
controlsNode, controlsNode,
rowDatasetPrefix, rowDatasetPrefix,
@@ -3572,6 +3826,39 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSe
}; };
} }
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan(
renderState = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(),
{
familyId = "all",
sourceKind = "all",
previousViewModel = null,
} = {},
) {
const nextViewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(
renderState,
{ familyId, sourceKind },
);
const changed = previousViewModel === null ||
previousViewModel.selectedFamilyId !== nextViewModel.selectedFamilyId ||
previousViewModel.selectedSourceKind !== nextViewModel.selectedSourceKind;
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-selection-action-plan",
actionPlanVersion: 1,
phase: nextViewModel.ready ? "ready" : "blocked",
ready: nextViewModel.ready,
changed,
selectedFamilyId: nextViewModel.selectedFamilyId,
selectedSourceKind: nextViewModel.selectedSourceKind,
filteredSourceFileCount: nextViewModel.filteredSourceFileCount,
scopedSourceFileCount: nextViewModel.scopedSourceFileCount,
totalSourceFileCount: nextViewModel.totalSourceFileCount,
statusLine: changed
? `Ready: evidence expansion source filter changed to ${nextViewModel.selectedFamilyId} / ${nextViewModel.selectedSourceKind}`
: "Ready: evidence expansion source filter unchanged",
nextViewModel,
};
}
export function handleIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSelectionChange({ export function handleIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSelectionChange({
renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(), renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(),
viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState), viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState),
@@ -3628,6 +3915,62 @@ export function handleIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSe
}; };
} }
export function handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange({
renderState = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(),
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(renderState),
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
render = false,
} = {}) {
const selectedFamilyId = readPromotionFamilySourceFilterControlValue(
controlsNode,
contract.rowDatasetPrefix,
"family",
viewModel?.selectedFamilyId ?? "all",
);
const selectedSourceKind = readPromotionFamilySourceFilterControlValue(
controlsNode,
contract.rowDatasetPrefix,
"source-kind",
viewModel?.selectedSourceKind ?? "all",
);
const actionPlan = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan(
renderState,
{
familyId: selectedFamilyId,
sourceKind: selectedSourceKind,
previousViewModel: viewModel,
},
);
const renderResult = render
? renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(actionPlan.nextViewModel, {
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
})
: null;
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-selection-change",
workflowVersion: 1,
phase: actionPlan.phase,
ready: actionPlan.ready,
statusLine: actionPlan.statusLine,
selectedFamilyId: actionPlan.selectedFamilyId,
selectedSourceKind: actionPlan.selectedSourceKind,
actionPlan,
viewModel: actionPlan.nextViewModel,
renderResult,
};
}
export function bindIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSelectionControls({ export function bindIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSelectionControls({
renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(), renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(),
viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState), viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState),
@@ -3720,6 +4063,98 @@ export function bindIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSele
return binding; return binding;
} }
export function bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls({
renderState = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(),
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(renderState),
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
render = true,
onChange = null,
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
const selectNodes = Array.from(controlsNode?.children ?? [])
.filter((node) => typeof node?.dataset?.[`${contract.rowDatasetPrefix}Select`] === "string");
if (!domReadiness.ready || selectNodes.length === 0) {
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-selection-controls-binding",
bindingVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.ready ? "selector controls missing" : domReadiness.missing.join(", ")}`,
boundControlCount: 0,
controlIds: [],
domReadiness,
lastChange: null,
triggerChange: () => null,
unbind: () => ({ unbound: 0 }),
};
}
const binding = {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-selection-controls-binding",
bindingVersion: 1,
phase: "ready",
ready: true,
statusLine: `Ready: ${selectNodes.length} selector controls bound`,
boundControlCount: selectNodes.length,
controlIds: selectNodes.map((node) => node.dataset[`${contract.rowDatasetPrefix}Select`]),
domReadiness,
lastChange: null,
triggerChange: null,
unbind: null,
};
const handleChange = () => {
const changeResult = handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange({
renderState,
viewModel,
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
render,
});
binding.lastChange = changeResult;
if (typeof onChange === "function") {
onChange(changeResult);
}
return changeResult;
};
const unbinders = selectNodes.map((node) => {
if (typeof node.addEventListener === "function") {
node.addEventListener("change", handleChange);
return () => node.removeEventListener?.("change", handleChange);
}
node.onchange = handleChange;
return () => {
if (node.onchange === handleChange) {
node.onchange = null;
}
};
});
binding.triggerChange = handleChange;
binding.unbind = () => {
for (const unbind of unbinders) {
unbind();
}
return { unbound: unbinders.length };
};
return binding;
}
export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterState( export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterState(
viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(), viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(),
{ {
@@ -3892,6 +4327,32 @@ export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSt
}; };
} }
export function renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(),
{
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const renderResult = renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterState(viewModel, {
rowDatasetPrefix,
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
mountNode.dataset.handoffScope = "workflow-overview-evidence-expansion-family-source-filter";
renderResult.dataset.handoffScope = mountNode.dataset.handoffScope;
return renderResult;
}
export function mountIniPanelShellWorkflowOverviewPromotionFamilySourceFilterState({ export function mountIniPanelShellWorkflowOverviewPromotionFamilySourceFilterState({
viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(), viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(),
rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter", rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter",
@@ -3962,6 +4423,76 @@ export function mountIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSta
} }
} }
export function mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState({
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(),
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
viewModel,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(viewModel, {
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-dom-mount",
workflowVersion: 1,
phase: viewModel?.phase === "ready" ? "ready" : "blocked",
ready: viewModel?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
viewModel,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "evidence expansion source filter DOM mount error"}`,
contract,
domReadiness,
viewModel,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewPromotionFamilyRowsDomContract({ export function createIniPanelShellWorkflowOverviewPromotionFamilyRowsDomContract({
rowDatasetPrefix = "workflowOverviewPromotionFamily", rowDatasetPrefix = "workflowOverviewPromotionFamily",
selectors = {}, selectors = {},
@@ -6852,6 +7383,28 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan,
createWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState: createWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState,
createWorkflowOverviewEvidenceExpansionFamilyRowsRenderState:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange:
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls:
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState:
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState:
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
createWorkflowOverviewPromotionFamilyRowsRenderState: createWorkflowOverviewPromotionFamilyRowsRenderState:
createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState, createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState,
createWorkflowOverviewPromotionFamilySourceFilterViewModel: createWorkflowOverviewPromotionFamilySourceFilterViewModel:

View File

@@ -162,6 +162,11 @@
<div class="source-filter-controls" data-workflow-overview-promotion-family-source-filter-controls></div> <div class="source-filter-controls" data-workflow-overview-promotion-family-source-filter-controls></div>
<dl data-workflow-overview-promotion-family-source-filter-rows></dl> <dl data-workflow-overview-promotion-family-source-filter-rows></dl>
</section> </section>
<section class="overview-status" aria-label="Evidence expansion family source filter" data-workflow-overview-evidence-expansion-family-source-filter>
<p data-workflow-overview-evidence-expansion-family-source-filter-status>Waiting for evidence expansion family source evidence.</p>
<div class="source-filter-controls" data-workflow-overview-evidence-expansion-family-source-filter-controls></div>
<dl data-workflow-overview-evidence-expansion-family-source-filter-rows></dl>
</section>
</section> </section>
</main> </main>
<script type="module"> <script type="module">
@@ -205,6 +210,17 @@
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness,
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState, renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState, mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState, createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel, createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract, createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract,
@@ -256,6 +272,20 @@
const browserDiagnosticsUrlInput = document.querySelector("[data-browser-diagnostics-url-input]"); const browserDiagnosticsUrlInput = document.querySelector("[data-browser-diagnostics-url-input]");
const releaseArtifactUrlWorkflowForm = document.querySelector("[data-release-artifact-url-workflow-form]"); const releaseArtifactUrlWorkflowForm = document.querySelector("[data-release-artifact-url-workflow-form]");
function getWorkflowOverviewEvidenceExpansionFilterPreset(locationRef = window.location) {
const searchParams = new URLSearchParams(locationRef?.search ?? "");
const hashText = String(locationRef?.hash ?? "").replace(/^#/, "");
const hashParams = new URLSearchParams(hashText);
return {
familyId: searchParams.get("evidenceExpansionFamily") ??
hashParams.get("evidenceExpansionFamily") ??
"all",
sourceKind: searchParams.get("evidenceExpansionSourceKind") ??
hashParams.get("evidenceExpansionSourceKind") ??
"all",
};
}
async function runWorkflowOverviewReleaseReadinessArtifactUrlForm(options = {}) { async function runWorkflowOverviewReleaseReadinessArtifactUrlForm(options = {}) {
const artifactUrl = String(options.artifactUrl ?? releaseArtifactUrlInput?.value ?? "").trim(); const artifactUrl = String(options.artifactUrl ?? releaseArtifactUrlInput?.value ?? "").trim();
const diagnosticsUrl = String(options.diagnosticsUrl ?? browserDiagnosticsUrlInput?.value ?? "").trim(); const diagnosticsUrl = String(options.diagnosticsUrl ?? browserDiagnosticsUrlInput?.value ?? "").trim();
@@ -326,7 +356,45 @@
document.body.dataset.promotionFamilySourceFilterSourceKind = document.body.dataset.promotionFamilySourceFilterSourceKind =
changeResult.selectedSourceKind; changeResult.selectedSourceKind;
document.body.dataset.promotionFamilySourceFilterCount = document.body.dataset.promotionFamilySourceFilterCount =
String(changeResult.actionPlan.filteredSourceFileCount);
},
});
const evidenceExpansionFamilyRowsRenderState =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(summary);
const evidenceExpansionFamilySourceFilter =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(
evidenceExpansionFamilyRowsRenderState,
options.evidenceExpansionFilterPreset ??
getWorkflowOverviewEvidenceExpansionFilterPreset(window.location),
);
const evidenceExpansionFamilySourceFilterSummary =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(
evidenceExpansionFamilySourceFilter,
);
const evidenceExpansionFamilySourceFilterActionPlan =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan(
evidenceExpansionFamilySourceFilterSummary,
);
const evidenceExpansionFamilySourceFilterMountResult =
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState({
viewModel: evidenceExpansionFamilySourceFilter,
documentRef: document,
});
const evidenceExpansionFamilySourceFilterBinding =
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls({
renderState: evidenceExpansionFamilyRowsRenderState,
viewModel: evidenceExpansionFamilySourceFilter,
documentRef: document,
render: true,
onChange: (changeResult) => {
document.body.dataset.evidenceExpansionFamilySourceFilterFamily =
changeResult.selectedFamilyId;
document.body.dataset.evidenceExpansionFamilySourceFilterSourceKind =
changeResult.selectedSourceKind;
document.body.dataset.evidenceExpansionFamilySourceFilterCount =
String(changeResult.actionPlan.filteredSourceFileCount); String(changeResult.actionPlan.filteredSourceFileCount);
document.body.dataset.evidenceExpansionFamilySourceFilterSummary =
changeResult.actionPlan.statusLine;
}, },
}); });
document.body.dataset.releaseArtifactUrlWorkflowPhase = workflow.phase; document.body.dataset.releaseArtifactUrlWorkflowPhase = workflow.phase;
@@ -337,6 +405,16 @@
promotionFamilySourceFilter.ready ? "true" : "false"; promotionFamilySourceFilter.ready ? "true" : "false";
document.body.dataset.promotionFamilySourceFilterCount = document.body.dataset.promotionFamilySourceFilterCount =
String(promotionFamilySourceFilter.filteredSourceFileCount); String(promotionFamilySourceFilter.filteredSourceFileCount);
document.body.dataset.evidenceExpansionFamilySourceFilterReady =
evidenceExpansionFamilySourceFilter.ready ? "true" : "false";
document.body.dataset.evidenceExpansionFamilySourceFilterFamily =
evidenceExpansionFamilySourceFilter.selectedFamilyId;
document.body.dataset.evidenceExpansionFamilySourceFilterSourceKind =
evidenceExpansionFamilySourceFilter.selectedSourceKind;
document.body.dataset.evidenceExpansionFamilySourceFilterCount =
String(evidenceExpansionFamilySourceFilter.filteredSourceFileCount);
document.body.dataset.evidenceExpansionFamilySourceFilterSummary =
evidenceExpansionFamilySourceFilterActionPlan.statusLine;
return { return {
workflow, workflow,
summary, summary,
@@ -355,6 +433,12 @@
promotionFamilySourceFilter, promotionFamilySourceFilter,
promotionFamilySourceFilterMountResult, promotionFamilySourceFilterMountResult,
promotionFamilySourceFilterBinding, promotionFamilySourceFilterBinding,
evidenceExpansionFamilyRowsRenderState,
evidenceExpansionFamilySourceFilter,
evidenceExpansionFamilySourceFilterSummary,
evidenceExpansionFamilySourceFilterActionPlan,
evidenceExpansionFamilySourceFilterMountResult,
evidenceExpansionFamilySourceFilterBinding,
}; };
} }
@@ -459,6 +543,50 @@
getWorkflowOverviewPromotionFamilyRowsRenderState: (summaryViewModel) => ( getWorkflowOverviewPromotionFamilyRowsRenderState: (summaryViewModel) => (
createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(summaryViewModel) createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(summaryViewModel)
), ),
getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState: (summaryViewModel) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(summaryViewModel)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel: (renderState, options) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(renderState, options)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract: (options) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract(options)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness: (options) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness(
options ?? { documentRef: document },
)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary: (viewModel) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(viewModel)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan: (summary) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan(summary)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan: (renderState, options) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan(renderState, options)
),
handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange: (options) => (
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange(
options ?? { documentRef: document },
)
),
bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls: (options) => (
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls(
options ?? { documentRef: document },
)
),
renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState: (viewModel, options) => (
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(
viewModel,
options ?? { documentRef: document },
)
),
mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState: (options) => (
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(
options ?? { documentRef: document },
)
),
getWorkflowOverviewPromotionFamilySourceFilterViewModel: (renderState, options) => ( getWorkflowOverviewPromotionFamilySourceFilterViewModel: (renderState, options) => (
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState, options) createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState, options)
), ),

View File

@@ -2793,10 +2793,17 @@ M2
report = createVirtualHalSimConfigEvidenceExpansionReport(), report = createVirtualHalSimConfigEvidenceExpansionReport(),
) { ) {
const rows = Array.isArray(report.rows) ? report.rows : []; const rows = Array.isArray(report.rows) ? report.rows : [];
const familyRows = Array.isArray(report.familyRows) ? report.familyRows : [];
const readyRows = rows.filter((row) => row.complete === true); const readyRows = rows.filter((row) => row.complete === true);
const blockedRows = rows.filter((row) => row.complete !== true); const blockedRows = rows.filter((row) => row.complete !== true);
const promotionAllowedRows = rows.filter((row) => row.promotionAllowed === true); const promotionAllowedRows = rows.filter((row) => row.promotionAllowed === true);
const preferredRow = rows[0] ?? null; const preferredRow = rows[0] ?? null;
const familySummary = familyRows.length > 0
? familyRows.map((row) => {
const readyFamily = row.complete === true && row.browserDiagnosticsExpansionReady === true;
return `${row.id}: ${row.completeCount ?? 0}/${row.candidateCount ?? 0} ${readyFamily ? "ready" : "blocked"}`;
}).join("; ")
: "missing";
const ready = report.complete === true && const ready = report.complete === true &&
report.inventoryBaselineUnchanged === true && report.inventoryBaselineUnchanged === true &&
report.promotionAllowed === false && report.promotionAllowed === false &&
@@ -2813,6 +2820,9 @@ M2
preferredCandidateId: preferredRow?.id ?? null, preferredCandidateId: preferredRow?.id ?? null,
candidateIds: rows.map((row) => row.id), candidateIds: rows.map((row) => row.id),
gcodePaths: rows.map((row) => row.gcodePath), gcodePaths: rows.map((row) => row.gcodePath),
familyRows,
familyCount: familyRows.length,
familySummary,
sourceFileCount: new Set(rows.flatMap((row) => row.sourceFiles ?? [])).size, sourceFileCount: new Set(rows.flatMap((row) => row.sourceFiles ?? [])).size,
promotionAllowedCount: promotionAllowedRows.length, promotionAllowedCount: promotionAllowedRows.length,
inventoryBaselineUnchanged: report.inventoryBaselineUnchanged === true, inventoryBaselineUnchanged: report.inventoryBaselineUnchanged === true,
@@ -2820,6 +2830,15 @@ M2
{ id: "candidate-count", label: "Expansion", value: `${readyRows.length}/${rows.length} ready` }, { id: "candidate-count", label: "Expansion", value: `${readyRows.length}/${rows.length} ready` },
{ id: "preferred-candidate", label: "First case", value: preferredRow?.id ?? "missing" }, { id: "preferred-candidate", label: "First case", value: preferredRow?.id ?? "missing" },
{ id: "candidate-list", label: "Cases", value: rows.map((row) => row.id).join(", ") || "missing" }, { id: "candidate-list", label: "Cases", value: rows.map((row) => row.id).join(", ") || "missing" },
{ id: "family-count", label: "Families", value: `${familyRows.length}` },
{ id: "family-summary", label: "Family summary", value: familySummary },
{
id: "family-source-count-list",
label: "Family source counts",
value: familyRows.length > 0
? familyRows.map((row) => `${row.id}:${row.sourceFileCount ?? row.sourceFiles?.length ?? 0}`).join(", ")
: "missing",
},
{ id: "source-files", label: "Source files", value: `${new Set(rows.flatMap((row) => row.sourceFiles ?? [])).size}` }, { id: "source-files", label: "Source files", value: `${new Set(rows.flatMap((row) => row.sourceFiles ?? [])).size}` },
{ id: "promotion-allowed", label: "Allowed", value: `${promotionAllowedRows.length} baseline changes` }, { id: "promotion-allowed", label: "Allowed", value: `${promotionAllowedRows.length} baseline changes` },
{ id: "inventory-baseline", label: "Inventory", value: report.inventoryBaselineUnchanged === true ? "unchanged" : "changing" }, { id: "inventory-baseline", label: "Inventory", value: report.inventoryBaselineUnchanged === true ? "unchanged" : "changing" },

View File

@@ -244,7 +244,7 @@ TOOL_TABLE = browser-shell-tool.tbl
"shell handoff action-plan next steps", "shell handoff action-plan next steps",
); );
assertEqual(handoffChecklist.ready, true, "shell handoff checklist readiness"); assertEqual(handoffChecklist.ready, true, "shell handoff checklist readiness");
assertEqual(handoffChecklist.checks.length, 5, "shell handoff checklist checks"); assertEqual(handoffChecklist.checks.length, 11, "shell handoff checklist checks");
assertEqual( assertEqual(
handoffChecklist.checks.map(({ status }) => status).join(","), handoffChecklist.checks.map(({ status }) => status).join(","),
"pass,pass,pass,pass,pass", "pass,pass,pass,pass,pass",
@@ -1041,14 +1041,29 @@ TOOL_TABLE = browser-shell-tool.tbl
); );
assertEqual( assertEqual(
workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value, workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins", "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins",
"shell workflow overview release artifact URL workflow evidence expansion full candidate list", "shell workflow overview release artifact URL workflow evidence expansion full candidate list",
); );
assertEqual( assertEqual(
workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-gcode-list")?.value, workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-gcode-list")?.value,
"linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc",
"shell workflow overview release artifact URL workflow evidence expansion full gcode list", "shell workflow overview release artifact URL workflow evidence expansion full gcode list",
); );
assertEqual(
workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-family-count")?.value,
"3 families",
"shell workflow overview release artifact URL workflow evidence expansion family count",
);
assertEqual(
workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-family-summary")?.value,
"woodpecker: 1/1 ready; vismach-remap-sims: 2/2 ready; five-axis-trt: 8/8 ready",
"shell workflow overview release artifact URL workflow evidence expansion family summary",
);
assertEqual(
workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-family-source-count-list")?.value,
"woodpecker:3, vismach-remap-sims:6, five-axis-trt:12",
"shell workflow overview release artifact URL workflow evidence expansion family source count",
);
assertEqual( assertEqual(
workflowOverviewReleaseArtifactUrlWorkflowRenderResult.rowIds.includes("hard-block-runtime-lock"), workflowOverviewReleaseArtifactUrlWorkflowRenderResult.rowIds.includes("hard-block-runtime-lock"),
true, true,

View File

@@ -33,9 +33,11 @@
} }
} }
async function loadWorkflowOverviewFrame() { async function loadWorkflowOverviewFrame(
src = "../../runtime/ui/ini-panel/workflow-overview.html",
) {
const frame = document.createElement("iframe"); const frame = document.createElement("iframe");
frame.src = "../../runtime/ui/ini-panel/workflow-overview.html"; frame.src = src;
document.body.appendChild(frame); document.body.appendChild(frame);
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
frame.addEventListener("load", resolve, { once: true }); frame.addEventListener("load", resolve, { once: true });
@@ -72,6 +74,17 @@
!workflowApi?.renderWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState || !workflowApi?.renderWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState ||
!workflowApi?.mountWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState || !workflowApi?.mountWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState ||
!workflowApi?.getWorkflowOverviewPromotionFamilyRowsRenderState || !workflowApi?.getWorkflowOverviewPromotionFamilyRowsRenderState ||
!workflowApi?.getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState ||
!workflowApi?.getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel ||
!workflowApi?.getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract ||
!workflowApi?.getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness ||
!workflowApi?.getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary ||
!workflowApi?.getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan ||
!workflowApi?.getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan ||
!workflowApi?.handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange ||
!workflowApi?.bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls ||
!workflowApi?.renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState ||
!workflowApi?.mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState ||
!workflowApi?.getWorkflowOverviewPromotionFamilySourceFilterViewModel || !workflowApi?.getWorkflowOverviewPromotionFamilySourceFilterViewModel ||
!workflowApi?.getWorkflowOverviewPromotionFamilySourceFilterDomContract || !workflowApi?.getWorkflowOverviewPromotionFamilySourceFilterDomContract ||
!workflowApi?.getWorkflowOverviewPromotionFamilySourceFilterDomReadiness || !workflowApi?.getWorkflowOverviewPromotionFamilySourceFilterDomReadiness ||
@@ -741,12 +754,12 @@
); );
assertEqual( assertEqual(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value, releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins", "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins",
"workflow overview release artifact URL workflow evidence expansion full candidate list", "workflow overview release artifact URL workflow evidence expansion full candidate list",
); );
assertEqual( assertEqual(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-gcode-list")?.value, releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-gcode-list")?.value,
"linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc",
"workflow overview release artifact URL workflow evidence expansion full gcode list", "workflow overview release artifact URL workflow evidence expansion full gcode list",
); );
assertEqual( assertEqual(
@@ -1042,14 +1055,29 @@
); );
assertEqual( assertEqual(
workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="evidence-expansion-full-candidate-list"]').textContent, workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="evidence-expansion-full-candidate-list"]').textContent,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins", "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins",
"workflow overview fixed URL workflow form evidence expansion full candidate list row", "workflow overview fixed URL workflow form evidence expansion full candidate list row",
); );
assertEqual( assertEqual(
workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="evidence-expansion-full-gcode-list"]').textContent, workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="evidence-expansion-full-gcode-list"]').textContent,
"linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc",
"workflow overview fixed URL workflow form evidence expansion full gcode list row", "workflow overview fixed URL workflow form evidence expansion full gcode list row",
); );
assertEqual(
workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="evidence-expansion-family-count"]').textContent,
"3 families",
"workflow overview fixed URL workflow form evidence expansion family count row",
);
assertEqual(
workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="evidence-expansion-family-summary"]').textContent,
"woodpecker: 1/1 ready; vismach-remap-sims: 2/2 ready; five-axis-trt: 8/8 ready",
"workflow overview fixed URL workflow form evidence expansion family summary row",
);
assertEqual(
workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="evidence-expansion-family-source-count-list"]').textContent,
"woodpecker:3, vismach-remap-sims:6, five-axis-trt:12",
"workflow overview fixed URL workflow form evidence expansion family source count row",
);
assertEqual( assertEqual(
workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="virtual-hal-promotion-source-file-count"]').textContent, workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="virtual-hal-promotion-source-file-count"]').textContent,
"17 source files", "17 source files",
@@ -1198,6 +1226,142 @@
"0", "0",
"workflow overview source filter changed rose engine promotion allowed", "workflow overview source filter changed rose engine promotion allowed",
); );
const evidenceExpansionSourceFilterMount = workflowDoc.querySelector("[data-workflow-overview-evidence-expansion-family-source-filter]");
const evidenceExpansionSourceFilterFamilySelect = workflowDoc.querySelector(
'[data-workflow-overview-evidence-expansion-family-source-filter-select="family"]',
);
const evidenceExpansionSourceFilterKindSelect = workflowDoc.querySelector(
'[data-workflow-overview-evidence-expansion-family-source-filter-select="source-kind"]',
);
assertEqual(
evidenceExpansionSourceFilterMount.dataset.selectedFamilyId,
"all",
"workflow overview evidence expansion source filter default family",
);
assertEqual(
workflowDoc.body.dataset.evidenceExpansionFamilySourceFilterReady,
"true",
"workflow overview evidence expansion source filter ready",
);
assertEqual(
workflowDoc.body.dataset.evidenceExpansionFamilySourceFilterCount,
"21",
"workflow overview evidence expansion source filter default source count",
);
evidenceExpansionSourceFilterFamilySelect.value = "evidence-expansion-family-five-axis-trt";
evidenceExpansionSourceFilterKindSelect.value = "gcode";
evidenceExpansionSourceFilterFamilySelect.dispatchEvent(new Event("change", { bubbles: true }));
assertEqual(
workflowDoc.body.dataset.evidenceExpansionFamilySourceFilterFamily,
"evidence-expansion-family-five-axis-trt",
"workflow overview evidence expansion source filter change body family",
);
assertEqual(
workflowDoc.body.dataset.evidenceExpansionFamilySourceFilterSourceKind,
"gcode",
"workflow overview evidence expansion source filter change body source kind",
);
assertEqual(
workflowDoc.body.dataset.evidenceExpansionFamilySourceFilterCount,
"8",
"workflow overview evidence expansion source filter changed source count",
);
assertEqual(
evidenceExpansionSourceFilterMount.dataset.handoffScope,
"workflow-overview-evidence-expansion-family-source-filter",
"workflow overview evidence expansion source filter scope",
);
assertEqual(
workflowDoc.querySelectorAll(
'[data-workflow-overview-evidence-expansion-family-source-filter-type="source-row"]',
).length,
16,
"workflow overview evidence expansion source filter changed source DOM nodes",
);
assertEqual(
workflowDoc.querySelectorAll(
'[data-workflow-overview-evidence-expansion-family-source-filter-type="candidate-row"]',
).length,
16,
"workflow overview evidence expansion source filter changed candidate DOM nodes",
);
assertEqual(
workflowDoc.querySelector(
'[data-workflow-overview-evidence-expansion-family-source-filter-type="candidate-row"][data-workflow-overview-evidence-expansion-family-source-filter-value="linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc"]',
)?.dataset.workflowOverviewEvidenceExpansionFamilySourceFilterCandidateStatus,
"evidence-expansion-ready",
"workflow overview evidence expansion source filter TRT candidate status",
);
assertEqual(
workflowDoc.querySelector(
'[data-workflow-overview-evidence-expansion-family-source-filter-type="candidate-row"][data-workflow-overview-evidence-expansion-family-source-filter-value="linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc"]',
)?.dataset.workflowOverviewEvidenceExpansionFamilySourceFilterPromotionAllowed,
"0",
"workflow overview evidence expansion source filter promotion allowed",
);
const presetWorkflowDoc = await loadWorkflowOverviewFrame(
"../../runtime/ui/ini-panel/workflow-overview.html?evidenceExpansionFamily=evidence-expansion-family-five-axis-trt&evidenceExpansionSourceKind=gcode",
);
const presetWorkflowApi = presetWorkflowDoc.defaultView.linuxCncIniPanelWorkflowOverviewApi;
presetWorkflowDoc.querySelector("[data-release-artifact-url-input]").value =
"../../tests/fixtures/project-release-readiness-ready.json";
presetWorkflowDoc.querySelector("[data-browser-diagnostics-url-input]").value =
"../../tests/fixtures/real-browser-simulation-diagnostics-ready.json";
const presetReleaseArtifactUrlFormResult = await presetWorkflowApi.runWorkflowOverviewReleaseReadinessArtifactUrlForm({
fetchRef: async (url) => {
if (String(url).endsWith("real-browser-simulation-diagnostics-ready.json")) {
return {
ok: true,
status: 200,
text: async () => diagnosticsArtifactJson,
};
}
return fetch(url);
},
});
const presetEvidenceExpansionSourceFilterMount = presetWorkflowDoc.querySelector(
"[data-workflow-overview-evidence-expansion-family-source-filter]",
);
assertEqual(
presetWorkflowDoc.body.dataset.evidenceExpansionFamilySourceFilterFamily,
"evidence-expansion-family-five-axis-trt",
"workflow overview evidence expansion query preset body family",
);
assertEqual(
presetWorkflowDoc.body.dataset.evidenceExpansionFamilySourceFilterSourceKind,
"gcode",
"workflow overview evidence expansion query preset body source kind",
);
assertEqual(
presetWorkflowDoc.body.dataset.evidenceExpansionFamilySourceFilterCount,
"8",
"workflow overview evidence expansion query preset source count",
);
assertEqual(
presetWorkflowDoc.body.dataset.evidenceExpansionFamilySourceFilterSummary,
"Ready: evidence expansion filter evidence-expansion-family-five-axis-trt / gcode is externally readable",
"workflow overview evidence expansion query preset summary",
);
assertEqual(
presetEvidenceExpansionSourceFilterMount.dataset.selectedFamilyId,
"evidence-expansion-family-five-axis-trt",
"workflow overview evidence expansion query preset mount family",
);
assertEqual(
presetEvidenceExpansionSourceFilterMount.dataset.selectedSourceKind,
"gcode",
"workflow overview evidence expansion query preset mount source kind",
);
assertEqual(
presetReleaseArtifactUrlFormResult.evidenceExpansionFamilySourceFilterSummary.filteredSourceFileCount,
8,
"workflow overview evidence expansion query preset summary source count",
);
assertEqual(
presetReleaseArtifactUrlFormResult.evidenceExpansionFamilySourceFilterActionPlan.baselineChanging,
false,
"workflow overview evidence expansion query preset baseline unchanged",
);
assertEqual( assertEqual(
releaseArtifactJsonWorkflow.statusLine, releaseArtifactJsonWorkflow.statusLine,
"Ready: Artifact JSON workflow complete", "Ready: Artifact JSON workflow complete",

View File

@@ -669,8 +669,8 @@
!diagnosticsArtifact.virtualHalSimConfigSourceCoverage?.sourceFiles?.includes("linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini") || !diagnosticsArtifact.virtualHalSimConfigSourceCoverage?.sourceFiles?.includes("linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini") ||
diagnosticsArtifact.virtualHalSimConfigPromotionCandidates?.complete !== true || diagnosticsArtifact.virtualHalSimConfigPromotionCandidates?.complete !== true ||
diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.complete !== true || diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.complete !== true ||
diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.candidateCount !== 5 || diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.candidateCount !== 11 ||
diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.readyCandidateCount !== 5 || diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.readyCandidateCount !== 11 ||
diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.promotionAllowed !== false || diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.promotionAllowed !== false ||
!diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.rows?.some((row) => !diagnosticsArtifact.virtualHalSimConfigEvidenceExpansion?.rows?.some((row) =>
row.id === "trt-boat-xyzac" && row.id === "trt-boat-xyzac" &&
@@ -699,12 +699,15 @@
doc.body.dataset.promotionCandidateReady !== "true" || doc.body.dataset.promotionCandidateReady !== "true" ||
doc.body.dataset.promotionCandidatePreferred !== "qtdragon-multi-joint-on-abort" || doc.body.dataset.promotionCandidatePreferred !== "qtdragon-multi-joint-on-abort" ||
doc.body.dataset.evidenceExpansionReady !== "true" || doc.body.dataset.evidenceExpansionReady !== "true" ||
doc.body.dataset.evidenceExpansionCount !== "5" || doc.body.dataset.evidenceExpansionCount !== "11" ||
doc.body.dataset.evidenceExpansionReadyCount !== "5" || doc.body.dataset.evidenceExpansionReadyCount !== "11" ||
api.getVirtualHalEvidenceExpansionSummary?.().ready !== true || api.getVirtualHalEvidenceExpansionSummary?.().ready !== true ||
api.getVirtualHalEvidenceExpansionSummary?.().candidateIds?.join(", ") !== "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins" || api.getVirtualHalEvidenceExpansionSummary?.().candidateIds?.join(", ") !== "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins" ||
doc.querySelector('[data-evidence-expansion-summary-value="candidate-count"]')?.textContent !== "5/5 ready" || doc.querySelector('[data-evidence-expansion-summary-value="candidate-count"]')?.textContent !== "11/11 ready" ||
doc.querySelector('[data-evidence-expansion-summary-value="candidate-list"]')?.textContent !== "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins" || doc.querySelector('[data-evidence-expansion-summary-value="candidate-list"]')?.textContent !== "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins" ||
doc.querySelector('[data-evidence-expansion-summary-value="family-count"]')?.textContent !== "3" ||
doc.querySelector('[data-evidence-expansion-summary-value="family-summary"]')?.textContent !== "woodpecker: 1/1 ready; vismach-remap-sims: 2/2 ready; five-axis-trt: 8/8 ready" ||
doc.querySelector('[data-evidence-expansion-summary-value="family-source-count-list"]')?.textContent !== "woodpecker:3, vismach-remap-sims:6, five-axis-trt:12" ||
doc.querySelector('[data-evidence-expansion-summary-value="promotion-allowed"]')?.textContent !== "0 baseline changes" || doc.querySelector('[data-evidence-expansion-summary-value="promotion-allowed"]')?.textContent !== "0 baseline changes" ||
doc.querySelector('[data-evidence-expansion-summary-value="inventory-baseline"]')?.textContent !== "unchanged" || doc.querySelector('[data-evidence-expansion-summary-value="inventory-baseline"]')?.textContent !== "unchanged" ||
doc.querySelector('[data-promotion-candidate-summary-value="preferred-candidate"]')?.textContent !== "qtdragon-multi-joint-on-abort" || doc.querySelector('[data-promotion-candidate-summary-value="preferred-candidate"]')?.textContent !== "qtdragon-multi-joint-on-abort" ||

View File

@@ -79,11 +79,31 @@ for (const phrase of [
"incremental_repetition_g533.ngc", "incremental_repetition_g533.ngc",
"trt-boat-xyzac", "trt-boat-xyzac",
"trt-xyzac-switchkins", "trt-xyzac-switchkins",
"candidateCount=5", "trt-boat-xyzbc",
"readyCandidateCount=5", "trt-impeller-7bl-xyzac",
"trt-xyzac-switchkins-test-1",
"trt-xyzac-switchkins-test-2",
"trt-xyzac-switchkins-test-3",
"trt-xyzbc-switchkins",
"candidateCount=11",
"readyCandidateCount=11",
"real-browser-simulation-evidence-expansion-summary", "real-browser-simulation-evidence-expansion-summary",
"evidence-expansion-full-candidate-list", "evidence-expansion-full-candidate-list",
"evidence-expansion-full-gcode-list", "evidence-expansion-full-gcode-list",
"evidence-expansion-family-count",
"evidence-expansion-family-summary",
"evidence-expansion-family-source-count-list",
"woodpecker: 1/1 ready; sources=3",
"vismach-remap-sims: 2/2 ready; sources=6",
"five-axis-trt: 8/8 ready; sources=12",
"2026-06-20 Evidence Expansion Source Filter",
"getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel",
"renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"21 source files",
"11 evidence-expansion candidate rows",
"evidence-expansion-family-five-axis-trt / gcode => 8 source files, 8 candidates",
"Browser and Node simulation no longer need host `halcmd`, `halrun`, or a", "Browser and Node simulation no longer need host `halcmd`, `halrun`, or a",
"servo-period stepping", "servo-period stepping",
"8 diagnostics-ready candidates across 3 families and 17 source files", "8 diagnostics-ready candidates across 3 families and 17 source files",

View File

@@ -302,11 +302,11 @@ assert.equal(
); );
assert.equal( assert.equal(
readySummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value, readySummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins", "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins",
); );
assert.equal( assert.equal(
readySummary.rows.find(({ id }) => id === "evidence-expansion-full-gcode-list")?.value, readySummary.rows.find(({ id }) => id === "evidence-expansion-full-gcode-list")?.value,
"linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc",
); );
assert.equal( assert.equal(
readySummary.rows.find(({ id }) => id === "evidence-expansion-artifact")?.value, readySummary.rows.find(({ id }) => id === "evidence-expansion-artifact")?.value,
@@ -388,8 +388,14 @@ assert.deepEqual(
["evidence-expansion-candidate-list", "woodpecker-on-abort, puma-cube, melfa-example"], ["evidence-expansion-candidate-list", "woodpecker-on-abort, puma-cube, melfa-example"],
["evidence-expansion-gcode-list", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc"], ["evidence-expansion-gcode-list", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc"],
["evidence-expansion-source-count-list", "3, 3, 3"], ["evidence-expansion-source-count-list", "3, 3, 3"],
["evidence-expansion-full-candidate-list", "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins"], ["evidence-expansion-full-candidate-list", "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins"],
["evidence-expansion-full-gcode-list", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc"], ["evidence-expansion-full-gcode-list", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc"],
["evidence-expansion-family-count", "3 families"],
["evidence-expansion-family-summary", "woodpecker: 1/1 ready; vismach-remap-sims: 2/2 ready; five-axis-trt: 8/8 ready"],
["evidence-expansion-family-source-count-list", "woodpecker:3, vismach-remap-sims:6, five-axis-trt:12"],
["evidence-expansion-family-woodpecker", "1/1 ready; sources=3; diagnostics=ready"],
["evidence-expansion-family-vismach-remap-sims", "2/2 ready; sources=6; diagnostics=ready"],
["evidence-expansion-family-five-axis-trt", "8/8 ready; sources=12; diagnostics=ready"],
["evidence-expansion-artifact", "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv"], ["evidence-expansion-artifact", "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv"],
["promotion-candidate-allowed", "0"], ["promotion-candidate-allowed", "0"],
["hard-block-runtime-locked-rows", "1"], ["hard-block-runtime-locked-rows", "1"],

View File

@@ -563,6 +563,9 @@ assert.deepEqual(
["evidence-expansion-source-count-list", "not provided"], ["evidence-expansion-source-count-list", "not provided"],
["evidence-expansion-full-candidate-list", "not provided"], ["evidence-expansion-full-candidate-list", "not provided"],
["evidence-expansion-full-gcode-list", "not provided"], ["evidence-expansion-full-gcode-list", "not provided"],
["evidence-expansion-family-count", "not provided"],
["evidence-expansion-family-summary", "not provided"],
["evidence-expansion-family-source-count-list", "not provided"],
["evidence-expansion-artifact", "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv"], ["evidence-expansion-artifact", "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv"],
["promotion-candidate-allowed", "0"], ["promotion-candidate-allowed", "0"],
["hard-block-runtime-locked-rows", "0"], ["hard-block-runtime-locked-rows", "0"],

View File

@@ -154,6 +154,17 @@ import {
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness,
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState, renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState, mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness,
@@ -299,6 +310,9 @@ const expectedPromotionCandidateArtifactSummary = {
promotionAllowedCount: 0, promotionAllowedCount: 0,
baselineChanging: false, baselineChanging: false,
nextEvidence: "browser-diagnostics-binding", nextEvidence: "browser-diagnostics-binding",
familyCount: 0,
familySummary: "not provided",
familyRows: [],
}, },
}; };
const hasFreshBoundaryArtifactHashes = (boundaryEvidence) => const hasFreshBoundaryArtifactHashes = (boundaryEvidence) =>
@@ -580,6 +594,50 @@ const requiredExports = [
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan", "createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan,
], ],
[
"createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState",
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
],
[
"createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel",
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
],
[
"createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract",
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
],
[
"createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness",
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
],
[
"createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary",
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
],
[
"createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan",
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
],
[
"createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan",
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
],
[
"handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange",
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
],
[
"bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls",
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
],
[
"renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
],
[
"mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
],
[ [
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel", "createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel",
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
@@ -1084,7 +1142,7 @@ assert.equal(virtualHalRuntime.getSimConfigPromotionCandidateReport({
simConfigSourceCoverage: simConfigSourceCoverageReport, simConfigSourceCoverage: simConfigSourceCoverageReport,
motionControllerMatrix: manifestCheckedMotionControllerMatrixReport, motionControllerMatrix: manifestCheckedMotionControllerMatrixReport,
}).complete, true); }).complete, true);
assert.equal(VIRTUAL_HAL_SIM_CONFIG_EVIDENCE_EXPANSION_CANDIDATES.length, 5); assert.equal(VIRTUAL_HAL_SIM_CONFIG_EVIDENCE_EXPANSION_CANDIDATES.length, 11);
const simConfigEvidenceExpansionReport = createVirtualHalSimConfigEvidenceExpansionReport({ const simConfigEvidenceExpansionReport = createVirtualHalSimConfigEvidenceExpansionReport({
manifestText: sourceManifestText, manifestText: sourceManifestText,
simConfigSourceCoverage: simConfigSourceCoverageReport, simConfigSourceCoverage: simConfigSourceCoverageReport,
@@ -1098,8 +1156,22 @@ assert.equal(simConfigEvidenceExpansionReport.complete, true);
assert.equal(simConfigEvidenceExpansionReport.webSimulationSatisfied, true); assert.equal(simConfigEvidenceExpansionReport.webSimulationSatisfied, true);
assert.equal(simConfigEvidenceExpansionReport.inventoryBaselineUnchanged, true); assert.equal(simConfigEvidenceExpansionReport.inventoryBaselineUnchanged, true);
assert.equal(simConfigEvidenceExpansionReport.promotionAllowed, false); assert.equal(simConfigEvidenceExpansionReport.promotionAllowed, false);
assert.equal(simConfigEvidenceExpansionReport.candidateCount, 5); assert.equal(simConfigEvidenceExpansionReport.candidateCount, 11);
assert.equal(simConfigEvidenceExpansionReport.readyCandidateCount, 5); assert.equal(simConfigEvidenceExpansionReport.readyCandidateCount, 11);
assert.deepEqual(
simConfigEvidenceExpansionReport.familyRows.map(({ id, candidateCount, completeCount, sourceFileCount, complete }) => [
id,
candidateCount,
completeCount,
sourceFileCount,
complete,
]),
[
["woodpecker", 1, 1, 3, true],
["vismach-remap-sims", 2, 2, 6, true],
["five-axis-trt", 8, 8, 12, true],
],
);
assert.equal(simConfigEvidenceExpansionReport.promotionAllowedViolations.length, 0); assert.equal(simConfigEvidenceExpansionReport.promotionAllowedViolations.length, 0);
assert.equal( assert.equal(
simConfigEvidenceExpansionReport.rows.some((row) => simConfigEvidenceExpansionReport.rows.some((row) =>
@@ -1135,6 +1207,25 @@ assert.equal(
), ),
true, true,
); );
for (const [id, gcodePath] of [
["trt-boat-xyzbc", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc"],
["trt-impeller-7bl-xyzac", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc"],
["trt-xyzac-switchkins-test-1", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc"],
["trt-xyzac-switchkins-test-2", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc"],
["trt-xyzac-switchkins-test-3", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc"],
["trt-xyzbc-switchkins", "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc"],
]) {
assert.equal(
simConfigEvidenceExpansionReport.rows.some((row) =>
row.id === id &&
row.currentMatrixBrowserStatus === "REP" &&
row.targetBrowserEvidence === "browser-diagnostics-expansion" &&
row.promotionAllowed === false &&
row.sourceFiles.includes(gcodePath)
),
true,
);
}
assert.equal(VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES.length >= 2, true); 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_BLOCKED_FIXTURES.length >= 2, true);
assert.equal(VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_AUDIT_CANDIDATES.length >= 2, true); assert.equal(VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_AUDIT_CANDIDATES.length >= 2, true);

View File

@@ -87,6 +87,17 @@ import {
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan,
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState, createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel, createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract, createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract,
@@ -793,6 +804,17 @@ assert.deepEqual(shellViewModel.shellWorkflowOverviewContract, {
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan", "getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState", "getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState",
"getWorkflowOverviewPromotionFamilyRowsRenderState", "getWorkflowOverviewPromotionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan",
"handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange",
"bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls",
"renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"getWorkflowOverviewPromotionFamilySourceFilterViewModel", "getWorkflowOverviewPromotionFamilySourceFilterViewModel",
"getWorkflowOverviewPromotionFamilySourceFilterDomContract", "getWorkflowOverviewPromotionFamilySourceFilterDomContract",
"getWorkflowOverviewPromotionFamilySourceFilterDomReadiness", "getWorkflowOverviewPromotionFamilySourceFilterDomReadiness",
@@ -2112,11 +2134,27 @@ assert.equal(
); );
assert.equal( assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value, releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins", "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins, trt-boat-xyzbc, trt-impeller-7bl-xyzac, trt-xyzac-switchkins-test-1, trt-xyzac-switchkins-test-2, trt-xyzac-switchkins-test-3, trt-xyzbc-switchkins",
); );
assert.equal( assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-gcode-list")?.value, releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-gcode-list")?.value,
"linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc", "linuxcnc/configs/sim/woodpecker/on_abort.ngc, linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ngc, linuxcnc/configs/sim/axis/vismach/melfa-sim/example.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc, linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc",
);
assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-family-count")?.value,
"3 families",
);
assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-family-summary")?.value,
"woodpecker: 1/1 ready; vismach-remap-sims: 2/2 ready; five-axis-trt: 8/8 ready",
);
assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-family-source-count-list")?.value,
"woodpecker:3, vismach-remap-sims:6, five-axis-trt:12",
);
assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-family-five-axis-trt")?.value,
"8/8 ready; sources=12; diagnostics=ready",
); );
assert.equal( assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "virtual-hal-promotion-candidate-baseline")?.value, releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "virtual-hal-promotion-candidate-baseline")?.value,
@@ -2694,6 +2732,263 @@ assert.equal(
), ),
true, true,
); );
const evidenceExpansionFamilyRowsRenderState =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(releaseArtifactUrlWorkflowSummary);
const evidenceExpansionFamilySourceFilterViewModel =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(
evidenceExpansionFamilyRowsRenderState,
);
const evidenceExpansionTrtGcodeFilterViewModel =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(
evidenceExpansionFamilyRowsRenderState,
{
familyId: "evidence-expansion-family-five-axis-trt",
sourceKind: "gcode",
},
);
const evidenceExpansionTrtGcodeFilterSummary =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(
evidenceExpansionTrtGcodeFilterViewModel,
);
const evidenceExpansionTrtGcodeFilterActionPlan =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan(
evidenceExpansionTrtGcodeFilterSummary,
);
assert.equal(evidenceExpansionFamilyRowsRenderState.ready, true);
assert.equal(evidenceExpansionFamilyRowsRenderState.statusLine, "Ready: 3 evidence expansion families ready");
assert.equal(evidenceExpansionFamilyRowsRenderState.rows.length, 3);
assert.equal(evidenceExpansionFamilyRowsRenderState.sourceFileCount, 21);
assert.equal(evidenceExpansionFamilyRowsRenderState.candidateCount, 11);
assert.deepEqual(
evidenceExpansionFamilyRowsRenderState.rows.map(({ id, sourceKindSummary }) => [id, sourceKindSummary]),
[
["evidence-expansion-family-woodpecker", "ini=1 gcode=1 source=1"],
["evidence-expansion-family-vismach-remap-sims", "ini=2 gcode=2 remap-subroutine=2"],
["evidence-expansion-family-five-axis-trt", "ini=1 gcode=8 remap-subroutine=3"],
],
);
assert.equal(evidenceExpansionFamilySourceFilterViewModel.ready, true);
assert.equal(evidenceExpansionFamilySourceFilterViewModel.statusLine, "Ready: 21/21 source files selected");
assert.equal(evidenceExpansionFamilySourceFilterViewModel.filteredCandidateCount, 11);
assert.deepEqual(
evidenceExpansionFamilySourceFilterViewModel.familyFilters.map(({ id, count, selected }) => [id, count, selected]),
[
["all", 21, true],
["evidence-expansion-family-woodpecker", 3, false],
["evidence-expansion-family-vismach-remap-sims", 6, false],
["evidence-expansion-family-five-axis-trt", 12, false],
],
);
assert.deepEqual(
evidenceExpansionFamilySourceFilterViewModel.sourceKindFilters.map(({ id, count, selected }) => [id, count, selected]),
[
["all", 21, true],
["ini", 4, false],
["gcode", 11, false],
["remap-subroutine", 5, false],
["source", 1, false],
],
);
assert.equal(evidenceExpansionTrtGcodeFilterViewModel.statusLine, "Ready: 8/21 source files selected");
assert.equal(evidenceExpansionTrtGcodeFilterViewModel.scopedSourceFileCount, 12);
assert.equal(evidenceExpansionTrtGcodeFilterViewModel.filteredSourceFileCount, 8);
assert.equal(evidenceExpansionTrtGcodeFilterViewModel.filteredCandidateCount, 8);
assert.equal(evidenceExpansionTrtGcodeFilterViewModel.familyRows[0]?.sourceKindSummary, "gcode=8");
assert.deepEqual(
{
ready: evidenceExpansionTrtGcodeFilterSummary.ready,
selectedFamilyId: evidenceExpansionTrtGcodeFilterSummary.selectedFamilyId,
selectedSourceKind: evidenceExpansionTrtGcodeFilterSummary.selectedSourceKind,
filteredSourceFileCount: evidenceExpansionTrtGcodeFilterSummary.filteredSourceFileCount,
filteredCandidateCount: evidenceExpansionTrtGcodeFilterSummary.filteredCandidateCount,
totalSourceFileCount: evidenceExpansionTrtGcodeFilterSummary.totalSourceFileCount,
promotionAllowed: evidenceExpansionTrtGcodeFilterActionPlan.promotionAllowed,
baselineChanging: evidenceExpansionTrtGcodeFilterActionPlan.baselineChanging,
nextCommand: evidenceExpansionTrtGcodeFilterActionPlan.nextCommand,
},
{
ready: true,
selectedFamilyId: "evidence-expansion-family-five-axis-trt",
selectedSourceKind: "gcode",
filteredSourceFileCount: 8,
filteredCandidateCount: 8,
totalSourceFileCount: 21,
promotionAllowed: false,
baselineChanging: false,
nextCommand: null,
},
);
assert.equal(
evidenceExpansionTrtGcodeFilterSummary.statusLine,
"Ready: evidence-expansion-family-five-axis-trt / gcode selects 8/21 source files",
);
assert.equal(
evidenceExpansionTrtGcodeFilterActionPlan.statusLine,
"Ready: evidence expansion filter evidence-expansion-family-five-axis-trt / gcode is externally readable",
);
assert.equal(
evidenceExpansionTrtGcodeFilterViewModel.sourceRows.every(({ familyId, sourceKind }) =>
familyId === "evidence-expansion-family-five-axis-trt" &&
sourceKind === "gcode"
),
true,
);
assert.equal(
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract().selectors.mount,
"[data-workflow-overview-evidence-expansion-family-source-filter]",
);
assert.equal(createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness().ready, false);
const evidenceExpansionSourceFilterMountNode = mountDocument.createElement("section");
evidenceExpansionSourceFilterMountNode.dataset.workflowOverviewEvidenceExpansionFamilySourceFilter = "";
const evidenceExpansionSourceFilterStatusNode = mountDocument.createElement("p");
evidenceExpansionSourceFilterStatusNode.dataset.workflowOverviewEvidenceExpansionFamilySourceFilterStatus = "";
const evidenceExpansionSourceFilterControlsNode = {
...mountDocument.createElement("div"),
children: [],
replaceChildren() {
this.children = [];
},
append(...nodes) {
this.children.push(...nodes);
},
};
evidenceExpansionSourceFilterControlsNode.dataset.workflowOverviewEvidenceExpansionFamilySourceFilterControls = "";
const evidenceExpansionSourceFilterRowsNode = {
...mountDocument.createElement("dl"),
children: [],
replaceChildren() {
this.children = [];
},
append(...nodes) {
this.children.push(...nodes);
},
};
evidenceExpansionSourceFilterRowsNode.dataset.workflowOverviewEvidenceExpansionFamilySourceFilterRows = "";
const evidenceExpansionSourceFilterRenderResult =
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(
evidenceExpansionTrtGcodeFilterViewModel,
{
documentRef: mountDocument,
mountNode: evidenceExpansionSourceFilterMountNode,
statusNode: evidenceExpansionSourceFilterStatusNode,
controlsNode: evidenceExpansionSourceFilterControlsNode,
rowsNode: evidenceExpansionSourceFilterRowsNode,
},
);
const evidenceExpansionSourceFilterMountResult =
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState({
viewModel: evidenceExpansionTrtGcodeFilterViewModel,
documentRef: mountDocument,
mountNode: evidenceExpansionSourceFilterMountNode,
statusNode: evidenceExpansionSourceFilterStatusNode,
controlsNode: evidenceExpansionSourceFilterControlsNode,
rowsNode: evidenceExpansionSourceFilterRowsNode,
});
assert.equal(evidenceExpansionSourceFilterRenderResult.rendered, true);
assert.equal(evidenceExpansionSourceFilterRenderResult.statusLine, "Ready: 8/21 source files selected");
assert.equal(evidenceExpansionSourceFilterRenderResult.rowCount, 24);
assert.equal(evidenceExpansionSourceFilterRenderResult.sourceFileCount, 8);
assert.equal(evidenceExpansionSourceFilterRenderResult.candidateCount, 8);
assert.deepEqual(evidenceExpansionSourceFilterRenderResult.dataset, {
handoffPhase: "ready",
handoffReady: "true",
handoffScope: "workflow-overview-evidence-expansion-family-source-filter",
selectedFamilyId: "evidence-expansion-family-five-axis-trt",
selectedSourceKind: "gcode",
});
assert.equal(
evidenceExpansionSourceFilterRowsNode.children.some((node) =>
node.dataset?.workflowOverviewEvidenceExpansionFamilySourceFilterType === "candidate-row" &&
node.dataset?.workflowOverviewEvidenceExpansionFamilySourceFilterFamily ===
"evidence-expansion-family-five-axis-trt" &&
node.dataset?.workflowOverviewEvidenceExpansionFamilySourceFilterCandidateStatus ===
"evidence-expansion-ready" &&
node.dataset?.workflowOverviewEvidenceExpansionFamilySourceFilterPromotionAllowed === "0" &&
node.textContent === "linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzac.ngc"
),
true,
);
assert.equal(evidenceExpansionSourceFilterMountResult.ready, true);
assert.equal(evidenceExpansionSourceFilterMountResult.renderResult.rowCount, 24);
const evidenceExpansionSourceFilterSelectionActionPlan =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan(
evidenceExpansionFamilyRowsRenderState,
{
familyId: "evidence-expansion-family-woodpecker",
sourceKind: "source",
previousViewModel: evidenceExpansionTrtGcodeFilterViewModel,
},
);
assert.equal(evidenceExpansionSourceFilterSelectionActionPlan.ready, true);
assert.equal(evidenceExpansionSourceFilterSelectionActionPlan.changed, true);
assert.equal(
evidenceExpansionSourceFilterSelectionActionPlan.statusLine,
"Ready: evidence expansion source filter changed to evidence-expansion-family-woodpecker / source",
);
assert.equal(evidenceExpansionSourceFilterSelectionActionPlan.nextViewModel.filteredSourceFileCount, 1);
const evidenceExpansionSourceFilterFamilySelect = evidenceExpansionSourceFilterControlsNode.children.find((node) =>
node.dataset?.workflowOverviewEvidenceExpansionFamilySourceFilterSelect === "family"
);
const evidenceExpansionSourceFilterKindSelect = evidenceExpansionSourceFilterControlsNode.children.find((node) =>
node.dataset?.workflowOverviewEvidenceExpansionFamilySourceFilterSelect === "source-kind"
);
evidenceExpansionSourceFilterFamilySelect.value = "evidence-expansion-family-woodpecker";
evidenceExpansionSourceFilterKindSelect.value = "source";
const evidenceExpansionSourceFilterSelectionChange =
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange({
renderState: evidenceExpansionFamilyRowsRenderState,
viewModel: evidenceExpansionTrtGcodeFilterViewModel,
documentRef: mountDocument,
mountNode: evidenceExpansionSourceFilterMountNode,
statusNode: evidenceExpansionSourceFilterStatusNode,
controlsNode: evidenceExpansionSourceFilterControlsNode,
rowsNode: evidenceExpansionSourceFilterRowsNode,
render: true,
});
assert.equal(evidenceExpansionSourceFilterSelectionChange.ready, true);
assert.equal(evidenceExpansionSourceFilterSelectionChange.selectedFamilyId, "evidence-expansion-family-woodpecker");
assert.equal(evidenceExpansionSourceFilterSelectionChange.selectedSourceKind, "source");
assert.equal(evidenceExpansionSourceFilterSelectionChange.renderResult.sourceFileCount, 1);
let evidenceExpansionSourceFilterBindingLastChange = null;
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(
evidenceExpansionTrtGcodeFilterViewModel,
{
documentRef: mountDocument,
mountNode: evidenceExpansionSourceFilterMountNode,
statusNode: evidenceExpansionSourceFilterStatusNode,
controlsNode: evidenceExpansionSourceFilterControlsNode,
rowsNode: evidenceExpansionSourceFilterRowsNode,
},
);
const evidenceExpansionSourceFilterSelectionBinding =
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls({
renderState: evidenceExpansionFamilyRowsRenderState,
viewModel: evidenceExpansionTrtGcodeFilterViewModel,
documentRef: mountDocument,
mountNode: evidenceExpansionSourceFilterMountNode,
statusNode: evidenceExpansionSourceFilterStatusNode,
controlsNode: evidenceExpansionSourceFilterControlsNode,
rowsNode: evidenceExpansionSourceFilterRowsNode,
render: true,
onChange: (changeResult) => {
evidenceExpansionSourceFilterBindingLastChange = changeResult;
},
});
assert.equal(evidenceExpansionSourceFilterSelectionBinding.ready, true);
assert.deepEqual(evidenceExpansionSourceFilterSelectionBinding.controlIds, ["family", "source-kind"]);
const boundEvidenceExpansionFamilySelect = evidenceExpansionSourceFilterControlsNode.children.find((node) =>
node.dataset?.workflowOverviewEvidenceExpansionFamilySourceFilterSelect === "family"
);
const boundEvidenceExpansionKindSelect = evidenceExpansionSourceFilterControlsNode.children.find((node) =>
node.dataset?.workflowOverviewEvidenceExpansionFamilySourceFilterSelect === "source-kind"
);
boundEvidenceExpansionFamilySelect.value = "evidence-expansion-family-woodpecker";
boundEvidenceExpansionKindSelect.value = "source";
const evidenceExpansionSourceFilterBoundChange = boundEvidenceExpansionFamilySelect.dispatchEvent("change");
assert.equal(evidenceExpansionSourceFilterBoundChange.ready, true);
assert.equal(evidenceExpansionSourceFilterBoundChange.selectedFamilyId, "evidence-expansion-family-woodpecker");
assert.equal(evidenceExpansionSourceFilterBindingLastChange.selectedSourceKind, "source");
assert.deepEqual(evidenceExpansionSourceFilterSelectionBinding.unbind(), { unbound: 2 });
assert.equal( assert.equal(
promotionFamilyRowsRenderState.sourceRows.some(({ sourceKind, manifestBacked, status, value }) => promotionFamilyRowsRenderState.sourceRows.some(({ sourceKind, manifestBacked, status, value }) =>
sourceKind === "ini" && sourceKind === "ini" &&
@@ -2866,7 +3161,7 @@ const releaseArtifactUrlWorkflowMountResult =
rowsNode: releaseArtifactUrlWorkflowRowsNode, rowsNode: releaseArtifactUrlWorkflowRowsNode,
}); });
assert.equal(releaseArtifactUrlWorkflowRenderResult.rendered, true); assert.equal(releaseArtifactUrlWorkflowRenderResult.rendered, true);
assert.equal(releaseArtifactUrlWorkflowRenderResult.rowCount, 55); assert.equal(releaseArtifactUrlWorkflowRenderResult.rowCount, 61);
assert.equal( assert.equal(
releaseArtifactUrlWorkflowRenderResult.rowIds.includes("browser-diagnostics"), releaseArtifactUrlWorkflowRenderResult.rowIds.includes("browser-diagnostics"),
true, true,
@@ -2924,7 +3219,7 @@ assert.equal(
true, true,
); );
assert.equal(releaseArtifactUrlWorkflowMountResult.ready, true); assert.equal(releaseArtifactUrlWorkflowMountResult.ready, true);
assert.equal(releaseArtifactUrlWorkflowMountResult.renderResult.rowCount, 55); assert.equal(releaseArtifactUrlWorkflowMountResult.renderResult.rowCount, 61);
const releaseArtifactUrlWorkflowMissingDom = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({ const releaseArtifactUrlWorkflowMissingDom = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({
artifactUrl: "/project-release-readiness.json", artifactUrl: "/project-release-readiness.json",
fetchRef: async () => ({ fetchRef: async () => ({
@@ -2984,6 +3279,34 @@ const workflowOverviewApi = {
getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan: () => releaseArtifactUrlWorkflow.actionPlan, getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan: () => releaseArtifactUrlWorkflow.actionPlan,
getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState: () => releaseArtifactUrlWorkflowRenderState, getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState: () => releaseArtifactUrlWorkflowRenderState,
getWorkflowOverviewPromotionFamilyRowsRenderState: () => promotionFamilyRowsRenderState, getWorkflowOverviewPromotionFamilyRowsRenderState: () => promotionFamilyRowsRenderState,
getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState: () => evidenceExpansionFamilyRowsRenderState,
getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel: () =>
evidenceExpansionFamilySourceFilterViewModel,
getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness: () => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness({
documentRef: mountDocument,
mountNode: evidenceExpansionSourceFilterMountNode,
statusNode: evidenceExpansionSourceFilterStatusNode,
controlsNode: evidenceExpansionSourceFilterControlsNode,
rowsNode: evidenceExpansionSourceFilterRowsNode,
})
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary: () =>
evidenceExpansionTrtGcodeFilterSummary,
getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan: () =>
evidenceExpansionTrtGcodeFilterActionPlan,
getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan: () =>
evidenceExpansionSourceFilterSelectionActionPlan,
handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange: () =>
evidenceExpansionSourceFilterSelectionChange,
bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls: () =>
evidenceExpansionSourceFilterSelectionBinding,
renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState: () =>
evidenceExpansionSourceFilterRenderResult,
mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState: () =>
evidenceExpansionSourceFilterMountResult,
getWorkflowOverviewPromotionFamilySourceFilterViewModel: () => promotionFamilySourceFilterViewModel, getWorkflowOverviewPromotionFamilySourceFilterViewModel: () => promotionFamilySourceFilterViewModel,
getWorkflowOverviewPromotionFamilySourceFilterDomContract: getWorkflowOverviewPromotionFamilySourceFilterDomContract:
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract, createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract,