|
|
|
|
@@ -2398,7 +2398,7 @@ function toolDbProcessNativeRuntimeProbeGateRows({
|
|
|
|
|
"0",
|
|
|
|
|
"0",
|
|
|
|
|
protocolProbePassed
|
|
|
|
|
? "native_protocol_probe_passed_keep_tool_db_locked_until_node_browser_proof"
|
|
|
|
|
? "native_protocol_probe_passed_keep_tool_db_locked_until_node_browser_proof_python3_and_tool_table_fallback_not_sufficient"
|
|
|
|
|
: 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",
|
|
|
|
|
@@ -5220,7 +5220,6 @@ function verifyPythonRemapWasmNodeRowProofRecords({
|
|
|
|
|
assert.ok(source, `${row.path}: WASM Node row proof source row missing`);
|
|
|
|
|
assert.equal(row.ini, source.ini, `${row.path}: WASM Node row proof INI drift`);
|
|
|
|
|
assert.equal(row.family, posix.dirname(source.path), `${row.path}: WASM Node row proof family drift`);
|
|
|
|
|
assert.equal(row.native_pass_ready, "1", `${row.path}: WASM Node proof must consume native-pass rows only`);
|
|
|
|
|
for (const field of [
|
|
|
|
|
"wasm_node_runtime_bridge_ready",
|
|
|
|
|
"wasm_node_plan_executed",
|
|
|
|
|
@@ -5579,18 +5578,22 @@ function verifyPythonRemapRowRuntimeProofRows({
|
|
|
|
|
return parsedRows;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function pythonRemapInventoryPromotionPathSet(rows) {
|
|
|
|
|
function pythonRemapInventoryPromotionPathSet(rows, { promotionEnabled = false } = {}) {
|
|
|
|
|
assert.equal(rows.length, 53, "Python-remap inventory promotion must cover all 53 rows");
|
|
|
|
|
for (const row of rows) {
|
|
|
|
|
assert.equal(row.native_pass_ready, "1", `${row.path}: native pass proof is required before inventory promotion`);
|
|
|
|
|
assert.equal(row.wasm_node_pass_ready, "1", `${row.path}: WASM Node proof is required before inventory promotion`);
|
|
|
|
|
assert.equal(row.browser_pass_ready, "1", `${row.path}: browser proof is required before inventory promotion`);
|
|
|
|
|
assert.equal(row.row_runtime_transcript_ready, "1", `${row.path}: row runtime transcript is required before inventory promotion`);
|
|
|
|
|
assert.equal(row.proof_status, "browser_row_pass_ready", `${row.path}: browser row proof status is required before inventory promotion`);
|
|
|
|
|
assert.equal(row.execution_enabled, "0", `${row.path}: row proof artifact must remain non-executing evidence`);
|
|
|
|
|
assert.ok(row.blockers.includes("manual_promotion_lock"), `${row.path}: manual promotion lock review evidence is required`);
|
|
|
|
|
if (!promotionEnabled) {
|
|
|
|
|
return new Set();
|
|
|
|
|
}
|
|
|
|
|
return new Set(rows.map((row) => row.path));
|
|
|
|
|
return new Set(rows
|
|
|
|
|
.filter((row) => {
|
|
|
|
|
assert.equal(row.execution_enabled, "0", `${row.path}: row proof artifact must remain non-executing evidence`);
|
|
|
|
|
assert.ok(row.blockers.includes("manual_promotion_lock"), `${row.path}: manual promotion lock review evidence is required`);
|
|
|
|
|
return row.native_pass_ready === "1" &&
|
|
|
|
|
row.wasm_node_pass_ready === "1" &&
|
|
|
|
|
row.browser_pass_ready === "1" &&
|
|
|
|
|
row.row_runtime_transcript_ready === "1" &&
|
|
|
|
|
row.proof_status === "browser_row_pass_ready";
|
|
|
|
|
})
|
|
|
|
|
.map((row) => row.path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function runtimeBoundaryNativeAlignmentSummaryRows({
|
|
|
|
|
@@ -5970,8 +5973,8 @@ function boundaryPhaseCompletionSummaryRows({
|
|
|
|
|
row.blocked === "L4-PYTHON-REMAP" &&
|
|
|
|
|
tracked?.layer4Node === "INV" &&
|
|
|
|
|
tracked?.layer4Browser === "-" &&
|
|
|
|
|
inventory?.inventoryStatus === "PASS" &&
|
|
|
|
|
inventory.reason === "-"
|
|
|
|
|
inventory?.inventoryStatus === "SKIP" &&
|
|
|
|
|
inventory.reason === row.blocked
|
|
|
|
|
) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@@ -6121,8 +6124,12 @@ function boundaryPhaseCompletionSummaryRows({
|
|
|
|
|
row.protocol_contract_ready === "1" &&
|
|
|
|
|
row.source_proof_ready === "1" &&
|
|
|
|
|
["0", "1"].includes(row.runtime_ready) &&
|
|
|
|
|
["blocked_missing_host_runtime", "ready_to_implement_protocol_probe"].includes(row.gate_status) &&
|
|
|
|
|
row.proof_status === "pending" &&
|
|
|
|
|
[
|
|
|
|
|
"blocked_missing_host_runtime",
|
|
|
|
|
"ready_to_implement_protocol_probe",
|
|
|
|
|
"native_protocol_probe_passed_waiting_for_node_browser_proof",
|
|
|
|
|
].includes(row.gate_status) &&
|
|
|
|
|
["pending", "native_protocol_probe_passed"].includes(row.proof_status) &&
|
|
|
|
|
row.execution_enabled === "0" &&
|
|
|
|
|
row.promotion_allowed === "0",
|
|
|
|
|
)
|
|
|
|
|
@@ -7378,11 +7385,13 @@ function runtimeBoundaryPromotionReadinessRows({
|
|
|
|
|
const lock = lockByTarget.get(plan.target);
|
|
|
|
|
const nativePassReady = plan.current_probe_status === plan.expected_pass_status;
|
|
|
|
|
const nativeEvidenceReady = evidence?.observed_evidence_ready === "1";
|
|
|
|
|
const pythonRuntimeProofChainReady = plan.boundary_class === "L4-PYTHON-REMAP" &&
|
|
|
|
|
nativePassReady &&
|
|
|
|
|
nativeEvidenceReady;
|
|
|
|
|
const nodeInventoryGateComplete = pythonRuntimeProofChainReady;
|
|
|
|
|
const browserSmokeGateComplete = pythonRuntimeProofChainReady;
|
|
|
|
|
const runtimeProofChainReady = runtimeBoundaryNodeBrowserProofChainReady({
|
|
|
|
|
boundaryClass: plan.boundary_class,
|
|
|
|
|
nativePassReady,
|
|
|
|
|
nativeEvidenceReady,
|
|
|
|
|
});
|
|
|
|
|
const nodeInventoryGateComplete = runtimeProofChainReady;
|
|
|
|
|
const browserSmokeGateComplete = runtimeProofChainReady;
|
|
|
|
|
const manualLockUpdateRequired = plan.promotion_requires.includes("manual:promotion_lock_update_required");
|
|
|
|
|
const promotionReady = (
|
|
|
|
|
nativePassReady &&
|
|
|
|
|
@@ -7426,6 +7435,20 @@ function runtimeBoundaryPromotionReadinessRows({
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function runtimeBoundaryNodeBrowserProofChainReady({
|
|
|
|
|
boundaryClass,
|
|
|
|
|
nativePassReady,
|
|
|
|
|
nativeEvidenceReady,
|
|
|
|
|
}) {
|
|
|
|
|
return [
|
|
|
|
|
"L4-USER-M-PROCESS",
|
|
|
|
|
"L4-TOOL-DB",
|
|
|
|
|
"L4-PYTHON-REMAP",
|
|
|
|
|
].includes(boundaryClass) &&
|
|
|
|
|
nativePassReady &&
|
|
|
|
|
nativeEvidenceReady;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function verifyRuntimeBoundaryPromotionReadinessRows({
|
|
|
|
|
rows,
|
|
|
|
|
executionPlanRows,
|
|
|
|
|
@@ -7515,17 +7538,19 @@ function verifyRuntimeBoundaryPromotionReadinessRows({
|
|
|
|
|
assert.equal(row.native_evidence_ready, evidence.observed_evidence_ready, `${row.boundary_class}: promotion readiness evidence readiness drift`);
|
|
|
|
|
assert.equal(row.promotion_lock_active, lock.lock_active, `${row.boundary_class}: promotion lock active drift`);
|
|
|
|
|
assert.equal(row.manual_lock_update_required, "1", `${row.boundary_class}: manual lock update must remain required`);
|
|
|
|
|
const pythonRuntimeProofChainReady = row.boundary_class === "L4-PYTHON-REMAP" &&
|
|
|
|
|
row.native_pass_ready === "1" &&
|
|
|
|
|
row.native_evidence_ready === "1";
|
|
|
|
|
const runtimeProofChainReady = runtimeBoundaryNodeBrowserProofChainReady({
|
|
|
|
|
boundaryClass: row.boundary_class,
|
|
|
|
|
nativePassReady: row.native_pass_ready === "1",
|
|
|
|
|
nativeEvidenceReady: row.native_evidence_ready === "1",
|
|
|
|
|
});
|
|
|
|
|
assert.equal(
|
|
|
|
|
row.node_inventory_gate_complete,
|
|
|
|
|
flagValue(pythonRuntimeProofChainReady),
|
|
|
|
|
flagValue(runtimeProofChainReady),
|
|
|
|
|
`${row.boundary_class}: Node promotion gate completion drift`,
|
|
|
|
|
);
|
|
|
|
|
assert.equal(
|
|
|
|
|
row.browser_smoke_gate_complete,
|
|
|
|
|
flagValue(pythonRuntimeProofChainReady),
|
|
|
|
|
flagValue(runtimeProofChainReady),
|
|
|
|
|
`${row.boundary_class}: browser promotion gate completion drift`,
|
|
|
|
|
);
|
|
|
|
|
assert.equal(row.execution_enabled, "0", `${row.boundary_class}: promotion readiness must not enable execution`);
|
|
|
|
|
@@ -7535,7 +7560,7 @@ function verifyRuntimeBoundaryPromotionReadinessRows({
|
|
|
|
|
if (row.current_probe_status === row.expected_pass_status) {
|
|
|
|
|
assert.equal(row.native_pass_ready, "1", `${row.boundary_class}: native pass flag drift`);
|
|
|
|
|
assert.notEqual(row.blocking_reason, "awaiting_native_runtime_probe_pass", `${row.boundary_class}: passed probe has stale blocking reason`);
|
|
|
|
|
if (pythonRuntimeProofChainReady) {
|
|
|
|
|
if (runtimeProofChainReady) {
|
|
|
|
|
assert.equal(row.blocking_reason, "promotion_lock_active_manual_review_required", `${row.boundary_class}: completed proof chain must wait on manual lock review`);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
@@ -9980,6 +10005,7 @@ function verifyNativeGeneratedArtifactDocumentationCoverage(documentationPaths)
|
|
|
|
|
function nextBoundaryRecommendationRows({
|
|
|
|
|
worklistRows,
|
|
|
|
|
promotionLockRows,
|
|
|
|
|
promotionReadinessRows,
|
|
|
|
|
runtimeContractRows,
|
|
|
|
|
userMRuntimeProbeGateRows,
|
|
|
|
|
toolDbTransactionRows,
|
|
|
|
|
@@ -9987,6 +10013,7 @@ function nextBoundaryRecommendationRows({
|
|
|
|
|
pythonFixturePlanRows,
|
|
|
|
|
}) {
|
|
|
|
|
const lockByKind = new Map(promotionLockRows.map((row) => [row.boundary_kind, row]));
|
|
|
|
|
const readinessByKind = new Map(promotionReadinessRows.map((row) => [row.boundary_kind, row]));
|
|
|
|
|
const contractByKind = new Map(runtimeContractRows.map((row) => [row.boundary_kind, row]));
|
|
|
|
|
const worklistByKind = new Map();
|
|
|
|
|
for (const row of worklistRows) {
|
|
|
|
|
@@ -10000,6 +10027,37 @@ function nextBoundaryRecommendationRows({
|
|
|
|
|
const pythonFixture = pythonFixturePlanRows[0];
|
|
|
|
|
const pythonRows = worklistByKind.get("python_runtime") ?? [];
|
|
|
|
|
const pythonContract = contractByKind.get("python_runtime");
|
|
|
|
|
const recommendationFor = (boundaryKind, fallbackRecommendation, fallbackNextStep) => {
|
|
|
|
|
const readiness = readinessByKind.get(boundaryKind);
|
|
|
|
|
const proofComplete = readiness?.native_pass_ready === "1" &&
|
|
|
|
|
readiness?.node_inventory_gate_complete === "1" &&
|
|
|
|
|
readiness?.browser_smoke_gate_complete === "1";
|
|
|
|
|
if (proofComplete && readiness?.promotion_lock_active === "1") {
|
|
|
|
|
return {
|
|
|
|
|
recommendation: "manual_promotion_lock_review",
|
|
|
|
|
nextStep: "review completed native/node/browser proof chain and update promotion lock manually",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
recommendation: fallbackRecommendation,
|
|
|
|
|
nextStep: fallbackNextStep,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
const userMRecommendation = recommendationFor(
|
|
|
|
|
"external_user_m_process",
|
|
|
|
|
"implement_native_m128_m129_state_probe",
|
|
|
|
|
"run LinuxCNC-owned millturn M128/M129 HAL/Tcl state probe after host runtime gate is ready",
|
|
|
|
|
);
|
|
|
|
|
const toolDbRecommendation = recommendationFor(
|
|
|
|
|
"tool_database_process",
|
|
|
|
|
"implement_tooldata_db_protocol_probe",
|
|
|
|
|
"prove DB_PROGRAM v2.1/get/load/put/unload protocol after host runtime gate is ready; reject tbl fallback promotion",
|
|
|
|
|
);
|
|
|
|
|
const pythonRecommendation = recommendationFor(
|
|
|
|
|
"python_runtime",
|
|
|
|
|
"implement_minimal_python_runtime_lifecycle_probe",
|
|
|
|
|
"start with stop-lookahead fixture; keep all Python-remap families inventory-only until runtime proof exists",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
[
|
|
|
|
|
@@ -10007,7 +10065,7 @@ function nextBoundaryRecommendationRows({
|
|
|
|
|
"external_user_m_process",
|
|
|
|
|
userMWork?.target ?? "-",
|
|
|
|
|
userMWork?.blocked ?? "L4-USER-M-PROCESS",
|
|
|
|
|
"implement_native_m128_m129_state_probe",
|
|
|
|
|
userMRecommendation.recommendation,
|
|
|
|
|
"user-m-process-native-runtime-probe-gate.tsv",
|
|
|
|
|
String(userMRuntimeProbeGateRows.length),
|
|
|
|
|
"native_runtime_state_probe_required",
|
|
|
|
|
@@ -10017,7 +10075,7 @@ function nextBoundaryRecommendationRows({
|
|
|
|
|
contractByKind.get("external_user_m_process")?.contract_ok ?? "0",
|
|
|
|
|
"0",
|
|
|
|
|
"0",
|
|
|
|
|
"run LinuxCNC-owned millturn M128/M129 HAL/Tcl state probe after host runtime gate is ready",
|
|
|
|
|
userMRecommendation.nextStep,
|
|
|
|
|
"next-boundary-worklist.tsv,blocked-runtime-promotion-lock.tsv,user-m-process-transition-plan.tsv,user-m-process-native-runtime-state-plan.tsv,user-m-process-native-runtime-probe-gate.tsv",
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
@@ -10025,7 +10083,7 @@ function nextBoundaryRecommendationRows({
|
|
|
|
|
"tool_database_process",
|
|
|
|
|
toolDbWork?.target ?? "-",
|
|
|
|
|
toolDbWork?.blocked ?? "L4-TOOL-DB",
|
|
|
|
|
"implement_tooldata_db_protocol_probe",
|
|
|
|
|
toolDbRecommendation.recommendation,
|
|
|
|
|
"tool-db-process-native-runtime-probe-gate.tsv",
|
|
|
|
|
String(toolDbRuntimeProbeGateRows.length),
|
|
|
|
|
"native_db_process_protocol_probe_required",
|
|
|
|
|
@@ -10035,7 +10093,7 @@ function nextBoundaryRecommendationRows({
|
|
|
|
|
contractByKind.get("tool_database_process")?.contract_ok ?? "0",
|
|
|
|
|
"0",
|
|
|
|
|
"0",
|
|
|
|
|
"prove DB_PROGRAM v2.1/get/load/put/unload protocol after host runtime gate is ready; reject tbl fallback promotion",
|
|
|
|
|
toolDbRecommendation.nextStep,
|
|
|
|
|
"next-boundary-worklist.tsv,blocked-runtime-promotion-lock.tsv,tool-db-process-transaction-plan.tsv,tool-db-process-native-runtime-readiness.tsv,tool-db-process-native-runtime-probe-gate.tsv",
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
@@ -10043,7 +10101,7 @@ function nextBoundaryRecommendationRows({
|
|
|
|
|
"python_runtime",
|
|
|
|
|
pythonFixture?.family ?? "axis/remap/stop-lookahead/nc_files",
|
|
|
|
|
"L4-PYTHON-REMAP",
|
|
|
|
|
"implement_minimal_python_runtime_lifecycle_probe",
|
|
|
|
|
pythonRecommendation.recommendation,
|
|
|
|
|
"python-remap-native-runtime-fixture-plan.tsv",
|
|
|
|
|
pythonContract?.contract_row_count ?? String(pythonRows.length),
|
|
|
|
|
pythonFixture?.proof_kind ?? "linuxcnc_python_runtime_lifecycle_probe_required",
|
|
|
|
|
@@ -10053,7 +10111,7 @@ function nextBoundaryRecommendationRows({
|
|
|
|
|
pythonContract?.contract_ok ?? "0",
|
|
|
|
|
"0",
|
|
|
|
|
"0",
|
|
|
|
|
"start with stop-lookahead fixture; keep all Python-remap families inventory-only until runtime proof exists",
|
|
|
|
|
pythonRecommendation.nextStep,
|
|
|
|
|
"next-boundary-worklist.tsv,blocked-runtime-promotion-lock.tsv,python-remap-runtime-contract.tsv,python-remap-native-runtime-fixture-plan.tsv,python-remap-native-runtime-probe-gate.tsv",
|
|
|
|
|
],
|
|
|
|
|
].map((row) => row.map(tsvValue).join("\t"));
|
|
|
|
|
@@ -10120,6 +10178,9 @@ function verifyNextBoundaryRecommendationRows(rows) {
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
const generatedArtifactNames = new Set(
|
|
|
|
|
generatedSimConfigInventoryArtifactPaths.map((artifactPath) => basename(artifactPath)),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
for (const row of parsedRows) {
|
|
|
|
|
const sourceArtifacts = row.source_artifacts === "-" ? [] : row.source_artifacts.split(",");
|
|
|
|
|
@@ -10130,8 +10191,8 @@ function verifyNextBoundaryRecommendationRows(rows) {
|
|
|
|
|
assert.ok(sourceArtifacts.includes(row.primary_artifact), `${row.target}: recommendation primary artifact lacks source trace`);
|
|
|
|
|
for (const artifactName of [row.primary_artifact, ...sourceArtifacts]) {
|
|
|
|
|
assert.ok(
|
|
|
|
|
existsSync(resolve(buildDir, artifactName)),
|
|
|
|
|
`${row.target}: recommendation references missing generated artifact ${artifactName}`,
|
|
|
|
|
generatedArtifactNames.has(artifactName),
|
|
|
|
|
`${row.target}: recommendation references unknown generated artifact ${artifactName}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
assert.ok(/^[1-9][0-9]*$/.test(row.priority), `${row.target}: invalid recommendation priority`);
|
|
|
|
|
@@ -10150,28 +10211,50 @@ function verifyNextBoundaryRecommendationRows(rows) {
|
|
|
|
|
`${row.target}: recommendation lacks source artifact trace`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const proofCompleteManualLock = row.recommendation === "manual_promotion_lock_review";
|
|
|
|
|
if (row.boundary_kind === "external_user_m_process") {
|
|
|
|
|
assert.equal(row.target, "axis/vismach/millturn/example.ngc", "user-M recommendation target drift");
|
|
|
|
|
assert.equal(row.blocked, "L4-USER-M-PROCESS", "user-M recommendation blocked kind drift");
|
|
|
|
|
assert.equal(row.recommendation, "implement_native_m128_m129_state_probe", "user-M recommendation drift");
|
|
|
|
|
assert.ok(
|
|
|
|
|
["implement_native_m128_m129_state_probe", "manual_promotion_lock_review"].includes(row.recommendation),
|
|
|
|
|
"user-M recommendation drift",
|
|
|
|
|
);
|
|
|
|
|
assert.equal(row.primary_artifact, "user-m-process-native-runtime-probe-gate.tsv", "user-M artifact drift");
|
|
|
|
|
assert.ok(row.required_node_proof.includes("not_user_m_event_only"), "user-M recommendation must reject event-only proof");
|
|
|
|
|
assert.ok(row.next_step.includes("M128/M129"), "user-M recommendation lacks M128/M129 next step");
|
|
|
|
|
if (proofCompleteManualLock) {
|
|
|
|
|
assert.ok(row.next_step.includes("promotion lock"), "user-M recommendation lacks manual lock next step");
|
|
|
|
|
} else {
|
|
|
|
|
assert.ok(row.next_step.includes("M128/M129"), "user-M recommendation lacks M128/M129 next step");
|
|
|
|
|
}
|
|
|
|
|
} else if (row.boundary_kind === "tool_database_process") {
|
|
|
|
|
assert.equal(row.target, "axis/db_demo/base.ngc", "tool DB recommendation target drift");
|
|
|
|
|
assert.equal(row.blocked, "L4-TOOL-DB", "tool DB recommendation blocked kind drift");
|
|
|
|
|
assert.equal(row.recommendation, "implement_tooldata_db_protocol_probe", "tool DB recommendation drift");
|
|
|
|
|
assert.ok(
|
|
|
|
|
["implement_tooldata_db_protocol_probe", "manual_promotion_lock_review"].includes(row.recommendation),
|
|
|
|
|
"tool DB recommendation drift",
|
|
|
|
|
);
|
|
|
|
|
assert.equal(row.primary_artifact, "tool-db-process-native-runtime-probe-gate.tsv", "tool DB artifact drift");
|
|
|
|
|
assert.ok(row.required_native_proof.includes("native_db_process_protocol_probe"), "tool DB recommendation must require native DB process proof");
|
|
|
|
|
assert.ok(row.next_step.includes("DB_PROGRAM"), "tool DB recommendation lacks DB_PROGRAM next step");
|
|
|
|
|
assert.ok(row.next_step.includes("tbl fallback"), "tool DB recommendation must reject tbl fallback");
|
|
|
|
|
if (proofCompleteManualLock) {
|
|
|
|
|
assert.ok(row.next_step.includes("promotion lock"), "tool DB recommendation lacks manual lock next step");
|
|
|
|
|
} else {
|
|
|
|
|
assert.ok(row.next_step.includes("DB_PROGRAM"), "tool DB recommendation lacks DB_PROGRAM next step");
|
|
|
|
|
assert.ok(row.next_step.includes("tbl fallback"), "tool DB recommendation must reject tbl fallback");
|
|
|
|
|
}
|
|
|
|
|
} else if (row.boundary_kind === "python_runtime") {
|
|
|
|
|
assert.equal(row.target, "axis/remap/stop-lookahead/nc_files", "Python recommendation target drift");
|
|
|
|
|
assert.equal(row.blocked, "L4-PYTHON-REMAP", "Python recommendation blocked kind drift");
|
|
|
|
|
assert.equal(row.recommendation, "implement_minimal_python_runtime_lifecycle_probe", "Python recommendation drift");
|
|
|
|
|
assert.ok(
|
|
|
|
|
["implement_minimal_python_runtime_lifecycle_probe", "manual_promotion_lock_review"].includes(row.recommendation),
|
|
|
|
|
"Python recommendation drift",
|
|
|
|
|
);
|
|
|
|
|
assert.equal(row.primary_artifact, "python-remap-native-runtime-fixture-plan.tsv", "Python artifact drift");
|
|
|
|
|
assert.ok(row.required_node_proof.includes("not_js_semantics"), "Python recommendation must reject JS semantics");
|
|
|
|
|
assert.ok(row.next_step.includes("stop-lookahead"), "Python recommendation lacks fixture next step");
|
|
|
|
|
if (proofCompleteManualLock) {
|
|
|
|
|
assert.ok(row.next_step.includes("promotion lock"), "Python recommendation lacks manual lock next step");
|
|
|
|
|
} else {
|
|
|
|
|
assert.ok(row.next_step.includes("stop-lookahead"), "Python recommendation lacks fixture next step");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
throw new Error(`${row.target}: unexpected recommendation boundary kind ${row.boundary_kind}`);
|
|
|
|
|
}
|
|
|
|
|
@@ -10372,7 +10455,7 @@ function verifyRuntimeFamilyContractAlignmentConsistency({
|
|
|
|
|
assert.equal(row.db_program, toolDbGate.db_program, `${row.transaction_phase}: tool DB program drift`);
|
|
|
|
|
requireDisabled(row, `${row.transaction_phase}: tool DB transaction`);
|
|
|
|
|
}
|
|
|
|
|
requireDisabled(toolDbGate, "tool DB probe gate");
|
|
|
|
|
requireDisabled(toolDbGate, "tool DB probe gate", ["pending", "native_protocol_probe_passed"]);
|
|
|
|
|
|
|
|
|
|
const pythonContract = contractByClass.get("L4-PYTHON-REMAP");
|
|
|
|
|
const pythonNative = nativeAlignmentByClass.get("L4-PYTHON-REMAP");
|
|
|
|
|
@@ -10799,6 +10882,11 @@ function runtimeProbeGateAlignmentRows({
|
|
|
|
|
(gateRow?.runtime_ready === "1" &&
|
|
|
|
|
gateRow?.gate_status === nativeRow?.probe_status &&
|
|
|
|
|
nativeRow?.probe_status?.startsWith("runtime_") &&
|
|
|
|
|
nativeRow?.probe_status?.endsWith("_passed")) ||
|
|
|
|
|
(gateRow?.runtime_ready === "1" &&
|
|
|
|
|
gateRow?.gate_status?.startsWith("native_") &&
|
|
|
|
|
gateRow?.gate_status?.includes("_passed") &&
|
|
|
|
|
nativeRow?.probe_status?.startsWith("runtime_") &&
|
|
|
|
|
nativeRow?.probe_status?.endsWith("_passed"))
|
|
|
|
|
);
|
|
|
|
|
const alignmentOk = (
|
|
|
|
|
@@ -13041,6 +13129,7 @@ const pythonRemapRowRuntimeProofRecords = verifyPythonRemapRowRuntimeProofRows({
|
|
|
|
|
});
|
|
|
|
|
const promotedPythonRemapInventoryPaths = pythonRemapInventoryPromotionPathSet(
|
|
|
|
|
pythonRemapRowRuntimeProofRecords,
|
|
|
|
|
{ promotionEnabled: process.env.ENABLE_PYTHON_REMAP_INVENTORY_PROMOTION === "1" },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const summaryRows = [];
|
|
|
|
|
@@ -13466,10 +13555,15 @@ function verifyPromotionCandidateRows(rows, summaryRows, boundaryRows) {
|
|
|
|
|
`${lockedKind}: locked inventory rows must not allow promotion`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
const pythonRemapLockedRows = parsedInventoryReady.filter((row) => row.skip_kind === "L4-PYTHON-REMAP");
|
|
|
|
|
assert.ok(
|
|
|
|
|
pythonRemapLockedRows.length > 0,
|
|
|
|
|
"Python-remap blocked rows must remain visible as locked promotion candidates until row proof promotion",
|
|
|
|
|
);
|
|
|
|
|
assert.equal(
|
|
|
|
|
parsedInventoryReady.filter((row) => row.skip_kind === "L4-PYTHON-REMAP").length,
|
|
|
|
|
pythonRemapLockedRows.filter((row) => row.promotion_allowed !== "0").length,
|
|
|
|
|
0,
|
|
|
|
|
"Python-remap rows must leave skipped promotion candidates after row proof promotion",
|
|
|
|
|
"Python-remap 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`);
|
|
|
|
|
@@ -13545,11 +13639,16 @@ function remainingSkipMainProgramPromotionAuditRows({
|
|
|
|
|
const readiness = readinessByBlocked.get(row.reason);
|
|
|
|
|
const promotionAllowed = promotion?.promotion_allowed === "1" &&
|
|
|
|
|
readiness?.promotion_ready === "1";
|
|
|
|
|
const runtimeProofComplete = readiness?.native_pass_ready === "1" &&
|
|
|
|
|
readiness?.node_inventory_gate_complete === "1" &&
|
|
|
|
|
readiness?.browser_smoke_gate_complete === "1";
|
|
|
|
|
const decision = promotionAllowed
|
|
|
|
|
? "promotable_main_program"
|
|
|
|
|
: row.reason === "UPSTREAM-DEMO"
|
|
|
|
|
? "not_promotable_upstream_demo_missing_motion_gcode"
|
|
|
|
|
: "not_promotable_runtime_proof_incomplete";
|
|
|
|
|
: runtimeProofComplete && readiness?.promotion_lock_active === "1"
|
|
|
|
|
? "not_promotable_manual_promotion_lock_active"
|
|
|
|
|
: "not_promotable_runtime_proof_incomplete";
|
|
|
|
|
const simulationProofStatus = readiness
|
|
|
|
|
? `${readiness.current_probe_status}:native=${readiness.native_pass_ready}:node=${readiness.node_inventory_gate_complete}:browser=${readiness.browser_smoke_gate_complete}`
|
|
|
|
|
: "no_runtime_promotion_readiness_for_skip_kind";
|
|
|
|
|
@@ -13631,7 +13730,7 @@ function verifyRemainingSkipMainProgramPromotionAuditRows({
|
|
|
|
|
expectedSkippedMain,
|
|
|
|
|
"remaining skipped-main audit must align with inventory-ready promotion candidates",
|
|
|
|
|
);
|
|
|
|
|
assert.equal(parsedRows.length, 2, "current remaining skipped main-program count drift");
|
|
|
|
|
assert.equal(parsedRows.length, expectedSkippedMain.length, "current remaining skipped main-program count drift");
|
|
|
|
|
assert.equal(
|
|
|
|
|
parsedRows.filter((row) => row.promotion_allowed === "1").length,
|
|
|
|
|
0,
|
|
|
|
|
@@ -13653,13 +13752,22 @@ function verifyRemainingSkipMainProgramPromotionAuditRows({
|
|
|
|
|
if (row.skip_kind === "L4-USER-M-PROCESS") {
|
|
|
|
|
assert.equal(row.path, "axis/vismach/millturn/example.ngc", `${row.path}: user-M skipped main path drift`);
|
|
|
|
|
assert.ok(
|
|
|
|
|
row.simulation_proof_status.includes("node=0") ||
|
|
|
|
|
row.simulation_proof_status.includes("browser=0"),
|
|
|
|
|
`${row.path}: user-M row must show incomplete Node/browser simulation proof`,
|
|
|
|
|
row.simulation_proof_status.includes(`native=${row.native_pass_ready}`),
|
|
|
|
|
`${row.path}: user-M native proof status drift`,
|
|
|
|
|
);
|
|
|
|
|
assert.ok(
|
|
|
|
|
row.simulation_proof_status.includes(`node=${row.node_inventory_gate_complete}`),
|
|
|
|
|
`${row.path}: user-M Node proof status drift`,
|
|
|
|
|
);
|
|
|
|
|
assert.ok(
|
|
|
|
|
row.simulation_proof_status.includes(`browser=${row.browser_smoke_gate_complete}`),
|
|
|
|
|
`${row.path}: user-M browser proof status drift`,
|
|
|
|
|
);
|
|
|
|
|
assert.equal(
|
|
|
|
|
row.promotion_decision,
|
|
|
|
|
"not_promotable_runtime_proof_incomplete",
|
|
|
|
|
row.node_inventory_gate_complete === "1" && row.browser_smoke_gate_complete === "1"
|
|
|
|
|
? "not_promotable_manual_promotion_lock_active"
|
|
|
|
|
: "not_promotable_runtime_proof_incomplete",
|
|
|
|
|
`${row.path}: user-M audit decision drift`,
|
|
|
|
|
);
|
|
|
|
|
} else if (row.skip_kind === "UPSTREAM-DEMO") {
|
|
|
|
|
@@ -13668,6 +13776,14 @@ function verifyRemainingSkipMainProgramPromotionAuditRows({
|
|
|
|
|
"not_promotable_upstream_demo_missing_motion_gcode",
|
|
|
|
|
`${row.path}: upstream demo audit decision drift`,
|
|
|
|
|
);
|
|
|
|
|
} else if (row.skip_kind === "L4-PYTHON-REMAP") {
|
|
|
|
|
assert.equal(
|
|
|
|
|
row.promotion_decision,
|
|
|
|
|
row.node_inventory_gate_complete === "1" && row.browser_smoke_gate_complete === "1"
|
|
|
|
|
? "not_promotable_manual_promotion_lock_active"
|
|
|
|
|
: "not_promotable_runtime_proof_incomplete",
|
|
|
|
|
`${row.path}: Python-remap audit decision drift`,
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
assert.fail(`${row.path}: unexpected remaining skipped main skip kind ${row.skip_kind}`);
|
|
|
|
|
}
|
|
|
|
|
@@ -13686,6 +13802,9 @@ function simulationImplementationMode(row) {
|
|
|
|
|
if (row.reason === "L4-USER-M-PROCESS") {
|
|
|
|
|
return "linuxcnc_runtime_boundary_virtual_hal_state_proof";
|
|
|
|
|
}
|
|
|
|
|
if (row.reason === "L4-PYTHON-REMAP") {
|
|
|
|
|
return "linuxcnc_python_remap_runtime_boundary_proof";
|
|
|
|
|
}
|
|
|
|
|
if (row.reason === "UPSTREAM-DEMO") {
|
|
|
|
|
return "upstream_demo_preserved_invalid_motion_source";
|
|
|
|
|
}
|
|
|
|
|
@@ -13702,6 +13821,9 @@ function simulationImplementationStatus(row) {
|
|
|
|
|
if (row.reason === "L4-USER-M-PROCESS") {
|
|
|
|
|
return "implemented_as_source_derived_boundary_state_proof_runtime_execution_blocked";
|
|
|
|
|
}
|
|
|
|
|
if (row.reason === "L4-PYTHON-REMAP") {
|
|
|
|
|
return "implemented_as_linuxcnc_python_remap_boundary_proof_runtime_execution_blocked";
|
|
|
|
|
}
|
|
|
|
|
if (row.reason === "UPSTREAM-DEMO") {
|
|
|
|
|
return "implemented_as_preserved_upstream_demo_edge_invalid_motion_not_forced_pass";
|
|
|
|
|
}
|
|
|
|
|
@@ -13712,6 +13834,9 @@ function simulationImplementationNextStep(row) {
|
|
|
|
|
if (row.reason === "L4-USER-M-PROCESS") {
|
|
|
|
|
return "run_opt_in_native_runtime_probe_before_any_inventory_promotion";
|
|
|
|
|
}
|
|
|
|
|
if (row.reason === "L4-PYTHON-REMAP") {
|
|
|
|
|
return "complete_python_remap_row_runtime_wasm_browser_proof_before_inventory_promotion";
|
|
|
|
|
}
|
|
|
|
|
if (row.reason === "UPSTREAM-DEMO") {
|
|
|
|
|
return "wait_for_upstream_source_fix_then_regenerate_inventory";
|
|
|
|
|
}
|
|
|
|
|
@@ -13756,7 +13881,7 @@ function remainingSkipSimulationImplementationCoverageRows({
|
|
|
|
|
const standaloneMainReady = row.className === "main" &&
|
|
|
|
|
row.reason === "-" &&
|
|
|
|
|
row.nativeStatus === "PASS";
|
|
|
|
|
const runtimePromotionBlocked = ["L4-USER-M-PROCESS", "UPSTREAM-DEMO"].includes(row.reason);
|
|
|
|
|
const runtimePromotionBlocked = ["L4-USER-M-PROCESS", "L4-PYTHON-REMAP", "UPSTREAM-DEMO"].includes(row.reason);
|
|
|
|
|
return [
|
|
|
|
|
row.path,
|
|
|
|
|
boundary?.ini ?? audit?.ini ?? "-",
|
|
|
|
|
@@ -13819,7 +13944,7 @@ function verifyRemainingSkipSimulationImplementationCoverageRows({
|
|
|
|
|
.filter((row) => row.inventoryStatus === "SKIP");
|
|
|
|
|
const auditByPath = new Map(remainingSkipAuditRows.map((row) => [row.path, row]));
|
|
|
|
|
|
|
|
|
|
assert.equal(parsedRows.length, 77, "remaining skip simulation implementation coverage count drift");
|
|
|
|
|
assert.equal(parsedRows.length, skippedSummaryRows.length, "remaining skip simulation implementation coverage count drift");
|
|
|
|
|
assert.deepEqual(
|
|
|
|
|
parsedRows.map((row) => row.path).sort(),
|
|
|
|
|
skippedSummaryRows.map((row) => row.path).sort(),
|
|
|
|
|
@@ -13834,6 +13959,7 @@ function verifyRemainingSkipSimulationImplementationCoverageRows({
|
|
|
|
|
),
|
|
|
|
|
{
|
|
|
|
|
"ASSET-ONLY": 65,
|
|
|
|
|
"L4-PYTHON-REMAP": 53,
|
|
|
|
|
"L4-USER-M-PROCESS": 1,
|
|
|
|
|
"NON_MAIN_CLASS": 10,
|
|
|
|
|
"UPSTREAM-DEMO": 1,
|
|
|
|
|
@@ -13874,6 +14000,17 @@ function verifyRemainingSkipSimulationImplementationCoverageRows({
|
|
|
|
|
"implemented_as_source_derived_boundary_state_proof_runtime_execution_blocked",
|
|
|
|
|
`${row.path}: user-M implementation status drift`,
|
|
|
|
|
);
|
|
|
|
|
} else if (row.skip_kind === "L4-PYTHON-REMAP") {
|
|
|
|
|
const audit = auditByPath.get(row.path);
|
|
|
|
|
if (row.main_program_class === "1") {
|
|
|
|
|
assert.ok(audit, `${row.path}: Python-remap skipped main row must have promotion audit`);
|
|
|
|
|
}
|
|
|
|
|
assert.equal(row.runtime_promotion_blocked, "1", `${row.path}: Python-remap runtime promotion block drift`);
|
|
|
|
|
assert.equal(
|
|
|
|
|
row.simulation_implementation_status,
|
|
|
|
|
"implemented_as_linuxcnc_python_remap_boundary_proof_runtime_execution_blocked",
|
|
|
|
|
`${row.path}: Python-remap implementation status drift`,
|
|
|
|
|
);
|
|
|
|
|
} else if (row.skip_kind === "UPSTREAM-DEMO") {
|
|
|
|
|
const audit = auditByPath.get(row.path);
|
|
|
|
|
assert.ok(audit, `${row.path}: upstream demo skipped main row must have promotion audit`);
|
|
|
|
|
@@ -14148,6 +14285,7 @@ const runtimeBoundaryPromotionBlockerRecords = verifyRuntimeBoundaryPromotionBlo
|
|
|
|
|
const nextBoundaryRecommendationRowsGenerated = nextBoundaryRecommendationRows({
|
|
|
|
|
worklistRows: nextBoundaryRecords,
|
|
|
|
|
promotionLockRows: blockedRuntimePromotionLockRecords,
|
|
|
|
|
promotionReadinessRows: runtimeBoundaryPromotionReadinessRecords,
|
|
|
|
|
runtimeContractRows: runtimeBoundaryContractSummaryRecords,
|
|
|
|
|
userMRuntimeProbeGateRows: userMProcessNativeRuntimeProbeGateRecords,
|
|
|
|
|
toolDbTransactionRows: toolDbProcessTransactionPlanRecords,
|
|
|
|
|
|