From 56175e29cc8ecbedd534212046847a4541805176 Mon Sep 17 00:00:00 2001 From: wangdequan Date: Tue, 16 Jun 2026 10:15:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E8=BF=9B=20workflow=20overview=20?= =?UTF-8?q?=E5=8F=91=E5=B8=83=20artifact=20URL=20workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PROJECT_COMPLETION_TRACKER.md | 6 +- text14.txt | 73 +++++++++++ wasm-port/docs/panel-entry.md | 5 + wasm-port/docs/project-release-handoff.md | 8 +- wasm-port/runtime/sdk/README.md | 4 + wasm-port/runtime/sdk/src/index.js | 1 + wasm-port/runtime/ui/ini-panel/launch.html | 3 + wasm-port/runtime/ui/ini-panel/ui-shell.js | 109 ++++++++++++++++ .../ui/ini-panel/workflow-overview.html | 4 + ...anel_shell_integration_workflow_smoke.html | 29 +++++ .../ini_panel_workflow_overview_smoke.html | 8 ++ .../verify_project_release_handoff_docs.mjs | 2 + .../project-release-readiness-ready.json | 116 ++++++++++++++++++ .../tests/sdk/node/verify_sdk_surface.mjs | 16 +++ .../ui/node/verify_ini_panel_entry_docs.mjs | 2 + .../verify_ini_panel_launch_api_manifest.mjs | 2 + ...y_ini_panel_shell_integration_manifest.mjs | 10 +- .../ui/node/verify_ini_panel_ui_shell.mjs | 53 ++++++++ 18 files changed, 443 insertions(+), 8 deletions(-) create mode 100644 wasm-port/tests/fixtures/project-release-readiness-ready.json diff --git a/PROJECT_COMPLETION_TRACKER.md b/PROJECT_COMPLETION_TRACKER.md index 63b55d9..ca3341f 100644 --- a/PROJECT_COMPLETION_TRACKER.md +++ b/PROJECT_COMPLETION_TRACKER.md @@ -9,7 +9,7 @@ turn-by-turn continuation notes and next-batch execution records. ## Current Status - Active continuation file: `text14.txt` -- Latest completed batch: workflow overview release readiness artifact DOM workflow +- Latest completed batch: workflow overview release readiness artifact URL workflow - Latest relevant commit: use `git log -1 --oneline` after each committed batch - Working tree at tracker creation: clean - Required policy: LinuxCNC remains the only CNC semantic source @@ -43,8 +43,8 @@ The project is complete for the current scope when all of the following are true | 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`. | | 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. | -| SDK/API surface | Stable for current scope | SDK re-exports core, OPFS/session readiness/load helpers, sim-config staging, project release readiness report/artifact validation, INI panel entry/launcher/control-page/shell/workflow overview helpers, the session readiness workflow report, and the shell API surface inventory with a Node surface smoke. | -| Browser/UI workflow | Stable for current scope | Workflow overview embedding mount DOM closure is complete, and INI panel session workflows plus read-only control/shell handoff expose, render, and report OPFS/session readiness, OPFS/session persistence summary, release readiness artifact validation/rendering, and API surface inventory before loading or reading WASM session state. | +| SDK/API surface | Stable for current scope | SDK re-exports core, OPFS/session readiness/load helpers, sim-config staging, project release readiness report/artifact validation plus URL loading workflow, INI panel entry/launcher/control-page/shell/workflow overview helpers, the session readiness workflow report, and the shell API surface inventory with a Node surface smoke. | +| Browser/UI workflow | Stable for current scope | Workflow overview embedding mount DOM closure is complete, and INI panel session workflows plus read-only control/shell handoff expose, render, fetch, validate, and report OPFS/session readiness, OPFS/session persistence summary, release readiness artifact validation/rendering, and API surface inventory before loading or reading WASM session state. | | Workflow overview embedding | Stable for current scope | Report/display/render, DOM contract/readiness/renderer, mount result/display/render, mount DOM contract/readiness/renderer/wrapper exist. | | Host/runtime boundary proof | Stable blocked state | Host smoke passes; runtime families remain blocked and `docs/host-runtime-boundary-handoff.md` records host readiness, promotion blockers, dispatch, and evidence gates. | | Documentation/release gate | Stable for current scope | `docs/project-release-handoff.md` links README, panel entry, SDK, OPFS/session, sim-config, host/runtime, source reuse, drift, tracker acceptance paths, and the machine-readable release readiness report/artifact. | diff --git a/text14.txt b/text14.txt index 0cc698a..eba09f1 100644 --- a/text14.txt +++ b/text14.txt @@ -3001,6 +3001,79 @@ project_release_gate=ok 继续只做实质能力推进。优先选择真实 browser/UI workflow 或外部 shell 可消费能力; 如果继续 release 路径,必须继续产出可调用 API、可验证 workflow、可执行 gate 或可消费 artifact。 +三十九、2026-06-16 继续执行记录:workflow overview release readiness artifact URL workflow + +本轮继续按“每批必须产出可调用 API、可验证 workflow、可执行 gate、或真实 UI/browser 能力”推进, +把 release readiness artifact validation 从 JSON 字符串调用推进到真实 browser URL 加载 workflow。外部 +shell 现在可以让 workflow overview iframe fetch artifact JSON URL、复用 validation/display/render/mount +链路,并得到结构化 ready/blocked workflow result。 + +完成内容: + +- `ui-shell.js` 新增: + - `loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()`; +- `createIniPanelShellWorkflowOverviewContract().methodNames` 新增: + - `loadWorkflowOverviewReleaseReadinessArtifactUrl`; +- `createIniPanelLaunchApiManifest().methods` 和 `launch.html` 暴露: + - `loadWorkflowOverviewReleaseReadinessArtifactUrl()`; +- `workflow-overview.html` 的 `linuxCncIniPanelWorkflowOverviewApi` 暴露: + - `loadWorkflowOverviewReleaseReadinessArtifactUrl()`; +- 新 workflow: + - fetch artifact URL; + - 复用 `validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson()`; + - 生成 display view-model 和 render-state; + - 可选 mount 到 caller-owned DOM; + - 对缺 URL、缺 fetch、HTTP failure、DOM missing 和 validation blocked 返回结构化 blocked result; +- `runtime/sdk/src/index.js` re-export 新 URL workflow helper; +- 新增 `tests/fixtures/project-release-readiness-ready.json`,用于真实 browser HTTP fetch smoke; +- `verify_ini_panel_ui_shell.mjs` 覆盖 ready URL workflow、missing DOM、HTTP blocked; +- `verify_ini_panel_shell_integration_manifest.mjs` 覆盖 workflow overview contract/readiness 新 method; +- `verify_ini_panel_launch_api_manifest.mjs` 覆盖 launch API manifest 和 browser namespace 暴露; +- `verify_sdk_surface.mjs` 覆盖 SDK export 和可调用 URL workflow; +- `ini_panel_workflow_overview_smoke.html` 在真实 workflow overview iframe 中 fetch fixture artifact 并 mount; +- `ini_panel_shell_integration_workflow_smoke.html` 从外部 shell 验证 iframe URL workflow 和 launch API 转发; +- `docs/panel-entry.md`、`docs/project-release-handoff.md`、`runtime/sdk/README.md` 记录新 URL workflow; +- `PROJECT_COMPLETION_TRACKER.md` 同步 latest completed batch、SDK/API surface 和 Browser/UI workflow 状态; +- 未新增控制按钮; +- 未执行 release gate/action-plan; +- 未解析 G-code; +- 未解释 canonical events; +- 未新增 JS CNC 语义; +- 未运行 opt-in runtime probes; +- 未 promotion blocked runtime family; +- 未改变 LinuxCNC interpreter、tool、parameter、planner、kinematics、remap 或 LinuxCNC-owned + runtime semantics。 + +验证已通过(先行 targeted): + +```bash +wasm-port/tests/sdk/node/verify_sdk_surface.sh +wasm-port/tests/ui/node/verify_ini_panel_ui_shell.sh +wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.sh +wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.sh +wasm-port/tests/ui/node/verify_ini_panel_entry_docs.sh +SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh +wasm-port/tests/docs/node/verify_project_release_handoff_docs.sh +``` + +关键输出: + +```text +sdk_surface_node_smoke=ok +ini_panel_ui_shell_node_smoke=ok +ini_panel_shell_integration_manifest_node_smoke=ok +ini_panel_launch_api_manifest_node_smoke=ok +ini_panel_entry_docs_node_smoke=ok +browser_ini_workflow_overview_smoke=ok +browser_ini_shell_integration_workflow_smoke=ok +project_release_handoff_docs_node_smoke=ok +``` + +下一步工作计划: + +继续只做实质能力推进。优先选择真实 browser/UI workflow、SDK/API surface、或可执行 release/host gate; +不要做只整理断言或局部常量化的批次。 + 三十九、2026-06-16 继续执行记录:workflow overview release readiness artifact DOM workflow 本轮继续按“每批必须产出可调用 API、可验证 workflow、可执行 gate、或真实 UI/browser 能力”推进, diff --git a/wasm-port/docs/panel-entry.md b/wasm-port/docs/panel-entry.md index fa96121..07c4868 100644 --- a/wasm-port/docs/panel-entry.md +++ b/wasm-port/docs/panel-entry.md @@ -64,6 +64,7 @@ import { renderIniPanelShellWorkflowOverviewEmbeddingMountState, mountIniPanelShellWorkflowOverviewEmbeddingMountState, validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson, + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract, @@ -162,6 +163,10 @@ when an outer shell needs to validate a project release readiness artifact JSON through the same read-only workflow overview surface. It parses the artifact, returns stable validation rows, and does not execute release gates or CNC behavior. +Use `loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()` or +`linuxCncIniPanelWorkflowOverviewApi.loadWorkflowOverviewReleaseReadinessArtifactUrl()` +when the shell should fetch the artifact JSON URL, validate it, and optionally +mount the render-state into caller-owned DOM without executing gates. Use `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract()`, diff --git a/wasm-port/docs/project-release-handoff.md b/wasm-port/docs/project-release-handoff.md index fa13e08..d835404 100644 --- a/wasm-port/docs/project-release-handoff.md +++ b/wasm-port/docs/project-release-handoff.md @@ -46,8 +46,12 @@ continuation records are in `../text14.txt`. and validate it with `createProjectReleaseReadinessArtifactValidation()`. Browser shells can also pass the JSON to `linuxCncIniPanelWorkflowOverviewApi.validateWorkflowOverviewReleaseReadinessArtifactJson()` - through the workflow overview iframe and receive stable validation rows. When - the outer shell needs DOM output, the workflow overview iframe also exposes + through the workflow overview iframe and receive stable validation rows. They + can also call + `linuxCncIniPanelWorkflowOverviewApi.loadWorkflowOverviewReleaseReadinessArtifactUrl()` + to fetch the artifact URL, validate it, and optionally mount the resulting + read-only render state. When the outer shell needs DOM output, the workflow + overview iframe also exposes display, render-state, DOM readiness, renderer, and mount helpers for the same release readiness artifact validation. - OPFS/session callers can use `createMachineSessionPersistenceSummary()` or diff --git a/wasm-port/runtime/sdk/README.md b/wasm-port/runtime/sdk/README.md index 7663c8a..63fd94d 100644 --- a/wasm-port/runtime/sdk/README.md +++ b/wasm-port/runtime/sdk/README.md @@ -64,6 +64,7 @@ import { isSupportedIniPanelControlPageApiManifest, isSupportedIniPanelLaunchApiManifest, isSupportedIniPanelShellIntegrationManifest, + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, loadMachineSessionFromOpfs, loadMachineSessionSnapshot, loadMachineTextFiles, @@ -273,6 +274,9 @@ for external browser shells: - `validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson()` for the read-only workflow overview artifact validation wrapper exposed by `workflow-overview.html`. Use + `loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()` when a + browser or shell should fetch the artifact JSON URL, validate it, and + optionally mount the resulting render-state into caller-owned DOM. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract()`, diff --git a/wasm-port/runtime/sdk/src/index.js b/wasm-port/runtime/sdk/src/index.js index 30d540d..5202abb 100644 --- a/wasm-port/runtime/sdk/src/index.js +++ b/wasm-port/runtime/sdk/src/index.js @@ -110,6 +110,7 @@ export { isSupportedIniPanelShellIntegrationManifest, isSupportedIniPanelShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffSummary, + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, mountIniPanelShellSessionHandoff, mountIniPanelShellWorkflowOverviewEmbedding, mountIniPanelShellWorkflowOverviewEmbeddingMountState, diff --git a/wasm-port/runtime/ui/ini-panel/launch.html b/wasm-port/runtime/ui/ini-panel/launch.html index 854eef3..b51b0cb 100644 --- a/wasm-port/runtime/ui/ini-panel/launch.html +++ b/wasm-port/runtime/ui/ini-panel/launch.html @@ -297,6 +297,9 @@ mountWorkflowOverviewEmbedding: (options) => ( shellViewModel.mountWorkflowOverviewEmbedding(options) ), + loadWorkflowOverviewReleaseReadinessArtifactUrl: (options) => ( + shellViewModel.loadWorkflowOverviewReleaseReadinessArtifactUrl(options) + ), getWorkflowOverviewEmbeddingReport: (embeddingResult, contract) => ( shellViewModel.createWorkflowOverviewEmbeddingReport(embeddingResult, contract) ), diff --git a/wasm-port/runtime/ui/ini-panel/ui-shell.js b/wasm-port/runtime/ui/ini-panel/ui-shell.js index 3daaf90..a3e6200 100644 --- a/wasm-port/runtime/ui/ini-panel/ui-shell.js +++ b/wasm-port/runtime/ui/ini-panel/ui-shell.js @@ -194,6 +194,7 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr "getWorkflowOverviewContract", "getWorkflowOverviewReadiness", "mountWorkflowOverviewEmbedding", + "loadWorkflowOverviewReleaseReadinessArtifactUrl", "getWorkflowOverviewEmbeddingReport", "getWorkflowOverviewEmbeddingDisplayViewModel", "getWorkflowOverviewEmbeddingRenderState", @@ -1874,6 +1875,7 @@ export function createIniPanelShellWorkflowOverviewContract() { "getWorkflowOverviewApiSurfaceInventory", "getWorkflowOverviewPersistenceSummary", "validateWorkflowOverviewReleaseReadinessArtifactJson", + "loadWorkflowOverviewReleaseReadinessArtifactUrl", "getWorkflowOverviewReleaseReadinessArtifactDisplayViewModel", "getWorkflowOverviewReleaseReadinessArtifactRenderState", "getWorkflowOverviewReleaseReadinessArtifactDomContract", @@ -1929,6 +1931,111 @@ export function validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJso } } +export async function loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({ + artifactUrl = "", + fetchRef = globalThis.fetch, + mount = false, + mountOptions = {}, +} = {}) { + const missing = [ + ...(artifactUrl ? [] : ["artifact-url"]), + ...(typeof fetchRef === "function" ? [] : ["fetch"]), + ]; + if (missing.length > 0) { + return { + apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow", + workflowVersion: 1, + phase: "blocked", + ready: false, + artifactUrl, + httpStatus: null, + missing, + error: null, + validation: null, + displayViewModel: null, + renderState: null, + mountResult: null, + statusLine: `Blocked: ${missing.join(", ")}`, + }; + } + + try { + const response = await fetchRef(artifactUrl); + const httpStatus = response?.status ?? null; + if (!response?.ok) { + return { + apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow", + workflowVersion: 1, + phase: "blocked", + ready: false, + artifactUrl, + httpStatus, + missing: ["artifact-url"], + error: `HTTP ${httpStatus ?? "error"}`, + validation: null, + displayViewModel: null, + renderState: null, + mountResult: null, + statusLine: `Blocked: HTTP ${httpStatus ?? "error"}`, + }; + } + + const artifactJson = await response.text(); + const validation = validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(artifactJson); + const displayViewModel = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel( + validation, + ); + const renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState( + displayViewModel, + ); + const mountResult = mount + ? mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState({ + renderState, + ...mountOptions, + }) + : null; + const mountMissing = mount && mountResult?.ready !== true + ? (mountResult?.domReadiness?.missing ?? ["release-readiness-artifact-dom"]) + : []; + const workflowMissing = [ + ...validation.missing, + ...mountMissing, + ]; + const ready = validation.ready === true && (!mount || mountResult?.ready === true); + return { + apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow", + workflowVersion: 1, + phase: ready ? "ready" : "blocked", + ready, + artifactUrl, + httpStatus, + missing: workflowMissing, + error: null, + validation, + displayViewModel, + renderState, + mountResult, + statusLine: ready ? renderState.statusLine : `Blocked: ${workflowMissing.join(", ")}`, + }; + } catch (error) { + return { + apiName: "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow", + workflowVersion: 1, + phase: "blocked", + ready: false, + artifactUrl, + httpStatus: null, + missing: ["artifact-url"], + error: error?.message ?? String(error), + validation: null, + displayViewModel: null, + renderState: null, + mountResult: null, + statusLine: `Blocked: ${error?.message ?? "release readiness artifact URL load error"}`, + }; + } +} + export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel( validation = validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson("{}"), ) { @@ -3163,6 +3270,8 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries mountShellSessionHandoffWorkflow: mountIniPanelShellSessionHandoffWorkflow, createWorkflowOverviewContract: createIniPanelShellWorkflowOverviewContract, createWorkflowOverviewReadiness: createIniPanelShellWorkflowOverviewReadiness, + loadWorkflowOverviewReleaseReadinessArtifactUrl: + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, mountWorkflowOverviewEmbedding: mountIniPanelShellWorkflowOverviewEmbedding, createWorkflowOverviewEmbeddingReport: createIniPanelShellWorkflowOverviewEmbeddingReport, createWorkflowOverviewEmbeddingDisplayViewModel: createIniPanelShellWorkflowOverviewEmbeddingDisplayViewModel, diff --git a/wasm-port/runtime/ui/ini-panel/workflow-overview.html b/wasm-port/runtime/ui/ini-panel/workflow-overview.html index 16ca4df..9ce2b53 100644 --- a/wasm-port/runtime/ui/ini-panel/workflow-overview.html +++ b/wasm-port/runtime/ui/ini-panel/workflow-overview.html @@ -106,6 +106,7 @@ renderIniPanelShellWorkflowOverviewEmbeddingMountState, mountIniPanelShellWorkflowOverviewEmbeddingMountState, validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson, + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract, @@ -143,6 +144,9 @@ validateWorkflowOverviewReleaseReadinessArtifactJson: (artifactJson) => ( validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(artifactJson) ), + loadWorkflowOverviewReleaseReadinessArtifactUrl: (options) => ( + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl(options) + ), getWorkflowOverviewReleaseReadinessArtifactDisplayViewModel: (validation) => ( createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel(validation) ), diff --git a/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html b/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html index 6740bd0..22bda1d 100644 --- a/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html +++ b/wasm-port/tests/browser/ini_panel_shell_integration_workflow_smoke.html @@ -115,6 +115,7 @@ TOOL_TABLE = browser-shell-tool.tbl !launchApi?.getWorkflowOverviewContract || !launchApi?.getWorkflowOverviewReadiness || !launchApi?.mountWorkflowOverviewEmbedding || + !launchApi?.loadWorkflowOverviewReleaseReadinessArtifactUrl || !launchApi?.getWorkflowOverviewEmbeddingReport || !launchApi?.getWorkflowOverviewEmbeddingDisplayViewModel || !launchApi?.getWorkflowOverviewEmbeddingRenderState || @@ -378,6 +379,19 @@ TOOL_TABLE = browser-shell-tool.tbl contract: workflowOverviewReleaseArtifactDomContract, documentRef: document, }); + const workflowOverviewReleaseArtifactUrlWorkflow = await workflowOverviewApi + .loadWorkflowOverviewReleaseReadinessArtifactUrl({ + artifactUrl: "../../tests/fixtures/project-release-readiness-ready.json", + mount: true, + mountOptions: { + contract: workflowOverviewReleaseArtifactDomContract, + documentRef: document, + }, + }); + const launchReleaseArtifactUrlWorkflow = await launchApi + .loadWorkflowOverviewReleaseReadinessArtifactUrl({ + artifactUrl: "../../tests/fixtures/project-release-readiness-ready.json", + }); const workflowOverviewEmbedding = launchApi.mountWorkflowOverviewEmbedding({ overviewApi: workflowOverviewApi, }); @@ -464,6 +478,21 @@ TOOL_TABLE = browser-shell-tool.tbl true, "shell workflow overview release artifact mount readiness", ); + assertEqual( + workflowOverviewReleaseArtifactUrlWorkflow.ready, + true, + "shell workflow overview release artifact URL workflow readiness", + ); + assertEqual( + workflowOverviewReleaseArtifactUrlWorkflow.mountResult.ready, + true, + "shell workflow overview release artifact URL workflow mount", + ); + assertEqual( + launchReleaseArtifactUrlWorkflow.ready, + true, + "launch release artifact URL workflow readiness", + ); assertEqual( document.querySelector("[data-external-release-artifact-status]").textContent, "Ready: No blocking reasons", 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 eaa0195..e5f4356 100644 --- a/wasm-port/tests/browser/ini_panel_workflow_overview_smoke.html +++ b/wasm-port/tests/browser/ini_panel_workflow_overview_smoke.html @@ -35,6 +35,7 @@ !workflowApi?.getWorkflowOverviewApiSurfaceInventory || !workflowApi?.getWorkflowOverviewPersistenceSummary || !workflowApi?.validateWorkflowOverviewReleaseReadinessArtifactJson || + !workflowApi?.loadWorkflowOverviewReleaseReadinessArtifactUrl || !workflowApi?.getWorkflowOverviewReleaseReadinessArtifactDisplayViewModel || !workflowApi?.getWorkflowOverviewReleaseReadinessArtifactRenderState || !workflowApi?.getWorkflowOverviewReleaseReadinessArtifactDomContract || @@ -271,11 +272,18 @@ const releaseArtifactMountResult = workflowApi.mountWorkflowOverviewReleaseReadinessArtifactState({ renderState: releaseArtifactRenderState, }); + const releaseArtifactUrlWorkflow = await workflowApi.loadWorkflowOverviewReleaseReadinessArtifactUrl({ + artifactUrl: "../../tests/fixtures/project-release-readiness-ready.json", + mount: true, + }); assertEqual(releaseArtifactDomReadinessReady.ready, true, "workflow overview release artifact DOM readiness"); assertEqual(releaseArtifactRenderResult.rendered, true, "workflow overview release artifact render result"); assertEqual(releaseArtifactRenderResult.rowCount, 3, "workflow overview release artifact render row count"); assertEqual(releaseArtifactMountResult.ready, true, "workflow overview release artifact mount readiness"); assertEqual(releaseArtifactMountResult.renderResult.rowCount, 3, "workflow overview release artifact mount rows"); + assertEqual(releaseArtifactUrlWorkflow.ready, true, "workflow overview release artifact URL workflow readiness"); + assertEqual(releaseArtifactUrlWorkflow.httpStatus, 200, "workflow overview release artifact URL workflow status"); + assertEqual(releaseArtifactUrlWorkflow.mountResult.ready, true, "workflow overview release artifact URL workflow mount"); assertEqual(releaseArtifactStatus.textContent, releaseArtifactRenderState.statusLine, "workflow overview release artifact rendered status"); assertEqual( workflowDoc.querySelector("[data-handoff-workflow]").dataset.handoffScope, diff --git a/wasm-port/tests/docs/node/verify_project_release_handoff_docs.mjs b/wasm-port/tests/docs/node/verify_project_release_handoff_docs.mjs index f164a66..e6d4f85 100644 --- a/wasm-port/tests/docs/node/verify_project_release_handoff_docs.mjs +++ b/wasm-port/tests/docs/node/verify_project_release_handoff_docs.mjs @@ -35,6 +35,7 @@ for (const phrase of [ "parseProjectReleaseReadinessArtifactJson()", "createProjectReleaseReadinessArtifactValidation()", "validateWorkflowOverviewReleaseReadinessArtifactJson()", + "loadWorkflowOverviewReleaseReadinessArtifactUrl()", "render-state", "DOM readiness", "createIniPanelShellApiSurfaceInventory()", @@ -96,6 +97,7 @@ for (const phrase of [ "createProjectReleaseReadinessReport()", "parseProjectReleaseReadinessArtifactJson()", "createProjectReleaseReadinessArtifactValidation()", + "loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()", "build/project-release-readiness.json", "INI panel shell handoff exports", "createIniPanelShellApiSurfaceInventory()", diff --git a/wasm-port/tests/fixtures/project-release-readiness-ready.json b/wasm-port/tests/fixtures/project-release-readiness-ready.json new file mode 100644 index 0000000..4bfe00f --- /dev/null +++ b/wasm-port/tests/fixtures/project-release-readiness-ready.json @@ -0,0 +1,116 @@ +{ + "apiName": "project-release-readiness-report", + "reportVersion": 1, + "phase": "ready", + "ready": true, + "missing": [], + "releaseGate": { + "command": "wasm-port/tests/host/verify_project_release_gate.sh", + "passed": true, + "expectedOutput": "project_release_gate=ok" + }, + "simConfigInventory": { + "executed": 28, + "passed": 28, + "skipped": 131, + "unexpectedFail": 0 + }, + "blockedRuntimeFamilies": [ + "L4-USER-M-PROCESS", + "L4-TOOL-DB", + "L4-PYTHON-REMAP" + ], + "promotedRuntimeFamilies": [], + "promotedBlockedFamilies": [], + "gates": [ + { + "id": "diff-check", + "label": "Git diff check", + "command": "git diff --check", + "expectedOutput": null, + "status": "passed", + "passed": true + }, + { + "id": "vendor-sync", + "label": "Vendor sync guard", + "command": "wasm-port/tools/verify_vendor_sync.sh", + "expectedOutput": "vendor sync up to date", + "status": "passed", + "passed": true + }, + { + "id": "standalone-cnc-semantics", + "label": "Standalone CNC semantics guard", + "command": "wasm-port/tools/verify_no_standalone_cnc_semantics.sh", + "expectedOutput": "standalone CNC semantics guard complete", + "status": "passed", + "passed": true + }, + { + "id": "interp-wasm", + "label": "Interpreter WASM Node smoke", + "command": "SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh", + "expectedOutput": "interp_wasm_node_smoke=ok", + "status": "passed", + "passed": true + }, + { + "id": "sim-config-inventory", + "label": "Sim config inventory WASM Node smoke", + "command": "SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh", + "expectedOutput": "sim_configs_wasm_node_inventory_unexpected_fail=0", + "status": "passed", + "passed": true + }, + { + "id": "ini-panel-browser", + "label": "INI panel browser smoke", + "command": "SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh", + "expectedOutput": "browser_ini_shell_integration_workflow_smoke=ok", + "status": "passed", + "passed": true + }, + { + "id": "ui-node-smokes", + "label": "UI Node smokes", + "command": "wasm-port/tests/ui/node/verify_ui_node_smokes.sh", + "expectedOutput": "ui_node_smokes=ok", + "status": "passed", + "passed": true + }, + { + "id": "host-smokes", + "label": "Host aggregate smoke", + "command": "wasm-port/tests/host/verify_host_smokes.sh", + "expectedOutput": "host_wasm_opfs_browser_smokes=ok", + "status": "passed", + "passed": true + }, + { + "id": "project-release-gate", + "label": "Project release gate", + "command": "wasm-port/tests/host/verify_project_release_gate.sh", + "expectedOutput": "project_release_gate=ok", + "status": "passed", + "passed": true + } + ], + "rows": [ + { + "id": "project-release-gate", + "label": "Project release gate", + "value": "passed" + }, + { + "id": "sim-config-inventory", + "label": "Sim config inventory", + "value": "unexpected_fail=0" + }, + { + "id": "blocked-runtime-families", + "label": "Blocked runtime families", + "value": "L4-USER-M-PROCESS, L4-TOOL-DB, L4-PYTHON-REMAP" + } + ] +} diff --git a/wasm-port/tests/sdk/node/verify_sdk_surface.mjs b/wasm-port/tests/sdk/node/verify_sdk_surface.mjs index 6a1ec64..0d4396c 100644 --- a/wasm-port/tests/sdk/node/verify_sdk_surface.mjs +++ b/wasm-port/tests/sdk/node/verify_sdk_surface.mjs @@ -46,6 +46,7 @@ import { isSupportedIniPanelControlPageApiManifest, isSupportedIniPanelLaunchApiManifest, isSupportedIniPanelShellIntegrationManifest, + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, loadMachineSessionFromOpfs, loadMachineSessionSnapshot, loadMachineTextFiles, @@ -89,6 +90,10 @@ const requiredExports = [ "validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson", validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson, ], + [ + "loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl", + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, + ], ["planIniFileContextStaging", planIniFileContextStaging], ["planSimConfigStaging", planSimConfigStaging], ["analyzeIniRuntimeBoundaries", analyzeIniRuntimeBoundaries], @@ -280,6 +285,17 @@ assert.equal( validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(JSON.stringify(releaseReadinessArtifact)).ready, true, ); +assert.equal( + (await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({ + artifactUrl: "/project-release-readiness.json", + fetchRef: async () => ({ + ok: true, + status: 200, + text: async () => JSON.stringify(releaseReadinessArtifact), + }), + })).ready, + true, +); assert.equal( createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState( createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel( diff --git a/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs b/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs index df0bb1e..367885b 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_entry_docs.mjs @@ -54,6 +54,7 @@ import { renderIniPanelShellWorkflowOverviewEmbeddingMountState, mountIniPanelShellWorkflowOverviewEmbeddingMountState, validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson, + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract, @@ -162,6 +163,7 @@ const requiredShellExports = [ "renderIniPanelShellWorkflowOverviewEmbeddingMountState", "mountIniPanelShellWorkflowOverviewEmbeddingMountState", "validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson", + "loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl", "createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel", "createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState", "createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract", diff --git a/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs b/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs index 82dc1b2..55a0867 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_launch_api_manifest.mjs @@ -82,6 +82,7 @@ assert.deepEqual(manifest, { "getWorkflowOverviewContract", "getWorkflowOverviewReadiness", "mountWorkflowOverviewEmbedding", + "loadWorkflowOverviewReleaseReadinessArtifactUrl", "getWorkflowOverviewEmbeddingReport", "getWorkflowOverviewEmbeddingDisplayViewModel", "getWorkflowOverviewEmbeddingRenderState", @@ -241,6 +242,7 @@ assert.match(launchText, /\bmountShellSessionHandoffWorkflow\b/); assert.match(launchText, /\bgetWorkflowOverviewContract\b/); assert.match(launchText, /\bgetWorkflowOverviewReadiness\b/); assert.match(launchText, /\bmountWorkflowOverviewEmbedding\b/); +assert.match(launchText, /\bloadWorkflowOverviewReleaseReadinessArtifactUrl\b/); assert.match(launchText, /\bgetWorkflowOverviewEmbeddingReport\b/); assert.match(launchText, /\bgetWorkflowOverviewEmbeddingDisplayViewModel\b/); assert.match(launchText, /\bgetWorkflowOverviewEmbeddingRenderState\b/); diff --git a/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs b/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs index 42861ec..0b2c4f8 100644 --- a/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs +++ b/wasm-port/tests/ui/node/verify_ini_panel_shell_integration_manifest.mjs @@ -52,6 +52,7 @@ import { renderIniPanelShellWorkflowOverviewEmbeddingMountState, mountIniPanelShellWorkflowOverviewEmbeddingMountState, validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson, + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract, @@ -186,7 +187,7 @@ assert.deepEqual(readiness, { counts: { pages: 3, launcherLinks: 3, - launchMethods: 58, + launchMethods: 59, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -249,7 +250,7 @@ assert.deepEqual(handoffSummary, { counts: { pages: 3, launcherLinks: 3, - launchMethods: 58, + launchMethods: 59, controlPageMethods: 11, persistenceCapabilities: 3, }, @@ -788,6 +789,7 @@ assert.deepEqual(createIniPanelShellWorkflowOverviewContract(), { "getWorkflowOverviewApiSurfaceInventory", "getWorkflowOverviewPersistenceSummary", "validateWorkflowOverviewReleaseReadinessArtifactJson", + "loadWorkflowOverviewReleaseReadinessArtifactUrl", "getWorkflowOverviewReleaseReadinessArtifactDisplayViewModel", "getWorkflowOverviewReleaseReadinessArtifactRenderState", "getWorkflowOverviewReleaseReadinessArtifactDomContract", @@ -832,6 +834,7 @@ assert.equal(typeof createIniPanelShellWorkflowOverviewEmbeddingMountDomReadines assert.equal(typeof renderIniPanelShellWorkflowOverviewEmbeddingMountState, "function"); assert.equal(typeof mountIniPanelShellWorkflowOverviewEmbeddingMountState, "function"); assert.equal(typeof validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson, "function"); +assert.equal(typeof loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, "function"); assert.equal(typeof createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel, "function"); assert.equal(typeof createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState, "function"); assert.equal(typeof createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract, "function"); @@ -855,6 +858,7 @@ assert.deepEqual( "getWorkflowOverviewSummary", "getWorkflowOverviewPersistenceSummary", "validateWorkflowOverviewReleaseReadinessArtifactJson", + "loadWorkflowOverviewReleaseReadinessArtifactUrl", "getWorkflowOverviewReleaseReadinessArtifactDisplayViewModel", "getWorkflowOverviewReleaseReadinessArtifactRenderState", "getWorkflowOverviewReleaseReadinessArtifactDomContract", @@ -1280,7 +1284,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), { counts: { pages: 3, launcherLinks: 3, - launchMethods: 58, + launchMethods: 59, controlPageMethods: 11, persistenceCapabilities: 3, }, 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 0e3497e..8b5b00b 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 @@ -52,6 +52,7 @@ import { renderIniPanelShellWorkflowOverviewEmbeddingMountState, mountIniPanelShellWorkflowOverviewEmbeddingMountState, validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson, + loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract, @@ -682,6 +683,7 @@ assert.deepEqual(shellViewModel.shellWorkflowOverviewContract, { "getWorkflowOverviewApiSurfaceInventory", "getWorkflowOverviewPersistenceSummary", "validateWorkflowOverviewReleaseReadinessArtifactJson", + "loadWorkflowOverviewReleaseReadinessArtifactUrl", "getWorkflowOverviewReleaseReadinessArtifactDisplayViewModel", "getWorkflowOverviewReleaseReadinessArtifactRenderState", "getWorkflowOverviewReleaseReadinessArtifactDomContract", @@ -1379,6 +1381,56 @@ assert.deepEqual( validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson("{").missing, ["artifact-json"], ); +assert.equal( + (await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()).statusLine, + "Blocked: artifact-url", +); +const releaseArtifactUrlWorkflow = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({ + artifactUrl: "/project-release-readiness.json", + fetchRef: async (url) => ({ + ok: url === "/project-release-readiness.json", + status: 200, + text: async () => releaseReadinessArtifactJson, + }), + mount: true, + mountOptions: { + documentRef: mountDocument, + mountNode: releaseArtifactMountNode, + statusNode: releaseArtifactStatusNode, + rowsNode: releaseArtifactRowsNode, + }, +}); +assert.equal( + releaseArtifactUrlWorkflow.apiName, + "ini-panel-shell-workflow-overview-release-readiness-artifact-url-workflow", +); +assert.equal(releaseArtifactUrlWorkflow.ready, true); +assert.equal(releaseArtifactUrlWorkflow.httpStatus, 200); +assert.equal(releaseArtifactUrlWorkflow.validation.ready, true); +assert.equal(releaseArtifactUrlWorkflow.renderState.statusLine, "Ready: No blocking reasons"); +assert.equal(releaseArtifactUrlWorkflow.mountResult.ready, true); +assert.equal(releaseArtifactUrlWorkflow.mountResult.renderResult.rowCount, 3); +const releaseArtifactUrlWorkflowMissingDom = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({ + artifactUrl: "/project-release-readiness.json", + fetchRef: async () => ({ + ok: true, + status: 200, + text: async () => releaseReadinessArtifactJson, + }), + mount: true, +}); +assert.equal(releaseArtifactUrlWorkflowMissingDom.ready, false); +assert.deepEqual(releaseArtifactUrlWorkflowMissingDom.missing, ["document", "mount", "status", "rows"]); +const releaseArtifactUrlWorkflowHttpBlocked = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({ + artifactUrl: "/missing.json", + fetchRef: async () => ({ + ok: false, + status: 404, + text: async () => "", + }), +}); +assert.equal(releaseArtifactUrlWorkflowHttpBlocked.ready, false); +assert.equal(releaseArtifactUrlWorkflowHttpBlocked.statusLine, "Blocked: HTTP 404"); assert.deepEqual(createIniPanelShellWorkflowOverviewReadiness(), { apiName: "ini-panel-shell-workflow-overview-readiness", readinessVersion: 1, @@ -1395,6 +1447,7 @@ const workflowOverviewApi = { getWorkflowOverviewApiSurfaceInventory: () => shellViewModel.shellApiSurfaceInventory, getWorkflowOverviewPersistenceSummary: () => shellViewModel.shellPersistenceSummary, validateWorkflowOverviewReleaseReadinessArtifactJson: () => ({ ready: true }), + loadWorkflowOverviewReleaseReadinessArtifactUrl: loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, getWorkflowOverviewReleaseReadinessArtifactDisplayViewModel: () => releaseArtifactDisplay, getWorkflowOverviewReleaseReadinessArtifactRenderState: () => releaseArtifactRenderState, getWorkflowOverviewReleaseReadinessArtifactDomContract: createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract,