接续上一轮,先做 L4-USER-M-PROCESS,完全接入仿真系统
结论:已将 L4-USER-M-PROCESS 的 millturn M128/M129 受控状态转换接入 virtual HAL、真实 browser simulation、OPFS 会话 payload、SDK API 和 release diagnostics validation;外部 user-M process execution 与 promotion 仍保持 locked,不伪装为 native process 解锁。
This commit is contained in:
@@ -12,8 +12,10 @@ import {
|
||||
VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES,
|
||||
VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES,
|
||||
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
||||
VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY,
|
||||
cloneVirtualHalState,
|
||||
createVirtualHalCommandScriptFixtureReport,
|
||||
createVirtualHalMillturnUserMProcessBoundaryReport,
|
||||
createVirtualHalMotionControllerMatrixReport,
|
||||
createVirtualHalSimConfigEvidenceExpansionReport,
|
||||
createVirtualHalSimConfigMacroLoadFixtureReport,
|
||||
@@ -74,6 +76,7 @@ function validateVirtualHalSessionPayload(virtualHal) {
|
||||
assertPlainObject(virtualHal.sourceCompliance, "virtual HAL session source compliance");
|
||||
assertPlainObject(virtualHal.simConfigSourceCoverage, "virtual HAL session sim-config source coverage");
|
||||
assertPlainObject(virtualHal.simConfigPromotionCandidates, "virtual HAL session sim-config promotion candidates");
|
||||
assertPlainObject(virtualHal.millturnUserMProcessBoundary, "virtual HAL session millturn user-M process boundary");
|
||||
assertPlainObject(virtualHal.simConfigMacroLoadFixtures, "virtual HAL session sim-config macro/load fixtures");
|
||||
assertPlainObject(virtualHal.commandScriptFixtures, "virtual HAL session command script fixtures");
|
||||
assertPlainObject(virtualHal.motionControllerMatrix, "virtual HAL session motion controller matrix");
|
||||
@@ -89,6 +92,9 @@ function validateVirtualHalSessionPayload(virtualHal) {
|
||||
if (virtualHal.simConfigPromotionCandidates.complete !== true) {
|
||||
throw new Error("virtual HAL sim-config promotion candidates are incomplete.");
|
||||
}
|
||||
if (virtualHal.millturnUserMProcessBoundary.complete !== true) {
|
||||
throw new Error("virtual HAL millturn user-M process boundary is incomplete.");
|
||||
}
|
||||
if (virtualHal.simConfigEvidenceExpansion.complete !== true) {
|
||||
throw new Error("virtual HAL sim-config evidence expansion candidates are incomplete.");
|
||||
}
|
||||
@@ -116,6 +122,7 @@ export function createVirtualHalSessionPayload(halState = createVirtualHalState(
|
||||
...VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES.flatMap((candidate) => candidate.sourceFiles ?? []),
|
||||
...VIRTUAL_HAL_SIM_CONFIG_EVIDENCE_EXPANSION_CANDIDATES.flatMap((candidate) => candidate.sourceFiles ?? []),
|
||||
...VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES.flatMap((fixture) => fixture.sourceFiles ?? []),
|
||||
...VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.sourceFiles,
|
||||
],
|
||||
}
|
||||
: {}
|
||||
@@ -137,6 +144,7 @@ export function createVirtualHalSessionPayload(halState = createVirtualHalState(
|
||||
commandScriptFixtures,
|
||||
motionControllerMatrix,
|
||||
});
|
||||
const millturnUserMProcessBoundary = options.millturnUserMProcessBoundary ?? createVirtualHalMillturnUserMProcessBoundaryReport(reportOptions);
|
||||
const sourceCompliance = options.sourceCompliance ?? createVirtualHalSourceComplianceReport({
|
||||
...reportOptions,
|
||||
halState: state,
|
||||
@@ -161,6 +169,7 @@ export function createVirtualHalSessionPayload(halState = createVirtualHalState(
|
||||
simConfigSourceCoverage,
|
||||
simConfigPromotionCandidates,
|
||||
simConfigEvidenceExpansion,
|
||||
millturnUserMProcessBoundary,
|
||||
simConfigMacroLoadFixtures,
|
||||
commandScriptFixtures,
|
||||
motionControllerMatrix,
|
||||
|
||||
@@ -318,7 +318,9 @@ private page state.
|
||||
`executeHalcmd()`, `stepMotion()`, `stepMotionController()`,
|
||||
`getSimulationRuntimeReport()`, `getSimulationReplacementReport()`,
|
||||
`getSourceComplianceReport()`, `getSimConfigPromotionCandidateReport()`,
|
||||
`getSimConfigMacroLoadFixtureReport()`, `getIntegrityReport()`,
|
||||
`getSimConfigMacroLoadFixtureReport()`,
|
||||
`getMillturnUserMProcessBoundaryReport()`,
|
||||
`applyMillturnUserMProcessState()`, `getIntegrityReport()`,
|
||||
`getPinInventory()`, `getProjectReport()`, and `applyToInterpSdk()`.
|
||||
- `VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES`,
|
||||
`VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS`,
|
||||
@@ -339,6 +341,18 @@ private page state.
|
||||
`manifestEntries`, the matrix report checks those associated sim-config
|
||||
source files against the vendored LinuxCNC manifest and exposes
|
||||
`manifestChecked` plus `missingManifestFiles`.
|
||||
- `VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY`,
|
||||
`createVirtualHalMillturnUserMProcessBoundaryReport()`, and
|
||||
`applyVirtualHalMillturnUserMProcessState()` expose the controlled
|
||||
millturn `M128`/`M129` user-M process boundary for browser/Node simulation.
|
||||
The report names the LinuxCNC `millturn.ini`, `example.ngc`, Tcl M-code
|
||||
scripts, and remap callers, then lists the source-derived
|
||||
`motion.switchkins-type`, `kinstype.is-*`, and `ini.[xyz].*` HAL state
|
||||
targets. `applyVirtualHalMillturnUserMProcessState()` can apply that
|
||||
controlled state to the virtual HAL for simulation display. It keeps
|
||||
`executionEnabled === false`, `promotionAllowed === false`, and
|
||||
`processExecutionReady === false`; it does not execute arbitrary external
|
||||
user-M processes or unlock `L4-USER-M-PROCESS`.
|
||||
- `VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES` and
|
||||
`createVirtualHalSimConfigPromotionCandidateReport()` expose the current
|
||||
source-derived sim-config promotion candidate set. The first candidates keep
|
||||
|
||||
@@ -5,6 +5,7 @@ export {
|
||||
VIRTUAL_HAL_AXISUI_PINS,
|
||||
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
||||
VIRTUAL_HAL_COVERAGE_STATES,
|
||||
VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY,
|
||||
VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES,
|
||||
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
||||
VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_AUDIT_CANDIDATES,
|
||||
@@ -23,6 +24,7 @@ export {
|
||||
VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS,
|
||||
applyVirtualHalToInterpSdk,
|
||||
applyVirtualHalAction,
|
||||
applyVirtualHalMillturnUserMProcessState,
|
||||
applyVirtualHalPinUpdates,
|
||||
cloneVirtualHalState,
|
||||
createLinuxCncVirtualHalRuntime,
|
||||
@@ -34,6 +36,7 @@ export {
|
||||
createVirtualHalLimitsHomeState,
|
||||
createVirtualHalMachineStatusState,
|
||||
createVirtualHalIntegrityReport,
|
||||
createVirtualHalMillturnUserMProcessBoundaryReport,
|
||||
createVirtualHalPinInventory,
|
||||
createVirtualHalPinRegistry,
|
||||
createVirtualHalProjectReport,
|
||||
|
||||
@@ -32,6 +32,84 @@ export const VIRTUAL_HAL_SOURCE_FILES = Object.freeze({
|
||||
vendoredMotionHeader: "wasm-port/vendor/linuxcnc/src/emc/motion/motion.h",
|
||||
});
|
||||
|
||||
export const VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY = Object.freeze({
|
||||
id: "millturn-user-m-process",
|
||||
label: "Millturn M128/M129 user-M process boundary",
|
||||
boundaryClass: "L4-USER-M-PROCESS",
|
||||
path: "axis/vismach/millturn/example.ngc",
|
||||
ini: "axis/vismach/millturn/millturn.ini",
|
||||
requiredRuntime: "linuxcnc_task_hal_tcl_user_m_process",
|
||||
sourceFiles: Object.freeze([
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/example.ngc",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M129",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc",
|
||||
]),
|
||||
manifestSourceFiles: Object.freeze([
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/example.ngc",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc",
|
||||
]),
|
||||
nativeProbe: "ENABLE_MILLTURN_USER_M_RUNTIME_PROBE=1 bash wasm-port/tests/native/probe_millturn_user_m_runtime.sh",
|
||||
cases: Object.freeze([
|
||||
Object.freeze({
|
||||
userMCode: "M128",
|
||||
remapCode: "M428",
|
||||
stateMode: "mill",
|
||||
guardPin: "kinstype.is-0",
|
||||
switchkinsOutputPin: "motion.analog-out-03",
|
||||
switchkinsTarget: 0,
|
||||
activeG5x: "G59.1",
|
||||
workOffsetPocket: "P7",
|
||||
workOffsetWords: "X-290 Y0 Z-160 A0",
|
||||
sourceField: "MIN_LIMIT/MAX_LIMIT",
|
||||
stateTargets: Object.freeze([
|
||||
Object.freeze({ pin: "ini.x.min_limit", value: -300, sourceSection: "AXIS_X", sourceField: "MIN_LIMIT" }),
|
||||
Object.freeze({ pin: "ini.x.max_limit", value: 300, sourceSection: "AXIS_X", sourceField: "MAX_LIMIT" }),
|
||||
Object.freeze({ pin: "ini.x.min_velocity", value: 60.0, sourceSection: "AXIS_X", sourceField: "MAX_VELOCITY" }),
|
||||
Object.freeze({ pin: "ini.x.max_acceleration", value: 400.0, sourceSection: "AXIS_X", sourceField: "MAX_ACCELERATION" }),
|
||||
Object.freeze({ pin: "ini.y.min_limit", value: -100, sourceSection: "AXIS_Y", sourceField: "MIN_LIMIT" }),
|
||||
Object.freeze({ pin: "ini.y.max_limit", value: 100, sourceSection: "AXIS_Y", sourceField: "MAX_LIMIT" }),
|
||||
Object.freeze({ pin: "ini.y.min_velocity", value: 60.0, sourceSection: "AXIS_Y", sourceField: "MAX_VELOCITY" }),
|
||||
Object.freeze({ pin: "ini.y.max_acceleration", value: 400.0, sourceSection: "AXIS_Y", sourceField: "MAX_ACCELERATION" }),
|
||||
Object.freeze({ pin: "ini.z.min_limit", value: -240, sourceSection: "AXIS_Z", sourceField: "MIN_LIMIT" }),
|
||||
Object.freeze({ pin: "ini.z.max_limit", value: 0, sourceSection: "AXIS_Z", sourceField: "MAX_LIMIT" }),
|
||||
Object.freeze({ pin: "ini.z.min_velocity", value: 60.0, sourceSection: "AXIS_Z", sourceField: "MAX_VELOCITY" }),
|
||||
Object.freeze({ pin: "ini.z.max_acceleration", value: 400.0, sourceSection: "AXIS_Z", sourceField: "MAX_ACCELERATION" }),
|
||||
]),
|
||||
}),
|
||||
Object.freeze({
|
||||
userMCode: "M129",
|
||||
remapCode: "M429",
|
||||
stateMode: "turn",
|
||||
guardPin: "kinstype.is-1",
|
||||
switchkinsOutputPin: "motion.analog-out-03",
|
||||
switchkinsTarget: 1,
|
||||
activeG5x: "G59.2",
|
||||
workOffsetPocket: "P8",
|
||||
workOffsetWords: "X-160 Y0 Z-290 A0",
|
||||
sourceField: "MIN_LIMIT_TURN/MAX_LIMIT_TURN",
|
||||
stateTargets: Object.freeze([
|
||||
Object.freeze({ pin: "ini.x.min_limit", value: -240, sourceSection: "AXIS_X", sourceField: "MIN_LIMIT_TURN" }),
|
||||
Object.freeze({ pin: "ini.x.max_limit", value: 0, sourceSection: "AXIS_X", sourceField: "MAX_LIMIT_TURN" }),
|
||||
Object.freeze({ pin: "ini.x.min_velocity", value: 60.0, sourceSection: "AXIS_X", sourceField: "MAX_VELOCITY" }),
|
||||
Object.freeze({ pin: "ini.x.max_acceleration", value: 400.0, sourceSection: "AXIS_X", sourceField: "MAX_ACCELERATION" }),
|
||||
Object.freeze({ pin: "ini.y.min_limit", value: -100, sourceSection: "AXIS_Y", sourceField: "MIN_LIMIT_TURN" }),
|
||||
Object.freeze({ pin: "ini.y.max_limit", value: 100, sourceSection: "AXIS_Y", sourceField: "MAX_LIMIT_TURN" }),
|
||||
Object.freeze({ pin: "ini.y.min_velocity", value: 60.0, sourceSection: "AXIS_Y", sourceField: "MAX_VELOCITY" }),
|
||||
Object.freeze({ pin: "ini.y.max_acceleration", value: 400.0, sourceSection: "AXIS_Y", sourceField: "MAX_ACCELERATION" }),
|
||||
Object.freeze({ pin: "ini.z.min_limit", value: -300, sourceSection: "AXIS_Z", sourceField: "MIN_LIMIT_TURN" }),
|
||||
Object.freeze({ pin: "ini.z.max_limit", value: 300, sourceSection: "AXIS_Z", sourceField: "MAX_LIMIT_TURN" }),
|
||||
Object.freeze({ pin: "ini.z.min_velocity", value: 60.0, sourceSection: "AXIS_Z", sourceField: "MAX_VELOCITY" }),
|
||||
Object.freeze({ pin: "ini.z.max_acceleration", value: 400.0, sourceSection: "AXIS_Z", sourceField: "MAX_ACCELERATION" }),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
});
|
||||
|
||||
export const VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS = Object.freeze([
|
||||
Object.freeze({
|
||||
id: "axis-foam",
|
||||
@@ -740,6 +818,31 @@ export const VIRTUAL_HAL_SYSTEM_PIN_FAMILIES = Object.freeze([
|
||||
{ name: "motion.switchkins-type", type: "HAL_FLOAT", direction: "HAL_IN", conditional: "switchable kinematics" },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: "millturn-user-m-process",
|
||||
component: "millturn",
|
||||
label: "Millturn user-M process boundary pins",
|
||||
sourceFiles: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.sourceFiles,
|
||||
sourceEvidence: "LinuxCNC millturn M128/M129 Tcl scripts and remap callers set switchkins guard state and ini.[xyz] HAL pins.",
|
||||
coverage: VIRTUAL_HAL_COVERAGE_STATES.runtimeBoundary,
|
||||
pins: Object.freeze([
|
||||
{ name: "motion.analog-out-03", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "kinstype.is-0", type: "HAL_BIT", direction: "HAL_OUT" },
|
||||
{ name: "kinstype.is-1", type: "HAL_BIT", direction: "HAL_OUT" },
|
||||
{ name: "ini.x.min_limit", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.x.max_limit", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.x.min_velocity", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.x.max_acceleration", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.y.min_limit", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.y.max_limit", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.y.min_velocity", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.y.max_acceleration", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.z.min_limit", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.z.max_limit", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.z.min_velocity", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
{ name: "ini.z.max_acceleration", type: "HAL_FLOAT", direction: "HAL_OUT" },
|
||||
]),
|
||||
},
|
||||
{
|
||||
id: "axis-motion",
|
||||
component: "axis",
|
||||
@@ -866,6 +969,11 @@ export const VIRTUAL_HAL_PROJECT_PIN_GROUPS = Object.freeze([
|
||||
label: "Tool pins",
|
||||
description: "Tool status, tool change, and motion tool-offset pins from HALUI, iocontrol, and motion.",
|
||||
},
|
||||
{
|
||||
id: "user-m-process",
|
||||
label: "User-M process boundary pins",
|
||||
description: "Controlled millturn M128/M129 state pins sourced from LinuxCNC Tcl user-M scripts and remap callers.",
|
||||
},
|
||||
]);
|
||||
|
||||
export const VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES = Object.freeze([
|
||||
@@ -879,6 +987,7 @@ export const VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES = Object.freeze([
|
||||
"axis-joint-position-feedback",
|
||||
"spindle-coolant-tool-status",
|
||||
"interpreter-hal-bridge-snapshot",
|
||||
"controlled-user-m-process-state-boundary",
|
||||
]);
|
||||
|
||||
export const VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS = Object.freeze([
|
||||
@@ -887,6 +996,24 @@ export const VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS = Object.freeze([
|
||||
"motion-controller",
|
||||
]);
|
||||
|
||||
const VIRTUAL_HAL_DEFAULT_MILLTURN_USER_M_EXTERNAL_PINS = Object.freeze({
|
||||
"motion.analog-out-03": Object.freeze({ kind: "pin", name: "motion.analog-out-03", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"kinstype.is-0": Object.freeze({ kind: "pin", name: "kinstype.is-0", type: "HAL_BIT", value: 0, connected: true }),
|
||||
"kinstype.is-1": Object.freeze({ kind: "pin", name: "kinstype.is-1", type: "HAL_BIT", value: 0, connected: true }),
|
||||
"ini.x.min_limit": Object.freeze({ kind: "pin", name: "ini.x.min_limit", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.x.max_limit": Object.freeze({ kind: "pin", name: "ini.x.max_limit", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.x.min_velocity": Object.freeze({ kind: "pin", name: "ini.x.min_velocity", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.x.max_acceleration": Object.freeze({ kind: "pin", name: "ini.x.max_acceleration", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.y.min_limit": Object.freeze({ kind: "pin", name: "ini.y.min_limit", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.y.max_limit": Object.freeze({ kind: "pin", name: "ini.y.max_limit", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.y.min_velocity": Object.freeze({ kind: "pin", name: "ini.y.min_velocity", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.y.max_acceleration": Object.freeze({ kind: "pin", name: "ini.y.max_acceleration", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.z.min_limit": Object.freeze({ kind: "pin", name: "ini.z.min_limit", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.z.max_limit": Object.freeze({ kind: "pin", name: "ini.z.max_limit", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.z.min_velocity": Object.freeze({ kind: "pin", name: "ini.z.min_velocity", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
"ini.z.max_acceleration": Object.freeze({ kind: "pin", name: "ini.z.max_acceleration", type: "HAL_FLOAT", value: 0, connected: true }),
|
||||
});
|
||||
|
||||
export const VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES = Object.freeze([
|
||||
Object.freeze({
|
||||
id: "pin-signal-net-show",
|
||||
@@ -1130,6 +1257,11 @@ export const VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES = Object.freeze({
|
||||
]),
|
||||
evidence: "Bridge snapshots only serialize source-derived virtual HAL pins and values into the LinuxCNC-backed interpreter HAL adapter.",
|
||||
}),
|
||||
"controlled-user-m-process-state-boundary": Object.freeze({
|
||||
label: "Controlled user-M process state boundary",
|
||||
sourceFiles: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.sourceFiles,
|
||||
evidence: "Millturn M128/M129 simulation exposes LinuxCNC source-derived Tcl/HAL state targets while keeping external process execution and promotion locked.",
|
||||
}),
|
||||
});
|
||||
|
||||
export function createVirtualHalState(overrides = {}) {
|
||||
@@ -1150,7 +1282,7 @@ export function createVirtualHalState(overrides = {}) {
|
||||
mode: "manual",
|
||||
},
|
||||
pins: Object.fromEntries(VIRTUAL_HAL_AXISUI_PINS.pins.map((pin) => [pin.name, pin.type === "HAL_FLOAT" ? 0 : false])),
|
||||
externalPins: {},
|
||||
externalPins: Object.fromEntries(Object.entries(VIRTUAL_HAL_DEFAULT_MILLTURN_USER_M_EXTERNAL_PINS).map(([name, entry]) => [name, { ...entry }])),
|
||||
position: Object.fromEntries(VIRTUAL_HAL_AXES.map((axis) => [axis, 0])),
|
||||
homed: Object.fromEntries(VIRTUAL_HAL_AXES.map((axis) => [axis, false])),
|
||||
limits: Object.fromEntries(VIRTUAL_HAL_AXES.map((axis) => [
|
||||
@@ -2210,6 +2342,12 @@ export function createVirtualHalBridgeReadiness(options = {}) {
|
||||
"halui.estop.is-activated",
|
||||
"spindle.0.speed-out",
|
||||
"iocontrol.0.coolant-flood",
|
||||
"motion.switchkins-type",
|
||||
"motion.analog-out-03",
|
||||
"kinstype.is-0",
|
||||
"kinstype.is-1",
|
||||
"ini.x.min_limit",
|
||||
"ini.z.max_limit",
|
||||
];
|
||||
const snapshotPins = new Set((snapshot.values ?? []).map(({ name }) => name));
|
||||
const missingPins = requiredPins.filter((name) => !snapshotPins.has(name));
|
||||
@@ -2337,6 +2475,7 @@ export function createVirtualHalProjectReport(options = {}) {
|
||||
registry: pinRegistry,
|
||||
systemCoverage,
|
||||
});
|
||||
const userMProcessBoundary = createVirtualHalMillturnUserMProcessBoundaryReport(options);
|
||||
return {
|
||||
apiName: "linuxcnc-wasm-virtual-hal-project-report",
|
||||
reportVersion: 1,
|
||||
@@ -2353,6 +2492,7 @@ export function createVirtualHalProjectReport(options = {}) {
|
||||
integrity,
|
||||
systemCoverage,
|
||||
simulationRuntime: createVirtualHalSimulationRuntimeReport(state),
|
||||
userMProcessBoundary,
|
||||
wasmBridgeSnapshot: snapshot,
|
||||
bridgeReadiness: readiness,
|
||||
bridgeActionPlan: actionPlan,
|
||||
@@ -2387,6 +2527,11 @@ export function createVirtualHalProjectReport(options = {}) {
|
||||
label: "Simulation HAL runtime",
|
||||
value: "ready",
|
||||
},
|
||||
{
|
||||
id: "user-m-process-boundary",
|
||||
label: "User-M process boundary",
|
||||
value: userMProcessBoundary.phase,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -3407,6 +3552,177 @@ export function createVirtualHalSimConfigMacroLoadFixtureReport(options = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
function virtualHalMillturnUserMCaseForCode(code) {
|
||||
const normalized = String(code ?? "").trim().toUpperCase();
|
||||
return VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.cases
|
||||
.find((entry) => entry.userMCode === normalized || entry.remapCode === normalized) ?? null;
|
||||
}
|
||||
|
||||
function createMillturnUserMStateTargetRows(boundaryCase) {
|
||||
return boundaryCase.stateTargets.map((target) => ({
|
||||
path: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.path,
|
||||
ini: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.ini,
|
||||
blocked: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.boundaryClass,
|
||||
userMCode: boundaryCase.userMCode,
|
||||
targetPin: target.pin,
|
||||
sourceSection: target.sourceSection,
|
||||
sourceField: target.sourceField,
|
||||
expectedValue: target.value,
|
||||
executionEnabled: false,
|
||||
promotionAllowed: false,
|
||||
proofStatus: "pending_native_runtime_probe",
|
||||
notes: "source_derived_virtual_hal_state_target_no_external_process_execution",
|
||||
}));
|
||||
}
|
||||
|
||||
export function createVirtualHalMillturnUserMProcessBoundaryReport(options = {}) {
|
||||
const boundary = VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY;
|
||||
const manifestProvided = typeof options.manifestText === "string" || Array.isArray(options.manifestEntries);
|
||||
const manifestSet = new Set([
|
||||
...sourceManifestSetFromText(options.manifestText ?? ""),
|
||||
...(options.manifestEntries ?? []).map(normalizeLinuxCncSourcePath),
|
||||
]);
|
||||
const sourceFiles = [...boundary.sourceFiles];
|
||||
const manifestSourceFiles = [...boundary.manifestSourceFiles];
|
||||
const missingManifestFiles = manifestProvided
|
||||
? manifestSourceFiles.filter((file) => !manifestSet.has(normalizeLinuxCncSourcePath(file)))
|
||||
: [];
|
||||
const rows = boundary.cases.map((entry) => {
|
||||
const stateTargetRows = createMillturnUserMStateTargetRows(entry);
|
||||
return {
|
||||
path: boundary.path,
|
||||
ini: boundary.ini,
|
||||
blocked: boundary.boundaryClass,
|
||||
remapCode: entry.remapCode,
|
||||
userMCode: entry.userMCode,
|
||||
stateMode: entry.stateMode,
|
||||
guardPin: entry.guardPin,
|
||||
switchkinsOutputPin: entry.switchkinsOutputPin,
|
||||
switchkinsTarget: entry.switchkinsTarget,
|
||||
activeG5x: entry.activeG5x,
|
||||
workOffsetPocket: entry.workOffsetPocket,
|
||||
workOffsetWords: entry.workOffsetWords,
|
||||
requiredRuntime: boundary.requiredRuntime,
|
||||
expectedStatePins: stateTargetRows.map((row) => row.targetPin),
|
||||
expectedStateValues: stateTargetRows.map((row) => `${row.targetPin}=${row.expectedValue}`),
|
||||
stateTargetCount: stateTargetRows.length,
|
||||
stateTargetRows,
|
||||
sourceFiles,
|
||||
manifestSourceFiles,
|
||||
sourceDerived: sourceFiles.length > 0,
|
||||
executionEnabled: false,
|
||||
promotionAllowed: false,
|
||||
proofStatus: "pending_native_runtime_probe",
|
||||
nativeProbe: boundary.nativeProbe,
|
||||
complete: sourceFiles.length > 0 && missingManifestFiles.length === 0,
|
||||
notes: "controlled_virtual_hal_state_boundary_keep_user_m_process_blocked",
|
||||
};
|
||||
});
|
||||
const complete = rows.length > 0 &&
|
||||
rows.every((row) => row.complete) &&
|
||||
missingManifestFiles.length === 0;
|
||||
return {
|
||||
apiName: "linuxcnc-wasm-virtual-hal-millturn-user-m-process-boundary-report",
|
||||
reportVersion: 1,
|
||||
source: "linuxcnc-configs-sim-source-derived-user-m-process-boundary",
|
||||
phase: complete ? "simulation-boundary-ready" : "blocked",
|
||||
complete,
|
||||
webSimulationSatisfied: complete,
|
||||
boundaryClass: boundary.boundaryClass,
|
||||
path: boundary.path,
|
||||
ini: boundary.ini,
|
||||
requiredRuntime: boundary.requiredRuntime,
|
||||
nativeProbe: boundary.nativeProbe,
|
||||
nativeRuntimeRequired: true,
|
||||
processExecutionReady: false,
|
||||
executionEnabled: false,
|
||||
promotionAllowed: false,
|
||||
inventoryBaselineUnchanged: true,
|
||||
jsCncSemantics: false,
|
||||
manifestChecked: manifestProvided,
|
||||
missingManifestFiles,
|
||||
sourceFiles,
|
||||
manifestSourceFiles,
|
||||
caseCount: rows.length,
|
||||
stateTargetCount: rows.reduce((sum, row) => sum + row.stateTargetCount, 0),
|
||||
rows,
|
||||
summaryRows: [
|
||||
{ id: "boundary", label: "User-M boundary", value: boundary.boundaryClass },
|
||||
{ id: "cases", label: "M-code cases", value: rows.map((row) => `${row.remapCode}->${row.userMCode}`).join(", ") },
|
||||
{ id: "state-targets", label: "HAL state targets", value: `${rows.reduce((sum, row) => sum + row.stateTargetCount, 0)}` },
|
||||
{ id: "execution", label: "External process execution", value: "locked" },
|
||||
{ id: "promotion", label: "Promotion allowed", value: "0" },
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function applyVirtualHalMillturnUserMProcessState(halState = createVirtualHalState(), codeOrOptions = "M128", options = {}) {
|
||||
const code = typeof codeOrOptions === "object" && codeOrOptions !== null
|
||||
? codeOrOptions.code ?? codeOrOptions.userMCode ?? codeOrOptions.remapCode
|
||||
: codeOrOptions;
|
||||
const boundaryCase = virtualHalMillturnUserMCaseForCode(code);
|
||||
if (!boundaryCase) {
|
||||
throw new Error(`unknown millturn user-M process code: ${code}`);
|
||||
}
|
||||
const report = createVirtualHalMillturnUserMProcessBoundaryReport(options);
|
||||
const row = report.rows.find((entry) => entry.userMCode === boundaryCase.userMCode);
|
||||
if (!row?.complete) {
|
||||
throw new Error(`millturn user-M process boundary is not source-complete for ${boundaryCase.userMCode}`);
|
||||
}
|
||||
|
||||
const guardUpdates = VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.cases.map((entry) => ({
|
||||
name: entry.guardPin,
|
||||
type: "HAL_BIT",
|
||||
value: entry.userMCode === boundaryCase.userMCode ? 1 : 0,
|
||||
}));
|
||||
const updates = [
|
||||
{ name: "motion.switchkins-type", type: "HAL_FLOAT", value: boundaryCase.switchkinsTarget },
|
||||
{ name: boundaryCase.switchkinsOutputPin, type: "HAL_FLOAT", value: boundaryCase.switchkinsTarget },
|
||||
...guardUpdates,
|
||||
...boundaryCase.stateTargets.map((target) => ({
|
||||
name: target.pin,
|
||||
type: "HAL_FLOAT",
|
||||
value: target.value,
|
||||
})),
|
||||
];
|
||||
const next = applyVirtualHalPinUpdates(halState, updates, { allowExternal: true });
|
||||
next.hal.commandLog = [
|
||||
...(next.hal.commandLog ?? []),
|
||||
{
|
||||
source: "virtual-user-m-process-boundary",
|
||||
action: "millturn-user-m-state",
|
||||
userMCode: boundaryCase.userMCode,
|
||||
remapCode: boundaryCase.remapCode,
|
||||
stateMode: boundaryCase.stateMode,
|
||||
executionEnabled: false,
|
||||
promotionAllowed: false,
|
||||
ok: true,
|
||||
},
|
||||
].slice(-200);
|
||||
next.revision += 1;
|
||||
return {
|
||||
apiName: "linuxcnc-wasm-virtual-hal-millturn-user-m-process-state-result",
|
||||
resultVersion: 1,
|
||||
source: "linuxcnc-configs-sim-source-derived-user-m-process-state",
|
||||
ok: true,
|
||||
boundaryClass: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.boundaryClass,
|
||||
path: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.path,
|
||||
ini: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.ini,
|
||||
userMCode: boundaryCase.userMCode,
|
||||
remapCode: boundaryCase.remapCode,
|
||||
stateMode: boundaryCase.stateMode,
|
||||
switchkinsTarget: boundaryCase.switchkinsTarget,
|
||||
activeG5x: boundaryCase.activeG5x,
|
||||
workOffsetPocket: boundaryCase.workOffsetPocket,
|
||||
appliedPins: updates.map((update) => update.name),
|
||||
executionEnabled: false,
|
||||
promotionAllowed: false,
|
||||
processExecutionReady: false,
|
||||
state: normalizeVirtualHalState(next),
|
||||
report,
|
||||
};
|
||||
}
|
||||
|
||||
export function createVirtualHalSourceComplianceReport(options = {}) {
|
||||
const halState = options.halState ?? createVirtualHalState();
|
||||
const snapshot = options.snapshot ?? createVirtualHalWasmBridgeSnapshot(halState);
|
||||
@@ -3422,6 +3738,7 @@ export function createVirtualHalSourceComplianceReport(options = {}) {
|
||||
...VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS.flatMap((target) => target.sourceFiles),
|
||||
...VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES.flatMap((fixture) => fixture.sourceFiles),
|
||||
...VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES.flatMap((fixture) => fixture.sourceFiles),
|
||||
...VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.sourceFiles,
|
||||
...(options.allowedSourceFiles ?? []),
|
||||
]);
|
||||
const requiredCapabilities = options.requiredCapabilities ?? VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES;
|
||||
@@ -3629,6 +3946,14 @@ export function createLinuxCncVirtualHalRuntime(initialState = createVirtualHalS
|
||||
getSimConfigMacroLoadFixtureReport(options = {}) {
|
||||
return createVirtualHalSimConfigMacroLoadFixtureReport(options);
|
||||
},
|
||||
getMillturnUserMProcessBoundaryReport(options = {}) {
|
||||
return createVirtualHalMillturnUserMProcessBoundaryReport(options);
|
||||
},
|
||||
applyMillturnUserMProcessState(codeOrOptions = "M128", options = {}) {
|
||||
const result = applyVirtualHalMillturnUserMProcessState(state, codeOrOptions, options);
|
||||
state = result.state;
|
||||
return result;
|
||||
},
|
||||
getCommandScriptFixtureReport(options = {}) {
|
||||
return createVirtualHalCommandScriptFixtureReport({ ...options, halState: state });
|
||||
},
|
||||
@@ -3826,6 +4151,9 @@ function isVirtualHalPinWritable(name) {
|
||||
if (/^(axis|joint)\./.test(name) || name.startsWith("spindle.")) {
|
||||
return true;
|
||||
}
|
||||
if (name.startsWith("ini.") || name.startsWith("kinstype.")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4014,6 +4342,9 @@ function applyAxisPinWrite(state, name, numeric, enabled) {
|
||||
}
|
||||
|
||||
function classifyVirtualHalPinGroup(name) {
|
||||
if (name.startsWith("ini.") || name.startsWith("kinstype.") || name === "motion.analog-out-03") {
|
||||
return "user-m-process";
|
||||
}
|
||||
if (name.startsWith("axisui.") || name.startsWith("jog.") || name.startsWith("notifications-") || name === "error" || name === "abort") {
|
||||
return "axisui";
|
||||
}
|
||||
|
||||
@@ -702,6 +702,38 @@ function isVirtualHalPromotionCandidateSummaryReady(summary) {
|
||||
arrayOrEmpty(summaryObject.blockedCandidateIds).length === 0;
|
||||
}
|
||||
|
||||
function isVirtualHalMillturnUserMProcessBoundaryReady(report) {
|
||||
const reportObject = objectOrEmpty(report);
|
||||
const rows = arrayOrEmpty(reportObject.rows);
|
||||
return reportObject.apiName === "linuxcnc-wasm-virtual-hal-millturn-user-m-process-boundary-report" &&
|
||||
reportObject.complete === true &&
|
||||
reportObject.webSimulationSatisfied === true &&
|
||||
reportObject.boundaryClass === "L4-USER-M-PROCESS" &&
|
||||
reportObject.path === "axis/vismach/millturn/example.ngc" &&
|
||||
reportObject.executionEnabled === false &&
|
||||
reportObject.promotionAllowed === false &&
|
||||
reportObject.processExecutionReady === false &&
|
||||
reportObject.stateTargetCount === 24 &&
|
||||
arrayOrEmpty(reportObject.sourceFiles).includes("linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128") &&
|
||||
arrayOrEmpty(reportObject.sourceFiles).includes("linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M129") &&
|
||||
rows.some((row) =>
|
||||
row.userMCode === "M128" &&
|
||||
row.remapCode === "M428" &&
|
||||
row.stateMode === "mill" &&
|
||||
row.stateTargetCount === 12 &&
|
||||
row.executionEnabled === false &&
|
||||
row.promotionAllowed === false
|
||||
) &&
|
||||
rows.some((row) =>
|
||||
row.userMCode === "M129" &&
|
||||
row.remapCode === "M429" &&
|
||||
row.stateMode === "turn" &&
|
||||
row.stateTargetCount === 12 &&
|
||||
row.executionEnabled === false &&
|
||||
row.promotionAllowed === false
|
||||
);
|
||||
}
|
||||
|
||||
export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifact = {}) {
|
||||
const artifactObject = objectOrEmpty(artifact);
|
||||
const sourceCompliance = objectOrEmpty(artifactObject.virtualHalSourceCompliance);
|
||||
@@ -712,6 +744,7 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
||||
const evidenceExpansion = objectOrEmpty(artifactObject.virtualHalSimConfigEvidenceExpansion);
|
||||
const promotionCandidateSummary = objectOrEmpty(artifactObject.virtualHalPromotionCandidateSummary);
|
||||
const macroLoadFixtures = objectOrEmpty(artifactObject.virtualHalSimConfigMacroLoadFixtures);
|
||||
const millturnUserMProcessBoundary = objectOrEmpty(artifactObject.virtualHalMillturnUserMProcessBoundary);
|
||||
const sessionDiagnostics = objectOrEmpty(artifactObject.virtualHalSessionDiagnostics);
|
||||
const replacement = objectOrEmpty(artifactObject.virtualHalSimulationReplacement);
|
||||
const virtualHal = objectOrEmpty(artifactObject.virtualHal);
|
||||
@@ -737,6 +770,9 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
||||
const hasMacroLoadFixtures = artifactObject.virtualHalSimConfigMacroLoadFixtures !== undefined;
|
||||
const macroLoadFixturesReady = hasMacroLoadFixtures &&
|
||||
isVirtualHalSimConfigMacroLoadFixtureReportReady(macroLoadFixtures);
|
||||
const hasMillturnUserMProcessBoundary = artifactObject.virtualHalMillturnUserMProcessBoundary !== undefined;
|
||||
const millturnUserMProcessBoundaryReady = hasMillturnUserMProcessBoundary &&
|
||||
isVirtualHalMillturnUserMProcessBoundaryReady(millturnUserMProcessBoundary);
|
||||
const replacementReady = replacement.ready === true &&
|
||||
replacement.replacesHostRuntimeForSimulation === true &&
|
||||
objectOrEmpty(replacement.sourceCompliance).webSimulationSatisfied === true &&
|
||||
@@ -750,6 +786,9 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
||||
objectOrEmpty(sessionDiagnostics.validation).ready === true &&
|
||||
objectOrEmpty(sessionDiagnostics.diagnosticsArtifact).apiName === "real-browser-simulation-diagnostics-artifact" &&
|
||||
objectOrEmpty(sessionDiagnostics.diagnosticsArtifact?.virtualHalSourceCompliance).complete === true &&
|
||||
isVirtualHalMillturnUserMProcessBoundaryReady(
|
||||
objectOrEmpty(sessionDiagnostics.diagnosticsArtifact?.virtualHalMillturnUserMProcessBoundary),
|
||||
) &&
|
||||
objectOrEmpty(sessionDiagnostics.diagnosticsArtifact?.virtualHalMotionControllerMatrix).manifestChecked === true
|
||||
);
|
||||
const missing = [
|
||||
@@ -762,6 +801,7 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
||||
...(evidenceExpansionReady ? [] : ["virtualHalSimConfigEvidenceExpansion"]),
|
||||
...(promotionCandidateSummaryReady ? [] : ["virtualHalPromotionCandidateSummary"]),
|
||||
...(macroLoadFixturesReady ? [] : ["virtualHalSimConfigMacroLoadFixtures"]),
|
||||
...(millturnUserMProcessBoundaryReady ? [] : ["virtualHalMillturnUserMProcessBoundary"]),
|
||||
...(commandScriptFixturesReady ? [] : ["virtualHalCommandScriptFixtures"]),
|
||||
...(motionControllerMatrixReady ? [] : ["virtualHalMotionControllerMatrix"]),
|
||||
...(sessionDiagnosticsReady ? [] : ["virtualHalSessionDiagnostics"]),
|
||||
@@ -785,6 +825,8 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
||||
hasPromotionCandidateSummary,
|
||||
macroLoadFixturesReady,
|
||||
hasMacroLoadFixtures,
|
||||
millturnUserMProcessBoundaryReady,
|
||||
hasMillturnUserMProcessBoundary,
|
||||
commandScriptFixturesReady,
|
||||
motionControllerMatrixReady,
|
||||
sessionDiagnosticsReady,
|
||||
@@ -795,6 +837,7 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
||||
...arrayOrEmpty(promotionCandidates.sourceFiles),
|
||||
...arrayOrEmpty(evidenceExpansion.sourceFiles),
|
||||
...arrayOrEmpty(macroLoadFixtures.sourceFiles),
|
||||
...arrayOrEmpty(millturnUserMProcessBoundary.sourceFiles),
|
||||
...arrayOrEmpty(commandScriptFixtures.sourceFiles),
|
||||
...arrayOrEmpty(motionControllerMatrix.sourceFiles),
|
||||
...arrayOrEmpty(motionControllerMatrix.simConfigSourceFiles),
|
||||
@@ -840,6 +883,11 @@ export function createProjectReleaseBrowserDiagnosticsArtifactValidation(artifac
|
||||
label: "Virtual HAL sim-config macro/load fixtures",
|
||||
value: hasMacroLoadFixtures ? (macroLoadFixturesReady ? "ready" : "missing") : "not provided",
|
||||
},
|
||||
{
|
||||
id: "millturn-user-m-process-boundary",
|
||||
label: "Millturn user-M process boundary",
|
||||
value: hasMillturnUserMProcessBoundary ? (millturnUserMProcessBoundaryReady ? "ready" : "missing") : "not provided",
|
||||
},
|
||||
{
|
||||
id: "command-script-fixtures",
|
||||
label: "Virtual HAL command script fixtures",
|
||||
|
||||
@@ -1732,6 +1732,12 @@ M2
|
||||
<dd><span data-python-remap-runtime="mode">contract-only</span> | callable <span data-python-remap-runtime="callable">locked</span> | generator <span data-python-remap-runtime="generator">locked</span> | state <span data-python-remap-runtime="interpreter">locked</span></dd>
|
||||
<dt>Python Promotion</dt>
|
||||
<dd>execution <span data-python-remap-runtime="execution">disabled</span> | promotion <span data-python-remap-runtime="promotion">locked</span></dd>
|
||||
<dt>User-M Process</dt>
|
||||
<dd><span data-user-m-process="boundary">L4-USER-M-PROCESS</span> | <span data-user-m-process="path">axis/vismach/millturn/example.ngc</span> | <span data-user-m-process="phase">ready</span></dd>
|
||||
<dt>Millturn Mode</dt>
|
||||
<dd><span data-user-m-process="active-code">none</span> | remap <span data-user-m-process="active-remap">none</span> | mode <span data-user-m-process="active-mode">none</span> | switchkins <span data-user-m-process="switchkins">none</span></dd>
|
||||
<dt>User-M Promotion</dt>
|
||||
<dd>execution <span data-user-m-process="execution">disabled</span> | promotion <span data-user-m-process="promotion">locked</span></dd>
|
||||
<dt>Limits/Home</dt>
|
||||
<dd data-limits-home-summary>source unavailable | X home no limit off/off fault none</dd>
|
||||
<dt>Overrides</dt>
|
||||
@@ -1851,7 +1857,9 @@ M2
|
||||
VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES as SHARED_VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES,
|
||||
VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES as SHARED_VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES,
|
||||
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS as SHARED_VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
||||
VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY as SHARED_VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY,
|
||||
applyVirtualHalAction as applySharedVirtualHalAction,
|
||||
applyVirtualHalMillturnUserMProcessState as applySharedVirtualHalMillturnUserMProcessState,
|
||||
applyVirtualHalPinUpdates as applySharedVirtualHalPinUpdates,
|
||||
cloneVirtualHalState as cloneSharedVirtualHalState,
|
||||
createVirtualHalCommandScriptFixtureReport as createSharedVirtualHalCommandScriptFixtureReport,
|
||||
@@ -1859,6 +1867,7 @@ M2
|
||||
createVirtualHalIntegrityReport as createSharedVirtualHalIntegrityReport,
|
||||
createVirtualHalLimitsHomeState as createSharedVirtualHalLimitsHomeState,
|
||||
createVirtualHalMachineStatusState as createSharedVirtualHalMachineStatusState,
|
||||
createVirtualHalMillturnUserMProcessBoundaryReport as createSharedVirtualHalMillturnUserMProcessBoundaryReport,
|
||||
createVirtualHalMotionControllerMatrixReport as createSharedVirtualHalMotionControllerMatrixReport,
|
||||
createVirtualHalPinRegistry as createSharedVirtualHalPinRegistry,
|
||||
createVirtualHalSimConfigEvidenceExpansionReport as createSharedVirtualHalSimConfigEvidenceExpansionReport,
|
||||
@@ -2036,7 +2045,22 @@ M2
|
||||
const VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES = SHARED_VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES;
|
||||
const VIRTUAL_HAL_SIM_CONFIG_EVIDENCE_EXPANSION_CANDIDATES = SHARED_VIRTUAL_HAL_SIM_CONFIG_EVIDENCE_EXPANSION_CANDIDATES;
|
||||
const VIRTUAL_HAL_MOTION_MATRIX_MANIFEST_ENTRIES = SHARED_VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS.flatMap((target) => target.sourceFiles ?? []);
|
||||
const VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY = SHARED_VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY;
|
||||
let virtualHalState = createVirtualHalState();
|
||||
let millturnUserMProcessState = {
|
||||
apiName: "real-browser-simulation-millturn-user-m-process-state",
|
||||
stateVersion: 1,
|
||||
phase: "ready",
|
||||
boundaryClass: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.boundaryClass,
|
||||
path: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.path,
|
||||
activeUserMCode: "none",
|
||||
activeRemapCode: "none",
|
||||
activeMode: "none",
|
||||
switchkinsTarget: "none",
|
||||
executionEnabled: false,
|
||||
promotionAllowed: false,
|
||||
processExecutionReady: false,
|
||||
};
|
||||
|
||||
function setAllText(selector, value) {
|
||||
document.querySelectorAll(selector).forEach((node) => {
|
||||
@@ -2562,6 +2586,67 @@ M2
|
||||
return createSharedVirtualHalSimulationReplacementReport(virtualHalState);
|
||||
}
|
||||
|
||||
function createVirtualHalMillturnUserMProcessBoundaryReport() {
|
||||
return createSharedVirtualHalMillturnUserMProcessBoundaryReport({
|
||||
manifestEntries: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.sourceFiles,
|
||||
});
|
||||
}
|
||||
|
||||
function renderMillturnUserMProcessState(state = millturnUserMProcessState) {
|
||||
const nextState = {
|
||||
apiName: "real-browser-simulation-millturn-user-m-process-state",
|
||||
stateVersion: 1,
|
||||
phase: state.phase ?? "ready",
|
||||
boundaryClass: state.boundaryClass ?? VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.boundaryClass,
|
||||
path: state.path ?? VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.path,
|
||||
activeUserMCode: state.activeUserMCode ?? "none",
|
||||
activeRemapCode: state.activeRemapCode ?? "none",
|
||||
activeMode: state.activeMode ?? "none",
|
||||
switchkinsTarget: state.switchkinsTarget ?? "none",
|
||||
executionEnabled: state.executionEnabled === true,
|
||||
promotionAllowed: state.promotionAllowed === true,
|
||||
processExecutionReady: state.processExecutionReady === true,
|
||||
};
|
||||
millturnUserMProcessState = nextState;
|
||||
document.body.dataset.userMProcessPhase = nextState.phase;
|
||||
document.body.dataset.userMProcessActiveCode = nextState.activeUserMCode;
|
||||
document.body.dataset.userMProcessActiveMode = nextState.activeMode;
|
||||
setAllText("[data-user-m-process=\"boundary\"]", nextState.boundaryClass);
|
||||
setAllText("[data-user-m-process=\"path\"]", nextState.path);
|
||||
setAllText("[data-user-m-process=\"phase\"]", nextState.phase);
|
||||
setAllText("[data-user-m-process=\"active-code\"]", nextState.activeUserMCode);
|
||||
setAllText("[data-user-m-process=\"active-remap\"]", nextState.activeRemapCode);
|
||||
setAllText("[data-user-m-process=\"active-mode\"]", nextState.activeMode);
|
||||
setAllText("[data-user-m-process=\"switchkins\"]", String(nextState.switchkinsTarget));
|
||||
setAllText("[data-user-m-process=\"execution\"]", nextState.executionEnabled ? "enabled" : "disabled");
|
||||
setAllText("[data-user-m-process=\"promotion\"]", nextState.promotionAllowed ? "allowed" : "locked");
|
||||
return { ...nextState };
|
||||
}
|
||||
|
||||
function applyMillturnUserMProcessState(codeOrOptions = "M128", options = {}) {
|
||||
const result = applySharedVirtualHalMillturnUserMProcessState(virtualHalState, codeOrOptions, {
|
||||
manifestEntries: VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.sourceFiles,
|
||||
...options,
|
||||
});
|
||||
virtualHalState = result.state;
|
||||
renderVirtualHalState();
|
||||
renderMillturnUserMProcessState({
|
||||
phase: "applied",
|
||||
boundaryClass: result.boundaryClass,
|
||||
path: result.path,
|
||||
activeUserMCode: result.userMCode,
|
||||
activeRemapCode: result.remapCode,
|
||||
activeMode: result.stateMode,
|
||||
switchkinsTarget: result.switchkinsTarget,
|
||||
executionEnabled: result.executionEnabled,
|
||||
promotionAllowed: result.promotionAllowed,
|
||||
processExecutionReady: result.processExecutionReady,
|
||||
});
|
||||
pushStatusHistory("user-m-process", `${result.remapCode}->${result.userMCode} ${result.stateMode}`);
|
||||
renderAxisStatusbar();
|
||||
return result;
|
||||
}
|
||||
|
||||
function createVirtualHalSourceComplianceReport() {
|
||||
return createSharedVirtualHalSourceComplianceReport({ halState: virtualHalState });
|
||||
}
|
||||
@@ -2741,6 +2826,7 @@ M2
|
||||
renderVirtualHalDro();
|
||||
}
|
||||
renderLimitsHomeState(createVirtualHalLimitsHomeState());
|
||||
renderMillturnUserMProcessState();
|
||||
const promotionCandidateReport = createVirtualHalSimConfigPromotionCandidateReport();
|
||||
renderPromotionFamilyRows(promotionCandidateReport);
|
||||
renderPromotionCandidateSummary(createVirtualHalPromotionCandidateSummary(promotionCandidateReport));
|
||||
@@ -2793,6 +2879,8 @@ M2
|
||||
virtualHal: cloneVirtualHalState(),
|
||||
virtualHalSimulationReplacement: createVirtualHalSimulationReplacementReport(),
|
||||
virtualHalSourceCompliance: createVirtualHalSourceComplianceReport(),
|
||||
virtualHalMillturnUserMProcessBoundary: createVirtualHalMillturnUserMProcessBoundaryReport(),
|
||||
virtualHalMillturnUserMProcessState: renderMillturnUserMProcessState(),
|
||||
virtualHalSimConfigSourceCoverage: createVirtualHalSimConfigSourceCoverageReport(),
|
||||
virtualHalSimConfigPromotionCandidates: createVirtualHalSimConfigPromotionCandidateReport(),
|
||||
virtualHalSimConfigEvidenceExpansion: createVirtualHalSimConfigEvidenceExpansionReport(),
|
||||
@@ -2833,6 +2921,7 @@ M2
|
||||
virtualHal: virtualHal.state,
|
||||
virtualHalSimulationReplacement: virtualHal.diagnostics,
|
||||
virtualHalSourceCompliance: virtualHal.sourceCompliance,
|
||||
virtualHalMillturnUserMProcessBoundary: virtualHal.millturnUserMProcessBoundary,
|
||||
virtualHalSimConfigSourceCoverage: virtualHal.simConfigSourceCoverage,
|
||||
virtualHalSimConfigPromotionCandidates: virtualHal.simConfigPromotionCandidates,
|
||||
virtualHalSimConfigEvidenceExpansion: virtualHal.simConfigEvidenceExpansion,
|
||||
@@ -3773,6 +3862,7 @@ M2
|
||||
...VIRTUAL_HAL_SIM_CONFIG_PROMOTION_CANDIDATES.flatMap((candidate) => candidate.sourceFiles ?? []),
|
||||
...VIRTUAL_HAL_SIM_CONFIG_EVIDENCE_EXPANSION_CANDIDATES.flatMap((candidate) => candidate.sourceFiles ?? []),
|
||||
...VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_FIXTURES.flatMap((fixture) => fixture.sourceFiles ?? []),
|
||||
...VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.sourceFiles,
|
||||
],
|
||||
});
|
||||
const payload = createMachineSessionSnapshotPayload(session.machineId, {
|
||||
@@ -4236,6 +4326,9 @@ M2
|
||||
stepVirtualHalMotionController: (options = {}) => stepVirtualHalMotionController(options),
|
||||
getVirtualHalSimulationRuntimeReport: () => createVirtualHalSimulationRuntimeReport(),
|
||||
getVirtualHalSimulationReplacementReport: () => createVirtualHalSimulationReplacementReport(),
|
||||
getVirtualHalMillturnUserMProcessBoundaryReport: () => createVirtualHalMillturnUserMProcessBoundaryReport(),
|
||||
getMillturnUserMProcessState: () => renderMillturnUserMProcessState(),
|
||||
applyMillturnUserMProcessState: (codeOrOptions = "M128", options = {}) => applyMillturnUserMProcessState(codeOrOptions, options),
|
||||
getVirtualHalSourceComplianceReport: () => createVirtualHalSourceComplianceReport(),
|
||||
getVirtualHalSimConfigSourceCoverageReport: () => createVirtualHalSimConfigSourceCoverageReport(),
|
||||
getVirtualHalSimConfigPromotionCandidateReport: () => createVirtualHalSimConfigPromotionCandidateReport(),
|
||||
|
||||
@@ -22,6 +22,7 @@ export {
|
||||
export {
|
||||
VIRTUAL_HAL_AXES,
|
||||
VIRTUAL_HAL_AXISUI_PINS,
|
||||
VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY,
|
||||
VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES,
|
||||
VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_AUDIT_CANDIDATES,
|
||||
VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_BLOCKED_FIXTURES,
|
||||
@@ -32,6 +33,7 @@ export {
|
||||
VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS,
|
||||
VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES,
|
||||
applyVirtualHalAction,
|
||||
applyVirtualHalMillturnUserMProcessState,
|
||||
applyVirtualHalPinUpdates,
|
||||
cloneVirtualHalState,
|
||||
createLinuxCncVirtualHalRuntime,
|
||||
@@ -41,6 +43,7 @@ export {
|
||||
createVirtualHalIntegrityReport,
|
||||
createVirtualHalLimitsHomeState,
|
||||
createVirtualHalMachineStatusState,
|
||||
createVirtualHalMillturnUserMProcessBoundaryReport,
|
||||
createVirtualHalPinRegistry,
|
||||
createVirtualHalSimConfigEvidenceExpansionReport,
|
||||
createVirtualHalSimConfigMacroLoadFixtureReport,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import {
|
||||
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
||||
createVirtualHalCommandScriptFixtureReport,
|
||||
createVirtualHalMillturnUserMProcessBoundaryReport,
|
||||
createVirtualHalMotionControllerMatrixReport,
|
||||
createVirtualHalSimConfigMacroLoadFixtureReport,
|
||||
createVirtualHalSimConfigEvidenceExpansionReport,
|
||||
@@ -433,6 +434,16 @@
|
||||
"linuxcnc/configs/sim/axis/external_offsets/eoffsets.ngc",
|
||||
],
|
||||
}),
|
||||
virtualHalMillturnUserMProcessBoundary: createVirtualHalMillturnUserMProcessBoundaryReport({
|
||||
manifestEntries: [
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/example.ngc",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M129",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc",
|
||||
],
|
||||
}),
|
||||
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport({ halState: diagnosticsVirtualHalState }),
|
||||
virtualHalMotionControllerMatrix: diagnosticsMotionControllerMatrix,
|
||||
};
|
||||
|
||||
@@ -241,6 +241,9 @@
|
||||
!api?.stepVirtualHalMotionController ||
|
||||
!api?.getVirtualHalSimulationRuntimeReport ||
|
||||
!api?.getVirtualHalSimulationReplacementReport ||
|
||||
!api?.getVirtualHalMillturnUserMProcessBoundaryReport ||
|
||||
!api?.getMillturnUserMProcessState ||
|
||||
!api?.applyMillturnUserMProcessState ||
|
||||
!api?.getVirtualHalSourceComplianceReport ||
|
||||
!api?.getVirtualHalSimConfigSourceCoverageReport ||
|
||||
!api?.getVirtualHalSimConfigPromotionCandidateReport ||
|
||||
@@ -442,7 +445,66 @@
|
||||
) {
|
||||
throw new Error(`simulation virtual HAL registry/integrity drift: ${JSON.stringify(initialVirtualHalRegistry)}`);
|
||||
}
|
||||
const diagnosticsArtifact = api.exportDiagnosticsArtifact();
|
||||
let diagnosticsArtifact = api.exportDiagnosticsArtifact();
|
||||
const millturnUserMBoundary = api.getVirtualHalMillturnUserMProcessBoundaryReport();
|
||||
if (
|
||||
millturnUserMBoundary.apiName !== "linuxcnc-wasm-virtual-hal-millturn-user-m-process-boundary-report" ||
|
||||
millturnUserMBoundary.boundaryClass !== "L4-USER-M-PROCESS" ||
|
||||
millturnUserMBoundary.complete !== true ||
|
||||
millturnUserMBoundary.webSimulationSatisfied !== true ||
|
||||
millturnUserMBoundary.executionEnabled !== false ||
|
||||
millturnUserMBoundary.promotionAllowed !== false ||
|
||||
millturnUserMBoundary.processExecutionReady !== false ||
|
||||
millturnUserMBoundary.rows.length !== 2 ||
|
||||
!millturnUserMBoundary.rows.some(({ userMCode, remapCode, stateTargetCount }) => userMCode === "M128" && remapCode === "M428" && stateTargetCount === 12) ||
|
||||
!millturnUserMBoundary.rows.some(({ userMCode, remapCode, stateTargetCount }) => userMCode === "M129" && remapCode === "M429" && stateTargetCount === 12) ||
|
||||
doc.body.dataset.userMProcessPhase !== "ready" ||
|
||||
doc.querySelector('[data-user-m-process="boundary"]')?.textContent !== "L4-USER-M-PROCESS" ||
|
||||
doc.querySelector('[data-user-m-process="path"]')?.textContent !== "axis/vismach/millturn/example.ngc" ||
|
||||
doc.querySelector('[data-user-m-process="execution"]')?.textContent !== "disabled" ||
|
||||
doc.querySelector('[data-user-m-process="promotion"]')?.textContent !== "locked"
|
||||
) {
|
||||
throw new Error(`simulation millturn user-M boundary drift: ${JSON.stringify(millturnUserMBoundary)}`);
|
||||
}
|
||||
const millturnM128 = api.applyMillturnUserMProcessState("M128");
|
||||
if (
|
||||
millturnM128.apiName !== "linuxcnc-wasm-virtual-hal-millturn-user-m-process-state-result" ||
|
||||
millturnM128.userMCode !== "M128" ||
|
||||
millturnM128.remapCode !== "M428" ||
|
||||
millturnM128.stateMode !== "mill" ||
|
||||
api.readVirtualHalPin("motion.switchkins-type")?.value !== 0 ||
|
||||
api.readVirtualHalPin("ini.x.min_limit")?.value !== -300 ||
|
||||
api.readVirtualHalPin("ini.z.max_limit")?.value !== 0 ||
|
||||
doc.body.dataset.userMProcessPhase !== "applied" ||
|
||||
doc.body.dataset.userMProcessActiveCode !== "M128" ||
|
||||
doc.body.dataset.userMProcessActiveMode !== "mill" ||
|
||||
doc.querySelector('[data-user-m-process="active-code"]')?.textContent !== "M128" ||
|
||||
doc.querySelector('[data-user-m-process="active-remap"]')?.textContent !== "M428" ||
|
||||
doc.querySelector('[data-user-m-process="active-mode"]')?.textContent !== "mill" ||
|
||||
doc.querySelector('[data-user-m-process="switchkins"]')?.textContent !== "0"
|
||||
) {
|
||||
throw new Error(`simulation M128 user-M state did not apply: ${JSON.stringify(millturnM128)}`);
|
||||
}
|
||||
const millturnM129 = api.applyMillturnUserMProcessState("M129");
|
||||
if (
|
||||
millturnM129.userMCode !== "M129" ||
|
||||
millturnM129.remapCode !== "M429" ||
|
||||
millturnM129.stateMode !== "turn" ||
|
||||
api.readVirtualHalPin("motion.switchkins-type")?.value !== 1 ||
|
||||
api.readVirtualHalPin("motion.analog-out-03")?.value !== 1 ||
|
||||
api.readVirtualHalPin("kinstype.is-0")?.value !== 0 ||
|
||||
api.readVirtualHalPin("kinstype.is-1")?.value !== 1 ||
|
||||
api.readVirtualHalPin("ini.x.max_limit")?.value !== 0 ||
|
||||
api.readVirtualHalPin("ini.z.max_limit")?.value !== 300 ||
|
||||
api.getMillturnUserMProcessState().activeMode !== "turn" ||
|
||||
doc.querySelector('[data-user-m-process="active-code"]')?.textContent !== "M129" ||
|
||||
doc.querySelector('[data-user-m-process="active-remap"]')?.textContent !== "M429" ||
|
||||
doc.querySelector('[data-user-m-process="active-mode"]')?.textContent !== "turn" ||
|
||||
doc.querySelector('[data-user-m-process="switchkins"]')?.textContent !== "1"
|
||||
) {
|
||||
throw new Error(`simulation M129 user-M state did not apply: ${JSON.stringify(millturnM129)}`);
|
||||
}
|
||||
diagnosticsArtifact = api.exportDiagnosticsArtifact();
|
||||
const promotionCandidateSummary = api.getVirtualHalPromotionCandidateSummary();
|
||||
const expectedPromotionCandidates = [
|
||||
[
|
||||
@@ -542,7 +604,14 @@
|
||||
diagnosticsArtifact.virtualHalSimulationReplacement?.sourceCompliance?.webSimulationSatisfied !== true ||
|
||||
diagnosticsArtifact.virtualHalSourceCompliance?.complete !== true ||
|
||||
diagnosticsArtifact.virtualHalSourceCompliance?.webSimulationSatisfied !== true ||
|
||||
!diagnosticsArtifact.virtualHalSourceCompliance?.sourceFiles?.includes("linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128") ||
|
||||
!diagnosticsArtifact.virtualHalSourceCompliance?.sourceFiles?.includes("linuxcnc/src/hal/utils/halcmd_commands.cc") ||
|
||||
diagnosticsArtifact.virtualHalMillturnUserMProcessBoundary?.complete !== true ||
|
||||
diagnosticsArtifact.virtualHalMillturnUserMProcessBoundary?.boundaryClass !== "L4-USER-M-PROCESS" ||
|
||||
diagnosticsArtifact.virtualHalMillturnUserMProcessState?.activeUserMCode !== "M129" ||
|
||||
diagnosticsArtifact.virtualHalMillturnUserMProcessState?.activeMode !== "turn" ||
|
||||
diagnosticsArtifact.virtualHalMillturnUserMProcessState?.executionEnabled !== false ||
|
||||
diagnosticsArtifact.virtualHalMillturnUserMProcessState?.promotionAllowed !== false ||
|
||||
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") ||
|
||||
@@ -976,6 +1045,8 @@
|
||||
savedVirtualHalSession.sessionDiagnostics?.ready !== true ||
|
||||
savedVirtualHalSession.sessionDiagnostics?.validation?.ready !== true ||
|
||||
savedVirtualHalSession.sessionDiagnostics?.validation?.motionControllerMatrixReady !== true ||
|
||||
savedVirtualHalSession.snapshot?.payload?.virtualHal?.millturnUserMProcessBoundary?.complete !== true ||
|
||||
savedVirtualHalSession.sessionDiagnostics?.diagnosticsArtifact?.virtualHalMillturnUserMProcessBoundary?.complete !== true ||
|
||||
savedVirtualHalSession.sessionDiagnostics?.diagnosticsArtifact?.virtualHalMotionControllerMatrix?.complete !== true ||
|
||||
doc.body.dataset.virtualHalSessionPhase !== "saved" ||
|
||||
!doc.querySelector("[data-virtual-hal-session-status]")?.textContent.includes("Saved HAL session")
|
||||
@@ -991,7 +1062,8 @@
|
||||
savedSessionDiagnosticsArtifact.validation?.ready !== true ||
|
||||
diagnosticsWithSavedSession.virtualHalSessionDiagnostics?.ready !== true ||
|
||||
diagnosticsWithSavedSession.virtualHalSessionDiagnostics?.validation?.ready !== true ||
|
||||
diagnosticsWithSavedSession.virtualHalSessionDiagnostics?.diagnosticsArtifact?.virtualHalSourceCompliance?.complete !== true
|
||||
diagnosticsWithSavedSession.virtualHalSessionDiagnostics?.diagnosticsArtifact?.virtualHalSourceCompliance?.complete !== true ||
|
||||
diagnosticsWithSavedSession.virtualHalSessionDiagnostics?.diagnosticsArtifact?.virtualHalMillturnUserMProcessBoundary?.complete !== true
|
||||
) {
|
||||
throw new Error(`AXIS-style virtual HAL session diagnostics did not become release-ready: ${JSON.stringify(diagnosticsWithSavedSession.virtualHalSessionDiagnostics)}`);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
createVirtualHalSimConfigPromotionCandidateReport,
|
||||
createVirtualHalSimConfigMacroLoadFixtureReport,
|
||||
createVirtualHalCommandScriptFixtureReport,
|
||||
createVirtualHalMillturnUserMProcessBoundaryReport,
|
||||
createVirtualHalMotionControllerMatrixReport,
|
||||
createVirtualHalSimConfigEvidenceExpansionReport,
|
||||
createVirtualHalSimulationReplacementReport,
|
||||
@@ -57,6 +58,9 @@ const virtualHalSimConfigEvidenceExpansion = createVirtualHalSimConfigEvidenceEx
|
||||
const virtualHalSimConfigMacroLoadFixtures = createVirtualHalSimConfigMacroLoadFixtureReport({
|
||||
manifestText: sourceManifestText,
|
||||
});
|
||||
const virtualHalMillturnUserMProcessBoundary = createVirtualHalMillturnUserMProcessBoundaryReport({
|
||||
manifestText: sourceManifestText,
|
||||
});
|
||||
const virtualHalState = createVirtualHalState();
|
||||
const pythonRemapRuntimeProof = {
|
||||
nativeLifecycleReady: true,
|
||||
@@ -97,6 +101,7 @@ const browserDiagnosticsArtifact = {
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
},
|
||||
virtualHalSimConfigMacroLoadFixtures,
|
||||
virtualHalMillturnUserMProcessBoundary,
|
||||
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport({ halState: virtualHalState }),
|
||||
virtualHalMotionControllerMatrix,
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
|
||||
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
||||
VIRTUAL_HAL_COVERAGE_STATES,
|
||||
VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY,
|
||||
VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES,
|
||||
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
||||
VIRTUAL_HAL_SIM_CONFIG_MACRO_LOAD_AUDIT_CANDIDATES,
|
||||
@@ -51,6 +52,7 @@ import {
|
||||
VIRTUAL_HAL_SYSTEM_PIN_FAMILIES,
|
||||
VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS,
|
||||
applyVirtualHalAction,
|
||||
applyVirtualHalMillturnUserMProcessState,
|
||||
applyVirtualHalPinUpdates,
|
||||
applyVirtualHalToInterpSdk,
|
||||
createVirtualHalSimulationRuntimeReport,
|
||||
@@ -58,6 +60,7 @@ import {
|
||||
createLinuxCncInterpSdk,
|
||||
createLinuxCncVirtualHalRuntime,
|
||||
createVirtualHalIntegrityReport,
|
||||
createVirtualHalMillturnUserMProcessBoundaryReport,
|
||||
createVirtualHalMotionControllerMatrixReport,
|
||||
createMachineSessionSnapshotPayload,
|
||||
createVirtualHalSessionPayload,
|
||||
@@ -356,6 +359,7 @@ const requiredExports = [
|
||||
["createProjectReleaseReadinessReport", createProjectReleaseReadinessReport],
|
||||
["createProjectReleaseReadinessSummaryViewModel", createProjectReleaseReadinessSummaryViewModel],
|
||||
["applyVirtualHalAction", applyVirtualHalAction],
|
||||
["applyVirtualHalMillturnUserMProcessState", applyVirtualHalMillturnUserMProcessState],
|
||||
["applyVirtualHalPinUpdates", applyVirtualHalPinUpdates],
|
||||
["applyVirtualHalToInterpSdk", applyVirtualHalToInterpSdk],
|
||||
["createLinuxCncVirtualHalRuntime", createLinuxCncVirtualHalRuntime],
|
||||
@@ -363,6 +367,7 @@ const requiredExports = [
|
||||
["createVirtualHalBridgeReadiness", createVirtualHalBridgeReadiness],
|
||||
["createVirtualHalCommandScriptFixtureReport", createVirtualHalCommandScriptFixtureReport],
|
||||
["createVirtualHalIntegrityReport", createVirtualHalIntegrityReport],
|
||||
["createVirtualHalMillturnUserMProcessBoundaryReport", createVirtualHalMillturnUserMProcessBoundaryReport],
|
||||
["createVirtualHalMotionControllerMatrixReport", createVirtualHalMotionControllerMatrixReport],
|
||||
["createVirtualHalPinInventory", createVirtualHalPinInventory],
|
||||
["createVirtualHalPinRegistry", createVirtualHalPinRegistry],
|
||||
@@ -648,6 +653,11 @@ assert.equal(VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS
|
||||
.sourceFiles.includes("linuxcnc/configs/sim/axis/external_offsets/M111"), true);
|
||||
assert.equal(VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES["halcmd-simulation-replacement"].sourceFiles.includes("linuxcnc/src/hal/utils/halcmd_commands.cc"), true);
|
||||
assert.equal(VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES["motion-controller-simulation-replacement"].sourceFiles.includes("linuxcnc/src/emc/motion/motion.c"), true);
|
||||
assert.equal(VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES["controlled-user-m-process-state-boundary"].sourceFiles.includes("linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128"), true);
|
||||
assert.equal(VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.boundaryClass, "L4-USER-M-PROCESS");
|
||||
assert.equal(VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.cases.length, 2);
|
||||
assert.equal(VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.cases.some(({ userMCode }) => userMCode === "M128"), true);
|
||||
assert.equal(VIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY.cases.some(({ userMCode }) => userMCode === "M129"), true);
|
||||
assert.equal(VIRTUAL_HAL_COVERAGE_STATES.runtimeBoundary, "runtime-boundary");
|
||||
assert.equal(VIRTUAL_HAL_SOURCE_FILES.halui, "linuxcnc/src/emc/usr_intf/halui.cc");
|
||||
assert.equal(VIRTUAL_HAL_SYSTEM_PIN_FAMILIES.some(({ id }) => id === "iocontrol"), true);
|
||||
@@ -656,6 +666,8 @@ assert.match(sdkIndexText, /\bVIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS\b/);
|
||||
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS\b/);
|
||||
assert.match(sdkIndexText, /\bVIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES\b/);
|
||||
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES\b/);
|
||||
assert.match(sdkIndexText, /\bVIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY\b/);
|
||||
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_MILLTURN_USER_M_PROCESS_BOUNDARY\b/);
|
||||
assert.match(sdkIndexText, /\bVIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES\b/);
|
||||
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES\b/);
|
||||
assert.match(sdkIndexText, /\bVIRTUAL_HAL_PROJECT_PIN_GROUPS\b/);
|
||||
@@ -672,6 +684,10 @@ assert.match(sdkIndexText, /\bVIRTUAL_HAL_SYSTEM_PIN_FAMILIES\b/);
|
||||
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_SYSTEM_PIN_FAMILIES\b/);
|
||||
assert.match(sdkIndexText, /\bexecuteVirtualHalCommand\b/);
|
||||
assert.match(sdkReadmeText, /\bexecuteVirtualHalCommand\b/);
|
||||
assert.match(sdkIndexText, /\bapplyVirtualHalMillturnUserMProcessState\b/);
|
||||
assert.match(sdkReadmeText, /\bapplyVirtualHalMillturnUserMProcessState\b/);
|
||||
assert.match(sdkIndexText, /\bcreateVirtualHalMillturnUserMProcessBoundaryReport\b/);
|
||||
assert.match(sdkReadmeText, /\bcreateVirtualHalMillturnUserMProcessBoundaryReport\b/);
|
||||
assert.match(sdkIndexText, /\bexecuteVirtualHalcmd\b/);
|
||||
assert.match(sdkReadmeText, /\bexecuteVirtualHalcmd\b/);
|
||||
assert.match(sdkIndexText, /\bcreateVirtualHalCommandScriptFixtureReport\b/);
|
||||
@@ -781,6 +797,38 @@ assert.equal(virtualHalReport.pinRegistry.byName["spindle.0.speed-out"].value, 1
|
||||
assert.equal(virtualHalReport.integrity.complete, true);
|
||||
const virtualHalRuntime = createLinuxCncVirtualHalRuntime(sdkVirtualHal);
|
||||
assert.equal(virtualHalRuntime.getProjectReport({ availableFunctions: VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS }).ready, true);
|
||||
const millturnUserMBoundaryReport = createVirtualHalMillturnUserMProcessBoundaryReport({ manifestText: sourceManifestText });
|
||||
assert.equal(millturnUserMBoundaryReport.apiName, "linuxcnc-wasm-virtual-hal-millturn-user-m-process-boundary-report");
|
||||
assert.equal(millturnUserMBoundaryReport.boundaryClass, "L4-USER-M-PROCESS");
|
||||
assert.equal(millturnUserMBoundaryReport.complete, true);
|
||||
assert.equal(millturnUserMBoundaryReport.webSimulationSatisfied, true);
|
||||
assert.equal(millturnUserMBoundaryReport.executionEnabled, false);
|
||||
assert.equal(millturnUserMBoundaryReport.promotionAllowed, false);
|
||||
assert.equal(millturnUserMBoundaryReport.processExecutionReady, false);
|
||||
assert.equal(millturnUserMBoundaryReport.inventoryBaselineUnchanged, true);
|
||||
assert.equal(millturnUserMBoundaryReport.missingManifestFiles.length, 0);
|
||||
assert.equal(millturnUserMBoundaryReport.rows.some(({ userMCode, remapCode }) => userMCode === "M128" && remapCode === "M428"), true);
|
||||
assert.equal(millturnUserMBoundaryReport.rows.some(({ userMCode, remapCode }) => userMCode === "M129" && remapCode === "M429"), true);
|
||||
assert.equal(millturnUserMBoundaryReport.rows.every(({ stateTargetCount }) => stateTargetCount === 12), true);
|
||||
assert.equal(millturnUserMBoundaryReport.rows.every(({ executionEnabled, promotionAllowed }) => executionEnabled === false && promotionAllowed === false), true);
|
||||
let millturnStateResult = applyVirtualHalMillturnUserMProcessState(virtualHalRuntime.getState(), "M128", { manifestText: sourceManifestText });
|
||||
assert.equal(millturnStateResult.apiName, "linuxcnc-wasm-virtual-hal-millturn-user-m-process-state-result");
|
||||
assert.equal(millturnStateResult.ok, true);
|
||||
assert.equal(millturnStateResult.userMCode, "M128");
|
||||
assert.equal(millturnStateResult.executionEnabled, false);
|
||||
assert.equal(millturnStateResult.promotionAllowed, false);
|
||||
assert.equal(readVirtualHalPin(millturnStateResult.state, "motion.switchkins-type").value, 0);
|
||||
assert.equal(readVirtualHalPin(millturnStateResult.state, "ini.x.min_limit").value, -300);
|
||||
assert.equal(readVirtualHalPin(millturnStateResult.state, "ini.z.max_limit").value, 0);
|
||||
millturnStateResult = virtualHalRuntime.applyMillturnUserMProcessState("M129", { manifestText: sourceManifestText });
|
||||
assert.equal(millturnStateResult.userMCode, "M129");
|
||||
assert.equal(readVirtualHalPin(virtualHalRuntime.getState(), "motion.switchkins-type").value, 1);
|
||||
assert.equal(readVirtualHalPin(virtualHalRuntime.getState(), "motion.analog-out-03").value, 1);
|
||||
assert.equal(readVirtualHalPin(virtualHalRuntime.getState(), "kinstype.is-0").value, 0);
|
||||
assert.equal(readVirtualHalPin(virtualHalRuntime.getState(), "kinstype.is-1").value, 1);
|
||||
assert.equal(readVirtualHalPin(virtualHalRuntime.getState(), "ini.x.max_limit").value, 0);
|
||||
assert.equal(readVirtualHalPin(virtualHalRuntime.getState(), "ini.z.max_limit").value, 300);
|
||||
assert.equal(virtualHalRuntime.getMillturnUserMProcessBoundaryReport({ manifestText: sourceManifestText }).complete, true);
|
||||
const virtualHalcmdResult = virtualHalRuntime.executeHalCommand(`
|
||||
loadrt trivkins
|
||||
addf motion-controller servo-thread
|
||||
@@ -1365,6 +1413,8 @@ assert.equal(virtualHalSessionPayload.simConfigSourceCoverage.complete, true);
|
||||
assert.equal(virtualHalSessionPayload.simConfigPromotionCandidates.complete, true);
|
||||
assert.equal(virtualHalSessionPayload.simConfigEvidenceExpansion.complete, true);
|
||||
assert.equal(virtualHalSessionPayload.simConfigMacroLoadFixtures.complete, true);
|
||||
assert.equal(virtualHalSessionPayload.millturnUserMProcessBoundary.complete, true);
|
||||
assert.equal(virtualHalSessionPayload.millturnUserMProcessBoundary.boundaryClass, "L4-USER-M-PROCESS");
|
||||
assert.equal(virtualHalSessionPayload.commandScriptFixtures.complete, true);
|
||||
assert.equal(virtualHalSessionPayload.motionControllerMatrix.complete, true);
|
||||
const virtualHalSessionSnapshot = createSessionSnapshot(
|
||||
@@ -1404,6 +1454,7 @@ const browserDiagnosticsArtifact = {
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
},
|
||||
virtualHalSimConfigMacroLoadFixtures: simConfigMacroLoadFixtureReport,
|
||||
virtualHalMillturnUserMProcessBoundary: millturnUserMBoundaryReport,
|
||||
virtualHalCommandScriptFixtures: commandScriptFixtureReport,
|
||||
virtualHalMotionControllerMatrix: manifestCheckedMotionControllerMatrixReport,
|
||||
};
|
||||
@@ -1435,6 +1486,8 @@ assert.equal(browserDiagnosticsArtifactValidation.promotionCandidateSummaryReady
|
||||
assert.equal(browserDiagnosticsArtifactValidation.hasPromotionCandidateSummary, true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.macroLoadFixturesReady, true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.hasMacroLoadFixtures, true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.millturnUserMProcessBoundaryReady, true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.hasMillturnUserMProcessBoundary, true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.commandScriptFixturesReady, true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.motionControllerMatrixReady, true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.hasSessionDiagnostics, true);
|
||||
@@ -1453,6 +1506,19 @@ assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc
|
||||
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/axis/rose_engine/rcone.ngc"), true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/axis/external_offsets/eoffsets.ini"), true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/axis/external_offsets/eoffsets.ngc"), true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128"), true);
|
||||
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M129"), true);
|
||||
assert.equal(createProjectReleaseBrowserDiagnosticsArtifactValidation({
|
||||
...browserDiagnosticsArtifact,
|
||||
virtualHalMillturnUserMProcessBoundary: undefined,
|
||||
}).missing.includes("virtualHalMillturnUserMProcessBoundary"), true);
|
||||
assert.equal(createProjectReleaseBrowserDiagnosticsArtifactValidation({
|
||||
...browserDiagnosticsArtifact,
|
||||
virtualHalMillturnUserMProcessBoundary: {
|
||||
...millturnUserMBoundaryReport,
|
||||
promotionAllowed: true,
|
||||
},
|
||||
}).millturnUserMProcessBoundaryReady, false);
|
||||
assert.equal(createProjectReleaseBrowserDiagnosticsArtifactValidation({
|
||||
...browserDiagnosticsArtifact,
|
||||
virtualHalPromotionCandidateSummary: undefined,
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import {
|
||||
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
||||
createVirtualHalCommandScriptFixtureReport,
|
||||
createVirtualHalMillturnUserMProcessBoundaryReport,
|
||||
createVirtualHalMotionControllerMatrixReport,
|
||||
createVirtualHalSimConfigMacroLoadFixtureReport,
|
||||
createVirtualHalSimConfigEvidenceExpansionReport,
|
||||
@@ -1473,6 +1474,16 @@ const releaseReadinessMacroLoadFixtures = createVirtualHalSimConfigMacroLoadFixt
|
||||
"linuxcnc/configs/sim/axis/external_offsets/eoffsets.ngc",
|
||||
],
|
||||
});
|
||||
const releaseReadinessMillturnUserMProcessBoundary = createVirtualHalMillturnUserMProcessBoundaryReport({
|
||||
manifestEntries: [
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/millturn.ini",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/example.ngc",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M128",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/mcodes/M129",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/428remap.ngc",
|
||||
"linuxcnc/configs/sim/axis/vismach/millturn/remap_subs/429remap.ngc",
|
||||
],
|
||||
});
|
||||
const pythonRemapRuntimeProof = {
|
||||
nativeLifecycleReady: true,
|
||||
nativeProbeStatus: "runtime_lifecycle_probe_passed",
|
||||
@@ -1524,6 +1535,7 @@ const browserDiagnosticsArtifact = {
|
||||
inventoryBaseline: "executed=82 passed=82 skipped=77 unexpected_fail=0",
|
||||
},
|
||||
virtualHalSimConfigMacroLoadFixtures: releaseReadinessMacroLoadFixtures,
|
||||
virtualHalMillturnUserMProcessBoundary: releaseReadinessMillturnUserMProcessBoundary,
|
||||
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport({ halState: browserDiagnosticsVirtualHalState }),
|
||||
virtualHalMotionControllerMatrix: releaseReadinessMotionControllerMatrix,
|
||||
};
|
||||
@@ -1957,6 +1969,8 @@ assert.equal(releaseArtifactUrlWorkflow.diagnosticsValidation.hasPromotionCandid
|
||||
assert.equal(releaseArtifactUrlWorkflow.diagnosticsValidation.promotionCandidatesReady, true);
|
||||
assert.equal(releaseArtifactUrlWorkflow.diagnosticsValidation.hasMacroLoadFixtures, true);
|
||||
assert.equal(releaseArtifactUrlWorkflow.diagnosticsValidation.macroLoadFixturesReady, true);
|
||||
assert.equal(releaseArtifactUrlWorkflow.diagnosticsValidation.hasMillturnUserMProcessBoundary, true);
|
||||
assert.equal(releaseArtifactUrlWorkflow.diagnosticsValidation.millturnUserMProcessBoundaryReady, true);
|
||||
assert.equal(releaseArtifactUrlWorkflow.diagnosticsValidation.hasSessionDiagnostics, true);
|
||||
assert.equal(releaseArtifactUrlWorkflow.diagnosticsValidation.sessionDiagnosticsReady, true);
|
||||
assert.equal(
|
||||
@@ -2111,7 +2125,7 @@ assert.equal(
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-locked-preview")?.value,
|
||||
"L4-PYTHON-REMAP:axis/laser/raster_test.ngc, L4-PYTHON-REMAP:axis/laser/vector_test.ngc, L4-PYTHON-REMAP:axis/laser/vector_test2.ngc",
|
||||
"L4-USER-M-PROCESS:axis/vismach/millturn/example.ngc",
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowSummary.rows.find(({ id }) => id === "hard-block-runtime-promotion-allowed")?.value,
|
||||
@@ -2841,7 +2855,7 @@ const releaseArtifactUrlWorkflowMountResult =
|
||||
rowsNode: releaseArtifactUrlWorkflowRowsNode,
|
||||
});
|
||||
assert.equal(releaseArtifactUrlWorkflowRenderResult.rendered, true);
|
||||
assert.equal(releaseArtifactUrlWorkflowRenderResult.rowCount, 57);
|
||||
assert.equal(releaseArtifactUrlWorkflowRenderResult.rowCount, 53);
|
||||
assert.equal(
|
||||
releaseArtifactUrlWorkflowRenderResult.rowIds.includes("browser-diagnostics"),
|
||||
true,
|
||||
@@ -2891,7 +2905,7 @@ assert.equal(
|
||||
true,
|
||||
);
|
||||
assert.equal(releaseArtifactUrlWorkflowMountResult.ready, true);
|
||||
assert.equal(releaseArtifactUrlWorkflowMountResult.renderResult.rowCount, 57);
|
||||
assert.equal(releaseArtifactUrlWorkflowMountResult.renderResult.rowCount, 53);
|
||||
const releaseArtifactUrlWorkflowMissingDom = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({
|
||||
artifactUrl: "/project-release-readiness.json",
|
||||
fetchRef: async () => ({
|
||||
|
||||
Reference in New Issue
Block a user