展开promotion证据行

结论:workflow overview promotion candidate drilldown 现在展示8条evidence-ready候选的family、G-code path、source count和manifest-backed状态,hard block仍保持locked,baseline保持28/28/131/0。
This commit is contained in:
2026-06-18 19:41:40 +08:00
parent 9ce8ad6f12
commit 31c83db696
2 changed files with 77 additions and 3 deletions

View File

@@ -3990,6 +3990,20 @@ export function createIniPanelShellWorkflowOverviewPromotionCandidateDrilldownVi
sourceKind: classifyPromotionFamilySource(sourceFile),
manifestBacked: candidate?.manifestChecked === true,
}));
const evidenceRows = candidateRows.map((row, index) => ({
id: `evidence-${index + 1}`,
label: row.id ?? `Evidence ${index + 1}`,
value: row.gcodePath ?? "not provided",
familyId: row.simConfigTarget ?? "not provided",
sourceFileCount: Array.isArray(row.sourceFiles) ? row.sourceFiles.length : 0,
manifestBacked: row.manifestChecked === true,
status: row.complete === true &&
row.currentNodeInventoryStatus === "PASS" &&
row.blockedKind === "-" &&
row.targetBrowserEvidence === "explicit-browser-diagnostics"
? "evidence-ready"
: "blocked",
}));
return {
apiName: "ini-panel-shell-workflow-overview-promotion-candidate-drilldown-view-model",
viewModelVersion: 1,
@@ -4005,7 +4019,9 @@ export function createIniPanelShellWorkflowOverviewPromotionCandidateDrilldownVi
candidate,
rows,
sourceRows,
evidenceRows,
sourceFileCount: sourceRows.length,
evidenceRowCount: evidenceRows.length,
requiredReports,
blockedFamilyExcluded,
nodeInventoryReady,
@@ -4029,11 +4045,19 @@ export function createIniPanelShellWorkflowOverviewPromotionCandidateDrilldownRe
...row,
label: `${row.label} (${row.sourceKind})`,
})),
].map(({ id, label, value, sourceKind, manifestBacked }) => ({
...(Array.isArray(viewModel?.evidenceRows) ? viewModel.evidenceRows : []).map((row) => ({
...row,
label: `${row.label} (${row.familyId})`,
evidenceReady: row.status === "evidence-ready",
})),
].map(({ id, label, value, sourceKind, manifestBacked, familyId, sourceFileCount, evidenceReady }) => ({
id,
label,
value: value == null ? "" : String(value),
...(sourceKind ? { sourceKind } : {}),
...(familyId ? { familyId } : {}),
...(sourceFileCount != null ? { sourceFileCount: Number(sourceFileCount) } : {}),
...(evidenceReady != null ? { evidenceReady: evidenceReady === true } : {}),
...(manifestBacked != null ? { manifestBacked: manifestBacked === true } : {}),
}));
const ready = viewModel?.ready === true;
@@ -4050,6 +4074,7 @@ export function createIniPanelShellWorkflowOverviewPromotionCandidateDrilldownRe
rows,
rowCount: rows.length,
sourceFileCount: viewModel?.sourceFileCount ?? 0,
evidenceRowCount: viewModel?.evidenceRowCount ?? 0,
dataset: viewModel?.dataset ?? {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
@@ -4154,6 +4179,12 @@ export function renderIniPanelShellWorkflowOverviewPromotionCandidateDrilldownSt
term.dataset[`${effectiveRowDatasetPrefix}SourceKind`] = row.sourceKind;
term.dataset[`${effectiveRowDatasetPrefix}ManifestBacked`] = row.manifestBacked ? "true" : "false";
}
if (row.familyId) {
term.dataset[`${effectiveRowDatasetPrefix}FamilyId`] = row.familyId;
term.dataset[`${effectiveRowDatasetPrefix}EvidenceReady`] = row.evidenceReady ? "true" : "false";
term.dataset[`${effectiveRowDatasetPrefix}SourceFileCount`] = String(row.sourceFileCount ?? 0);
term.dataset[`${effectiveRowDatasetPrefix}ManifestBacked`] = row.manifestBacked ? "true" : "false";
}
term.textContent = row.label;
const detail = documentRef.createElement("dd");
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
@@ -4162,6 +4193,12 @@ export function renderIniPanelShellWorkflowOverviewPromotionCandidateDrilldownSt
detail.dataset[`${effectiveRowDatasetPrefix}SourceKind`] = row.sourceKind;
detail.dataset[`${effectiveRowDatasetPrefix}ManifestBacked`] = row.manifestBacked ? "true" : "false";
}
if (row.familyId) {
detail.dataset[`${effectiveRowDatasetPrefix}FamilyId`] = row.familyId;
detail.dataset[`${effectiveRowDatasetPrefix}EvidenceReady`] = row.evidenceReady ? "true" : "false";
detail.dataset[`${effectiveRowDatasetPrefix}SourceFileCount`] = String(row.sourceFileCount ?? 0);
detail.dataset[`${effectiveRowDatasetPrefix}ManifestBacked`] = row.manifestBacked ? "true" : "false";
}
detail.textContent = row.value;
rowsNode.append(term, detail);
}
@@ -4171,6 +4208,7 @@ export function renderIniPanelShellWorkflowOverviewPromotionCandidateDrilldownSt
rowCount: rows.length,
rowIds: rows.map(({ id }) => id),
sourceFileCount: rows.filter(({ sourceKind }) => Boolean(sourceKind)).length,
evidenceRowCount: rows.filter(({ familyId }) => Boolean(familyId)).length,
dataset: {
handoffPhase: mountNode.dataset.handoffPhase,
handoffReady: mountNode.dataset.handoffReady,

View File

@@ -10,6 +10,7 @@ import {
createVirtualHalCommandScriptFixtureReport,
createVirtualHalMotionControllerMatrixReport,
createVirtualHalSimConfigMacroLoadFixtureReport,
createVirtualHalSimConfigEvidenceExpansionReport,
createVirtualHalSimConfigPromotionCandidateReport,
createVirtualHalSimConfigSourceCoverageReport,
createVirtualHalSimulationReplacementReport,
@@ -1431,6 +1432,13 @@ const releaseReadinessPromotionCandidates = createVirtualHalSimConfigPromotionCa
],
motionControllerMatrix: releaseReadinessMotionControllerMatrix,
});
const releaseReadinessEvidenceExpansion = createVirtualHalSimConfigEvidenceExpansionReport({
manifestEntries: [
...VIRTUAL_HAL_MOTION_MATRIX_MANIFEST_ENTRIES,
"linuxcnc/configs/sim/axis/vismach/puma/puma_cube.ini",
],
motionControllerMatrix: releaseReadinessMotionControllerMatrix,
});
const releaseReadinessMacroLoadFixtures = createVirtualHalSimConfigMacroLoadFixtureReport({
manifestEntries: [
...VIRTUAL_HAL_MOTION_MATRIX_MANIFEST_ENTRIES,
@@ -1445,6 +1453,7 @@ const releaseReadinessArtifactJson = JSON.stringify(createProjectReleaseReadines
gateResults: Object.fromEntries(createProjectReleaseGateManifest().gateIds.map((id) => [id, true])),
virtualHalSimConfigSourceCoverage: createVirtualHalSimConfigSourceCoverageReport(),
virtualHalSimConfigPromotionCandidates: releaseReadinessPromotionCandidates,
virtualHalSimConfigEvidenceExpansion: releaseReadinessEvidenceExpansion,
virtualHalSimConfigMacroLoadFixtures: releaseReadinessMacroLoadFixtures,
virtualHalMotionControllerMatrix: releaseReadinessMotionControllerMatrix,
}));
@@ -1457,6 +1466,7 @@ const browserDiagnosticsArtifact = {
virtualHalSourceCompliance: createVirtualHalSourceComplianceReport({ halState: browserDiagnosticsVirtualHalState }),
virtualHalSimConfigSourceCoverage: createVirtualHalSimConfigSourceCoverageReport(),
virtualHalSimConfigPromotionCandidates: releaseReadinessPromotionCandidates,
virtualHalSimConfigEvidenceExpansion: releaseReadinessEvidenceExpansion,
virtualHalPromotionCandidateSummary: {
apiName: "real-browser-simulation-promotion-candidate-summary",
summaryVersion: 1,
@@ -2013,6 +2023,22 @@ assert.equal(
"passed",
);
assert.equal(promotionCandidateDrilldownViewModel.sourceFileCount, 2);
assert.equal(promotionCandidateDrilldownViewModel.evidenceRowCount, 8);
assert.equal(
promotionCandidateDrilldownViewModel.evidenceRows.every(({ status, manifestBacked }) =>
status === "evidence-ready" && manifestBacked === true
),
true,
);
assert.equal(
promotionCandidateDrilldownViewModel.evidenceRows.some(({ label, value, familyId, sourceFileCount }) =>
label === "puma-seam-weld" &&
value === "linuxcnc/configs/sim/axis/vismach/puma/puma_seam_weld.ngc" &&
familyId === "vismach-remap-sims" &&
sourceFileCount === 3
),
true,
);
assert.deepEqual(
promotionCandidateDrilldownViewModel.sourceRows.map(({ value, sourceKind, manifestBacked }) => [
value,
@@ -2025,8 +2051,9 @@ assert.deepEqual(
],
);
assert.equal(promotionCandidateDrilldownRenderState.ready, true);
assert.equal(promotionCandidateDrilldownRenderState.rowCount, 11);
assert.equal(promotionCandidateDrilldownRenderState.rowCount, 19);
assert.equal(promotionCandidateDrilldownRenderState.sourceFileCount, 2);
assert.equal(promotionCandidateDrilldownRenderState.evidenceRowCount, 8);
assert.equal(
createIniPanelShellWorkflowOverviewPromotionCandidateDrilldownDomContract().selectors.mount,
"[data-workflow-overview-promotion-candidate-drilldown]",
@@ -2066,7 +2093,8 @@ const promotionCandidateDrilldownMountResult =
rowsNode: promotionCandidateDrilldownRowsNode,
});
assert.equal(promotionCandidateDrilldownRenderResult.rendered, true);
assert.equal(promotionCandidateDrilldownRenderResult.rowCount, 11);
assert.equal(promotionCandidateDrilldownRenderResult.rowCount, 19);
assert.equal(promotionCandidateDrilldownRenderResult.evidenceRowCount, 8);
assert.deepEqual(promotionCandidateDrilldownRenderResult.dataset, {
handoffPhase: "ready",
handoffReady: "true",
@@ -2082,8 +2110,16 @@ assert.equal(promotionCandidateDrilldownRowsNode.children.some((node) =>
node.dataset?.workflowOverviewPromotionCandidateDrilldownManifestBacked === "true" &&
node.textContent === "linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc"
), true);
assert.equal(promotionCandidateDrilldownRowsNode.children.some((node) =>
node.dataset?.workflowOverviewPromotionCandidateDrilldownValue === "evidence-7" &&
node.dataset?.workflowOverviewPromotionCandidateDrilldownFamilyId === "vismach-remap-sims" &&
node.dataset?.workflowOverviewPromotionCandidateDrilldownEvidenceReady === "true" &&
node.dataset?.workflowOverviewPromotionCandidateDrilldownSourceFileCount === "3" &&
node.textContent === "linuxcnc/configs/sim/axis/vismach/puma/puma_seam_weld.ngc"
), true);
assert.equal(promotionCandidateDrilldownMountResult.ready, true);
assert.equal(promotionCandidateDrilldownMountResult.renderResult.sourceFileCount, 2);
assert.equal(promotionCandidateDrilldownMountResult.renderResult.evidenceRowCount, 8);
assert.equal(
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "virtual-hal-promotion-families")?.value,
expectedPromotionFamilySummary,