From 51ae5d9a9a14cd80f1042a2e07f230f46bcd2e3c Mon Sep 17 00:00:00 2001 From: wangdequan Date: Fri, 19 Jun 2026 16:01:07 +0800 Subject: [PATCH] =?UTF-8?q?L4-TOOL-DB=E6=8E=A5=E5=85=A5=E6=95=B0=E6=8E=A7?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E4=BB=BF=E7=9C=9F=E8=AF=81=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 结论:L4-TOOL-DB 已接入浏览器/WASM/OPFS 仿真证明链,并纳入 release/host gate;axis/db_demo/base.ngc 仍保持 L4-TOOL-DB locked,promotion_allowed=0,sim-config baseline 保持 28/28/131/0。 --- .../sdk/src/project-release-readiness.js | 136 ++++++++++++++++++ .../sdk/src/tool-db-browser-worker-adapter.js | 8 +- .../runtime/workers/tool-db-python-worker.js | 37 ++++- .../ini_panel_workflow_overview_smoke.html | 2 +- .../tool_db_fake_python_runtime_worker.js | 2 - .../tool_db_process_browser_smoke.html | 21 ++- .../tool_db_python_runtime_module_worker.js | 1 + wasm-port/tests/host/verify_host_smokes.sh | 1 + .../host/verify_tool_db_process_proof.sh | 11 ++ ..._project_release_artifact_url_workflow.mjs | 2 + .../verify_project_release_gate_manifest.mjs | 58 +++++--- .../tests/sdk/node/verify_sdk_surface.mjs | 39 +++++ .../sdk/node/verify_tool_db_process_port.mjs | 8 +- .../ui/node/verify_ini_panel_ui_shell.mjs | 22 +-- 14 files changed, 311 insertions(+), 37 deletions(-) create mode 100644 wasm-port/tests/browser/tool_db_python_runtime_module_worker.js create mode 100755 wasm-port/tests/host/verify_tool_db_process_proof.sh diff --git a/wasm-port/runtime/sdk/src/project-release-readiness.js b/wasm-port/runtime/sdk/src/project-release-readiness.js index 35e51ad..d8124cf 100644 --- a/wasm-port/runtime/sdk/src/project-release-readiness.js +++ b/wasm-port/runtime/sdk/src/project-release-readiness.js @@ -40,6 +40,12 @@ const REQUIRED_RELEASE_GATES = [ command: "SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_opfs_session_workflow_browser.sh", expectedOutput: "browser_opfs_session_workflow_smoke=ok", }, + { + id: "tool-db-process-proof", + label: "Tool DB process protocol proof", + command: "wasm-port/tests/host/verify_tool_db_process_proof.sh", + expectedOutput: "tool_db_process_proof=ok", + }, { id: "release-artifact-url-browser", label: "Release artifact URL browser workflow smoke", @@ -276,6 +282,46 @@ function createHardBlockRuntimeLockSummary(blockedFamilies = [], promotedBlocked }; } +function createToolDbProcessProofSummary(toolDbProcessProof = {}) { + const proof = objectOrEmpty(toolDbProcessProof); + const nativeProtocolReady = proof.nativeProtocolReady === true; + const wasmProtocolReady = proof.wasmProtocolReady !== false; + const browserProtocolReady = proof.browserProtocolReady !== false; + const opfsPersistenceReady = proof.opfsPersistenceReady !== false; + const tblFallbackSufficient = proof.tblFallbackSufficient === true; + const promotionAllowed = proof.promotionAllowed === true; + const ready = wasmProtocolReady && + browserProtocolReady && + opfsPersistenceReady && + tblFallbackSufficient === false && + promotionAllowed === false; + + return { + apiName: "tool-db-process-proof-summary", + summaryVersion: 1, + phase: ready ? "ready" : "blocked", + ready, + boundaryClass: "L4-TOOL-DB", + path: proof.path ?? "axis/db_demo/base.ngc", + dbProgramPath: proof.dbProgramPath ?? "./db_nonran.py", + runtimeMode: proof.runtimeMode ?? "browser-python-wasm-worker", + nativeProtocolReady, + nativeRuntimeRequiredForPromotion: true, + wasmProtocolReady, + browserProtocolReady, + opfsPersistenceReady, + tblFallbackSufficient, + promotionAllowed, + executionEnabled: proof.executionEnabled === true, + requiredCommands: [ + "wasm-port/tests/sdk/node/verify_tool_db_process_port.sh", + "wasm-port/tests/opfs/node/verify_tool_db_store.sh", + "wasm-port/tests/wasm/node/verify_tool_db_process_port_wasm.sh", + "SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_tool_db_process_browser.sh", + ], + }; +} + const BLOCKED_RUNTIME_FAMILIES = [ "L4-USER-M-PROCESS", "L4-TOOL-DB", @@ -2023,6 +2069,7 @@ export function createProjectReleaseReadinessReport({ evidenceExpansionRows = [], virtualHalSimConfigMacroLoadFixtures = null, virtualHalMotionControllerMatrix = null, + toolDbProcessProof = {}, blockedRuntimeFamilies = BLOCKED_RUNTIME_FAMILIES, promotedRuntimeFamilies = [], axisScreenshotArtifacts = [], @@ -2082,12 +2129,15 @@ export function createProjectReleaseReadinessReport({ }); const axisScreenshotArtifactSummary = createAxisScreenshotArtifactSummary(axisScreenshotArtifacts); const axisScreenshotArtifactsReady = axisScreenshotArtifactSummary.ready; + const toolDbProcessProofSummary = createToolDbProcessProofSummary(toolDbProcessProof); + const toolDbProcessProofReady = toolDbProcessProofSummary.ready; const ready = releaseGatePassed && inventoryReady && virtualHalSimConfigSourceCoverageReady && virtualHalSimConfigPromotionCandidatesReady && virtualHalSimConfigMacroLoadFixturesReady && virtualHalMotionControllerMatrixReady && + toolDbProcessProofReady && blockedRuntimeReady && axisScreenshotArtifactsReady; const missing = [ @@ -2097,6 +2147,7 @@ export function createProjectReleaseReadinessReport({ ...(virtualHalSimConfigPromotionCandidatesReady ? [] : ["virtual-hal-sim-config-promotion-candidates"]), ...(virtualHalSimConfigMacroLoadFixturesReady ? [] : ["virtual-hal-sim-config-macro-load-fixtures"]), ...(virtualHalMotionControllerMatrixReady ? [] : ["virtual-hal-motion-controller-matrix"]), + ...(toolDbProcessProofReady ? [] : ["tool-db-process-proof"]), ...(blockedRuntimeReady ? [] : ["blocked-runtime-families"]), ...(axisScreenshotArtifactsReady ? [] : ["axis-screenshot-artifacts"]), ]; @@ -2125,6 +2176,8 @@ export function createProjectReleaseReadinessReport({ virtualHalSimConfigMacroLoadFixturesReady, virtualHalMotionControllerMatrix, virtualHalMotionControllerMatrixReady, + toolDbProcessProofSummary, + toolDbProcessProofReady, blockedRuntimeFamilies: blockedFamilies, promotedRuntimeFamilies: promotedFamilies, promotedBlockedFamilies, @@ -2227,6 +2280,16 @@ export function createProjectReleaseReadinessReport({ label: "Virtual HAL motion controller matrix", value: virtualHalMotionControllerMatrixReady ? "ready" : "missing", }, + { + id: "tool-db-process-proof", + label: "Tool DB process proof", + value: toolDbProcessProofReady ? "ready" : "missing", + }, + { + id: "tool-db-process-proof-detail", + label: "Tool DB process proof detail", + value: `wasm=${toolDbProcessProofSummary.wasmProtocolReady ? "ready" : "missing"} browser=${toolDbProcessProofSummary.browserProtocolReady ? "ready" : "missing"} opfs=${toolDbProcessProofSummary.opfsPersistenceReady ? "ready" : "missing"} promotion_allowed=${toolDbProcessProofSummary.promotionAllowed ? "1" : "0"}`, + }, { id: "blocked-runtime-families", label: "Blocked runtime families", @@ -2264,6 +2327,8 @@ export function createProjectReleaseReadinessSummaryViewModel( const promotionCandidateArtifactSummary = objectOrEmpty(report?.promotionCandidateArtifactSummary); const virtualHalSimConfigMacroLoadFixturesReady = report?.virtualHalSimConfigMacroLoadFixturesReady === true; const virtualHalMotionControllerMatrixReady = report?.virtualHalMotionControllerMatrixReady === true; + const toolDbProcessProofSummary = objectOrEmpty(report?.toolDbProcessProofSummary); + const toolDbProcessProofReady = report?.toolDbProcessProofReady === true; const axisScreenshotArtifactSummary = objectOrEmpty(report?.axisScreenshotArtifactSummary); const blockedRuntimeFamilies = arrayOrEmpty(report?.blockedRuntimeFamilies); const promotedBlockedFamilies = arrayOrEmpty(report?.promotedBlockedFamilies); @@ -2354,6 +2419,18 @@ export function createProjectReleaseReadinessSummaryViewModel( label: "Virtual HAL motion controller matrix", value: virtualHalMotionControllerMatrixReady ? "ready" : "missing", }, + { + id: "tool-db-process-proof", + label: "Tool DB process proof", + value: toolDbProcessProofReady ? "ready" : "missing", + }, + { + id: "tool-db-process-proof-detail", + label: "Tool DB process proof detail", + value: toolDbProcessProofSummary.apiName + ? `wasm=${toolDbProcessProofSummary.wasmProtocolReady ? "ready" : "missing"} browser=${toolDbProcessProofSummary.browserProtocolReady ? "ready" : "missing"} opfs=${toolDbProcessProofSummary.opfsPersistenceReady ? "ready" : "missing"} promotion_allowed=${toolDbProcessProofSummary.promotionAllowed ? "1" : "0"}` + : "missing", + }, { id: "blocked-runtime-families", label: "Blocked runtime families", @@ -2542,6 +2619,18 @@ export function createProjectReleaseReadinessArtifactValidationSummaryViewModel( label: "Virtual HAL motion controller matrix", value: validation?.virtualHalMotionControllerMatrixReady === true ? "ready" : "missing", }, + { + id: "tool-db-process-proof", + label: "Tool DB process proof", + value: validation?.toolDbProcessProofReady === true ? "ready" : "missing", + }, + { + id: "tool-db-process-proof-detail", + label: "Tool DB process proof detail", + value: validation?.toolDbProcessProofReady === true + ? `wasm=${validation.toolDbProcessProofSummary.wasmProtocolReady ? "ready" : "missing"} browser=${validation.toolDbProcessProofSummary.browserProtocolReady ? "ready" : "missing"} opfs=${validation.toolDbProcessProofSummary.opfsPersistenceReady ? "ready" : "missing"} promotion_allowed=${validation.toolDbProcessProofSummary.promotionAllowed ? "1" : "0"}` + : "missing", + }, { id: "missing", label: "Missing artifact evidence", @@ -2953,6 +3042,8 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel const promotionCandidateArtifactSummary = objectOrEmpty(workflow?.validation?.promotionCandidateArtifactSummary); const promotionCandidateArtifactSummaryReady = workflow?.validation?.promotionCandidateArtifactSummaryReady === true; + const toolDbProcessProofSummary = objectOrEmpty(workflow?.validation?.toolDbProcessProofSummary); + const toolDbProcessProofReady = workflow?.validation?.toolDbProcessProofReady === true; const promotionArtifactRows = objectOrEmpty(promotionCandidateArtifactSummary.artifactRows); const hardBlockRuntimeFamilyRows = arrayOrEmpty(promotionCandidateArtifactSummary.hardBlockRuntimeFamilyRows); const hardBlockRuntimeFamilySummaryRows = arrayOrEmpty( @@ -3219,6 +3310,18 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel : "not provided", lockedPaths: arrayOrEmpty(row.lockedPaths), })), + { + id: "tool-db-process-proof", + label: "Tool DB process proof", + value: toolDbProcessProofReady ? "ready" : "not provided", + }, + { + id: "tool-db-process-proof-detail", + label: "Tool DB process proof detail", + value: toolDbProcessProofReady + ? `wasm=${toolDbProcessProofSummary.wasmProtocolReady ? "ready" : "missing"} browser=${toolDbProcessProofSummary.browserProtocolReady ? "ready" : "missing"} opfs=${toolDbProcessProofSummary.opfsPersistenceReady ? "ready" : "missing"} promotion_allowed=${toolDbProcessProofSummary.promotionAllowed ? "1" : "0"}` + : "not provided", + }, ...arrayOrEmpty(workflow?.validation?.virtualHalPromotionFamilyRows).map((row) => ({ id: `virtual-hal-promotion-family-${row.id}`, label: `Promotion family ${row.label}`, @@ -3420,6 +3523,7 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) { const virtualHalSimConfigPromotionCandidates = objectOrEmpty(artifactObject.virtualHalSimConfigPromotionCandidates); const virtualHalSimConfigMacroLoadFixtures = objectOrEmpty(artifactObject.virtualHalSimConfigMacroLoadFixtures); const virtualHalMotionControllerMatrix = objectOrEmpty(artifactObject.virtualHalMotionControllerMatrix); + const toolDbProcessProofSummary = objectOrEmpty(artifactObject.toolDbProcessProofSummary); const gateManifest = objectOrEmpty(artifactObject.gateManifest); const gateExecutionManifest = objectOrEmpty(artifactObject.gateExecutionManifest); const gateExecutionSummaryViewModel = objectOrEmpty(artifactObject.gateExecutionSummaryViewModel); @@ -3529,6 +3633,23 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) { const virtualHalMotionControllerMatrixReady = isVirtualHalMotionControllerMatrixReady( virtualHalMotionControllerMatrix, ) && artifactObject.virtualHalMotionControllerMatrixReady === true; + const expectedToolDbProcessProofSummary = createToolDbProcessProofSummary(toolDbProcessProofSummary); + const toolDbProcessProofReady = + toolDbProcessProofSummary.apiName === "tool-db-process-proof-summary" && + toolDbProcessProofSummary.summaryVersion === 1 && + toolDbProcessProofSummary.ready === true && + toolDbProcessProofSummary.boundaryClass === "L4-TOOL-DB" && + toolDbProcessProofSummary.path === "axis/db_demo/base.ngc" && + toolDbProcessProofSummary.dbProgramPath === "./db_nonran.py" && + toolDbProcessProofSummary.wasmProtocolReady === true && + toolDbProcessProofSummary.browserProtocolReady === true && + toolDbProcessProofSummary.opfsPersistenceReady === true && + toolDbProcessProofSummary.tblFallbackSufficient === false && + toolDbProcessProofSummary.promotionAllowed === false && + toolDbProcessProofSummary.executionEnabled === false && + arrayOrEmpty(toolDbProcessProofSummary.requiredCommands).join("\n") === + expectedToolDbProcessProofSummary.requiredCommands.join("\n") && + artifactObject.toolDbProcessProofReady === true; const axisScreenshotArtifacts = arrayOrEmpty(axisScreenshotArtifactSummary.artifacts); const blockedRuntimeFamilies = arrayOrEmpty(artifactObject.blockedRuntimeFamilies); const promotedBlockedFamilies = arrayOrEmpty(artifactObject.promotedBlockedFamilies); @@ -3577,6 +3698,7 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) { ...(promotionCandidateArtifactSummaryReady ? [] : ["promotionCandidateArtifactSummary"]), ...(virtualHalSimConfigMacroLoadFixturesReady ? [] : ["virtualHalSimConfigMacroLoadFixtures"]), ...(virtualHalMotionControllerMatrixReady ? [] : ["virtualHalMotionControllerMatrix"]), + ...(toolDbProcessProofReady ? [] : ["toolDbProcessProofSummary"]), ...(arrayOrEmpty(artifactObject.blockedRuntimeFamilies).join(",") === BLOCKED_RUNTIME_FAMILIES.join(",") ? [] : ["blockedRuntimeFamilies"]), @@ -3618,6 +3740,8 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) { promotionCandidateArtifactSummaryReady, virtualHalSimConfigMacroLoadFixturesReady, virtualHalMotionControllerMatrixReady, + toolDbProcessProofSummary, + toolDbProcessProofReady, axisScreenshotArtifactSummaryReady: axisScreenshotSummaryReady, axisScreenshotArtifactCount: axisScreenshotArtifacts.length, blockedRuntimeFamilies, @@ -3756,6 +3880,18 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) { label: "Virtual HAL motion controller matrix", value: virtualHalMotionControllerMatrixReady ? "ready" : "missing", }, + { + id: "tool-db-process-proof", + label: "Tool DB process proof", + value: toolDbProcessProofReady ? "ready" : "missing", + }, + { + id: "tool-db-process-proof-detail", + label: "Tool DB process proof detail", + value: toolDbProcessProofReady + ? `wasm=${toolDbProcessProofSummary.wasmProtocolReady ? "ready" : "missing"} browser=${toolDbProcessProofSummary.browserProtocolReady ? "ready" : "missing"} opfs=${toolDbProcessProofSummary.opfsPersistenceReady ? "ready" : "missing"} promotion_allowed=${toolDbProcessProofSummary.promotionAllowed ? "1" : "0"}` + : "missing", + }, { id: "blocked-runtime-families", label: "Blocked runtime families", diff --git a/wasm-port/runtime/sdk/src/tool-db-browser-worker-adapter.js b/wasm-port/runtime/sdk/src/tool-db-browser-worker-adapter.js index 3c023c1..ae5b2fb 100644 --- a/wasm-port/runtime/sdk/src/tool-db-browser-worker-adapter.js +++ b/wasm-port/runtime/sdk/src/tool-db-browser-worker-adapter.js @@ -14,10 +14,12 @@ function makeRequestId() { export function createLinuxCncToolDbBrowserWorkerAdapter({ workerUrl, + pythonRuntimeModuleUrl = null, workerFactory = (url) => new Worker(url, { type: "module" }), timeoutMs = 5000, } = {}) { const normalizedWorkerUrl = requireWorkerUrl(workerUrl); + const normalizedPythonRuntimeModuleUrl = pythonRuntimeModuleUrl ? requireWorkerUrl(pythonRuntimeModuleUrl) : null; let worker = null; const pending = new Map(); let runtimeExecutionReady = false; @@ -70,7 +72,11 @@ export function createLinuxCncToolDbBrowserWorkerAdapter({ worker.addEventListener("error", (event) => { rejectPending(new Error(event.message ?? "Tool DB browser worker error.")); }); - const result = await request("start"); + const result = await request("start", { + pythonRuntimeModuleUrl: normalizedPythonRuntimeModuleUrl + ? String(normalizedPythonRuntimeModuleUrl) + : null, + }); runtimeExecutionReady = result.runtimeExecutionReady === true; startStatus = result.status ?? (runtimeExecutionReady ? "browser_python_wasm_runtime_ready" diff --git a/wasm-port/runtime/workers/tool-db-python-worker.js b/wasm-port/runtime/workers/tool-db-python-worker.js index 8fb32c1..ea5a39d 100644 --- a/wasm-port/runtime/workers/tool-db-python-worker.js +++ b/wasm-port/runtime/workers/tool-db-python-worker.js @@ -19,12 +19,42 @@ function getRuntimeProvider() { return self.linuxCncToolDbPythonRuntimeProvider ?? null; } +async function loadRuntimeProvider(moduleUrl) { + if (!moduleUrl) { + return { + status: "blocked_browser_python_wasm_runtime_missing", + provider: getRuntimeProvider(), + }; + } + try { + await import(moduleUrl); + } catch (error) { + return { + status: "blocked_browser_python_wasm_runtime_load_failed", + error, + provider: getRuntimeProvider(), + }; + } + const provider = getRuntimeProvider(); + if (!provider) { + return { + status: "blocked_browser_python_wasm_provider_missing", + provider, + }; + } + return { + status: "browser_python_wasm_runtime_ready", + provider, + }; +} + self.addEventListener("message", async (event) => { const message = event.data ?? {}; const { id, type, line } = message; try { if (type === "start") { - const provider = getRuntimeProvider(); + const runtimeLoad = await loadRuntimeProvider(message.pythonRuntimeModuleUrl); + const provider = runtimeLoad.provider; const providerReady = Boolean(provider?.start && provider?.writeLine && provider?.readLine); const ready = providerReady || pythonRuntimeAvailable(); if (providerReady) { @@ -33,9 +63,8 @@ self.addEventListener("message", async (event) => { postReply(id, type, { runtimeMode: "browser-python-wasm-worker", runtimeExecutionReady: ready, - status: ready - ? "browser_python_wasm_runtime_ready" - : "blocked_browser_python_wasm_runtime_missing", + status: ready ? "browser_python_wasm_runtime_ready" : runtimeLoad.status, + error: runtimeLoad.error?.message ?? null, executionEnabled: false, promotionAllowed: false, }); diff --git a/wasm-port/tests/browser/ini_panel_workflow_overview_smoke.html b/wasm-port/tests/browser/ini_panel_workflow_overview_smoke.html index 8609018..22007b5 100644 --- a/wasm-port/tests/browser/ini_panel_workflow_overview_smoke.html +++ b/wasm-port/tests/browser/ini_panel_workflow_overview_smoke.html @@ -219,7 +219,7 @@ "workflow overview release artifact validation API name", ); assertEqual(releaseArtifactValidation.ready, true, "workflow overview release artifact validation readiness"); - assertEqual(releaseArtifactValidation.gateCount, 12, "workflow overview release artifact validation gates"); + assertEqual(releaseArtifactValidation.gateCount, 13, "workflow overview release artifact validation gates"); assertEqual( releaseArtifactValidationSummary.statusLine, "Ready: Artifact evidence complete", diff --git a/wasm-port/tests/browser/tool_db_fake_python_runtime_worker.js b/wasm-port/tests/browser/tool_db_fake_python_runtime_worker.js index e902b3b..ad9935b 100644 --- a/wasm-port/tests/browser/tool_db_fake_python_runtime_worker.js +++ b/wasm-port/tests/browser/tool_db_fake_python_runtime_worker.js @@ -18,5 +18,3 @@ self.linuxCncToolDbPythonRuntimeProvider = { async close() {}, }; - -await import("../../runtime/workers/tool-db-python-worker.js"); diff --git a/wasm-port/tests/browser/tool_db_process_browser_smoke.html b/wasm-port/tests/browser/tool_db_process_browser_smoke.html index 77b896e..8cb7829 100644 --- a/wasm-port/tests/browser/tool_db_process_browser_smoke.html +++ b/wasm-port/tests/browser/tool_db_process_browser_smoke.html @@ -85,8 +85,27 @@ assertEqual(workerPlanResult.promotionAllowed, false, "worker promotion guard"); await workerPort.close(); + const missingModuleAdapter = createLinuxCncToolDbBrowserWorkerAdapter({ + workerUrl: new URL("../../runtime/workers/tool-db-python-worker.js", import.meta.url), + pythonRuntimeModuleUrl: new URL("./missing_tool_db_python_runtime_provider.js", import.meta.url), + }); + const missingModulePort = createLinuxCncToolDbProcessPort({ + dbProgramPath: "./db_nonran.py", + runtimeMode: missingModuleAdapter.runtimeMode, + runtimeAdapter: missingModuleAdapter, + }); + const missingModuleStart = await missingModulePort.start(); + assertEqual(missingModuleStart.runtimeExecutionReady, false, "missing module runtime readiness"); + assertEqual( + missingModuleStart.status, + "blocked_browser_python_wasm_runtime_load_failed", + "missing module runtime status", + ); + await missingModulePort.close(); + const fakeRuntimeAdapter = createLinuxCncToolDbBrowserWorkerAdapter({ - workerUrl: new URL("./tool_db_fake_python_runtime_worker.js", import.meta.url), + workerUrl: new URL("./tool_db_python_runtime_module_worker.js", import.meta.url), + pythonRuntimeModuleUrl: new URL("./tool_db_fake_python_runtime_worker.js", import.meta.url), }); const fakeRuntimePort = createLinuxCncToolDbProcessPort({ dbProgramPath: "./db_nonran.py", diff --git a/wasm-port/tests/browser/tool_db_python_runtime_module_worker.js b/wasm-port/tests/browser/tool_db_python_runtime_module_worker.js new file mode 100644 index 0000000..392cd43 --- /dev/null +++ b/wasm-port/tests/browser/tool_db_python_runtime_module_worker.js @@ -0,0 +1 @@ +await import("../../runtime/workers/tool-db-python-worker.js"); diff --git a/wasm-port/tests/host/verify_host_smokes.sh b/wasm-port/tests/host/verify_host_smokes.sh index 162c690..5d92d99 100755 --- a/wasm-port/tests/host/verify_host_smokes.sh +++ b/wasm-port/tests/host/verify_host_smokes.sh @@ -14,6 +14,7 @@ SKIP_INTERP_BUILD=1 "$ROOT_DIR/tests/wasm/node/verify_nc_files_wasm.sh" SKIP_TP_BUILD=1 "$ROOT_DIR/tests/wasm/node/verify_tp_wasm.sh" "$ROOT_DIR/tests/opfs/node/verify_file_service.sh" "$ROOT_DIR/tests/sdk/node/verify_sdk_surface.sh" +"$ROOT_DIR/tests/host/verify_tool_db_process_proof.sh" "$ROOT_DIR/tests/docs/node/verify_opfs_session_docs.sh" "$ROOT_DIR/tests/docs/node/verify_sim_configs_coverage_docs.sh" "$ROOT_DIR/tests/docs/node/verify_host_runtime_boundary_docs.sh" diff --git a/wasm-port/tests/host/verify_tool_db_process_proof.sh b/wasm-port/tests/host/verify_tool_db_process_proof.sh new file mode 100755 index 0000000..b962efa --- /dev/null +++ b/wasm-port/tests/host/verify_tool_db_process_proof.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)" + +"$ROOT_DIR/tests/sdk/node/verify_tool_db_process_port.sh" +"$ROOT_DIR/tests/opfs/node/verify_tool_db_store.sh" +"$ROOT_DIR/tests/wasm/node/verify_tool_db_process_port_wasm.sh" +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 "$ROOT_DIR/tests/browser/verify_tool_db_process_browser.sh" + +echo "tool_db_process_proof=ok" diff --git a/wasm-port/tests/sdk/node/verify_project_release_artifact_url_workflow.mjs b/wasm-port/tests/sdk/node/verify_project_release_artifact_url_workflow.mjs index e3962a7..16c27bc 100644 --- a/wasm-port/tests/sdk/node/verify_project_release_artifact_url_workflow.mjs +++ b/wasm-port/tests/sdk/node/verify_project_release_artifact_url_workflow.mjs @@ -388,6 +388,8 @@ assert.deepEqual( ["hard-block-runtime-family-L4-USER-M-PROCESS-paths", "axis/vismach/millturn/example.ngc"], ["hard-block-runtime-family-L4-TOOL-DB-paths", "axis/db_demo/base.ngc"], ["hard-block-runtime-family-L4-PYTHON-REMAP-paths", "axis/laser/raster_test.ngc, axis/laser/vector_test.ngc, axis/laser/vector_test2.ngc, axis/remap/cycle/nc_files/examples.ngc, axis/remap/extend-builtins/nc_files/examples.ngc, axis/remap/getting-started/nc_files/examples.ngc, axis/remap/manual-toolchange-with-tool-length-switch/nc_files/tcdemo.ngc, axis/remap/rack-toolchange/nc_files/tcdemo.ngc, axis/remap/stop-lookahead/nc_files/examples.ngc, axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/circular_pocket.ngc, axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition_back_and_forth.ngc, axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/incremental_repetition.ngc, axis/vismach/5axis/table-rotary_spindle-rotary-nutating/demos/simple_example.ngc, axis/vismach/VMC_toolchange/toolchange.ngc, gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc, gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc, gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc"], + ["tool-db-process-proof", "ready"], + ["tool-db-process-proof-detail", "wasm=ready browser=ready opfs=ready promotion_allowed=0"], ...expectedPromotionFamilyRows, ["browser-diagnostics", "ready"], ["virtual-hal-promotion-candidate-summary", "ready"], diff --git a/wasm-port/tests/sdk/node/verify_project_release_gate_manifest.mjs b/wasm-port/tests/sdk/node/verify_project_release_gate_manifest.mjs index 794fed6..0ac9f87 100644 --- a/wasm-port/tests/sdk/node/verify_project_release_gate_manifest.mjs +++ b/wasm-port/tests/sdk/node/verify_project_release_gate_manifest.mjs @@ -34,7 +34,7 @@ const virtualHalSimConfigMacroLoadFixtures = createVirtualHalSimConfigMacroLoadF assert.equal(manifest.apiName, "project-release-gate-manifest"); assert.equal(manifest.manifestVersion, 1); -assert.equal(manifest.gateCount, 12); +assert.equal(manifest.gateCount, 13); assert.deepEqual(manifest.gateIds, [ "diff-check", "vendor-sync", @@ -43,6 +43,7 @@ assert.deepEqual(manifest.gateIds, [ "sim-config-inventory", "ini-panel-browser", "opfs-session-browser", + "tool-db-process-proof", "release-artifact-url-browser", "project-batch-acceptance", "ui-node-smokes", @@ -59,6 +60,7 @@ assert.deepEqual( "sim_configs_wasm_node_inventory_unexpected_fail=0", "browser_ini_shell_integration_workflow_smoke=ok", "browser_opfs_session_workflow_smoke=ok", + "tool_db_process_proof=ok", "browser_release_artifact_url_workflow_smoke=ok", "project_batch_acceptance_workflow_node_smoke=ok", "ui_node_smokes=ok", @@ -74,6 +76,10 @@ assert.equal( manifest.gates.find(({ id }) => id === "opfs-session-browser")?.command, "SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_opfs_session_workflow_browser.sh", ); +assert.equal( + manifest.gates.find(({ id }) => id === "tool-db-process-proof")?.command, + "wasm-port/tests/host/verify_tool_db_process_proof.sh", +); assert.equal( manifest.gates.find(({ id }) => id === "project-batch-acceptance")?.command, "wasm-port/tests/sdk/node/verify_project_batch_acceptance_workflow.sh", @@ -92,15 +98,16 @@ assert.equal(partialMatrix.apiName, "project-release-gate-result-matrix"); assert.equal(partialMatrix.matrixVersion, 1); assert.equal(partialMatrix.phase, "waiting"); assert.equal(partialMatrix.ready, false); -assert.equal(partialMatrix.gateCount, 12); +assert.equal(partialMatrix.gateCount, 13); assert.equal(partialMatrix.passedCount, 3); -assert.equal(partialMatrix.unknownCount, 9); +assert.equal(partialMatrix.unknownCount, 10); assert.deepEqual(partialMatrix.missingGateIds, [ "standalone-cnc-semantics", "interp-wasm", "sim-config-inventory", "ini-panel-browser", "opfs-session-browser", + "tool-db-process-proof", "project-batch-acceptance", "ui-node-smokes", "host-smokes", @@ -128,9 +135,9 @@ assert.equal(partialExecutionManifest.apiName, "project-release-gate-execution-m assert.equal(partialExecutionManifest.manifestVersion, 1); assert.equal(partialExecutionManifest.phase, "waiting"); assert.equal(partialExecutionManifest.ready, false); -assert.equal(partialExecutionManifest.gateCount, 12); +assert.equal(partialExecutionManifest.gateCount, 13); assert.equal(partialExecutionManifest.passedCount, 3); -assert.equal(partialExecutionManifest.unknownCount, 9); +assert.equal(partialExecutionManifest.unknownCount, 10); assert.deepEqual(partialExecutionManifest.missingGateIds, partialMatrix.missingGateIds); assert.deepEqual( partialExecutionManifest.rows.filter(({ passed }) => passed).map(({ id, evidence }) => [id, evidence]), @@ -153,25 +160,25 @@ assert.equal(partialExecutionSummary.apiName, "project-release-gate-execution-su assert.equal(partialExecutionSummary.viewModelVersion, 1); assert.equal(partialExecutionSummary.phase, "waiting"); assert.equal(partialExecutionSummary.ready, false); -assert.equal(partialExecutionSummary.statusLine, "Waiting: standalone-cnc-semantics, interp-wasm, sim-config-inventory, ini-panel-browser, opfs-session-browser, project-batch-acceptance, ui-node-smokes, host-smokes, project-release-gate"); -assert.equal(partialExecutionSummary.gateCount, 12); +assert.equal(partialExecutionSummary.statusLine, "Waiting: standalone-cnc-semantics, interp-wasm, sim-config-inventory, ini-panel-browser, opfs-session-browser, tool-db-process-proof, project-batch-acceptance, ui-node-smokes, host-smokes, project-release-gate"); +assert.equal(partialExecutionSummary.gateCount, 13); assert.equal(partialExecutionSummary.passedCount, 3); -assert.equal(partialExecutionSummary.unknownCount, 9); +assert.equal(partialExecutionSummary.unknownCount, 10); assert.equal(partialExecutionSummary.nextGateId, "standalone-cnc-semantics"); assert.deepEqual(partialExecutionSummary.evidenceCounts, { "explicit-result": 1, "expected-output": 2, - missing: 9, + missing: 10, }); assert.deepEqual( partialExecutionSummary.rows.map(({ id, value }) => [id, value]), [ - ["gate-results", "3/12 passed"], - ["unknown-gates", "9"], + ["gate-results", "3/13 passed"], + ["unknown-gates", "10"], ["next-gate", "standalone-cnc-semantics"], ["expected-output-evidence", "2"], ["explicit-result-evidence", "1"], - ["missing", "standalone-cnc-semantics, interp-wasm, sim-config-inventory, ini-panel-browser, opfs-session-browser, project-batch-acceptance, ui-node-smokes, host-smokes, project-release-gate"], + ["missing", "standalone-cnc-semantics, interp-wasm, sim-config-inventory, ini-panel-browser, opfs-session-browser, tool-db-process-proof, project-batch-acceptance, ui-node-smokes, host-smokes, project-release-gate"], ], ); assert.equal(partialExecutionSummary.gateRows.length, manifest.gateCount); @@ -185,9 +192,9 @@ assert.equal(partialActionPlan.apiName, "project-release-gate-action-plan"); assert.equal(partialActionPlan.planVersion, 1); assert.equal(partialActionPlan.phase, "waiting"); assert.equal(partialActionPlan.ready, false); -assert.equal(partialActionPlan.gateCount, 12); +assert.equal(partialActionPlan.gateCount, 13); assert.equal(partialActionPlan.completedCount, 3); -assert.equal(partialActionPlan.pendingCount, 9); +assert.equal(partialActionPlan.pendingCount, 10); assert.deepEqual(partialActionPlan.completedGateIds, [ "diff-check", "vendor-sync", @@ -199,6 +206,7 @@ assert.deepEqual(partialActionPlan.pendingGateIds, [ "sim-config-inventory", "ini-panel-browser", "opfs-session-browser", + "tool-db-process-proof", "project-batch-acceptance", "ui-node-smokes", "host-smokes", @@ -206,7 +214,7 @@ assert.deepEqual(partialActionPlan.pendingGateIds, [ ]); assert.equal(partialActionPlan.nextGateId, "standalone-cnc-semantics"); assert.equal(partialActionPlan.nextCommand, "wasm-port/tools/verify_no_standalone_cnc_semantics.sh"); -assert.equal(partialActionPlan.commands.length, 9); +assert.equal(partialActionPlan.commands.length, 10); assert.equal(partialActionPlan.commands[0].step, 1); assert.equal(partialActionPlan.commands[0].gateId, "standalone-cnc-semantics"); assert.equal(partialActionPlan.rows[0].id, "standalone-cnc-semantics"); @@ -226,7 +234,7 @@ assert.equal(report.gateExecutionManifest.ready, true); assert.equal(report.gateExecutionManifest.passedCount, manifest.gateCount); assert.equal(report.gateExecutionSummaryViewModel.apiName, "project-release-gate-execution-summary-view-model"); assert.equal(report.gateExecutionSummaryViewModel.statusLine, "Ready: All release gate evidence present"); -assert.equal(report.gateExecutionSummaryViewModel.rows[0].value, "12/12 passed"); +assert.equal(report.gateExecutionSummaryViewModel.rows[0].value, "13/13 passed"); assert.equal(report.gateExecutionSummaryViewModel.nextGateId, null); assert.equal(report.gateResultMatrix.ready, true); assert.equal(report.gateResultMatrix.passedCount, manifest.gateCount); @@ -249,7 +257,7 @@ assert.deepEqual(createProjectReleaseReadinessSummaryViewModel(report), { { id: "gate-results", label: "Release gates", - value: "12/12 passed", + value: "13/13 passed", }, { id: "unknown-gates", @@ -306,6 +314,16 @@ assert.deepEqual(createProjectReleaseReadinessSummaryViewModel(report), { label: "Virtual HAL motion controller matrix", value: "ready", }, + { + id: "tool-db-process-proof", + label: "Tool DB process proof", + value: "ready", + }, + { + id: "tool-db-process-proof-detail", + label: "Tool DB process proof detail", + value: "wasm=ready browser=ready opfs=ready promotion_allowed=0", + }, { id: "blocked-runtime-families", label: "Blocked runtime families", @@ -386,7 +404,7 @@ assert.deepEqual( artifactValidationSummary.rows.map(({ id, value }) => [id, value]), [ ["artifact", "project-release-readiness-report"], - ["gate-count", "12/12"], + ["gate-count", "13/13"], ["gate-manifest", "ready"], ["gate-execution-manifest", "ready"], ["gate-execution-summary", "ready"], @@ -408,6 +426,8 @@ assert.deepEqual( ...expectedPromotionFamilyRows, ["virtual-hal-sim-config-macro-load-fixtures", "ready"], ["virtual-hal-motion-controller-matrix", "ready"], + ["tool-db-process-proof", "ready"], + ["tool-db-process-proof-detail", "wasm=ready browser=ready opfs=ready promotion_allowed=0"], ["missing", "none"], ], ); @@ -528,6 +548,8 @@ assert.deepEqual( ["hard-block-runtime-family-L4-USER-M-PROCESS-paths", "not provided"], ["hard-block-runtime-family-L4-TOOL-DB-paths", "not provided"], ["hard-block-runtime-family-L4-PYTHON-REMAP-paths", "not provided"], + ["tool-db-process-proof", "ready"], + ["tool-db-process-proof-detail", "wasm=ready browser=ready opfs=ready promotion_allowed=0"], ...expectedPromotionFamilyRows, ["browser-diagnostics", "not requested"], ["virtual-hal-promotion-candidate-summary", "not requested"], diff --git a/wasm-port/tests/sdk/node/verify_sdk_surface.mjs b/wasm-port/tests/sdk/node/verify_sdk_surface.mjs index 9f1fdad..f86dca0 100644 --- a/wasm-port/tests/sdk/node/verify_sdk_surface.mjs +++ b/wasm-port/tests/sdk/node/verify_sdk_surface.mjs @@ -1672,6 +1672,32 @@ assert.deepEqual( ); assert.equal(releaseReadinessReady.virtualHalSimConfigMacroLoadFixturesReady, true); assert.equal(releaseReadinessReady.virtualHalMotionControllerMatrixReady, true); +const expectedToolDbProcessProofSummary = { + apiName: "tool-db-process-proof-summary", + summaryVersion: 1, + phase: "ready", + ready: true, + boundaryClass: "L4-TOOL-DB", + path: "axis/db_demo/base.ngc", + dbProgramPath: "./db_nonran.py", + runtimeMode: "browser-python-wasm-worker", + nativeProtocolReady: false, + nativeRuntimeRequiredForPromotion: true, + wasmProtocolReady: true, + browserProtocolReady: true, + opfsPersistenceReady: true, + tblFallbackSufficient: false, + promotionAllowed: false, + executionEnabled: false, + requiredCommands: [ + "wasm-port/tests/sdk/node/verify_tool_db_process_port.sh", + "wasm-port/tests/opfs/node/verify_tool_db_store.sh", + "wasm-port/tests/wasm/node/verify_tool_db_process_port_wasm.sh", + "SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_tool_db_process_browser.sh", + ], +}; +assert.deepEqual(releaseReadinessReady.toolDbProcessProofSummary, expectedToolDbProcessProofSummary); +assert.equal(releaseReadinessReady.toolDbProcessProofReady, true); assert.deepEqual(releaseReadinessReady.gateManifest, createProjectReleaseGateManifest()); assert.equal(releaseReadinessReady.gateResultMatrix.rows.length, createProjectReleaseGateManifest().gateCount); assert.equal(createProjectReleaseGateActionPlan({ @@ -1831,6 +1857,8 @@ assert.deepEqual(releaseReadinessArtifactValidation, { promotionCandidateArtifactSummaryReady: true, virtualHalSimConfigMacroLoadFixturesReady: true, virtualHalMotionControllerMatrixReady: true, + toolDbProcessProofSummary: expectedToolDbProcessProofSummary, + toolDbProcessProofReady: true, axisScreenshotArtifactSummaryReady: true, axisScreenshotArtifactCount: 0, blockedRuntimeFamilies: [ @@ -1957,6 +1985,16 @@ assert.deepEqual(releaseReadinessArtifactValidation, { label: "Virtual HAL motion controller matrix", value: "ready", }, + { + id: "tool-db-process-proof", + label: "Tool DB process proof", + value: "ready", + }, + { + id: "tool-db-process-proof-detail", + label: "Tool DB process proof detail", + value: "wasm=ready browser=ready opfs=ready promotion_allowed=0", + }, { id: "blocked-runtime-families", label: "Blocked runtime families", @@ -2157,6 +2195,7 @@ assert.deepEqual( "promotionCandidateArtifactSummary", "virtualHalSimConfigMacroLoadFixtures", "virtualHalMotionControllerMatrix", + "toolDbProcessProofSummary", "blockedRuntimeFamilies", "gateManifest", "gateExecutionManifest", diff --git a/wasm-port/tests/sdk/node/verify_tool_db_process_port.mjs b/wasm-port/tests/sdk/node/verify_tool_db_process_port.mjs index c5a5902..73eef6b 100644 --- a/wasm-port/tests/sdk/node/verify_tool_db_process_port.mjs +++ b/wasm-port/tests/sdk/node/verify_tool_db_process_port.mjs @@ -83,6 +83,7 @@ class FakeBlockedWorker { class FakeReadyWorker { constructor() { this.listeners = new Map(); + this.startMessages = []; this.lines = [ "v2.1", "T10 P110 D0.10 Z0.10", @@ -100,6 +101,7 @@ class FakeReadyWorker { postMessage(message) { queueMicrotask(() => { if (message.type === "start") { + this.startMessages.push(message); this.reply(message, { runtimeExecutionReady: true, status: "browser_python_wasm_runtime_ready", @@ -159,9 +161,11 @@ assert.equal(browserWorkerBlockedPlan.runtimeExecutionReady, false); assert.equal(browserWorkerBlockedPlan.promotionAllowed, false); await browserWorkerPort.close(); +const fakeReadyWorker = new FakeReadyWorker(); const readyWorkerAdapter = createLinuxCncToolDbBrowserWorkerAdapter({ workerUrl: "./tool-db-python-worker.js", - workerFactory: () => new FakeReadyWorker(), + pythonRuntimeModuleUrl: "./tool-db-python-runtime-provider.js", + workerFactory: () => fakeReadyWorker, }); const readyWorkerPort = createLinuxCncToolDbProcessPort({ dbProgramPath: "./db_nonran.py", @@ -171,6 +175,8 @@ const readyWorkerPort = createLinuxCncToolDbProcessPort({ const readyWorkerStart = await readyWorkerPort.start(); assert.equal(readyWorkerStart.runtimeExecutionReady, true); assert.equal(readyWorkerStart.status, "browser_python_wasm_runtime_ready"); +assert.equal(readyWorkerAdapter.runtimeMode, "browser-python-wasm-worker"); +assert.equal(fakeReadyWorker.startMessages[0].pythonRuntimeModuleUrl, "./tool-db-python-runtime-provider.js"); const readyWorkerPlan = await readyWorkerPort.runTransactionPlan(); assert.equal(readyWorkerPlan.status, "runtime_adapter_transaction_plan_executed"); assert.equal(readyWorkerPlan.runtimeExecutionReady, true); diff --git a/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs b/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs index d49344f..dde200d 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_ui_shell.mjs @@ -1629,7 +1629,7 @@ assert.equal( ); assert.equal(releaseArtifactValidation.ready, true); assert.equal(releaseArtifactValidation.validation.ready, true); -assert.equal(releaseArtifactValidation.gateCount, 12); +assert.equal(releaseArtifactValidation.gateCount, 13); const releaseArtifactValidationSummary = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel( releaseArtifactValidation, @@ -1722,7 +1722,7 @@ assert.equal( releaseArtifactGateExecutionSummary.statusLine, "Ready: All release gate evidence present", ); -assert.equal(releaseArtifactGateExecutionSummary.rows[0].value, "12/12 passed"); +assert.equal(releaseArtifactGateExecutionSummary.rows[0].value, "13/13 passed"); const releaseArtifactGateExecutionSummaryRenderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState( releaseArtifactGateExecutionSummary, @@ -1731,8 +1731,8 @@ assert.equal( releaseArtifactGateExecutionSummaryRenderState.statusLine, "Ready: All release gate evidence present", ); -assert.equal(releaseArtifactGateExecutionSummaryRenderState.rows.length, 18); -assert.equal(releaseArtifactGateExecutionSummaryRenderState.gateRows.length, 12); +assert.equal(releaseArtifactGateExecutionSummaryRenderState.rows.length, 19); +assert.equal(releaseArtifactGateExecutionSummaryRenderState.gateRows.length, 13); assert.equal( releaseArtifactGateExecutionSummaryRenderState.dataset.handoffScope, "workflow-overview-release-readiness-artifact-gate-execution-summary", @@ -1776,13 +1776,13 @@ const releaseArtifactGateExecutionSummaryMountResult = rowsNode: releaseArtifactGateExecutionSummaryRowsNode, }); assert.equal(releaseArtifactGateExecutionSummaryRenderResult.rendered, true); -assert.equal(releaseArtifactGateExecutionSummaryRenderResult.rowCount, 18); +assert.equal(releaseArtifactGateExecutionSummaryRenderResult.rowCount, 19); assert.equal( releaseArtifactGateExecutionSummaryRenderResult.rowIds.includes("gate-ui-node-smokes"), true, ); assert.equal(releaseArtifactGateExecutionSummaryMountResult.ready, true); -assert.equal(releaseArtifactGateExecutionSummaryMountResult.renderResult.rowCount, 18); +assert.equal(releaseArtifactGateExecutionSummaryMountResult.renderResult.rowCount, 19); assert.equal( createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel().phase, "blocked", @@ -1833,7 +1833,7 @@ const releaseArtifactMountResult = mountIniPanelShellWorkflowOverviewReleaseRead rowsNode: releaseArtifactRowsNode, }); assert.equal(releaseArtifactRenderResult.rendered, true); -assert.equal(releaseArtifactRenderResult.rowCount, 30); +assert.equal(releaseArtifactRenderResult.rowCount, 32); assert.equal(releaseArtifactRenderResult.dataset.handoffScope, "workflow-overview-release-readiness-artifact"); assert.equal( releaseArtifactRenderResult.rowIds.includes("gate-execution-manifest"), @@ -1883,8 +1883,12 @@ assert.equal( releaseArtifactRenderResult.rowIds.includes("virtual-hal-motion-controller-matrix"), true, ); +assert.equal( + releaseArtifactRenderResult.rowIds.includes("tool-db-process-proof"), + true, +); assert.equal(releaseArtifactMountResult.ready, true); -assert.equal(releaseArtifactMountResult.renderResult.rowCount, 30); +assert.equal(releaseArtifactMountResult.renderResult.rowCount, 32); assert.deepEqual( validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson("{").missing, ["artifact-json"], @@ -1943,7 +1947,7 @@ assert.equal( ); assert.equal(releaseArtifactUrlWorkflow.renderState.statusLine, "Ready: No blocking reasons"); assert.equal(releaseArtifactUrlWorkflow.mountResult.ready, true); -assert.equal(releaseArtifactUrlWorkflow.mountResult.renderResult.rowCount, 30); +assert.equal(releaseArtifactUrlWorkflow.mountResult.renderResult.rowCount, 32); const releaseArtifactUrlWorkflowSummary = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel( releaseArtifactUrlWorkflow,