推进QtDragon虚拟HAL浏览器诊断证据

This commit is contained in:
2026-06-18 04:53:59 +08:00
parent 0bc6896b36
commit 3bc3b453c4
7 changed files with 275 additions and 35 deletions

View File

@@ -516,3 +516,61 @@ git diff --check ok
`qtdragon_hd_z_compensation`、`qtvcp_screens/qtdragon`。
3. 将 `axis/vismach/puma/puma_seam_weld.ngc` 与 `axis/rose_engine/rcone_demo.ngc`
纳入 browser diagnostics candidate evidence形成非 QtDragon 的 promotion 案例。
### 二、2026-06-18 QtDragon Family Browser Diagnostics Promotion
本批接续上一批 candidate report完成 QtDragon family 全组 browser diagnostics evidence
推进,并保持 inventory baseline 不变。
新增实质能力:
- `VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS` 的 `qtdragon-on-abort` target 补齐:
- `qtdragon/qtdragon_xyz45/qtdragon_xyza.ini`
- `qtdragon/qtdragon_xyz45/on_abort.ngc`
- `qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini`
- `qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc`
- release diagnostics validation 从只要求
`qtdragon-multi-joint-on-abort` 扩展为要求 QtDragon family 6 个 candidate 全部
ready
- `qtdragon-multi-joint-on-abort`
- `qtdragon-xyz-on-abort`
- `qtdragon-xyz45-on-abort`
- `qtdragon-hd-xyz-on-abort`
- `qtdragon-hd-z-compensation-on-abort`
- `qtvcp-screens-qtdragon-on-abort`
- 每个 QtDragon candidate 必须满足:
- `complete === true`
- `currentNodeInventoryStatus === "PASS"`
- `blockedKind === "-"`
- `targetBrowserEvidence === "explicit-browser-diagnostics"`
- source files 同时包含对应 LinuxCNC INI 与 G-code 文件;
- real browser simulation diagnostics artifact 同步要求 QtDragon family 全组 candidate
evidence
- coverage matrix 注释从“browser representative delegated to woodpecker”同步为
virtual HAL promotion candidate gate 已导出 explicit browser diagnostics evidence
- promotion analysis 文档新增本批 QtDragon family promotion evidence 小节。
语义边界:
- 本批没有降低 inventory skip count
- 当前 baseline 仍是 `executed=28`、`passed=28`、`skipped=131`、
`unexpected_fail=0`
- 本批只推进 source-derived diagnostics evidence不新增
G-code/interpreter/planner/kinematics/remap 语义;
- virtual HAL 已满足 Web 方式数控系统仿真系统,并在仿真范围内替代 LinuxCNC
realtime HAL、`halcmd`、motion controller
- virtual HAL 仍不提供 Linux kernel hard-realtime ABI、外部硬件驱动 ABI 或 native
HAL module ABI
- `L4-PYTHON-REMAP`、`L4-TOOL-DB`、`L4-USER-M-PROCESS`、`UPSTREAM-DEMO` 仍保持
locked
- G-code/interpreter/planner/canonical motion 语义仍来自 LinuxCNC-backed WASM。
下一步工作建议:
1. 推进非 QtDragon browser diagnostics promotion
`axis/vismach/puma/puma_seam_weld.ngc` 与
`axis/rose_engine/rcone_demo.ngc`。
2. 为 PUMA / rose engine 增加 release diagnostics validation 中的 required candidate
gate形成非 Qt、非 on-abort family 的 promotion proof。
3. 之后再设计 macro/load non-main fixture report不把 macro/load 误作为 standalone
browser main program 执行。

View File

@@ -175,6 +175,44 @@ wasm-port/tests/sdk/node/verify_sdk_surface.sh
SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh
```
## 2026-06-18 QtDragon Family Promotion Evidence
The first promotion-candidate gate has now been extended from a single
`qtdragon/qtdragon_multi_joint/on_abort.ngc` row to the full QtDragon
on-abort family:
- `qtdragon/qtdragon_multi_joint/on_abort.ngc`
- `qtdragon/qtdragon_xyz/on_abort.ngc`
- `qtdragon/qtdragon_xyz45/on_abort.ngc`
- `qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc`
- `qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc`
- `qtvcp_screens/qtdragon/on_abort.ngc`
The implementation remains a diagnostics/evidence promotion, not an inventory
baseline change. The rows still report Node inventory `PASS` with matrix
`INV`, but the virtual HAL promotion candidate report and real browser
diagnostics artifact now require every QtDragon candidate to be complete, to
name its LinuxCNC INI and G-code source files, to keep `currentNodeInventoryStatus
=== "PASS"`, and to target `explicit-browser-diagnostics`.
The virtual HAL sim-config source coverage target also includes the previously
missing QtDragon `qtdragon_xyz45` and `qtdragon_hd_z_compensation` INI/program
source files. This keeps the report source-derived from vendored LinuxCNC
machine files rather than browser-owned CNC behavior.
Inventory baseline remains:
```text
sim_configs_wasm_node_inventory_executed=28
sim_configs_wasm_node_inventory_passed=28
sim_configs_wasm_node_inventory_skipped=131
sim_configs_wasm_node_inventory_unexpected_fail=0
```
The next practical promotion slice is to add non-Qt evidence for
`axis/vismach/puma/puma_seam_weld.ngc` and
`axis/rose_engine/rcone_demo.ngc`.
## Boundary Statement
This analysis relies on the improved virtual HAL only for Web simulation

View File

@@ -617,14 +617,14 @@ Legend:
| `qtaxis/non-trivial/scara/remap_subs/428remap.ngc` | `qtaxis/non-trivial` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
| `qtaxis/non-trivial/scara/remap_subs/429remap.ngc` | `qtaxis/non-trivial` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
| `qtaxis/non-trivial/scara/remap_subs/430remap.ngc` | `qtaxis/non-trivial` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
| `qtdragon/qtdragon_multi_joint/on_abort.ngc` | `qtdragon/qtdragon_multi_joint` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table now allow Node inventory coverage; browser representative still delegated to the shared `woodpecker/on_abort.ngc` class sample |
| `qtdragon/qtdragon_xyz/on_abort.ngc` | `qtdragon/qtdragon_xyz` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table now allow Node inventory coverage; browser representative still delegated to the shared `woodpecker/on_abort.ngc` class sample |
| `qtdragon/qtdragon_xyz45/on_abort.ngc` | `qtdragon/qtdragon_xyz45` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table now allow Node inventory coverage; browser representative still delegated to the shared `woodpecker/on_abort.ngc` class sample |
| `qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc` | `qtdragon_hd/qtdragon_hd_xyz` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table now allow Node inventory coverage; browser representative still delegated to the shared `woodpecker/on_abort.ngc` class sample |
| `qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc` | `qtdragon_hd/qtdragon_hd_z_compensation` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table now allow Node inventory coverage; browser representative still delegated to the shared `woodpecker/on_abort.ngc` class sample |
| `qtdragon/qtdragon_multi_joint/on_abort.ngc` | `qtdragon/qtdragon_multi_joint` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table allow Node inventory coverage; virtual HAL promotion candidate gate now exports explicit browser diagnostics evidence while inventory baseline remains unchanged |
| `qtdragon/qtdragon_xyz/on_abort.ngc` | `qtdragon/qtdragon_xyz` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table allow Node inventory coverage; QtDragon family promotion candidate gate now exports explicit browser diagnostics evidence while inventory baseline remains unchanged |
| `qtdragon/qtdragon_xyz45/on_abort.ngc` | `qtdragon/qtdragon_xyz45` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table allow Node inventory coverage; QtDragon family promotion candidate gate now exports explicit browser diagnostics evidence while inventory baseline remains unchanged |
| `qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc` | `qtdragon_hd/qtdragon_hd_xyz` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table allow Node inventory coverage; QtDragon family promotion candidate gate now exports explicit browser diagnostics evidence while inventory baseline remains unchanged |
| `qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc` | `qtdragon_hd/qtdragon_hd_z_compensation` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table allow Node inventory coverage; QtDragon family promotion candidate gate now exports explicit browser diagnostics evidence while inventory baseline remains unchanged |
| `qtvcp_screens/industrial_lathe_wear/toolchange.ngc` | `qtvcp_screens/industrial_lathe_wear` | `macro_load` | `PASS` | `-` | `-` | `-` | `-` | `-` | inventory-only macro/load path; macro_load class coverage is represented by `axis/external_offsets/circles.ngc` unless this family is deliberately promoted later |
| `qtvcp_screens/non-trivial/scara/remap_subs/428remap.ngc` | `qtvcp_screens/non-trivial` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
| `qtvcp_screens/non-trivial/scara/remap_subs/429remap.ngc` | `qtvcp_screens/non-trivial` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
| `qtvcp_screens/non-trivial/scara/remap_subs/430remap.ngc` | `qtvcp_screens/non-trivial` | `remap_subroutine` | `PASS` | `-` | `-` | `N/A` | `N/A` | `ASSET-ONLY` | subroutine asset; validate by parse/remap path rather than standalone main-program execution |
| `qtvcp_screens/qtdragon/on_abort.ngc` | `qtvcp_screens/qtdragon` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table now allow Node inventory coverage; browser representative still delegated to the shared `woodpecker/on_abort.ngc` class sample |
| `qtvcp_screens/qtdragon/on_abort.ngc` | `qtvcp_screens/qtdragon` | `main` | `PASS` | `-` | `-` | `INV` | `-` | `-` | vendored INI/tool-table allow Node inventory coverage; QtDragon family promotion candidate gate now exports explicit browser diagnostics evidence while inventory baseline remains unchanged |
| `woodpecker/on_abort.ngc` | `woodpecker` | `main` | `PASS` | `-` | `-` | `REP` | `REP` | `-` | Layer 4 deterministic on_abort class representative now covered |

View File

@@ -97,8 +97,12 @@ export const VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS = Object.freeze([
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc",
"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/on_abort.ngc",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc",
"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini",
"linuxcnc/configs/sim/qtvcp_screens/qtdragon/on_abort.ngc",
]),

View File

@@ -88,6 +88,51 @@ const BLOCKED_RUNTIME_FAMILIES = [
const PROJECT_RELEASE_READINESS_ARTIFACT_API = "project-release-readiness-report";
const PROJECT_RELEASE_READINESS_ARTIFACT_VERSION = 1;
const REQUIRED_QTDRAGON_PROMOTION_CANDIDATES = [
{
id: "qtdragon-multi-joint-on-abort",
sourceFiles: [
"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc",
],
},
{
id: "qtdragon-xyz-on-abort",
sourceFiles: [
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc",
],
},
{
id: "qtdragon-xyz45-on-abort",
sourceFiles: [
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/on_abort.ngc",
],
},
{
id: "qtdragon-hd-xyz-on-abort",
sourceFiles: [
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc",
],
},
{
id: "qtdragon-hd-z-compensation-on-abort",
sourceFiles: [
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc",
],
},
{
id: "qtvcp-screens-qtdragon-on-abort",
sourceFiles: [
"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini",
"linuxcnc/configs/sim/qtvcp_screens/qtdragon/on_abort.ngc",
],
},
];
function isVirtualHalSimConfigSourceCoverageReady(report) {
const coverage = objectOrEmpty(report);
return coverage.apiName === "linuxcnc-wasm-virtual-hal-sim-config-source-coverage-report" &&
@@ -96,7 +141,24 @@ function isVirtualHalSimConfigSourceCoverageReady(report) {
arrayOrEmpty(coverage.missingTargets).length === 0 &&
arrayOrEmpty(coverage.missingCapabilities).length === 0 &&
arrayOrEmpty(coverage.sourceFiles).includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini") &&
arrayOrEmpty(coverage.sourceFiles).includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc");
arrayOrEmpty(coverage.sourceFiles).includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc") &&
arrayOrEmpty(coverage.sourceFiles).includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini") &&
arrayOrEmpty(coverage.sourceFiles).includes(
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini",
);
}
function hasRequiredQtDragonPromotionCandidates(rows) {
return REQUIRED_QTDRAGON_PROMOTION_CANDIDATES.every((candidate) =>
rows.some((row) =>
row.id === candidate.id &&
row.complete === true &&
row.currentNodeInventoryStatus === "PASS" &&
row.blockedKind === "-" &&
row.targetBrowserEvidence === "explicit-browser-diagnostics" &&
candidate.sourceFiles.every((file) => arrayOrEmpty(row.sourceFiles).includes(file))
)
);
}
function isVirtualHalMotionControllerMatrixReady(report) {
@@ -131,15 +193,7 @@ function isVirtualHalSimConfigPromotionCandidateReportReady(report) {
arrayOrEmpty(candidateReport.blockedCandidateIds).length === 0 &&
arrayOrEmpty(candidateReport.missingManifestFiles).length === 0 &&
arrayOrEmpty(candidateReport.missingRequiredReports).length === 0 &&
rows.some((row) =>
row.id === "qtdragon-multi-joint-on-abort" &&
row.complete === true &&
row.currentNodeInventoryStatus === "PASS" &&
row.blockedKind === "-" &&
row.targetBrowserEvidence === "explicit-browser-diagnostics" &&
arrayOrEmpty(row.sourceFiles).includes("linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini") &&
arrayOrEmpty(row.sourceFiles).includes("linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc")
);
hasRequiredQtDragonPromotionCandidates(rows);
}
export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifact = {}) {

View File

@@ -408,6 +408,38 @@
throw new Error(`simulation virtual HAL registry/integrity drift: ${JSON.stringify(initialVirtualHalRegistry)}`);
}
const diagnosticsArtifact = api.exportDiagnosticsArtifact();
const expectedQtDragonPromotionCandidates = [
[
"qtdragon-multi-joint-on-abort",
"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc",
],
[
"qtdragon-xyz-on-abort",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc",
],
[
"qtdragon-xyz45-on-abort",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/on_abort.ngc",
],
[
"qtdragon-hd-xyz-on-abort",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc",
],
[
"qtdragon-hd-z-compensation-on-abort",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc",
],
[
"qtvcp-screens-qtdragon-on-abort",
"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini",
"linuxcnc/configs/sim/qtvcp_screens/qtdragon/on_abort.ngc",
],
];
if (
diagnosticsArtifact.apiName !== "real-browser-simulation-diagnostics-artifact" ||
diagnosticsArtifact.statusHistory.length === 0 ||
@@ -419,12 +451,18 @@
!diagnosticsArtifact.virtualHalSourceCompliance?.sourceFiles?.includes("linuxcnc/src/hal/utils/halcmd_commands.cc") ||
diagnosticsArtifact.virtualHalSimConfigSourceCoverage?.complete !== true ||
!diagnosticsArtifact.virtualHalSimConfigSourceCoverage?.sourceFiles?.includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini") ||
!diagnosticsArtifact.virtualHalSimConfigSourceCoverage?.sourceFiles?.includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini") ||
!diagnosticsArtifact.virtualHalSimConfigSourceCoverage?.sourceFiles?.includes("linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini") ||
diagnosticsArtifact.virtualHalSimConfigPromotionCandidates?.complete !== true ||
!diagnosticsArtifact.virtualHalSimConfigPromotionCandidates?.rows?.some((row) =>
row.id === "qtdragon-multi-joint-on-abort" &&
!expectedQtDragonPromotionCandidates.every(([id, iniPath, gcodePath]) =>
diagnosticsArtifact.virtualHalSimConfigPromotionCandidates?.rows?.some((row) =>
row.id === id &&
row.complete === true &&
row.currentNodeInventoryStatus === "PASS" &&
row.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini")
row.targetBrowserEvidence === "explicit-browser-diagnostics" &&
row.sourceFiles.includes(iniPath) &&
row.sourceFiles.includes(gcodePath)
)
) ||
diagnosticsArtifact.virtualHalCommandScriptFixtures?.complete !== true ||
!diagnosticsArtifact.virtualHalCommandScriptFixtures?.coveredActions?.includes("loadusr") ||
@@ -865,9 +903,14 @@
!api.getVirtualHalSimConfigSourceCoverageReport().sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc") ||
promotionCandidateReport.complete !== true ||
promotionCandidateReport.inventoryBaselineUnchanged !== true ||
!promotionCandidateReport.rows.some(({ id, targetBrowserEvidence }) =>
id === "qtdragon-multi-joint-on-abort" &&
targetBrowserEvidence === "explicit-browser-diagnostics"
!expectedQtDragonPromotionCandidates.every(([id, iniPath, gcodePath]) =>
promotionCandidateReport.rows.some((row) =>
row.id === id &&
row.complete === true &&
row.targetBrowserEvidence === "explicit-browser-diagnostics" &&
row.sourceFiles.includes(iniPath) &&
row.sourceFiles.includes(gcodePath)
)
) ||
api.getVirtualRealtimeHalRuntimeReport().ready !== true ||
api.getVirtualHalSimulationRuntimeReport().replacesHostRuntimeForSimulation !== true

View File

@@ -747,6 +747,13 @@ assert.equal(simConfigSourceCoverageReport.missingTargets.length, 0);
assert.equal(simConfigSourceCoverageReport.missingCapabilities.length, 0);
assert.equal(simConfigSourceCoverageReport.sourceFiles.includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini"), true);
assert.equal(simConfigSourceCoverageReport.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc"), true);
assert.equal(simConfigSourceCoverageReport.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini"), true);
assert.equal(
simConfigSourceCoverageReport.sourceFiles.includes(
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini",
),
true,
);
assert.equal(simConfigSourceCoverageReport.rows.every(({ sourceDerived }) => sourceDerived), true);
assert.equal(virtualHalRuntime.getSimConfigSourceCoverageReport({ manifestText: sourceManifestText }).complete, true);
assert.equal(VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES.length >= 8, true);
@@ -767,17 +774,51 @@ assert.equal(simConfigPromotionCandidateReport.missingCandidates.length, 0);
assert.equal(simConfigPromotionCandidateReport.blockedCandidateIds.length, 0);
assert.equal(simConfigPromotionCandidateReport.missingManifestFiles.length, 0);
assert.equal(simConfigPromotionCandidateReport.missingRequiredReports.length, 0);
assert.equal(
const expectedQtDragonPromotionCandidates = [
[
"qtdragon-multi-joint-on-abort",
"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc",
],
[
"qtdragon-xyz-on-abort",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/qtdragon_inch.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc",
],
[
"qtdragon-xyz45-on-abort",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini",
"linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/on_abort.ngc",
],
[
"qtdragon-hd-xyz-on-abort",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/qtdragon_hd_vertical.ini",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_xyz/on_abort.ngc",
],
[
"qtdragon-hd-z-compensation-on-abort",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/qtdragon_hd_z_compensation.ini",
"linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc",
],
[
"qtvcp-screens-qtdragon-on-abort",
"linuxcnc/configs/sim/qtvcp_screens/qtdragon/qtdragon_mpg.ini",
"linuxcnc/configs/sim/qtvcp_screens/qtdragon/on_abort.ngc",
],
];
for (const [id, iniPath, gcodePath] of expectedQtDragonPromotionCandidates) {
assert.equal(
simConfigPromotionCandidateReport.rows.some((row) =>
row.id === "qtdragon-multi-joint-on-abort" &&
row.id === id &&
row.complete === true &&
row.currentNodeInventoryStatus === "PASS" &&
row.targetBrowserEvidence === "explicit-browser-diagnostics" &&
row.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini") &&
row.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc")
row.sourceFiles.includes(iniPath) &&
row.sourceFiles.includes(gcodePath)
),
true,
);
);
}
assert.equal(simConfigPromotionCandidateReport.rows.every(({ blockedKind }) => blockedKind === "-"), true);
assert.equal(virtualHalRuntime.getSimConfigPromotionCandidateReport({
manifestText: sourceManifestText,
@@ -864,6 +905,8 @@ assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/axis/external_offsets/dynamic_offsets.ini"), true);
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/qtdragon_xyyz.ini"), true);
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_multi_joint/on_abort.ngc"), true);
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz45/qtdragon_xyza.ini"), true);
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/qtdragon_hd/qtdragon_hd_z_compensation/on_abort.ngc"), true);
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/axis/vismach/puma/puma.ini"), true);
const runtimeProjectReport = virtualHalRuntime.getProjectReport({ availableFunctions: VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS });
assert.equal(runtimeProjectReport.simulationRuntime.replacesHostRuntimeForSimulation, true);