解锁L4-TOOL-DB主机运行环境
结论:已识别RIP版LinuxCNC主机运行时,Tool DB native protocol probe可通过,inventory baseline保持28/28/131/0且promotion继续锁定。
This commit is contained in:
@@ -2108,6 +2108,26 @@ function linuxCncSourceExecutable(relPath) {
|
||||
}
|
||||
}
|
||||
|
||||
function linuxCncHostCommandPath(command) {
|
||||
const pathCommand = commandPath(command);
|
||||
if (pathCommand !== "") {
|
||||
return pathCommand;
|
||||
}
|
||||
const ripScriptCommands = new Set(["linuxcnc", "halrun"]);
|
||||
const ripRelativePath = ripScriptCommands.has(command)
|
||||
? `scripts/${command}`
|
||||
: `bin/${command}`;
|
||||
const ripPath = resolve(workspaceRoot, "linuxcnc", ripRelativePath);
|
||||
try {
|
||||
if ((statSync(ripPath).mode & 0o111) !== 0) {
|
||||
return ripPath;
|
||||
}
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function toolDbProcessNativeRuntimeReadinessRows(transactionRows) {
|
||||
const first = transactionRows[0];
|
||||
if (!first) {
|
||||
@@ -2126,22 +2146,22 @@ function toolDbProcessNativeRuntimeReadinessRows(transactionRows) {
|
||||
kind: "host_command",
|
||||
requirement: "linuxcnc",
|
||||
purpose: "provide_linuxcnc_python_runtime_and_task_context",
|
||||
available: commandPath("linuxcnc") !== "",
|
||||
evidence: commandPath("linuxcnc"),
|
||||
available: linuxCncHostCommandPath("linuxcnc") !== "",
|
||||
evidence: linuxCncHostCommandPath("linuxcnc"),
|
||||
},
|
||||
{
|
||||
kind: "host_command",
|
||||
requirement: "milltask",
|
||||
purpose: "own_db_program_startup_and_tooldata_protocol",
|
||||
available: commandPath("milltask") !== "",
|
||||
evidence: commandPath("milltask"),
|
||||
available: linuxCncHostCommandPath("milltask") !== "",
|
||||
evidence: linuxCncHostCommandPath("milltask"),
|
||||
},
|
||||
{
|
||||
kind: "host_command",
|
||||
requirement: "halcmd",
|
||||
purpose: "provide_linuxcnc_runtime_environment_for_db_program_sync",
|
||||
available: commandPath("halcmd") !== "",
|
||||
evidence: commandPath("halcmd"),
|
||||
available: linuxCncHostCommandPath("halcmd") !== "",
|
||||
evidence: linuxCncHostCommandPath("halcmd"),
|
||||
},
|
||||
{
|
||||
kind: "source_config_file",
|
||||
@@ -2326,9 +2346,20 @@ function toolDbProcessNativeRuntimeProbeGateRows({
|
||||
pythonModulesReady &&
|
||||
protocolContractReady
|
||||
);
|
||||
const gateStatus = runtimeReady && sourceProofReady
|
||||
? "ready_to_implement_protocol_probe"
|
||||
: "blocked_missing_host_runtime";
|
||||
const nativeRuntimeProbeRows = existsSync(nativeRuntimeProbeSummarySourcePath)
|
||||
? parseTsv(readFileSync(nativeRuntimeProbeSummarySourcePath, "utf8"))
|
||||
: [];
|
||||
const nativeToolDbProbe = nativeRuntimeProbeRows.find((row) =>
|
||||
row.boundary_class === "L4-TOOL-DB" &&
|
||||
row.runtime_probe === "linuxcnc_tool_db_runtime_probe",
|
||||
);
|
||||
const protocolProbePassed = nativeToolDbProbe?.probe_status === "runtime_protocol_probe_passed";
|
||||
const gateStatus = protocolProbePassed
|
||||
? "native_protocol_probe_passed_waiting_for_node_browser_proof"
|
||||
: runtimeReady && sourceProofReady
|
||||
? "ready_to_implement_protocol_probe"
|
||||
: "blocked_missing_host_runtime";
|
||||
const proofStatus = protocolProbePassed ? "native_protocol_probe_passed" : "pending";
|
||||
|
||||
return [[
|
||||
first.path,
|
||||
@@ -2351,12 +2382,14 @@ function toolDbProcessNativeRuntimeProbeGateRows({
|
||||
flagValue(sourceProofReady),
|
||||
"native_db_process_protocol_probe_required",
|
||||
gateStatus,
|
||||
"pending",
|
||||
proofStatus,
|
||||
"0",
|
||||
"0",
|
||||
runtimeReady
|
||||
? "host_and_source_ready_write_native_db_protocol_probe_python3_and_tbl_fallback_not_sufficient"
|
||||
: "python3_and_tool_table_fallback_not_sufficient_keep_tool_db_blocked",
|
||||
protocolProbePassed
|
||||
? "native_protocol_probe_passed_keep_tool_db_locked_until_node_browser_proof"
|
||||
: runtimeReady
|
||||
? "host_and_source_ready_write_native_db_protocol_probe_python3_and_tbl_fallback_not_sufficient"
|
||||
: "python3_and_tool_table_fallback_not_sufficient_keep_tool_db_blocked",
|
||||
].map(tsvValue).join("\t")];
|
||||
}
|
||||
|
||||
@@ -2437,13 +2470,26 @@ function verifyToolDbProcessNativeRuntimeProbeGateRows({
|
||||
assert.equal(row.runtime_ready, flagValue(allRuntimeReady), "tool DB runtime readiness drift");
|
||||
assert.equal(row.source_proof_ready, "1", "tool DB source proof must be ready before runtime probe implementation");
|
||||
assert.equal(row.required_native_proof, "native_db_process_protocol_probe_required", "tool DB native proof drift");
|
||||
assert.equal(row.proof_status, "pending", "tool DB probe gate must remain pending");
|
||||
assert.ok(
|
||||
["pending", "native_protocol_probe_passed"].includes(row.proof_status),
|
||||
"tool DB probe gate proof status drift",
|
||||
);
|
||||
assert.equal(row.execution_enabled, "0", "tool DB probe gate must not enable execution");
|
||||
assert.equal(row.promotion_allowed, "0", "tool DB probe gate must not allow promotion");
|
||||
|
||||
if (allRuntimeReady) {
|
||||
assert.equal(row.missing_requirements, "-", "ready tool DB runtime has missing requirements");
|
||||
assert.equal(row.gate_status, "ready_to_implement_protocol_probe", "ready tool DB gate status drift");
|
||||
assert.ok(
|
||||
[
|
||||
"ready_to_implement_protocol_probe",
|
||||
"native_protocol_probe_passed_waiting_for_node_browser_proof",
|
||||
].includes(row.gate_status),
|
||||
"ready tool DB gate status drift",
|
||||
);
|
||||
if (row.gate_status === "native_protocol_probe_passed_waiting_for_node_browser_proof") {
|
||||
assert.equal(row.proof_status, "native_protocol_probe_passed", "passed tool DB proof status drift");
|
||||
assert.ok(row.notes.includes("node_browser_proof"), "passed tool DB gate must keep node/browser proof lock");
|
||||
}
|
||||
} else {
|
||||
assert.deepEqual(
|
||||
splitSummaryList(row.missing_requirements).sort(),
|
||||
@@ -4168,8 +4214,8 @@ function pythonRemapNativeRuntimeReadinessRows(contractRows) {
|
||||
kind: "host_command",
|
||||
requirement: "linuxcnc",
|
||||
purpose: "provide_linuxcnc_task_interpreter_python_context",
|
||||
available: commandPath("linuxcnc") !== "",
|
||||
evidence: commandPath("linuxcnc"),
|
||||
available: linuxCncHostCommandPath("linuxcnc") !== "",
|
||||
evidence: linuxCncHostCommandPath("linuxcnc"),
|
||||
},
|
||||
{
|
||||
kind: "linuxcnc_source_file",
|
||||
@@ -5563,7 +5609,7 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
)
|
||||
);
|
||||
const runtimeBoundaryHostUnblockPlanOk = (
|
||||
runtimeBoundaryHostUnblockPlanRows.length === 4 &&
|
||||
runtimeBoundaryHostUnblockPlanRows.length === runtimeBoundaryHostRequirementSummaryRows.filter((row) => row.missing_blocks_runtime === "1").length &&
|
||||
runtimeBoundaryHostUnblockPlanRows.every((row) =>
|
||||
row.requirement_kind === "host_command" &&
|
||||
row.available === "0" &&
|
||||
@@ -5581,14 +5627,21 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
const runtimeBoundaryFamilyHostReadinessOk = (
|
||||
runtimeBoundaryFamilyHostReadinessRows.length === 3 &&
|
||||
runtimeBoundaryFamilyHostReadinessRows.every((row) =>
|
||||
/^[1-9][0-9]*$/.test(row.missing_requirement_count) &&
|
||||
row.missing_host_requirements !== "-" &&
|
||||
/^[0-9]+$/.test(row.missing_requirement_count) &&
|
||||
/^[1-9][0-9]*$/.test(row.available_requirement_count) &&
|
||||
row.available_requirements !== "-" &&
|
||||
/^ENABLE_[A-Z0-9_]+=1$/.test(row.opt_in_env) &&
|
||||
row.execution_command.includes(row.opt_in_env) &&
|
||||
row.preflight_status === "blocked_missing_host_runtime" &&
|
||||
row.family_host_status === "blocked_missing_host_requirements" &&
|
||||
(
|
||||
(row.missing_requirement_count === "0" &&
|
||||
row.missing_host_requirements === "-" &&
|
||||
row.preflight_status === "ready_to_run_opt_in_native_probe" &&
|
||||
row.family_host_status === "host_ready_to_run_opt_in_probe") ||
|
||||
(row.missing_requirement_count !== "0" &&
|
||||
row.missing_host_requirements !== "-" &&
|
||||
row.preflight_status === "blocked_missing_host_runtime" &&
|
||||
row.family_host_status === "blocked_missing_host_requirements")
|
||||
) &&
|
||||
row.execution_enabled === "0" &&
|
||||
row.promotion_allowed === "0",
|
||||
)
|
||||
@@ -5596,17 +5649,17 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
const runtimeBoundaryHostReadinessRollupOk = (
|
||||
runtimeBoundaryHostReadinessRollupRows.length === 1 &&
|
||||
runtimeBoundaryHostReadinessRollupRows.every((row) =>
|
||||
row.scope === "blocked_runtime_host_readiness" &&
|
||||
row.scope === "blocked_runtime_host_readiness" &&
|
||||
row.family_count === "3" &&
|
||||
row.host_ready_family_count === "0" &&
|
||||
row.host_blocked_family_count === "3" &&
|
||||
row.blocked_families !== "-" &&
|
||||
row.missing_host_requirements !== "-" &&
|
||||
row.missing_host_requirement_count === "4" &&
|
||||
row.ready_opt_in_command_count === "0" &&
|
||||
row.ready_opt_in_commands === "-" &&
|
||||
row.blocked_opt_in_commands !== "-" &&
|
||||
row.host_readiness_status === "host_blocked_for_all_opt_in_native_probes" &&
|
||||
/^[0-9]+$/.test(row.host_ready_family_count) &&
|
||||
/^[0-9]+$/.test(row.host_blocked_family_count) &&
|
||||
/^[0-9]+$/.test(row.missing_host_requirement_count) &&
|
||||
/^[0-9]+$/.test(row.ready_opt_in_command_count) &&
|
||||
[
|
||||
"host_ready_for_all_opt_in_native_probes",
|
||||
"host_partially_ready_for_opt_in_native_probes",
|
||||
"host_blocked_for_all_opt_in_native_probes",
|
||||
].includes(row.host_readiness_status) &&
|
||||
row.execution_enabled === "0" &&
|
||||
row.promotion_allowed === "0",
|
||||
)
|
||||
@@ -5616,10 +5669,16 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
runtimeBoundaryOptInProbeDispatchPlanRows.every((row) =>
|
||||
/^ENABLE_[A-Z0-9_]+=1$/.test(row.opt_in_env) &&
|
||||
row.execution_command.includes(row.opt_in_env) &&
|
||||
row.family_host_status === "blocked_missing_host_requirements" &&
|
||||
row.missing_host_requirements !== "-" &&
|
||||
row.host_action === "skip_missing_host_requirements" &&
|
||||
row.dispatch_allowed === "0" &&
|
||||
(
|
||||
(row.family_host_status === "host_ready_to_run_opt_in_probe" &&
|
||||
row.missing_host_requirements === "-" &&
|
||||
row.host_action === "ready_for_manual_opt_in_native_probe" &&
|
||||
row.dispatch_allowed === "1") ||
|
||||
(row.family_host_status === "blocked_missing_host_requirements" &&
|
||||
row.missing_host_requirements !== "-" &&
|
||||
row.host_action === "skip_missing_host_requirements" &&
|
||||
row.dispatch_allowed === "0")
|
||||
) &&
|
||||
row.execution_enabled === "0" &&
|
||||
row.promotion_allowed === "0",
|
||||
)
|
||||
@@ -5627,12 +5686,16 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
const runtimeBoundaryOptInProbeDispatchRollupOk = (
|
||||
runtimeBoundaryOptInProbeDispatchRollupRows.length === 1 &&
|
||||
runtimeBoundaryOptInProbeDispatchRollupRows.every((row) =>
|
||||
row.scope === "blocked_runtime_opt_in_probe_dispatch" &&
|
||||
row.scope === "blocked_runtime_opt_in_probe_dispatch" &&
|
||||
row.probe_count === "3" &&
|
||||
row.dispatch_allowed_count === "0" &&
|
||||
row.dispatch_blocked_count === "3" &&
|
||||
row.dispatch_actions === "skip_missing_host_requirements" &&
|
||||
row.dispatch_status === "dispatch_blocked_for_all_opt_in_native_probes" &&
|
||||
/^[0-9]+$/.test(row.dispatch_allowed_count) &&
|
||||
/^[0-9]+$/.test(row.dispatch_blocked_count) &&
|
||||
row.dispatch_actions !== "-" &&
|
||||
[
|
||||
"dispatch_allowed_for_all_opt_in_native_probes",
|
||||
"dispatch_partially_allowed_for_opt_in_native_probes",
|
||||
"dispatch_blocked_for_all_opt_in_native_probes",
|
||||
].includes(row.dispatch_status) &&
|
||||
row.execution_enabled === "0" &&
|
||||
row.promotion_allowed === "0",
|
||||
)
|
||||
@@ -5640,13 +5703,19 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
const runtimeBoundaryOptInProbeSkipEvidenceContractOk = (
|
||||
runtimeBoundaryOptInProbeSkipEvidenceContractRows.length === 3 &&
|
||||
runtimeBoundaryOptInProbeSkipEvidenceContractRows.every((row) =>
|
||||
row.host_action === "skip_missing_host_requirements" &&
|
||||
row.skip_reason === "missing_host_requirements" &&
|
||||
row.missing_host_requirements !== "-" &&
|
||||
row.current_probe_status === "skipped_missing_host_runtime" &&
|
||||
(
|
||||
(row.host_action === "ready_for_manual_opt_in_native_probe" &&
|
||||
row.skip_reason === "-" &&
|
||||
row.missing_host_requirements === "-" &&
|
||||
row.skip_evidence_status === "skip_contract_not_applicable_dispatch_allowed") ||
|
||||
(row.host_action === "skip_missing_host_requirements" &&
|
||||
row.skip_reason === "missing_host_requirements" &&
|
||||
row.missing_host_requirements !== "-" &&
|
||||
row.current_probe_status === "skipped_missing_host_runtime" &&
|
||||
row.skip_evidence_status === "skip_valid_until_host_requirements_available")
|
||||
) &&
|
||||
row.evidence_required_now === "0" &&
|
||||
row.observed_evidence_ready === "0" &&
|
||||
row.skip_evidence_status === "skip_valid_until_host_requirements_available" &&
|
||||
row.execution_enabled === "0" &&
|
||||
row.promotion_allowed === "0",
|
||||
)
|
||||
@@ -5654,12 +5723,12 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
const runtimeBoundaryOptInProbeSkipEvidenceRollupOk = (
|
||||
runtimeBoundaryOptInProbeSkipEvidenceRollupRows.length === 1 &&
|
||||
runtimeBoundaryOptInProbeSkipEvidenceRollupRows.every((row) =>
|
||||
row.scope === "blocked_runtime_opt_in_probe_skip_evidence" &&
|
||||
row.scope === "blocked_runtime_opt_in_probe_skip_evidence" &&
|
||||
row.probe_count === "3" &&
|
||||
row.skip_count === "3" &&
|
||||
/^[0-9]+$/.test(row.skip_count) &&
|
||||
row.evidence_required_now_count === "0" &&
|
||||
row.observed_evidence_ready_count === "0" &&
|
||||
row.skip_evidence_statuses === "skip_valid_until_host_requirements_available" &&
|
||||
row.skip_evidence_statuses !== "-" &&
|
||||
row.evidence_rollup_status === "no_native_pass_evidence_accepted_while_host_blocked" &&
|
||||
row.execution_enabled === "0" &&
|
||||
row.promotion_allowed === "0",
|
||||
@@ -5668,11 +5737,10 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
const runtimeBoundaryNativeEvidenceAcceptanceGateOk = (
|
||||
runtimeBoundaryNativeEvidenceAcceptanceGateRows.length === 3 &&
|
||||
runtimeBoundaryNativeEvidenceAcceptanceGateRows.every((row) =>
|
||||
row.current_probe_status === "skipped_missing_host_runtime" &&
|
||||
row.native_evidence_status === "pending_until_native_pass" &&
|
||||
row.native_evidence_status === "pending_until_native_pass" &&
|
||||
row.evidence_required_now === "0" &&
|
||||
row.observed_evidence_ready === "0" &&
|
||||
row.native_evidence_gate === "blocked_until_host_requirements_available" &&
|
||||
["blocked_until_host_requirements_available", "blocked_until_native_pass_evidence"].includes(row.native_evidence_gate) &&
|
||||
row.evidence_acceptance_allowed === "0" &&
|
||||
row.promotion_ready === "0" &&
|
||||
row.execution_enabled === "0" &&
|
||||
@@ -5698,7 +5766,7 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
classOrderMatches(runtimeBoundaryOptInProbeSkipEvidenceContractRows) &&
|
||||
classOrderMatches(runtimeBoundaryNativeEvidenceAcceptanceGateRows) &&
|
||||
runtimeBoundaryOptInProbeDispatchPlanRows.every((row) =>
|
||||
row.dispatch_allowed === "0" &&
|
||||
["0", "1"].includes(row.dispatch_allowed) &&
|
||||
row.execution_enabled === "0" &&
|
||||
row.promotion_allowed === "0",
|
||||
) &&
|
||||
@@ -5708,8 +5776,7 @@ function boundaryPhaseCompletionSummaryRows({
|
||||
row.promotion_allowed === "0",
|
||||
) &&
|
||||
runtimeBoundaryPromotionBlockerRows.every((row) =>
|
||||
row.blocker_keys.includes("host_runtime_requirements_missing") &&
|
||||
row.blocker_keys.includes("promotion_lock_active") &&
|
||||
row.blocker_keys.includes("promotion_lock_active") &&
|
||||
row.blocker_keys.includes("manual_lock_update_required"),
|
||||
)
|
||||
);
|
||||
@@ -6085,7 +6152,11 @@ function verifyBoundaryPhaseCompletionSummaryRows(rows) {
|
||||
);
|
||||
for (const row of parsedRows) {
|
||||
assert.equal(row.passed, "1", `${row.criterion}: completion criterion failed`);
|
||||
assert.ok(/^[1-9][0-9]*$/.test(row.count), `${row.criterion}: invalid criterion count`);
|
||||
if (row.criterion === "runtime_boundary_host_unblock_plan") {
|
||||
assert.ok(/^[0-9]+$/.test(row.count), `${row.criterion}: invalid criterion count`);
|
||||
} else {
|
||||
assert.ok(/^[1-9][0-9]*$/.test(row.count), `${row.criterion}: invalid criterion count`);
|
||||
}
|
||||
assert.notEqual(row.evidence, "-", `${row.criterion}: missing criterion evidence`);
|
||||
}
|
||||
const rowByCriterion = new Map(parsedRows.map((row) => [row.criterion, row]));
|
||||
@@ -7233,9 +7304,9 @@ function verifyRuntimeBoundaryHostRequirementSummaryRows(rows, preflightRows) {
|
||||
|
||||
const byRequirement = new Map(parsedRows.map((row) => [row.requirement, row]));
|
||||
for (const required of [
|
||||
["linuxcnc", "0", "3", "L4-PYTHON-REMAP,L4-TOOL-DB,L4-USER-M-PROCESS"],
|
||||
["halcmd", "0", "2", "L4-TOOL-DB,L4-USER-M-PROCESS"],
|
||||
["milltask", "0", "1", "L4-TOOL-DB"],
|
||||
["linuxcnc", "1", "3", "-"],
|
||||
["halcmd", "1", "2", "-"],
|
||||
["milltask", "1", "1", "-"],
|
||||
["python3", "1", "2", "-"],
|
||||
["tclsh", "1", "1", "-"],
|
||||
]) {
|
||||
@@ -7439,45 +7510,22 @@ function verifyRuntimeBoundaryFamilyHostReadinessRows(rows, preflightRows) {
|
||||
expectedHeaders,
|
||||
);
|
||||
const preflightByClass = new Map(preflightRows.map((row) => [row.boundary_class, row]));
|
||||
const expected = new Map([
|
||||
[
|
||||
"L4-USER-M-PROCESS",
|
||||
{
|
||||
missingCount: "3",
|
||||
missing: "halrun,halcmd,linuxcnc",
|
||||
available: "tclsh",
|
||||
},
|
||||
],
|
||||
[
|
||||
"L4-TOOL-DB",
|
||||
{
|
||||
missingCount: "3",
|
||||
missing: "linuxcnc,milltask,halcmd",
|
||||
available: "python3,axis/db_demo/db_nonran.py,linuxcnc.so,tooldb.py",
|
||||
},
|
||||
],
|
||||
[
|
||||
"L4-PYTHON-REMAP",
|
||||
{
|
||||
missingCount: "1",
|
||||
missing: "linuxcnc",
|
||||
available: "python3,src/emc/rs274ngc/interp_python.cc,src/emc/pythonplugin/python_plugin.cc,axis/remap/stop-lookahead/python/remap.py,axis/remap/stop-lookahead/python/toplevel.py",
|
||||
},
|
||||
],
|
||||
]);
|
||||
const expectedClasses = [
|
||||
"L4-USER-M-PROCESS",
|
||||
"L4-TOOL-DB",
|
||||
"L4-PYTHON-REMAP",
|
||||
];
|
||||
|
||||
assert.equal(parsedRows.length, expected.size, "family host readiness row count drift");
|
||||
assert.equal(parsedRows.length, expectedClasses.length, "family host readiness row count drift");
|
||||
assert.deepEqual(
|
||||
parsedRows.map((row) => row.boundary_class),
|
||||
[...expected.keys()],
|
||||
expectedClasses,
|
||||
"family host readiness order drift",
|
||||
);
|
||||
|
||||
for (const row of parsedRows) {
|
||||
const preflight = preflightByClass.get(row.boundary_class);
|
||||
const expectedRow = expected.get(row.boundary_class);
|
||||
assert.ok(preflight, `${row.boundary_class}: family host readiness lacks preflight row`);
|
||||
assert.ok(expectedRow, `${row.boundary_class}: unexpected family host readiness row`);
|
||||
assert.equal(row.boundary_kind, preflight.boundary_kind, `${row.boundary_class}: family host readiness kind drift`);
|
||||
assert.equal(row.target, preflight.target, `${row.boundary_class}: family host readiness target drift`);
|
||||
assert.equal(row.blocked, preflight.blocked, `${row.boundary_class}: family host readiness blocked drift`);
|
||||
@@ -7486,11 +7534,20 @@ function verifyRuntimeBoundaryFamilyHostReadinessRows(rows, preflightRows) {
|
||||
assert.equal(row.execution_command, preflight.execution_command, `${row.boundary_class}: family host readiness command drift`);
|
||||
assert.equal(row.current_probe_status, preflight.current_probe_status, `${row.boundary_class}: family host readiness probe status drift`);
|
||||
assert.equal(row.preflight_status, preflight.preflight_status, `${row.boundary_class}: family host readiness preflight status drift`);
|
||||
assert.equal(row.missing_requirement_count, expectedRow.missingCount, `${row.boundary_class}: family host readiness missing count drift`);
|
||||
assert.equal(row.missing_host_requirements, expectedRow.missing, `${row.boundary_class}: family host readiness missing requirements drift`);
|
||||
assert.equal(row.available_requirements, expectedRow.available, `${row.boundary_class}: family host readiness available requirements drift`);
|
||||
assert.equal(row.available_requirement_count, String(splitSummaryList(expectedRow.available).length), `${row.boundary_class}: family host readiness available count drift`);
|
||||
assert.equal(row.family_host_status, "blocked_missing_host_requirements", `${row.boundary_class}: family host readiness should remain blocked on this host`);
|
||||
assert.equal(row.missing_host_requirements, preflight.missing_requirements, `${row.boundary_class}: family host readiness missing requirements drift`);
|
||||
assert.equal(row.missing_requirement_count, String(splitSummaryList(preflight.missing_requirements).length), `${row.boundary_class}: family host readiness missing count drift`);
|
||||
assert.equal(
|
||||
row.available_requirement_count,
|
||||
String(splitSummaryList(row.available_requirements).length),
|
||||
`${row.boundary_class}: family host readiness available count drift`,
|
||||
);
|
||||
if (preflight.runtime_ready === "1") {
|
||||
assert.equal(row.missing_host_requirements, "-", `${row.boundary_class}: ready family must not list missing requirements`);
|
||||
assert.equal(row.family_host_status, "host_ready_to_run_opt_in_probe", `${row.boundary_class}: ready family host status drift`);
|
||||
} else {
|
||||
assert.notEqual(row.missing_host_requirements, "-", `${row.boundary_class}: blocked family must list missing requirements`);
|
||||
assert.equal(row.family_host_status, "blocked_missing_host_requirements", `${row.boundary_class}: blocked family host status drift`);
|
||||
}
|
||||
assert.equal(row.execution_enabled, "0", `${row.boundary_class}: family host readiness must not enable execution`);
|
||||
assert.equal(row.promotion_allowed, "0", `${row.boundary_class}: family host readiness must not allow promotion`);
|
||||
assert.ok(row.notes.includes("no_automatic_promotion"), `${row.boundary_class}: family host readiness note drift`);
|
||||
@@ -7571,22 +7628,33 @@ function verifyRuntimeBoundaryHostReadinessRollupRows({
|
||||
.filter((requirement) => requirement.missing_blocks_runtime === "1")
|
||||
.map((requirement) => requirement.requirement),
|
||||
);
|
||||
const readyFamilies = familyHostReadinessRows.filter((family) =>
|
||||
family.family_host_status === "host_ready_to_run_opt_in_probe",
|
||||
);
|
||||
const blockedFamilies = familyHostReadinessRows.filter((family) =>
|
||||
family.family_host_status !== "host_ready_to_run_opt_in_probe",
|
||||
);
|
||||
|
||||
assert.equal(parsedRows.length, 1, "host readiness rollup row count drift");
|
||||
assert.equal(row.scope, "blocked_runtime_host_readiness", "host readiness rollup scope drift");
|
||||
assert.equal(row.family_count, String(familyHostReadinessRows.length), "host readiness rollup family count drift");
|
||||
assert.equal(row.host_ready_family_count, "0", "host readiness rollup must have no ready families on this host");
|
||||
assert.equal(row.host_blocked_family_count, String(familyHostReadinessRows.length), "host readiness rollup blocked family count drift");
|
||||
assert.equal(row.blocked_families, "L4-PYTHON-REMAP,L4-TOOL-DB,L4-USER-M-PROCESS", "host readiness rollup blocked families drift");
|
||||
assert.equal(row.host_ready_family_count, String(readyFamilies.length), "host readiness rollup ready family count drift");
|
||||
assert.equal(row.host_blocked_family_count, String(blockedFamilies.length), "host readiness rollup blocked family count drift");
|
||||
assert.equal(row.blocked_families, listValue(uniqueSorted(blockedFamilies.map((family) => family.boundary_class))), "host readiness rollup blocked families drift");
|
||||
assert.equal(row.missing_host_requirements, listValue(expectedMissingRequirements), "host readiness rollup missing requirements drift");
|
||||
assert.equal(row.missing_host_requirement_count, String(expectedMissingRequirements.length), "host readiness rollup missing requirement count drift");
|
||||
assert.equal(row.ready_opt_in_command_count, "0", "host readiness rollup must not report ready opt-in commands");
|
||||
assert.equal(row.ready_opt_in_commands, "-", "host readiness rollup must not list ready opt-in commands");
|
||||
assert.notEqual(row.blocked_opt_in_commands, "-", "host readiness rollup must list blocked opt-in commands");
|
||||
for (const family of familyHostReadinessRows) {
|
||||
assert.equal(row.ready_opt_in_command_count, String(readyFamilies.length), "host readiness rollup ready command count drift");
|
||||
assert.equal(row.ready_opt_in_commands, listValue(uniqueSorted(readyFamilies.map((family) => family.execution_command))), "host readiness rollup ready commands drift");
|
||||
assert.equal(row.blocked_opt_in_commands, listValue(uniqueSorted(blockedFamilies.map((family) => family.execution_command))), "host readiness rollup blocked commands drift");
|
||||
for (const family of blockedFamilies) {
|
||||
assert.ok(row.blocked_opt_in_commands.includes(family.execution_command), `${family.boundary_class}: host readiness rollup missing blocked command`);
|
||||
}
|
||||
assert.equal(row.host_readiness_status, "host_blocked_for_all_opt_in_native_probes", "host readiness rollup status drift");
|
||||
const expectedHostReadinessStatus = readyFamilies.length === familyHostReadinessRows.length
|
||||
? "host_ready_for_all_opt_in_native_probes"
|
||||
: readyFamilies.length > 0
|
||||
? "host_partially_ready_for_opt_in_native_probes"
|
||||
: "host_blocked_for_all_opt_in_native_probes";
|
||||
assert.equal(row.host_readiness_status, expectedHostReadinessStatus, "host readiness rollup status drift");
|
||||
assert.equal(row.execution_enabled, "0", "host readiness rollup must not enable execution");
|
||||
assert.equal(row.promotion_allowed, "0", "host readiness rollup must not allow promotion");
|
||||
assert.ok(row.notes.includes("no_automatic_promotion"), "host readiness rollup note drift");
|
||||
@@ -7685,14 +7753,19 @@ function verifyRuntimeBoundaryOptInProbeDispatchPlanRows({
|
||||
assert.equal(row.missing_host_requirements, readiness.missing_host_requirements, `${row.boundary_class}: dispatch missing requirement drift`);
|
||||
assert.equal(row.host_readiness_status, rollup.host_readiness_status, `${row.boundary_class}: dispatch rollup status drift`);
|
||||
assert.ok(row.execution_command.includes(row.opt_in_env), `${row.boundary_class}: dispatch command must include opt-in env`);
|
||||
assert.equal(row.family_host_status, "blocked_missing_host_requirements", `${row.boundary_class}: current host must remain blocked`);
|
||||
assert.notEqual(row.missing_host_requirements, "-", `${row.boundary_class}: blocked dispatch must list missing requirements`);
|
||||
assert.equal(row.host_readiness_status, "host_blocked_for_all_opt_in_native_probes", `${row.boundary_class}: dispatch host readiness status drift`);
|
||||
assert.equal(row.host_action, "skip_missing_host_requirements", `${row.boundary_class}: current host dispatch action drift`);
|
||||
assert.equal(row.dispatch_allowed, "0", `${row.boundary_class}: current host dispatch must not be allowed`);
|
||||
if (readiness.family_host_status === "host_ready_to_run_opt_in_probe") {
|
||||
assert.equal(row.missing_host_requirements, "-", `${row.boundary_class}: ready dispatch must not list missing requirements`);
|
||||
assert.equal(row.host_action, "ready_for_manual_opt_in_native_probe", `${row.boundary_class}: ready dispatch action drift`);
|
||||
assert.equal(row.dispatch_allowed, "1", `${row.boundary_class}: ready dispatch should be allowed manually`);
|
||||
assert.ok(row.next_action.includes("manually_run_opt_in_probe"), `${row.boundary_class}: ready dispatch next action drift`);
|
||||
} else {
|
||||
assert.notEqual(row.missing_host_requirements, "-", `${row.boundary_class}: blocked dispatch must list missing requirements`);
|
||||
assert.equal(row.host_action, "skip_missing_host_requirements", `${row.boundary_class}: blocked dispatch action drift`);
|
||||
assert.equal(row.dispatch_allowed, "0", `${row.boundary_class}: blocked dispatch must not be allowed`);
|
||||
assert.ok(row.next_action.includes(row.missing_host_requirements), `${row.boundary_class}: blocked dispatch next action must name missing requirements`);
|
||||
}
|
||||
assert.equal(row.execution_enabled, "0", `${row.boundary_class}: dispatch plan must not enable execution`);
|
||||
assert.equal(row.promotion_allowed, "0", `${row.boundary_class}: dispatch plan must not allow promotion`);
|
||||
assert.ok(row.next_action.includes(row.missing_host_requirements), `${row.boundary_class}: dispatch next action must name missing requirements`);
|
||||
assert.ok(row.notes.includes("no_automatic_promotion"), `${row.boundary_class}: dispatch plan note drift`);
|
||||
}
|
||||
|
||||
@@ -7752,6 +7825,7 @@ function verifyRuntimeBoundaryOptInProbeDispatchRollupRows({
|
||||
expectedHeaders,
|
||||
);
|
||||
const row = parsedRows[0];
|
||||
const dispatchAllowedRows = dispatchPlanRows.filter((plan) => plan.dispatch_allowed === "1");
|
||||
const dispatchBlockedRows = dispatchPlanRows.filter((plan) => plan.dispatch_allowed !== "1");
|
||||
const expectedMissingRequirements = uniqueSorted(dispatchBlockedRows.flatMap((plan) =>
|
||||
splitSummaryList(plan.missing_host_requirements),
|
||||
@@ -7760,17 +7834,22 @@ function verifyRuntimeBoundaryOptInProbeDispatchRollupRows({
|
||||
assert.equal(parsedRows.length, 1, "opt-in probe dispatch rollup row count drift");
|
||||
assert.equal(row.scope, "blocked_runtime_opt_in_probe_dispatch", "opt-in probe dispatch rollup scope drift");
|
||||
assert.equal(row.probe_count, String(dispatchPlanRows.length), "opt-in probe dispatch rollup probe count drift");
|
||||
assert.equal(row.dispatch_allowed_count, "0", "opt-in probe dispatch rollup must not allow probes on this host");
|
||||
assert.equal(row.dispatch_blocked_count, String(dispatchPlanRows.length), "opt-in probe dispatch rollup blocked count drift");
|
||||
assert.equal(row.blocked_families, "L4-PYTHON-REMAP,L4-TOOL-DB,L4-USER-M-PROCESS", "opt-in probe dispatch rollup blocked families drift");
|
||||
assert.equal(row.dispatch_actions, "skip_missing_host_requirements", "opt-in probe dispatch rollup action drift");
|
||||
assert.equal(row.dispatch_allowed_commands, "-", "opt-in probe dispatch rollup must not list allowed commands");
|
||||
assert.notEqual(row.dispatch_blocked_commands, "-", "opt-in probe dispatch rollup must list blocked commands");
|
||||
for (const plan of dispatchPlanRows) {
|
||||
assert.equal(row.dispatch_allowed_count, String(dispatchAllowedRows.length), "opt-in probe dispatch rollup allowed count drift");
|
||||
assert.equal(row.dispatch_blocked_count, String(dispatchBlockedRows.length), "opt-in probe dispatch rollup blocked count drift");
|
||||
assert.equal(row.blocked_families, listValue(uniqueSorted(dispatchBlockedRows.map((plan) => plan.boundary_class))), "opt-in probe dispatch rollup blocked families drift");
|
||||
assert.equal(row.dispatch_actions, listValue(uniqueSorted(dispatchPlanRows.map((plan) => plan.host_action))), "opt-in probe dispatch rollup action drift");
|
||||
assert.equal(row.dispatch_allowed_commands, listValue(uniqueSorted(dispatchAllowedRows.map((plan) => plan.execution_command))), "opt-in probe dispatch rollup allowed commands drift");
|
||||
assert.equal(row.dispatch_blocked_commands, listValue(uniqueSorted(dispatchBlockedRows.map((plan) => plan.execution_command))), "opt-in probe dispatch rollup blocked commands drift");
|
||||
for (const plan of dispatchBlockedRows) {
|
||||
assert.ok(row.dispatch_blocked_commands.includes(plan.execution_command), `${plan.boundary_class}: opt-in probe dispatch rollup missing blocked command`);
|
||||
}
|
||||
assert.equal(row.missing_host_requirements, listValue(expectedMissingRequirements), "opt-in probe dispatch rollup missing requirement drift");
|
||||
assert.equal(row.dispatch_status, "dispatch_blocked_for_all_opt_in_native_probes", "opt-in probe dispatch rollup status drift");
|
||||
const expectedDispatchStatus = dispatchAllowedRows.length === dispatchPlanRows.length
|
||||
? "dispatch_allowed_for_all_opt_in_native_probes"
|
||||
: dispatchAllowedRows.length > 0
|
||||
? "dispatch_partially_allowed_for_opt_in_native_probes"
|
||||
: "dispatch_blocked_for_all_opt_in_native_probes";
|
||||
assert.equal(row.dispatch_status, expectedDispatchStatus, "opt-in probe dispatch rollup status drift");
|
||||
assert.equal(row.execution_enabled, "0", "opt-in probe dispatch rollup must not enable execution");
|
||||
assert.equal(row.promotion_allowed, "0", "opt-in probe dispatch rollup must not allow promotion");
|
||||
assert.ok(row.notes.includes("no_automatic_promotion"), "opt-in probe dispatch rollup note drift");
|
||||
@@ -7869,12 +7948,8 @@ function verifyRuntimeBoundaryOptInProbeSkipEvidenceContractRows({
|
||||
assert.equal(row.runtime_probe, evidence.runtime_probe, `${row.boundary_class}: skip evidence runtime probe drift`);
|
||||
assert.equal(row.opt_in_env, dispatch.opt_in_env, `${row.boundary_class}: skip evidence opt-in drift`);
|
||||
assert.equal(row.execution_command, dispatch.execution_command, `${row.boundary_class}: skip evidence command drift`);
|
||||
assert.equal(row.host_action, "skip_missing_host_requirements", `${row.boundary_class}: current host skip action drift`);
|
||||
assert.equal(row.host_action, dispatch.host_action, `${row.boundary_class}: skip evidence host action drift`);
|
||||
assert.equal(row.skip_reason, "missing_host_requirements", `${row.boundary_class}: skip evidence reason drift`);
|
||||
assert.equal(row.missing_host_requirements, dispatch.missing_host_requirements, `${row.boundary_class}: skip evidence missing requirements drift`);
|
||||
assert.notEqual(row.missing_host_requirements, "-", `${row.boundary_class}: skip evidence must list missing host requirements`);
|
||||
assert.equal(row.current_probe_status, "skipped_missing_host_runtime", `${row.boundary_class}: skip evidence current probe status drift`);
|
||||
assert.equal(row.current_probe_status, evidence.current_probe_status, `${row.boundary_class}: skip evidence probe status must match pass evidence contract`);
|
||||
assert.equal(row.evidence_required_now, "0", `${row.boundary_class}: skipped probe must not require evidence now`);
|
||||
assert.equal(row.evidence_required_now, evidence.evidence_required_now, `${row.boundary_class}: skip evidence required-now drift`);
|
||||
@@ -7882,7 +7957,18 @@ function verifyRuntimeBoundaryOptInProbeSkipEvidenceContractRows({
|
||||
assert.equal(row.observed_evidence_ready, evidence.observed_evidence_ready, `${row.boundary_class}: skip evidence readiness drift`);
|
||||
assert.equal(row.native_evidence_status, "pending_until_native_pass", `${row.boundary_class}: skip evidence status drift`);
|
||||
assert.equal(row.native_evidence_status, evidence.evidence_status, `${row.boundary_class}: skip evidence native status drift`);
|
||||
assert.equal(row.skip_evidence_status, "skip_valid_until_host_requirements_available", `${row.boundary_class}: skip evidence contract status drift`);
|
||||
if (dispatch.dispatch_allowed === "1") {
|
||||
assert.equal(row.host_action, "ready_for_manual_opt_in_native_probe", `${row.boundary_class}: ready skip evidence action drift`);
|
||||
assert.equal(row.skip_reason, "-", `${row.boundary_class}: ready dispatch must not have skip reason`);
|
||||
assert.equal(row.missing_host_requirements, "-", `${row.boundary_class}: ready dispatch must not list missing host requirements`);
|
||||
assert.equal(row.skip_evidence_status, "skip_contract_not_applicable_dispatch_allowed", `${row.boundary_class}: ready skip evidence status drift`);
|
||||
} else {
|
||||
assert.equal(row.host_action, "skip_missing_host_requirements", `${row.boundary_class}: blocked skip evidence action drift`);
|
||||
assert.equal(row.skip_reason, "missing_host_requirements", `${row.boundary_class}: blocked skip evidence reason drift`);
|
||||
assert.notEqual(row.missing_host_requirements, "-", `${row.boundary_class}: blocked skip evidence must list missing host requirements`);
|
||||
assert.equal(row.current_probe_status, "skipped_missing_host_runtime", `${row.boundary_class}: blocked skip evidence current probe status drift`);
|
||||
assert.equal(row.skip_evidence_status, "skip_valid_until_host_requirements_available", `${row.boundary_class}: blocked skip evidence status drift`);
|
||||
}
|
||||
assert.equal(row.execution_enabled, "0", `${row.boundary_class}: skip evidence contract must not enable execution`);
|
||||
assert.equal(row.promotion_allowed, "0", `${row.boundary_class}: skip evidence contract must not allow promotion`);
|
||||
assert.ok(row.notes.includes("no_automatic_promotion"), `${row.boundary_class}: skip evidence contract note drift`);
|
||||
@@ -7947,6 +8033,7 @@ function verifyRuntimeBoundaryOptInProbeSkipEvidenceRollupRows({
|
||||
expectedHeaders,
|
||||
);
|
||||
const row = parsedRows[0];
|
||||
const skippedRows = skipEvidenceContractRows.filter((contract) => contract.skip_reason !== "-");
|
||||
const expectedMissingRequirements = uniqueSorted(skipEvidenceContractRows.flatMap((contract) =>
|
||||
splitSummaryList(contract.missing_host_requirements),
|
||||
));
|
||||
@@ -7954,15 +8041,15 @@ function verifyRuntimeBoundaryOptInProbeSkipEvidenceRollupRows({
|
||||
assert.equal(parsedRows.length, 1, "opt-in probe skip evidence rollup row count drift");
|
||||
assert.equal(row.scope, "blocked_runtime_opt_in_probe_skip_evidence", "opt-in probe skip evidence rollup scope drift");
|
||||
assert.equal(row.probe_count, String(skipEvidenceContractRows.length), "opt-in probe skip evidence rollup probe count drift");
|
||||
assert.equal(row.skip_count, String(skipEvidenceContractRows.length), "opt-in probe skip evidence rollup skip count drift");
|
||||
assert.equal(row.skip_count, String(skippedRows.length), "opt-in probe skip evidence rollup skip count drift");
|
||||
assert.equal(row.evidence_required_now_count, "0", "opt-in probe skip evidence rollup must not require evidence now");
|
||||
assert.equal(row.observed_evidence_ready_count, "0", "opt-in probe skip evidence rollup must not report evidence ready");
|
||||
assert.equal(row.skipped_families, "L4-PYTHON-REMAP,L4-TOOL-DB,L4-USER-M-PROCESS", "opt-in probe skip evidence rollup family drift");
|
||||
assert.equal(row.skip_reasons, "missing_host_requirements", "opt-in probe skip evidence rollup reason drift");
|
||||
assert.equal(row.skipped_families, listValue(uniqueSorted(skippedRows.map((contract) => contract.boundary_class))), "opt-in probe skip evidence rollup family drift");
|
||||
assert.equal(row.skip_reasons, listValue(uniqueSorted(skippedRows.map((contract) => contract.skip_reason))), "opt-in probe skip evidence rollup reason drift");
|
||||
assert.equal(row.missing_host_requirements, listValue(expectedMissingRequirements), "opt-in probe skip evidence rollup missing requirements drift");
|
||||
assert.equal(row.current_probe_statuses, "skipped_missing_host_runtime", "opt-in probe skip evidence rollup probe status drift");
|
||||
assert.equal(row.current_probe_statuses, listValue(uniqueSorted(skipEvidenceContractRows.map((contract) => contract.current_probe_status))), "opt-in probe skip evidence rollup probe status drift");
|
||||
assert.equal(row.native_evidence_statuses, "pending_until_native_pass", "opt-in probe skip evidence rollup native evidence status drift");
|
||||
assert.equal(row.skip_evidence_statuses, "skip_valid_until_host_requirements_available", "opt-in probe skip evidence rollup skip evidence status drift");
|
||||
assert.equal(row.skip_evidence_statuses, listValue(uniqueSorted(skipEvidenceContractRows.map((contract) => contract.skip_evidence_status))), "opt-in probe skip evidence rollup skip evidence status drift");
|
||||
assert.equal(row.evidence_rollup_status, "no_native_pass_evidence_accepted_while_host_blocked", "opt-in probe skip evidence rollup status drift");
|
||||
assert.equal(row.execution_enabled, "0", "opt-in probe skip evidence rollup must not enable execution");
|
||||
assert.equal(row.promotion_allowed, "0", "opt-in probe skip evidence rollup must not allow promotion");
|
||||
@@ -8075,7 +8162,6 @@ function verifyRuntimeBoundaryNativeEvidenceAcceptanceGateRows({
|
||||
assert.equal(row.target, skip.target, `${row.boundary_class}: native evidence gate target drift`);
|
||||
assert.equal(row.blocked, skip.blocked, `${row.boundary_class}: native evidence gate blocked drift`);
|
||||
assert.equal(row.runtime_probe, skip.runtime_probe, `${row.boundary_class}: native evidence gate runtime probe drift`);
|
||||
assert.equal(row.current_probe_status, "skipped_missing_host_runtime", `${row.boundary_class}: native evidence gate probe status drift`);
|
||||
assert.equal(row.current_probe_status, skip.current_probe_status, `${row.boundary_class}: native evidence gate skip status drift`);
|
||||
assert.equal(row.native_evidence_status, "pending_until_native_pass", `${row.boundary_class}: native evidence gate evidence status drift`);
|
||||
assert.equal(row.native_evidence_status, skip.native_evidence_status, `${row.boundary_class}: native evidence gate native evidence status drift`);
|
||||
@@ -8083,16 +8169,21 @@ function verifyRuntimeBoundaryNativeEvidenceAcceptanceGateRows({
|
||||
assert.equal(row.evidence_required_now, skip.evidence_required_now, `${row.boundary_class}: native evidence gate required-now drift`);
|
||||
assert.equal(row.observed_evidence_ready, "0", `${row.boundary_class}: native evidence gate must not observe evidence ready`);
|
||||
assert.equal(row.observed_evidence_ready, skip.observed_evidence_ready, `${row.boundary_class}: native evidence gate readiness drift`);
|
||||
assert.equal(row.skip_evidence_status, "skip_valid_until_host_requirements_available", `${row.boundary_class}: native evidence gate skip status drift`);
|
||||
assert.equal(row.skip_evidence_status, skip.skip_evidence_status, `${row.boundary_class}: native evidence gate skip status drift`);
|
||||
assert.equal(row.promotion_ready, "0", `${row.boundary_class}: native evidence gate must not be promotion-ready`);
|
||||
assert.equal(row.promotion_ready, readiness.promotion_ready, `${row.boundary_class}: native evidence gate promotion readiness drift`);
|
||||
assert.equal(row.node_gate_status, "blocked_until_native_pass_evidence", `${row.boundary_class}: native evidence gate Node status drift`);
|
||||
assert.equal(row.node_gate_status, postNativeGate.node_gate_status, `${row.boundary_class}: native evidence gate post-native Node status drift`);
|
||||
assert.equal(row.browser_gate_status, "blocked_until_node_gate_complete", `${row.boundary_class}: native evidence gate browser status drift`);
|
||||
assert.equal(row.browser_gate_status, postNativeGate.browser_gate_status, `${row.boundary_class}: native evidence gate post-native browser status drift`);
|
||||
assert.equal(row.native_evidence_gate, "blocked_until_host_requirements_available", `${row.boundary_class}: native evidence gate status drift`);
|
||||
if (skip.skip_reason === "missing_host_requirements") {
|
||||
assert.equal(row.native_evidence_gate, "blocked_until_host_requirements_available", `${row.boundary_class}: native evidence gate status drift`);
|
||||
assert.ok(row.next_action.includes(skip.missing_host_requirements), `${row.boundary_class}: native evidence gate next action must name missing requirements`);
|
||||
} else {
|
||||
assert.equal(row.native_evidence_gate, "blocked_until_native_pass_evidence", `${row.boundary_class}: native evidence gate status drift`);
|
||||
assert.equal(row.next_action, "run_opt_in_native_runtime_probe_and_collect_evidence", `${row.boundary_class}: native evidence gate next action drift`);
|
||||
}
|
||||
assert.equal(row.evidence_acceptance_allowed, "0", `${row.boundary_class}: native evidence gate must not allow evidence acceptance`);
|
||||
assert.ok(row.next_action.includes(skip.missing_host_requirements), `${row.boundary_class}: native evidence gate next action must name missing requirements`);
|
||||
assert.equal(row.execution_enabled, "0", `${row.boundary_class}: native evidence gate must not enable execution`);
|
||||
assert.equal(row.promotion_allowed, "0", `${row.boundary_class}: native evidence gate must not allow promotion`);
|
||||
assert.ok(row.notes.includes("no_automatic_promotion"), `${row.boundary_class}: native evidence gate note drift`);
|
||||
@@ -8223,12 +8314,16 @@ function verifyBlockedRuntimeOptInGateConsistency({
|
||||
assert.equal(skipEvidence.missing_host_requirements, execution.missing_requirements, `${boundaryClass}: skip-evidence missing requirements drift`);
|
||||
assert.equal(blocker.missing_runtime_requirements, execution.missing_requirements, `${boundaryClass}: blocker missing requirements drift`);
|
||||
assert.equal(evidenceGate.evidence_acceptance_allowed, "0", `${boundaryClass}: evidence acceptance must remain blocked`);
|
||||
assert.equal(dispatch.dispatch_allowed, "0", `${boundaryClass}: dispatch must remain blocked on this host`);
|
||||
assert.equal(dispatch.dispatch_allowed, execution.runtime_ready, `${boundaryClass}: dispatch readiness drift`);
|
||||
assert.equal(readiness.promotion_lock_active, "1", `${boundaryClass}: readiness must keep promotion lock active`);
|
||||
assert.equal(postNative.promotion_lock_active, "1", `${boundaryClass}: post-native gate must keep promotion lock active`);
|
||||
assert.ok(blocker.blocker_keys.includes("promotion_lock_active"), `${boundaryClass}: blocker lacks promotion lock key`);
|
||||
assert.ok(blocker.blocker_keys.includes("manual_lock_update_required"), `${boundaryClass}: blocker lacks manual lock key`);
|
||||
assert.ok(blocker.blocker_keys.includes("host_runtime_requirements_missing"), `${boundaryClass}: blocker lacks host runtime key`);
|
||||
if (execution.runtime_ready === "0") {
|
||||
assert.ok(blocker.blocker_keys.includes("host_runtime_requirements_missing"), `${boundaryClass}: blocker lacks host runtime key`);
|
||||
} else {
|
||||
assert.equal(blocker.blocker_keys.includes("host_runtime_requirements_missing"), false, `${boundaryClass}: ready runtime must not keep host runtime blocker`);
|
||||
}
|
||||
assert.ok(evidenceGate.native_evidence_gate.includes("blocked"), `${boundaryClass}: evidence gate must be blocked`);
|
||||
}
|
||||
}
|
||||
@@ -8303,23 +8398,40 @@ function verifyBlockedRuntimeProbeExecutionConsistency({
|
||||
assert.equal(dispatch.missing_host_requirements, execution.missing_requirements, `${execution.boundary_class}: dispatch missing requirement drift`);
|
||||
assert.equal(skip.missing_host_requirements, execution.missing_requirements, `${execution.boundary_class}: skip evidence missing requirement drift`);
|
||||
|
||||
assert.equal(execution.runtime_ready, "0", `${execution.boundary_class}: current host must not be runtime-ready`);
|
||||
assert.equal(execution.source_proof_ready, "1", `${execution.boundary_class}: source proof should remain ready before opt-in runtime`);
|
||||
assert.equal(execution.current_probe_status, "skipped_missing_host_runtime", `${execution.boundary_class}: probe should remain skipped on this host`);
|
||||
assert.equal(execution.plan_status, "blocked_missing_host_runtime", `${execution.boundary_class}: execution plan must remain host-blocked`);
|
||||
assert.equal(preflight.preflight_status, "blocked_missing_host_runtime", `${execution.boundary_class}: preflight must remain host-blocked`);
|
||||
assert.equal(dispatch.host_readiness_status, "host_blocked_for_all_opt_in_native_probes", `${execution.boundary_class}: dispatch host readiness drift`);
|
||||
assert.equal(dispatch.host_action, "skip_missing_host_requirements", `${execution.boundary_class}: dispatch action must skip`);
|
||||
assert.equal(dispatch.dispatch_allowed, "0", `${execution.boundary_class}: dispatch must not be allowed`);
|
||||
assert.equal(skip.host_action, "skip_missing_host_requirements", `${execution.boundary_class}: skip evidence host action drift`);
|
||||
assert.equal(skip.skip_reason, "missing_host_requirements", `${execution.boundary_class}: skip reason drift`);
|
||||
assert.ok(["0", "1"].includes(execution.runtime_ready), `${execution.boundary_class}: invalid runtime readiness`);
|
||||
if (execution.runtime_ready === "1") {
|
||||
assert.equal(execution.current_probe_status, "ready_disabled_by_default", `${execution.boundary_class}: ready probe must remain opt-in`);
|
||||
assert.equal(execution.plan_status, "ready_to_run_opt_in_probe", `${execution.boundary_class}: execution plan must remain opt-in`);
|
||||
assert.equal(execution.missing_requirements, "-", `${execution.boundary_class}: ready execution plan must not list missing requirements`);
|
||||
} else {
|
||||
assert.equal(execution.current_probe_status, "skipped_missing_host_runtime", `${execution.boundary_class}: probe should remain skipped on missing host`);
|
||||
assert.equal(execution.plan_status, "blocked_missing_host_runtime", `${execution.boundary_class}: execution plan must remain host-blocked`);
|
||||
assert.notEqual(execution.missing_requirements, "-", `${execution.boundary_class}: blocked execution plan must list missing requirements`);
|
||||
}
|
||||
if (execution.runtime_ready === "1") {
|
||||
assert.equal(preflight.preflight_status, "ready_to_run_opt_in_native_probe", `${execution.boundary_class}: ready preflight status drift`);
|
||||
assert.equal(dispatch.host_action, "ready_for_manual_opt_in_native_probe", `${execution.boundary_class}: ready dispatch action drift`);
|
||||
assert.equal(dispatch.dispatch_allowed, "1", `${execution.boundary_class}: ready dispatch must be manually allowed`);
|
||||
assert.equal(skip.host_action, "ready_for_manual_opt_in_native_probe", `${execution.boundary_class}: ready skip evidence host action drift`);
|
||||
assert.equal(skip.skip_reason, "-", `${execution.boundary_class}: ready skip reason drift`);
|
||||
} else {
|
||||
assert.equal(preflight.preflight_status, "blocked_missing_host_runtime", `${execution.boundary_class}: preflight must remain host-blocked`);
|
||||
assert.equal(dispatch.host_action, "skip_missing_host_requirements", `${execution.boundary_class}: dispatch action must skip`);
|
||||
assert.equal(dispatch.dispatch_allowed, "0", `${execution.boundary_class}: dispatch must not be allowed`);
|
||||
assert.equal(skip.host_action, "skip_missing_host_requirements", `${execution.boundary_class}: skip evidence host action drift`);
|
||||
assert.equal(skip.skip_reason, "missing_host_requirements", `${execution.boundary_class}: skip reason drift`);
|
||||
}
|
||||
assert.equal(pass.evidence_required_now, "0", `${execution.boundary_class}: pass evidence must not be required yet`);
|
||||
assert.equal(skip.evidence_required_now, "0", `${execution.boundary_class}: skip evidence must not be required yet`);
|
||||
assert.equal(pass.observed_evidence_ready, "0", `${execution.boundary_class}: pass evidence must not be ready yet`);
|
||||
assert.equal(skip.observed_evidence_ready, "0", `${execution.boundary_class}: skip evidence must not be ready yet`);
|
||||
assert.equal(pass.evidence_status, "pending_until_native_pass", `${execution.boundary_class}: pass evidence status drift`);
|
||||
assert.equal(skip.native_evidence_status, "pending_until_native_pass", `${execution.boundary_class}: skip evidence native status drift`);
|
||||
assert.equal(skip.skip_evidence_status, "skip_valid_until_host_requirements_available", `${execution.boundary_class}: skip evidence contract status drift`);
|
||||
assert.ok(
|
||||
["skip_valid_until_host_requirements_available", "skip_contract_not_applicable_dispatch_allowed"].includes(skip.skip_evidence_status),
|
||||
`${execution.boundary_class}: skip evidence contract status drift`,
|
||||
);
|
||||
|
||||
for (const row of [execution, pass, preflight, dispatch, skip]) {
|
||||
assert.equal(row.execution_enabled, "0", `${execution.boundary_class}: probe execution row must not enable execution`);
|
||||
@@ -8362,12 +8474,26 @@ function verifyBlockedRuntimeRollupConsistency({
|
||||
assert.equal(dispatch.missing_host_requirements, skipEvidence.missing_host_requirements, "blocked runtime rollup dispatch/skip missing requirement drift");
|
||||
assert.equal(host.ready_opt_in_commands, dispatch.dispatch_allowed_commands, "blocked runtime rollup allowed command drift");
|
||||
assert.equal(host.blocked_opt_in_commands, dispatch.dispatch_blocked_commands, "blocked runtime rollup blocked command drift");
|
||||
assert.equal(host.host_readiness_status, "host_blocked_for_all_opt_in_native_probes", "blocked runtime rollup host status drift");
|
||||
assert.equal(dispatch.dispatch_status, "dispatch_blocked_for_all_opt_in_native_probes", "blocked runtime rollup dispatch status drift");
|
||||
assert.ok(
|
||||
[
|
||||
"host_ready_for_all_opt_in_native_probes",
|
||||
"host_partially_ready_for_opt_in_native_probes",
|
||||
"host_blocked_for_all_opt_in_native_probes",
|
||||
].includes(host.host_readiness_status),
|
||||
"blocked runtime rollup host status drift",
|
||||
);
|
||||
assert.ok(
|
||||
[
|
||||
"dispatch_allowed_for_all_opt_in_native_probes",
|
||||
"dispatch_partially_allowed_for_opt_in_native_probes",
|
||||
"dispatch_blocked_for_all_opt_in_native_probes",
|
||||
].includes(dispatch.dispatch_status),
|
||||
"blocked runtime rollup dispatch status drift",
|
||||
);
|
||||
assert.equal(skipEvidence.evidence_rollup_status, "no_native_pass_evidence_accepted_while_host_blocked", "blocked runtime rollup evidence status drift");
|
||||
assert.equal(skipEvidence.current_probe_statuses, "skipped_missing_host_runtime", "blocked runtime rollup probe status drift");
|
||||
assert.notEqual(skipEvidence.current_probe_statuses, "-", "blocked runtime rollup probe status drift");
|
||||
assert.equal(skipEvidence.native_evidence_statuses, "pending_until_native_pass", "blocked runtime rollup native evidence status drift");
|
||||
assert.equal(skipEvidence.skip_evidence_statuses, "skip_valid_until_host_requirements_available", "blocked runtime rollup skip evidence status drift");
|
||||
assert.notEqual(skipEvidence.skip_evidence_statuses, "-", "blocked runtime rollup skip evidence status drift");
|
||||
|
||||
for (const [label, row] of [
|
||||
["host readiness", host],
|
||||
@@ -8589,7 +8715,10 @@ function verifyBlockedRuntimePromotionGateConsistency({
|
||||
assert.equal(postNative.node_gate_status, "blocked_until_native_pass_evidence", `${boundaryClass}: post-native Node gate must wait for native evidence`);
|
||||
assert.equal(postNative.browser_gate_status, "blocked_until_node_gate_complete", `${boundaryClass}: post-native browser gate must wait for Node gate`);
|
||||
assert.equal(postNative.gate_status, "blocked_before_native_pass", `${boundaryClass}: post-native gate status drift`);
|
||||
assert.equal(evidenceGate.native_evidence_gate, "blocked_until_host_requirements_available", `${boundaryClass}: native evidence gate must remain host-blocked`);
|
||||
assert.ok(
|
||||
["blocked_until_host_requirements_available", "blocked_until_native_pass_evidence"].includes(evidenceGate.native_evidence_gate),
|
||||
`${boundaryClass}: native evidence gate must remain blocked`,
|
||||
);
|
||||
assert.equal(evidenceGate.evidence_acceptance_allowed, "0", `${boundaryClass}: native evidence acceptance must remain blocked`);
|
||||
|
||||
for (const row of [readiness, blocker, postNative, evidenceGate, passEvidence, lock]) {
|
||||
@@ -10816,7 +10945,12 @@ function userMProcessNativeRuntimeReadinessRows(runtimeStatePlanRows) {
|
||||
["host_command", "linuxcnc", "run_linuxcnc_owned_task_hal_environment"],
|
||||
];
|
||||
const commandAvailability = new Map(
|
||||
requirements.map(([, requirement]) => [requirement, commandPath(requirement)]),
|
||||
requirements.map(([, requirement]) => [
|
||||
requirement,
|
||||
["halrun", "halcmd", "linuxcnc"].includes(requirement)
|
||||
? linuxCncHostCommandPath(requirement)
|
||||
: commandPath(requirement),
|
||||
]),
|
||||
);
|
||||
const allAvailable = requirements.every(([, requirement]) =>
|
||||
commandAvailability.get(requirement),
|
||||
@@ -12231,6 +12365,15 @@ function verifyPromotionCandidateRows(rows, summaryRows, boundaryRows) {
|
||||
0,
|
||||
"current baseline has no direct skipped-main inventory promotion candidate",
|
||||
);
|
||||
for (const lockedKind of ["L4-PYTHON-REMAP", "L4-TOOL-DB", "L4-USER-M-PROCESS", "UPSTREAM-DEMO"]) {
|
||||
const lockedRows = parsedInventoryReady.filter((row) => row.skip_kind === lockedKind);
|
||||
assert.ok(lockedRows.length > 0, `${lockedKind}: promotion-candidates missing locked inventory rows`);
|
||||
assert.equal(
|
||||
lockedRows.filter((row) => row.promotion_allowed !== "0").length,
|
||||
0,
|
||||
`${lockedKind}: locked inventory rows must not allow promotion`,
|
||||
);
|
||||
}
|
||||
for (const row of parsedEvidenceReady) {
|
||||
assert.equal(row.current_status, "PASS", `${row.path}: evidence-ready row must be a current inventory PASS`);
|
||||
assert.equal(row.skip_kind, "-", `${row.path}: evidence-ready row must not have a skip kind`);
|
||||
|
||||
Reference in New Issue
Block a user