虚拟HAL完全满足Web数控仿真
结论:ini-panel workflow overview 已提供固定 URL 表单和按钮,用户可直接输入 release artifact URL 与 browser diagnostics URL 并运行 release URL workflow;该流程验证的 virtual HAL evidence 仍完全来自 LinuxCNC source-derived reports,virtual HAL 继续满足 Web 数控系统仿真范围,不声明 Linux kernel hard-realtime ABI、外部硬件驱动 ABI 或 native HAL module ABI。
This commit is contained in:
76
text17.txt
76
text17.txt
@@ -1190,3 +1190,79 @@ git diff --check ok
|
|||||||
source files 与 vendored LinuxCNC manifest 做显式一致性验证。
|
source files 与 vendored LinuxCNC manifest 做显式一致性验证。
|
||||||
3. 将 virtual HAL session diagnostics artifact 纳入 release artifact URL workflow 的示例
|
3. 将 virtual HAL session diagnostics artifact 纳入 release artifact URL workflow 的示例
|
||||||
fixtures,使 URL workflow 同时覆盖 live diagnostics 与 saved-session diagnostics。
|
fixtures,使 URL workflow 同时覆盖 live diagnostics 与 saved-session diagnostics。
|
||||||
|
|
||||||
|
### 十三、2026-06-17 INI Workflow Overview URL Form
|
||||||
|
|
||||||
|
继续按本文件铁律推进:虚拟 HAL 的功能完全来源于 LinuxCNC 源程序,并且虚拟 HAL
|
||||||
|
完全满足 Web 方式数控系统仿真系统。本批完成上一节下一步第 1 项,把 ini-panel
|
||||||
|
workflow overview 的 diagnostics URL workflow 接入固定页面表单和按钮,让用户可在页面上
|
||||||
|
输入 release artifact URL 与 browser diagnostics URL 后直接运行验证。
|
||||||
|
|
||||||
|
新增实质能力:
|
||||||
|
|
||||||
|
- `workflow-overview.html` 新增固定 URL workflow 表单:
|
||||||
|
- Release artifact URL 输入;
|
||||||
|
- Browser diagnostics URL 输入;
|
||||||
|
- `Run URL Workflow` 按钮;
|
||||||
|
- release artifact URL workflow 状态区;
|
||||||
|
- release artifact URL workflow rows 区;
|
||||||
|
- 页面脚本新增:
|
||||||
|
- `runWorkflowOverviewReleaseReadinessArtifactUrlForm(options)`;
|
||||||
|
- 从页面输入框读取 artifact URL 与 diagnostics URL;
|
||||||
|
- 复用 `loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()`;
|
||||||
|
- 复用 release URL workflow summary/render/mount helpers;
|
||||||
|
- 写入 `document.body.dataset.releaseArtifactUrlWorkflowPhase`;
|
||||||
|
- 写入 `document.body.dataset.releaseArtifactUrlWorkflowReady`;
|
||||||
|
- Browser API 新增:
|
||||||
|
- `runWorkflowOverviewReleaseReadinessArtifactUrlForm()`;
|
||||||
|
- 表单输入使用 `type="text"` 与 `inputmode="url"`,同时支持相对 fixture 路径和真实
|
||||||
|
HTTP/HTTPS URL。
|
||||||
|
|
||||||
|
新增/扩展验证:
|
||||||
|
|
||||||
|
- `ini_panel_workflow_overview_smoke.html` 覆盖:
|
||||||
|
- workflow overview API 暴露 `runWorkflowOverviewReleaseReadinessArtifactUrlForm()`;
|
||||||
|
- 页面固定输入框可写入 release artifact URL 与 diagnostics URL;
|
||||||
|
- 表单 runner 可复用 diagnostics artifact fetch stub;
|
||||||
|
- 表单 runner 返回 `workflow.ready === true`;
|
||||||
|
- 表单 runner 返回 `mountResult.ready === true`;
|
||||||
|
- 页面 body dataset 标记 URL workflow ready;
|
||||||
|
- 页面固定 workflow rows 中 `browser-diagnostics` 行显示 `ready`;
|
||||||
|
- `verify_ini_panel_browser.sh` 聚合确认 workflow overview 页面、launch、control、
|
||||||
|
shell integration 仍全部通过;
|
||||||
|
- `verify_ui_node_smokes.sh` 聚合确认 ui-shell/API manifest/docs 不回归。
|
||||||
|
|
||||||
|
关键验证:
|
||||||
|
|
||||||
|
```text
|
||||||
|
browser_ini_opfs_smoke=ok
|
||||||
|
browser_ini_control_page_smoke=ok
|
||||||
|
browser_ini_launch_smoke=ok
|
||||||
|
browser_ini_workflow_overview_smoke=ok
|
||||||
|
browser_ini_shell_integration_workflow_smoke=ok
|
||||||
|
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
|
||||||
|
ui_node_smokes=ok
|
||||||
|
git diff --check ok
|
||||||
|
```
|
||||||
|
|
||||||
|
语义边界:
|
||||||
|
|
||||||
|
- 本批没有新增 G-code/interpreter/planner/kinematics/remap 语义;
|
||||||
|
- workflow overview 表单只加载并验证 release artifact 与 browser diagnostics artifact;
|
||||||
|
- browser diagnostics artifact 中的 virtual HAL evidence 仍来自 source-derived virtual HAL
|
||||||
|
reports;
|
||||||
|
- virtual HAL 仍不声称提供 Linux kernel hard-realtime ABI、外部硬件驱动 ABI 或 native
|
||||||
|
HAL module ABI;
|
||||||
|
- G-code/interpreter/planner/canonical motion 语义仍来自 LinuxCNC-backed WASM。
|
||||||
|
|
||||||
|
下一步工作内容:
|
||||||
|
|
||||||
|
1. 为 motion matrix 增加 manifest-backed source check,把 matrix 关联的 sim config
|
||||||
|
source files 与 vendored LinuxCNC manifest 做显式一致性验证。
|
||||||
|
2. 将 virtual HAL session diagnostics artifact 纳入 release artifact URL workflow 的示例
|
||||||
|
fixtures,使 URL workflow 同时覆盖 live diagnostics 与 saved-session diagnostics。
|
||||||
|
3. 将 workflow overview 固定 URL 表单的 action-plan 与 gate execution summary rows
|
||||||
|
同屏渲染,便于用户看到 URL workflow 的下一步命令和 gate evidence。
|
||||||
|
|||||||
@@ -68,6 +68,39 @@
|
|||||||
color: var(--text);
|
color: var(--text);
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
.url-workflow-form {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
padding-top: 12px;
|
||||||
|
}
|
||||||
|
.url-workflow-form label {
|
||||||
|
display: grid;
|
||||||
|
gap: 4px;
|
||||||
|
color: var(--muted);
|
||||||
|
font: 12px/1.4 "Segoe UI", "Noto Sans", sans-serif;
|
||||||
|
}
|
||||||
|
.url-workflow-form input {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 32px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
color: var(--text);
|
||||||
|
font: 13px/1.4 "Segoe UI", "Noto Sans", sans-serif;
|
||||||
|
}
|
||||||
|
.url-workflow-form button {
|
||||||
|
justify-self: start;
|
||||||
|
min-height: 32px;
|
||||||
|
border: 1px solid #0f5f9d;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--accent);
|
||||||
|
color: #fff;
|
||||||
|
padding: 6px 12px;
|
||||||
|
font: 13px/1.4 "Segoe UI", "Noto Sans", sans-serif;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -79,6 +112,21 @@
|
|||||||
<p data-handoff-workflow-status>Checking shell handoff workflow summary.</p>
|
<p data-handoff-workflow-status>Checking shell handoff workflow summary.</p>
|
||||||
<dl data-handoff-workflow-rows></dl>
|
<dl data-handoff-workflow-rows></dl>
|
||||||
</section>
|
</section>
|
||||||
|
<form class="url-workflow-form" data-release-artifact-url-workflow-form>
|
||||||
|
<label>
|
||||||
|
Release artifact URL
|
||||||
|
<input type="text" inputmode="url" data-release-artifact-url-input placeholder="../../tests/fixtures/project-release-readiness-ready.json">
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Browser diagnostics URL
|
||||||
|
<input type="text" inputmode="url" data-browser-diagnostics-url-input placeholder="../../tests/fixtures/real-browser-simulation-diagnostics-ready.json">
|
||||||
|
</label>
|
||||||
|
<button type="submit" data-run-release-artifact-url-workflow>Run URL Workflow</button>
|
||||||
|
</form>
|
||||||
|
<section class="overview-status" aria-label="Release artifact URL workflow" data-workflow-overview-release-readiness-artifact-url-workflow>
|
||||||
|
<p data-workflow-overview-release-readiness-artifact-url-workflow-status>Waiting for release artifact URL workflow.</p>
|
||||||
|
<dl data-workflow-overview-release-readiness-artifact-url-workflow-rows></dl>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
@@ -149,6 +197,46 @@
|
|||||||
const shellViewModel = createIniPanelShellViewModel();
|
const shellViewModel = createIniPanelShellViewModel();
|
||||||
const workflowRenderState = shellViewModel.shellSessionHandoffWorkflowRenderState;
|
const workflowRenderState = shellViewModel.shellSessionHandoffWorkflowRenderState;
|
||||||
renderIniPanelShellSessionHandoffWorkflowState(workflowRenderState, { documentRef: document });
|
renderIniPanelShellSessionHandoffWorkflowState(workflowRenderState, { documentRef: document });
|
||||||
|
const releaseArtifactUrlInput = document.querySelector("[data-release-artifact-url-input]");
|
||||||
|
const browserDiagnosticsUrlInput = document.querySelector("[data-browser-diagnostics-url-input]");
|
||||||
|
const releaseArtifactUrlWorkflowForm = document.querySelector("[data-release-artifact-url-workflow-form]");
|
||||||
|
|
||||||
|
async function runWorkflowOverviewReleaseReadinessArtifactUrlForm(options = {}) {
|
||||||
|
const artifactUrl = String(options.artifactUrl ?? releaseArtifactUrlInput?.value ?? "").trim();
|
||||||
|
const diagnosticsUrl = String(options.diagnosticsUrl ?? browserDiagnosticsUrlInput?.value ?? "").trim();
|
||||||
|
const workflow = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({
|
||||||
|
artifactUrl,
|
||||||
|
diagnosticsUrl,
|
||||||
|
fetchRef: options.fetchRef,
|
||||||
|
mount: options.mount ?? true,
|
||||||
|
});
|
||||||
|
const summary = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(workflow);
|
||||||
|
const renderState = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState(summary);
|
||||||
|
const mountResult = mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState({
|
||||||
|
renderState,
|
||||||
|
documentRef: document,
|
||||||
|
});
|
||||||
|
document.body.dataset.releaseArtifactUrlWorkflowPhase = workflow.phase;
|
||||||
|
document.body.dataset.releaseArtifactUrlWorkflowReady = workflow.ready ? "true" : "false";
|
||||||
|
return {
|
||||||
|
workflow,
|
||||||
|
summary,
|
||||||
|
renderState,
|
||||||
|
mountResult,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseArtifactUrlWorkflowForm?.addEventListener("submit", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
runWorkflowOverviewReleaseReadinessArtifactUrlForm().catch((error) => {
|
||||||
|
const status = document.querySelector("[data-workflow-overview-release-readiness-artifact-url-workflow-status]");
|
||||||
|
if (status) {
|
||||||
|
status.textContent = `Blocked: ${error?.message ?? "release artifact URL workflow failed"}`;
|
||||||
|
}
|
||||||
|
document.body.dataset.releaseArtifactUrlWorkflowPhase = "blocked";
|
||||||
|
document.body.dataset.releaseArtifactUrlWorkflowReady = "false";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
window.linuxCncIniPanelWorkflowOverviewApi = {
|
window.linuxCncIniPanelWorkflowOverviewApi = {
|
||||||
getWorkflowOverviewRenderState: () => shellViewModel.shellSessionHandoffWorkflowRenderState,
|
getWorkflowOverviewRenderState: () => shellViewModel.shellSessionHandoffWorkflowRenderState,
|
||||||
@@ -207,6 +295,7 @@
|
|||||||
loadWorkflowOverviewReleaseReadinessArtifactUrl: (options) => (
|
loadWorkflowOverviewReleaseReadinessArtifactUrl: (options) => (
|
||||||
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl(options)
|
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl(options)
|
||||||
),
|
),
|
||||||
|
runWorkflowOverviewReleaseReadinessArtifactUrlForm,
|
||||||
getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel: (workflow) => (
|
getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel: (workflow) => (
|
||||||
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(workflow)
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(workflow)
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
!workflowApi?.getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness ||
|
!workflowApi?.getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness ||
|
||||||
!workflowApi?.renderWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState ||
|
!workflowApi?.renderWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState ||
|
||||||
!workflowApi?.mountWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState ||
|
!workflowApi?.mountWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState ||
|
||||||
|
!workflowApi?.runWorkflowOverviewReleaseReadinessArtifactUrlForm ||
|
||||||
!workflowApi?.getWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel ||
|
!workflowApi?.getWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel ||
|
||||||
!workflowApi?.getWorkflowOverviewReleaseReadinessArtifactValidationActionPlan ||
|
!workflowApi?.getWorkflowOverviewReleaseReadinessArtifactValidationActionPlan ||
|
||||||
!workflowApi?.getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState ||
|
!workflowApi?.getWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState ||
|
||||||
@@ -372,6 +373,20 @@
|
|||||||
},
|
},
|
||||||
mount: true,
|
mount: true,
|
||||||
});
|
});
|
||||||
|
workflowDoc.querySelector("[data-release-artifact-url-input]").value = "../../tests/fixtures/project-release-readiness-ready.json";
|
||||||
|
workflowDoc.querySelector("[data-browser-diagnostics-url-input]").value = "../../tests/fixtures/real-browser-simulation-diagnostics-ready.json";
|
||||||
|
const releaseArtifactUrlFormResult = await workflowApi.runWorkflowOverviewReleaseReadinessArtifactUrlForm({
|
||||||
|
fetchRef: async (url) => {
|
||||||
|
if (String(url).endsWith("real-browser-simulation-diagnostics-ready.json")) {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
text: async () => diagnosticsArtifactJson,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return fetch(url);
|
||||||
|
},
|
||||||
|
});
|
||||||
const releaseArtifactUrlWorkflowSummary = workflowApi
|
const releaseArtifactUrlWorkflowSummary = workflowApi
|
||||||
.getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(releaseArtifactUrlWorkflow);
|
.getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(releaseArtifactUrlWorkflow);
|
||||||
const releaseArtifactUrlWorkflowActionPlan = workflowApi
|
const releaseArtifactUrlWorkflowActionPlan = workflowApi
|
||||||
@@ -519,6 +534,26 @@
|
|||||||
"Ready: Artifact URL workflow complete",
|
"Ready: Artifact URL workflow complete",
|
||||||
"workflow overview release artifact URL workflow rendered status",
|
"workflow overview release artifact URL workflow rendered status",
|
||||||
);
|
);
|
||||||
|
assertEqual(
|
||||||
|
releaseArtifactUrlFormResult.workflow.ready,
|
||||||
|
true,
|
||||||
|
"workflow overview fixed URL workflow form readiness",
|
||||||
|
);
|
||||||
|
assertEqual(
|
||||||
|
releaseArtifactUrlFormResult.mountResult.ready,
|
||||||
|
true,
|
||||||
|
"workflow overview fixed URL workflow form mount readiness",
|
||||||
|
);
|
||||||
|
assertEqual(
|
||||||
|
workflowDoc.body.dataset.releaseArtifactUrlWorkflowReady,
|
||||||
|
"true",
|
||||||
|
"workflow overview fixed URL workflow form body ready",
|
||||||
|
);
|
||||||
|
assertEqual(
|
||||||
|
workflowDoc.querySelector('[data-workflow-overview-release-readiness-artifact-url-workflow-value="browser-diagnostics"]').textContent,
|
||||||
|
"ready",
|
||||||
|
"workflow overview fixed URL workflow form browser diagnostics row",
|
||||||
|
);
|
||||||
assertEqual(
|
assertEqual(
|
||||||
releaseArtifactJsonWorkflow.statusLine,
|
releaseArtifactJsonWorkflow.statusLine,
|
||||||
"Ready: Artifact JSON workflow complete",
|
"Ready: Artifact JSON workflow complete",
|
||||||
|
|||||||
Reference in New Issue
Block a user