按接续文件text31持续推进

结论:已将五项evidence expansion从API/smoke推进到real simulation diagnostics panel和release URL/INI workflow完整列表可见面;baseline保持82/82/77/0,promotionAllowed保持false。
This commit is contained in:
2026-06-20 08:26:55 +08:00
parent fab42a8bdb
commit 8a1c4699b1
13 changed files with 265 additions and 4 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: five-axis TRT browser diagnostics evidence expansion - Latest completed batch: evidence expansion UI surface
- 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`. | | 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. |
| 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

@@ -279,3 +279,79 @@ standalone CNC semantics guard complete
- inventoryBaselineUnchanged=true - inventoryBaselineUnchanged=true
- real browser diagnostics artifact smoke 覆盖。 - real browser diagnostics artifact smoke 覆盖。
``` ```
八、本轮接续推进evidence expansion UI surface
执行时间2026-06-20 CST
已完成第七节优先建议中的 UI 可见性推进:
```text
1. real simulation diagnostics panel 显示 evidence expansion ready count
2. real simulation diagnostics panel 显示完整 5 个 ready candidates
3. release artifact URL workflow summary 暴露完整 candidate / G-code list
4. INI workflow overview URL summary 暴露完整 candidate / G-code list
5. 保留原有 preview 的前三项,兼容既有 UI 和测试。
```
新增可见/API 字段:
```text
real-browser-simulation-evidence-expansion-summary
data-evidence-expansion-summary-value="candidate-count" => 5/5 ready
data-evidence-expansion-summary-value="candidate-list" =>
woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins
evidence-expansion-full-candidate-list
evidence-expansion-full-gcode-list
```
边界仍保持:
```text
inventoryBaselineUnchanged=true
promotionAllowed=false
inventory baseline=82/82/77/0
```
本轮已运行验证:
```text
wasm-port/tests/sdk/node/verify_project_release_artifact_url_workflow.sh
wasm-port/tests/sdk/node/verify_project_release_gate_manifest.sh
wasm-port/tests/sdk/node/verify_sdk_surface.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
project_release_artifact_url_workflow_node_smoke=ok
project_release_gate_manifest_node_smoke=ok
sdk_surface_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 family 的 browser diagnostics evidence不改变
`82/82/77/0` baseline。建议下一批新增
```text
axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc
axis/vismach/5axis/table-rotary-tilting/demos/impeller-7bl-xyzac.ngc
axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_1.ngc
axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_2.ngc
axis/vismach/5axis/table-rotary-tilting/demos/xyzac_switchkins_test_3.ngc
axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc
```
每批仍只做 browser diagnostics / release evidence expansion不能改
`promotionAllowed=false`,不能把 SKIP 或 REP 伪装为 inventory baseline
promotion。

View File

@@ -728,6 +728,23 @@ evidence expansion report has `candidateCount=5` and `readyCandidateCount=5`,
including the two TRT rows above. The inventory baseline remains including the two 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
The evidence expansion data is now visible outside the raw diagnostics JSON:
```text
real-browser-simulation-evidence-expansion-summary
evidence-expansion-full-candidate-list
evidence-expansion-full-gcode-list
```
The real simulation diagnostics panel renders `5/5 ready`, the full five-row
candidate list, source-file count, promotion lock state, and unchanged
inventory state. The project release URL workflow summary and INI workflow
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
all five ready evidence-expansion rows without opening the raw artifact.
## Boundary Statement ## Boundary Statement
This analysis relies on the improved virtual HAL only for Web simulation This analysis relies on the improved virtual HAL only for Web simulation

View File

@@ -3225,6 +3225,7 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
); );
const preferredEvidenceExpansion = evidenceExpansionRows[0] ?? {}; const preferredEvidenceExpansion = evidenceExpansionRows[0] ?? {};
const evidenceExpansionPreviewRows = evidenceExpansionRows.slice(0, 3); const evidenceExpansionPreviewRows = evidenceExpansionRows.slice(0, 3);
const evidenceExpansionFullRows = evidenceExpansionRows;
const ready = workflow?.ready === true; const ready = workflow?.ready === true;
const statusText = ready ? "Ready" : "Blocked"; const statusText = ready ? "Ready" : "Blocked";
const detailText = ready const detailText = ready
@@ -3386,6 +3387,20 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
).join(", ") ).join(", ")
: "not provided", : "not provided",
}, },
{
id: "evidence-expansion-full-candidate-list",
label: "Evidence expansion full candidate list",
value: evidenceExpansionFullRows.length > 0
? evidenceExpansionFullRows.map((row) => row.id).join(", ")
: "not provided",
},
{
id: "evidence-expansion-full-gcode-list",
label: "Evidence expansion full G-code list",
value: evidenceExpansionFullRows.length > 0
? evidenceExpansionFullRows.map((row) => row.gcodePath).join(", ")
: "not provided",
},
{ {
id: "evidence-expansion-artifact", id: "evidence-expansion-artifact",
label: "Evidence expansion artifact", label: "Evidence expansion artifact",

View File

@@ -2606,6 +2606,9 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
const evidenceExpansionPreviewRows = Array.isArray(evidenceExpansionRows) const evidenceExpansionPreviewRows = Array.isArray(evidenceExpansionRows)
? evidenceExpansionRows.slice(0, 3) ? evidenceExpansionRows.slice(0, 3)
: []; : [];
const evidenceExpansionFullRows = Array.isArray(evidenceExpansionRows)
? evidenceExpansionRows
: [];
const ready = workflow?.ready === true; const ready = workflow?.ready === true;
const promotionFamilyRows = ( const promotionFamilyRows = (
workflow?.validation?.virtualHalPromotionFamilyRows workflow?.validation?.virtualHalPromotionFamilyRows
@@ -2800,6 +2803,20 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
).join(", ") ).join(", ")
: "not provided", : "not provided",
}, },
{
id: "evidence-expansion-full-candidate-list",
label: "Evidence expansion full candidate list",
value: evidenceExpansionFullRows.length > 0
? evidenceExpansionFullRows.map((row) => row.id).join(", ")
: "not provided",
},
{
id: "evidence-expansion-full-gcode-list",
label: "Evidence expansion full G-code list",
value: evidenceExpansionFullRows.length > 0
? evidenceExpansionFullRows.map((row) => row.gcodePath).join(", ")
: "not provided",
},
{ {
id: "hard-block-runtime-lock", id: "hard-block-runtime-lock",
label: "Hard-block runtime lock", label: "Hard-block runtime lock",

View File

@@ -1757,6 +1757,7 @@ M2
<div><span>Shortcut</span><strong data-diagnostics="shortcut">-</strong></div> <div><span>Shortcut</span><strong data-diagnostics="shortcut">-</strong></div>
<div class="promotion-family-panel" data-promotion-family-rows></div> <div class="promotion-family-panel" data-promotion-family-rows></div>
<div class="promotion-candidate-panel" data-promotion-candidate-summary></div> <div class="promotion-candidate-panel" data-promotion-candidate-summary></div>
<div class="promotion-candidate-panel" data-evidence-expansion-summary></div>
<div class="tool-table-mini" data-axis-shell="tool-table"> <div class="tool-table-mini" data-axis-shell="tool-table">
<table aria-label="Loaded tool table"> <table aria-label="Loaded tool table">
<thead> <thead>
@@ -2788,6 +2789,67 @@ M2
return summary; return summary;
} }
function createVirtualHalEvidenceExpansionSummary(
report = createVirtualHalSimConfigEvidenceExpansionReport(),
) {
const rows = Array.isArray(report.rows) ? report.rows : [];
const readyRows = rows.filter((row) => row.complete === true);
const blockedRows = rows.filter((row) => row.complete !== true);
const promotionAllowedRows = rows.filter((row) => row.promotionAllowed === true);
const preferredRow = rows[0] ?? null;
const ready = report.complete === true &&
report.inventoryBaselineUnchanged === true &&
report.promotionAllowed === false &&
readyRows.length === rows.length &&
blockedRows.length === 0 &&
promotionAllowedRows.length === 0;
return {
apiName: "real-browser-simulation-evidence-expansion-summary",
summaryVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
candidateCount: rows.length,
readyCandidateCount: readyRows.length,
preferredCandidateId: preferredRow?.id ?? null,
candidateIds: rows.map((row) => row.id),
gcodePaths: rows.map((row) => row.gcodePath),
sourceFileCount: new Set(rows.flatMap((row) => row.sourceFiles ?? [])).size,
promotionAllowedCount: promotionAllowedRows.length,
inventoryBaselineUnchanged: report.inventoryBaselineUnchanged === true,
rows: [
{ id: "candidate-count", label: "Expansion", value: `${readyRows.length}/${rows.length} ready` },
{ id: "preferred-candidate", label: "First case", value: preferredRow?.id ?? "missing" },
{ id: "candidate-list", label: "Cases", value: rows.map((row) => row.id).join(", ") || "missing" },
{ 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: "inventory-baseline", label: "Inventory", value: report.inventoryBaselineUnchanged === true ? "unchanged" : "changing" },
],
};
}
function renderEvidenceExpansionSummary(summary = createVirtualHalEvidenceExpansionSummary()) {
const container = document.querySelector("[data-evidence-expansion-summary]");
if (!container) {
return summary;
}
container.textContent = "";
document.body.dataset.evidenceExpansionReady = summary.ready ? "true" : "false";
document.body.dataset.evidenceExpansionCount = String(summary.candidateCount);
document.body.dataset.evidenceExpansionReadyCount = String(summary.readyCandidateCount);
for (const row of summary.rows) {
const item = document.createElement("div");
item.dataset.evidenceExpansionSummaryRow = row.id;
const label = document.createElement("span");
label.textContent = row.label;
const value = document.createElement("strong");
value.dataset.evidenceExpansionSummaryValue = row.id;
value.textContent = row.value;
item.append(label, value);
container.append(item);
}
return summary;
}
function renderMachineStatusDom(machineStatus) { function renderMachineStatusDom(machineStatus) {
const statusMap = { const statusMap = {
"spindle-state": machineStatus.spindle.state, "spindle-state": machineStatus.spindle.state,
@@ -2828,8 +2890,10 @@ M2
renderLimitsHomeState(createVirtualHalLimitsHomeState()); renderLimitsHomeState(createVirtualHalLimitsHomeState());
renderMillturnUserMProcessState(); renderMillturnUserMProcessState();
const promotionCandidateReport = createVirtualHalSimConfigPromotionCandidateReport(); const promotionCandidateReport = createVirtualHalSimConfigPromotionCandidateReport();
const evidenceExpansionReport = createVirtualHalSimConfigEvidenceExpansionReport();
renderPromotionFamilyRows(promotionCandidateReport); renderPromotionFamilyRows(promotionCandidateReport);
renderPromotionCandidateSummary(createVirtualHalPromotionCandidateSummary(promotionCandidateReport)); renderPromotionCandidateSummary(createVirtualHalPromotionCandidateSummary(promotionCandidateReport));
renderEvidenceExpansionSummary(createVirtualHalEvidenceExpansionSummary(evidenceExpansionReport));
document.querySelector("[data-axis-machine-control-state]")?.setAttribute("data-state", "ready"); document.querySelector("[data-axis-machine-control-state]")?.setAttribute("data-state", "ready");
return cloneVirtualHalState(); return cloneVirtualHalState();
} }
@@ -4333,6 +4397,7 @@ M2
getVirtualHalSimConfigSourceCoverageReport: () => createVirtualHalSimConfigSourceCoverageReport(), getVirtualHalSimConfigSourceCoverageReport: () => createVirtualHalSimConfigSourceCoverageReport(),
getVirtualHalSimConfigPromotionCandidateReport: () => createVirtualHalSimConfigPromotionCandidateReport(), getVirtualHalSimConfigPromotionCandidateReport: () => createVirtualHalSimConfigPromotionCandidateReport(),
getVirtualHalSimConfigEvidenceExpansionReport: () => createVirtualHalSimConfigEvidenceExpansionReport(), getVirtualHalSimConfigEvidenceExpansionReport: () => createVirtualHalSimConfigEvidenceExpansionReport(),
getVirtualHalEvidenceExpansionSummary: () => renderEvidenceExpansionSummary(),
getVirtualHalPromotionCandidateSummary: () => renderPromotionCandidateSummary(), getVirtualHalPromotionCandidateSummary: () => renderPromotionCandidateSummary(),
getVirtualHalPromotionFamilyRows: () => renderPromotionFamilyRows(), getVirtualHalPromotionFamilyRows: () => renderPromotionFamilyRows(),
getVirtualHalSimConfigMacroLoadFixtureReport: () => createVirtualHalSimConfigMacroLoadFixtureReport(), getVirtualHalSimConfigMacroLoadFixtureReport: () => createVirtualHalSimConfigMacroLoadFixtureReport(),

View File

@@ -1039,6 +1039,16 @@ TOOL_TABLE = browser-shell-tool.tbl
"3, 3, 3", "3, 3, 3",
"shell workflow overview release artifact URL workflow evidence expansion source count list", "shell workflow overview release artifact URL workflow evidence expansion source count list",
); );
assertEqual(
workflowOverviewReleaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins",
"shell workflow overview release artifact URL workflow evidence expansion full candidate list",
);
assertEqual(
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",
"shell workflow overview release artifact URL workflow evidence expansion full gcode list",
);
assertEqual( assertEqual(
workflowOverviewReleaseArtifactUrlWorkflowRenderResult.rowIds.includes("hard-block-runtime-lock"), workflowOverviewReleaseArtifactUrlWorkflowRenderResult.rowIds.includes("hard-block-runtime-lock"),
true, true,

View File

@@ -739,6 +739,16 @@
"3, 3, 3", "3, 3, 3",
"workflow overview release artifact URL workflow evidence expansion source count list", "workflow overview release artifact URL workflow evidence expansion source count list",
); );
assertEqual(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins",
"workflow overview release artifact URL workflow evidence expansion full candidate list",
);
assertEqual(
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",
"workflow overview release artifact URL workflow evidence expansion full gcode list",
);
assertEqual( assertEqual(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-artifact")?.value, releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-artifact")?.value,
"wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv", "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv",
@@ -1030,6 +1040,16 @@
"3, 3, 3", "3, 3, 3",
"workflow overview fixed URL workflow form evidence expansion source count list row", "workflow overview fixed URL workflow form evidence expansion source count list row",
); );
assertEqual(
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",
"workflow overview fixed URL workflow form evidence expansion full candidate list row",
);
assertEqual(
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",
"workflow overview fixed URL workflow form evidence expansion full gcode list 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",

View File

@@ -698,6 +698,15 @@
promotionCandidateSummary.preferredIniPath !== "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini" || promotionCandidateSummary.preferredIniPath !== "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini" ||
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.evidenceExpansionCount !== "5" ||
doc.body.dataset.evidenceExpansionReadyCount !== "5" ||
api.getVirtualHalEvidenceExpansionSummary?.().ready !== true ||
api.getVirtualHalEvidenceExpansionSummary?.().candidateIds?.join(", ") !== "woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins" ||
doc.querySelector('[data-evidence-expansion-summary-value="candidate-count"]')?.textContent !== "5/5 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="promotion-allowed"]')?.textContent !== "0 baseline changes" ||
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" ||
doc.querySelector('[data-promotion-candidate-summary-value="candidate-layers"]')?.textContent !== "evidence-ready=8 inventory-ready=2" || doc.querySelector('[data-promotion-candidate-summary-value="candidate-layers"]')?.textContent !== "evidence-ready=8 inventory-ready=2" ||
doc.querySelector('[data-promotion-candidate-summary-value="inventory-baseline"]')?.textContent !== "82/82 pass; 77 skip" || doc.querySelector('[data-promotion-candidate-summary-value="inventory-baseline"]')?.textContent !== "82/82 pass; 77 skip" ||

View File

@@ -72,6 +72,7 @@ for (const phrase of [
"Web Simulation Improvements From Virtual HAL", "Web Simulation Improvements From Virtual HAL",
"2026-06-20 Remaining Skip Promotion Audit", "2026-06-20 Remaining Skip Promotion Audit",
"2026-06-20 Five-Axis TRT Evidence Expansion", "2026-06-20 Five-Axis TRT Evidence Expansion",
"2026-06-20 Evidence Expansion UI Surface",
"remaining_skipped_main_program_promotion_allowed=0", "remaining_skipped_main_program_promotion_allowed=0",
"direct_inventory_promotion_rows=0", "direct_inventory_promotion_rows=0",
"axis/vismach/millturn/example.ngc", "axis/vismach/millturn/example.ngc",
@@ -80,6 +81,9 @@ for (const phrase of [
"trt-xyzac-switchkins", "trt-xyzac-switchkins",
"candidateCount=5", "candidateCount=5",
"readyCandidateCount=5", "readyCandidateCount=5",
"real-browser-simulation-evidence-expansion-summary",
"evidence-expansion-full-candidate-list",
"evidence-expansion-full-gcode-list",
"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

@@ -300,6 +300,14 @@ assert.equal(
readySummary.rows.find(({ id }) => id === "evidence-expansion-source-count-list")?.value, readySummary.rows.find(({ id }) => id === "evidence-expansion-source-count-list")?.value,
"3, 3, 3", "3, 3, 3",
); );
assert.equal(
readySummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins",
);
assert.equal(
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",
);
assert.equal( assert.equal(
readySummary.rows.find(({ id }) => id === "evidence-expansion-artifact")?.value, readySummary.rows.find(({ id }) => id === "evidence-expansion-artifact")?.value,
"wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv", "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv",
@@ -380,6 +388,8 @@ 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-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-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

@@ -561,6 +561,8 @@ assert.deepEqual(
["evidence-expansion-candidate-list", "not provided"], ["evidence-expansion-candidate-list", "not provided"],
["evidence-expansion-gcode-list", "not provided"], ["evidence-expansion-gcode-list", "not provided"],
["evidence-expansion-source-count-list", "not provided"], ["evidence-expansion-source-count-list", "not provided"],
["evidence-expansion-full-candidate-list", "not provided"],
["evidence-expansion-full-gcode-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

@@ -2110,6 +2110,14 @@ assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-source-count-list")?.value, releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-source-count-list")?.value,
"3, 3, 3", "3, 3, 3",
); );
assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "evidence-expansion-full-candidate-list")?.value,
"woodpecker-on-abort, puma-cube, melfa-example, trt-boat-xyzac, trt-xyzac-switchkins",
);
assert.equal(
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",
);
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,
"executed=82 passed=82 skipped=77 unexpected_fail=0", "executed=82 passed=82 skipped=77 unexpected_fail=0",
@@ -2858,7 +2866,7 @@ const releaseArtifactUrlWorkflowMountResult =
rowsNode: releaseArtifactUrlWorkflowRowsNode, rowsNode: releaseArtifactUrlWorkflowRowsNode,
}); });
assert.equal(releaseArtifactUrlWorkflowRenderResult.rendered, true); assert.equal(releaseArtifactUrlWorkflowRenderResult.rendered, true);
assert.equal(releaseArtifactUrlWorkflowRenderResult.rowCount, 53); assert.equal(releaseArtifactUrlWorkflowRenderResult.rowCount, 55);
assert.equal( assert.equal(
releaseArtifactUrlWorkflowRenderResult.rowIds.includes("browser-diagnostics"), releaseArtifactUrlWorkflowRenderResult.rowIds.includes("browser-diagnostics"),
true, true,
@@ -2903,12 +2911,20 @@ assert.equal(
releaseArtifactUrlWorkflowRenderResult.rowIds.includes("evidence-expansion-source-count-list"), releaseArtifactUrlWorkflowRenderResult.rowIds.includes("evidence-expansion-source-count-list"),
true, true,
); );
assert.equal(
releaseArtifactUrlWorkflowRenderResult.rowIds.includes("evidence-expansion-full-candidate-list"),
true,
);
assert.equal(
releaseArtifactUrlWorkflowRenderResult.rowIds.includes("evidence-expansion-full-gcode-list"),
true,
);
assert.equal( assert.equal(
releaseArtifactUrlWorkflowRenderResult.rowIds.includes("mount-result"), releaseArtifactUrlWorkflowRenderResult.rowIds.includes("mount-result"),
true, true,
); );
assert.equal(releaseArtifactUrlWorkflowMountResult.ready, true); assert.equal(releaseArtifactUrlWorkflowMountResult.ready, true);
assert.equal(releaseArtifactUrlWorkflowMountResult.renderResult.rowCount, 53); assert.equal(releaseArtifactUrlWorkflowMountResult.renderResult.rowCount, 55);
const releaseArtifactUrlWorkflowMissingDom = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({ const releaseArtifactUrlWorkflowMissingDom = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({
artifactUrl: "/project-release-readiness.json", artifactUrl: "/project-release-readiness.json",
fetchRef: async () => ({ fetchRef: async () => ({