export const PYTHON_REMAP_RUNTIME_PORT_CONTRACT_VERSION = 1; export const PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE = Object.freeze({ fixtureFamily: "axis/remap/stop-lookahead/nc_files", fixtureId: "stop_lookahead_python_runtime_lifecycle", iniPath: "axis/remap/stop-lookahead/demo.ini", pythonPathPrepend: "python", topLevelPath: "python/toplevel.py", modules: [ "axis/remap/stop-lookahead/python/remap.py", "axis/remap/stop-lookahead/python/toplevel.py", ], callableName: "queuebuster", expectedFirstYield: 2, }); export const PYTHON_REMAP_LIFECYCLE_PLAN = [ { phase: "initialize_python", method: "initializePython" }, { phase: "apply_ini_python_path", method: "applyIniPythonPath" }, { phase: "execute_toplevel", method: "executeTopLevel" }, { phase: "import_module", method: "importModule", modulePath: "python/remap.py" }, { phase: "callable_lookup", method: "lookupCallable", callableName: "queuebuster" }, { phase: "callable_invoke", method: "invokeGenerator", callableName: "queuebuster" }, { phase: "remap_phase_dispatch", method: "observeFirstYield", expectedYield: 2 }, { phase: "generator_finish", method: "finishGenerator" }, { phase: "export_interpreter_state", method: "exportInterpreterState" }, { phase: "export_diagnostics", method: "exportDiagnostics" }, ]; export const PYTHON_REMAP_ROW_RUNTIME_PROOF_PHASES = Object.freeze([ "initialize_python", "apply_ini_python_path", "execute_toplevel", "import_module", "callable_lookup", "callable_invoke", "remap_phase_dispatch", "generator_finish", "stage_ngc_remap_asset", "reject_ngc_only_standalone", "export_interpreter_state", "export_canonical_events", "export_diagnostics", ]); function requireString(value, label) { if (typeof value !== "string" || value.length === 0) { throw new Error(`${label} must be a non-empty string.`); } return value; } function normalizeSourceFiles(sourceFiles = []) { if (!Array.isArray(sourceFiles)) { throw new Error("sourceFiles must be an array."); } return sourceFiles.map((sourceFile) => requireString(sourceFile, "source file")); } function normalizeStringList(values = [], label = "value") { if (values === "-" || values === null || values === undefined) { return []; } if (!Array.isArray(values)) { throw new Error(`${label} must be an array.`); } return values .filter((value) => value !== "-") .map((value) => requireString(value, label)); } function callableNameFromSpec(callableSpec) { return requireString(callableSpec, "callable").split("@")[0]; } function stableTextHash(text) { let hash = 0x811c9dc5; for (let index = 0; index < text.length; index += 1) { hash ^= text.charCodeAt(index); hash = Math.imul(hash, 0x01000193) >>> 0; } return hash.toString(16).padStart(8, "0"); } function clonePlan(plan) { return plan.map((step) => ({ ...step })); } function transcriptText(transcript) { return transcript .map((entry) => `${entry.phase}:${entry.status}:${entry.value ?? ""}`) .join("\n"); } function normalizeLifecycleResult(phase, result = {}) { return { phase, status: result.status ?? "ok", value: result.value ?? null, ready: result.ready !== false, source: result.source ?? "runtime-adapter", }; } function defaultRowRuntimePlan({ sourceFiles, pythonRemapFunctions, prologFunctions, epilogFunctions, ngcRemapFiles, ngcOnlySubpaths, }) { const callables = [ ...pythonRemapFunctions, ...prologFunctions, ...epilogFunctions, ]; return [ { phase: "initialize_python", method: "initializePython" }, { phase: "apply_ini_python_path", method: "applyIniPythonPath" }, { phase: "execute_toplevel", method: "executeTopLevel" }, ...sourceFiles.map((modulePath) => ({ phase: "import_module", method: "importModule", modulePath, })), ...callables.flatMap((callableSpec) => { const callableName = callableNameFromSpec(callableSpec); return [ { phase: "callable_lookup", method: "lookupCallable", callableName, callableSpec, }, { phase: "callable_invoke", method: "invokeGenerator", callableName, callableSpec, }, { phase: "remap_phase_dispatch", method: "observeFirstYield", callableName, callableSpec, }, { phase: "generator_finish", method: "finishGenerator", callableName, callableSpec, }, ]; }), ...ngcRemapFiles.map((ngcPath) => ({ phase: "stage_ngc_remap_asset", method: "stageNgcRemapAsset", ngcPath, })), ...ngcOnlySubpaths.map((ngcPath) => ({ phase: "reject_ngc_only_standalone", method: "rejectNgcOnlyStandalone", ngcPath, })), { phase: "export_interpreter_state", method: "exportInterpreterState" }, { phase: "export_canonical_events", method: "exportCanonicalEvents" }, { phase: "export_diagnostics", method: "exportDiagnostics" }, ]; } export function createPythonRemapLifecyclePlan() { return clonePlan(PYTHON_REMAP_LIFECYCLE_PLAN); } export function createPythonRemapRowRuntimePlan({ sourceFiles = [], pythonRemapFunctions = [], prologFunctions = [], epilogFunctions = [], ngcRemapFiles = [], ngcOnlySubpaths = [], } = {}) { return clonePlan(defaultRowRuntimePlan({ sourceFiles: normalizeStringList(sourceFiles, "source file"), pythonRemapFunctions: normalizeStringList(pythonRemapFunctions, "Python remap function"), prologFunctions: normalizeStringList(prologFunctions, "prolog function"), epilogFunctions: normalizeStringList(epilogFunctions, "epilog function"), ngcRemapFiles: normalizeStringList(ngcRemapFiles, "NGC remap file"), ngcOnlySubpaths: normalizeStringList(ngcOnlySubpaths, "NGC-only subpath"), })); } export function validatePythonRemapLifecycleTranscript(transcript) { if (!Array.isArray(transcript)) { throw new Error("transcript must be an array."); } const byPhase = new Map(transcript.map((entry) => [entry?.phase, entry])); const requiredPhases = PYTHON_REMAP_LIFECYCLE_PLAN.map((step) => step.phase); const missingPhases = requiredPhases.filter((phase) => !byPhase.has(phase)); const failedPhases = transcript .filter((entry) => entry?.ready === false || entry?.status === "blocked" || entry?.status === "failed") .map((entry) => entry.phase); const firstYield = byPhase.get("remap_phase_dispatch")?.value ?? null; const expectedValues = { apply_ini_python_path: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.pythonPathPrepend, execute_toplevel: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.topLevelPath, import_module: "python/remap.py", callable_lookup: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.callableName, }; const mismatchedValues = Object.entries(expectedValues) .filter(([phase, expectedValue]) => byPhase.get(phase)?.value !== expectedValue) .map(([phase]) => phase); const hasInterpreterState = byPhase.has("export_interpreter_state"); const hasDiagnostics = byPhase.has("export_diagnostics"); const ready = ( missingPhases.length === 0 && failedPhases.length === 0 && mismatchedValues.length === 0 && Number(firstYield) === PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.expectedFirstYield && hasInterpreterState && hasDiagnostics ); return { contractVersion: PYTHON_REMAP_RUNTIME_PORT_CONTRACT_VERSION, fixtureFamily: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.fixtureFamily, callableName: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.callableName, requiredPhases, observedPhases: transcript.map((entry) => entry.phase), missingPhases, failedPhases, mismatchedValues, firstYield, hasInterpreterState, hasDiagnostics, lifecycleTranscriptReady: ready, callableLookupReady: byPhase.get("callable_lookup")?.ready === true, generatorLifecycleReady: byPhase.get("generator_finish")?.ready === true, interpreterStateBindingReady: hasInterpreterState, ready, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; } export function createPythonRemapRuntimeDiagnostics({ fixtureFamily = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.fixtureFamily, iniPath = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.iniPath, pythonPathPrepend = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.pythonPathPrepend, topLevelPath = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.topLevelPath, modules = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.modules, callableName = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.callableName, runtimeMode = "contract-only", runtimeExecutionReady = false, transcript = [], } = {}) { const validation = validatePythonRemapLifecycleTranscript(transcript); return { contractVersion: PYTHON_REMAP_RUNTIME_PORT_CONTRACT_VERSION, runtimeMode, runtimeExecutionReady: runtimeExecutionReady === true, fixtureFamily, fixtureId: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.fixtureId, iniPath, pythonPathPrepend, topLevelPath, modules: [...modules], callableName, lifecycleTranscriptReady: validation.lifecycleTranscriptReady, callableLookupReady: validation.callableLookupReady, generatorLifecycleReady: validation.generatorLifecycleReady, interpreterStateBindingReady: validation.interpreterStateBindingReady, transcriptHash: stableTextHash(transcriptText(transcript)), transcriptPhaseCount: transcript.length, linuxCncOwnedLifecycle: true, jsCncSemantics: false, ngcOnlySubroutinePromoted: false, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; } export function validatePythonRemapRowRuntimeTranscript({ rowPath, transcript, sourceFiles = [], pythonRemapFunctions = [], prologFunctions = [], epilogFunctions = [], ngcRemapFiles = [], ngcOnlySubpaths = [], } = {}) { requireString(rowPath, "rowPath"); if (!Array.isArray(transcript)) { throw new Error("transcript must be an array."); } const expectedPlan = createPythonRemapRowRuntimePlan({ sourceFiles, pythonRemapFunctions, prologFunctions, epilogFunctions, ngcRemapFiles, ngcOnlySubpaths, }); const expectedPhases = expectedPlan.map((step) => step.phase); const observedPhases = transcript.map((entry) => entry.phase); const phaseCounts = new Map(); for (const phase of observedPhases) { phaseCounts.set(phase, (phaseCounts.get(phase) ?? 0) + 1); } const failedPhases = transcript .filter((entry) => entry?.ready === false || entry?.status === "blocked" || entry?.status === "failed") .map((entry) => entry.phase); const missingPhases = [...new Set(expectedPhases)].filter((phase) => !phaseCounts.has(phase)); const expectedModuleCount = normalizeStringList(sourceFiles, "source file").length; const expectedCallableCount = [ ...normalizeStringList(pythonRemapFunctions, "Python remap function"), ...normalizeStringList(prologFunctions, "prolog function"), ...normalizeStringList(epilogFunctions, "epilog function"), ].length; const expectedNgcRemapCount = normalizeStringList(ngcRemapFiles, "NGC remap file").length; const expectedNgcOnlyCount = normalizeStringList(ngcOnlySubpaths, "NGC-only subpath").length; const countDrift = [ ["import_module", expectedModuleCount], ["callable_lookup", expectedCallableCount], ["callable_invoke", expectedCallableCount], ["remap_phase_dispatch", expectedCallableCount], ["generator_finish", expectedCallableCount], ["stage_ngc_remap_asset", expectedNgcRemapCount], ["reject_ngc_only_standalone", expectedNgcOnlyCount], ].filter(([phase, expectedCount]) => (phaseCounts.get(phase) ?? 0) !== expectedCount) .map(([phase]) => phase); const hasInterpreterState = phaseCounts.has("export_interpreter_state"); const hasCanonicalEvents = phaseCounts.has("export_canonical_events"); const hasDiagnostics = phaseCounts.has("export_diagnostics"); const ready = ( missingPhases.length === 0 && failedPhases.length === 0 && countDrift.length === 0 && hasInterpreterState && hasCanonicalEvents && hasDiagnostics ); return { contractVersion: PYTHON_REMAP_RUNTIME_PORT_CONTRACT_VERSION, rowPath, requiredPhases: [...new Set(expectedPhases)], observedPhases, missingPhases, failedPhases, countDrift, moduleImportReady: (phaseCounts.get("import_module") ?? 0) === expectedModuleCount, callableLookupReady: (phaseCounts.get("callable_lookup") ?? 0) === expectedCallableCount, generatorLifecycleReady: ( (phaseCounts.get("callable_invoke") ?? 0) === expectedCallableCount && (phaseCounts.get("remap_phase_dispatch") ?? 0) === expectedCallableCount && (phaseCounts.get("generator_finish") ?? 0) === expectedCallableCount ), ngcRemapAssetsReady: (phaseCounts.get("stage_ngc_remap_asset") ?? 0) === expectedNgcRemapCount, ngcOnlySubpathsGuarded: (phaseCounts.get("reject_ngc_only_standalone") ?? 0) === expectedNgcOnlyCount, interpreterStateBindingReady: hasInterpreterState, canonicalEventsReady: hasCanonicalEvents, diagnosticsReady: hasDiagnostics, rowRuntimeTranscriptReady: ready, ready, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; } export function createLinuxCncPythonRemapRuntimePort({ fixtureFamily = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.fixtureFamily, iniPath = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.iniPath, pythonPathPrepend = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.pythonPathPrepend, topLevelPath = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.topLevelPath, sourceFiles = PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.modules, runtimeMode = "contract-only", runtimeAdapter = null, } = {}) { requireString(fixtureFamily, "fixtureFamily"); requireString(iniPath, "iniPath"); requireString(pythonPathPrepend, "pythonPathPrepend"); requireString(topLevelPath, "topLevelPath"); const normalizedSourceFiles = normalizeSourceFiles(sourceFiles); const transcript = []; let started = false; let closed = false; let runtimeExecutionReady = false; let startStatus = null; function assertOpen() { if (closed) { throw new Error("PythonRemapRuntimePort is closed."); } } async function callAdapterMethod(method, payload = {}) { if (!runtimeAdapter?.[method]) { return normalizeLifecycleResult(payload.phase ?? method, { status: "blocked", ready: false, source: "missing-runtime-adapter-method", }); } return normalizeLifecycleResult(payload.phase ?? method, await runtimeAdapter[method](payload)); } async function runStep(step) { const payload = { ...step, fixtureFamily, iniPath, pythonPathPrepend, topLevelPath, sourceFiles: normalizedSourceFiles, }; const result = await callAdapterMethod(step.method, payload); transcript.push(result); return result; } return { fixtureFamily, iniPath, pythonPathPrepend, topLevelPath, sourceFiles: normalizedSourceFiles, runtimeMode, async start() { assertOpen(); started = true; let adapterStartResult = {}; if (runtimeAdapter?.start) { adapterStartResult = await runtimeAdapter.start({ fixtureFamily, iniPath, pythonPathPrepend, topLevelPath, sourceFiles: normalizedSourceFiles, }); } runtimeExecutionReady = adapterStartResult.runtimeExecutionReady === true; startStatus = adapterStartResult.status ?? (runtimeExecutionReady ? "python_remap_runtime_adapter_started" : null); return { runtimeMode, runtimeExecutionReady, status: startStatus, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; }, async initializePython() { assertOpen(); if (!started) { throw new Error("PythonRemapRuntimePort must be started before initializePython()."); } return runStep({ phase: "initialize_python", method: "initializePython" }); }, async applyIniPythonPath() { assertOpen(); if (!started) { throw new Error("PythonRemapRuntimePort must be started before applyIniPythonPath()."); } return runStep({ phase: "apply_ini_python_path", method: "applyIniPythonPath" }); }, async executeTopLevel() { assertOpen(); if (!started) { throw new Error("PythonRemapRuntimePort must be started before executeTopLevel()."); } return runStep({ phase: "execute_toplevel", method: "executeTopLevel" }); }, async importModule(modulePath) { assertOpen(); if (!started) { throw new Error("PythonRemapRuntimePort must be started before importModule()."); } return runStep({ phase: "import_module", method: "importModule", modulePath }); }, async lookupCallable(callableName) { assertOpen(); if (!started) { throw new Error("PythonRemapRuntimePort must be started before lookupCallable()."); } return runStep({ phase: "callable_lookup", method: "lookupCallable", callableName }); }, async invokeGenerator(callableName, args = []) { assertOpen(); if (!started) { throw new Error("PythonRemapRuntimePort must be started before invokeGenerator()."); } return runStep({ phase: "callable_invoke", method: "invokeGenerator", callableName, args }); }, async runLifecyclePlan(plan = createPythonRemapLifecyclePlan()) { assertOpen(); if (!started) { throw new Error("PythonRemapRuntimePort must be started before runLifecyclePlan()."); } if (!runtimeAdapter || runtimeExecutionReady !== true) { return { status: runtimeAdapter ? (startStatus ?? "blocked_runtime_execution_not_ready") : "blocked_runtime_adapter_required", plan: clonePlan(plan), runtimeExecutionReady: false, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; } for (const step of plan) { await runStep(step); } return { status: "runtime_adapter_lifecycle_plan_executed", plan: clonePlan(plan), transcript: this.exportTranscript(), validation: validatePythonRemapLifecycleTranscript(transcript), runtimeExecutionReady: true, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; }, exportTranscript() { return transcript.map((entry) => ({ ...entry })); }, exportDiagnostics() { return createPythonRemapRuntimeDiagnostics({ fixtureFamily, iniPath, pythonPathPrepend, topLevelPath, modules: normalizedSourceFiles, runtimeMode, runtimeExecutionReady, transcript, }); }, async close() { if (runtimeAdapter?.close) { await runtimeAdapter.close(); } closed = true; return { closed, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; }, }; } export function createLinuxCncPythonRemapRowRuntimePort({ path, iniPath, family = null, machineRoot = "", pythonPathPrepend = "-", topLevelPath = "-", sourceFiles = [], remapDeclarations = [], pythonRemapFunctions = [], prologFunctions = [], epilogFunctions = [], ngcRemapFiles = [], ngcOnlySubpaths = [], runtimeMode = "row-runtime-contract-only", runtimeAdapter = null, } = {}) { requireString(path, "path"); requireString(iniPath, "iniPath"); const normalizedFamily = family ?? path.split("/").slice(0, -1).join("/"); requireString(normalizedFamily, "family"); const normalizedMachineRoot = machineRoot === "-" ? "" : String(machineRoot ?? ""); const normalizedPythonPathPrepend = pythonPathPrepend === "-" ? "" : String(pythonPathPrepend ?? ""); const normalizedTopLevelPath = topLevelPath === "-" ? "" : String(topLevelPath ?? ""); const normalizedSourceFiles = normalizeStringList(sourceFiles, "source file"); const normalizedRemapDeclarations = normalizeStringList(remapDeclarations, "remap declaration"); const normalizedPythonRemapFunctions = normalizeStringList(pythonRemapFunctions, "Python remap function"); const normalizedPrologFunctions = normalizeStringList(prologFunctions, "prolog function"); const normalizedEpilogFunctions = normalizeStringList(epilogFunctions, "epilog function"); const normalizedNgcRemapFiles = normalizeStringList(ngcRemapFiles, "NGC remap file"); const normalizedNgcOnlySubpaths = normalizeStringList(ngcOnlySubpaths, "NGC-only subpath"); const transcript = []; let started = false; let closed = false; let runtimeExecutionReady = false; let startStatus = null; function assertOpen() { if (closed) { throw new Error("PythonRemapRowRuntimePort is closed."); } } async function callAdapterMethod(method, payload = {}) { if (!runtimeAdapter?.[method]) { return normalizeLifecycleResult(payload.phase ?? method, { status: "blocked", ready: false, source: "missing-runtime-adapter-method", }); } return normalizeLifecycleResult(payload.phase ?? method, await runtimeAdapter[method](payload)); } async function runStep(step) { const payload = { ...step, path, iniPath, family: normalizedFamily, machineRoot: normalizedMachineRoot, pythonPathPrepend: normalizedPythonPathPrepend, topLevelPath: normalizedTopLevelPath, sourceFiles: normalizedSourceFiles, remapDeclarations: normalizedRemapDeclarations, pythonRemapFunctions: normalizedPythonRemapFunctions, prologFunctions: normalizedPrologFunctions, epilogFunctions: normalizedEpilogFunctions, ngcRemapFiles: normalizedNgcRemapFiles, ngcOnlySubpaths: normalizedNgcOnlySubpaths, }; const result = await callAdapterMethod(step.method, payload); transcript.push(result); return result; } function rowPlan() { return createPythonRemapRowRuntimePlan({ sourceFiles: normalizedSourceFiles, pythonRemapFunctions: normalizedPythonRemapFunctions, prologFunctions: normalizedPrologFunctions, epilogFunctions: normalizedEpilogFunctions, ngcRemapFiles: normalizedNgcRemapFiles, ngcOnlySubpaths: normalizedNgcOnlySubpaths, }); } function validation() { return validatePythonRemapRowRuntimeTranscript({ rowPath: path, transcript, sourceFiles: normalizedSourceFiles, pythonRemapFunctions: normalizedPythonRemapFunctions, prologFunctions: normalizedPrologFunctions, epilogFunctions: normalizedEpilogFunctions, ngcRemapFiles: normalizedNgcRemapFiles, ngcOnlySubpaths: normalizedNgcOnlySubpaths, }); } return { path, iniPath, family: normalizedFamily, machineRoot: normalizedMachineRoot, pythonPathPrepend: normalizedPythonPathPrepend, topLevelPath: normalizedTopLevelPath, sourceFiles: normalizedSourceFiles, remapDeclarations: normalizedRemapDeclarations, pythonRemapFunctions: normalizedPythonRemapFunctions, prologFunctions: normalizedPrologFunctions, epilogFunctions: normalizedEpilogFunctions, ngcRemapFiles: normalizedNgcRemapFiles, ngcOnlySubpaths: normalizedNgcOnlySubpaths, runtimeMode, createRowRuntimePlan: rowPlan, async start() { assertOpen(); started = true; let adapterStartResult = {}; if (runtimeAdapter?.start) { adapterStartResult = await runtimeAdapter.start({ path, iniPath, family: normalizedFamily, machineRoot: normalizedMachineRoot, pythonPathPrepend: normalizedPythonPathPrepend, topLevelPath: normalizedTopLevelPath, sourceFiles: normalizedSourceFiles, remapDeclarations: normalizedRemapDeclarations, pythonRemapFunctions: normalizedPythonRemapFunctions, prologFunctions: normalizedPrologFunctions, epilogFunctions: normalizedEpilogFunctions, ngcRemapFiles: normalizedNgcRemapFiles, ngcOnlySubpaths: normalizedNgcOnlySubpaths, }); } runtimeExecutionReady = adapterStartResult.runtimeExecutionReady === true; startStatus = adapterStartResult.status ?? (runtimeExecutionReady ? "python_remap_row_runtime_adapter_started" : null); return { runtimeMode, runtimeExecutionReady, status: startStatus, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; }, async runRowRuntimePlan(plan = rowPlan()) { assertOpen(); if (!started) { throw new Error("PythonRemapRowRuntimePort must be started before runRowRuntimePlan()."); } if (!runtimeAdapter || runtimeExecutionReady !== true) { return { status: runtimeAdapter ? (startStatus ?? "blocked_row_runtime_execution_not_ready") : "blocked_row_runtime_adapter_required", plan: clonePlan(plan), runtimeExecutionReady: false, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; } for (const step of plan) { await runStep(step); } return { status: "row_runtime_adapter_plan_executed", plan: clonePlan(plan), transcript: this.exportTranscript(), validation: validation(), runtimeExecutionReady: true, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; }, exportTranscript() { return transcript.map((entry) => ({ ...entry })); }, exportDiagnostics() { const rowValidation = validation(); return { contractVersion: PYTHON_REMAP_RUNTIME_PORT_CONTRACT_VERSION, runtimeMode, runtimeExecutionReady, path, iniPath, family: normalizedFamily, machineRoot: normalizedMachineRoot, pythonPathPrepend: normalizedPythonPathPrepend, topLevelPath: normalizedTopLevelPath, sourceFiles: [...normalizedSourceFiles], remapDeclarations: [...normalizedRemapDeclarations], pythonRemapFunctions: [...normalizedPythonRemapFunctions], prologFunctions: [...normalizedPrologFunctions], epilogFunctions: [...normalizedEpilogFunctions], ngcRemapFiles: [...normalizedNgcRemapFiles], ngcOnlySubpaths: [...normalizedNgcOnlySubpaths], rowRuntimeTranscriptReady: rowValidation.rowRuntimeTranscriptReady, moduleImportReady: rowValidation.moduleImportReady, callableLookupReady: rowValidation.callableLookupReady, generatorLifecycleReady: rowValidation.generatorLifecycleReady, ngcRemapAssetsReady: rowValidation.ngcRemapAssetsReady, ngcOnlySubpathsGuarded: rowValidation.ngcOnlySubpathsGuarded, interpreterStateBindingReady: rowValidation.interpreterStateBindingReady, canonicalEventsReady: rowValidation.canonicalEventsReady, transcriptHash: stableTextHash(transcriptText(transcript)), transcriptPhaseCount: transcript.length, linuxCncOwnedLifecycle: true, jsCncSemantics: false, ngcOnlySubroutinePromoted: false, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; }, async close() { if (runtimeAdapter?.close) { await runtimeAdapter.close(); } closed = true; return { closed, executionEnabled: false, promotionAllowed: false, bulkPromotionAllowed: false, }; }, }; }