import type { ManualPrimaryExecutionRouter } from '../compatibility/manualPrimaryExecutionBridge'; import type { RuntimeRolloutPolicy } from '../domain/runtimeRollout'; import type { RuntimeRolloutLoadAudit, RuntimeRolloutLoadResult, } from '../ports/runtimeRolloutLoader'; import type { ManualPrimaryRuntimeReceiptLifecycle } from '../ports/manualPrimaryRuntimeReceipt'; import type { PrimaryCancellationStopResult } from './primaryCancellationLifecycle'; import type { PrimaryCompletionReceiptStopResult } from './primaryCompletionReceiptLifecycle'; import type { PrimaryRunStartupSummary } from './primaryRunStartupSupervisor'; import type { PrimaryTimeoutStopResult } from './primaryTimeoutLifecycle'; export type ManualPrimaryActivationState = | 'not_activated' | 'selected' | 'reconciled' | 'activated' | 'failed' | 'stopped'; export interface ManualPrimaryActivationAudit extends RuntimeRolloutLoadAudit { activation: ManualPrimaryActivationState; recovery?: { scanned: number; verifiedRunning: number; recoveredRunning: number; completedFromReceipt: number; quarantinedReceipts: number; publishGraceWaits: number; markedLost: number; }; } export interface ManualPrimaryActivationStack { router: ManualPrimaryExecutionRouter; reconcile(): Promise; startCompletion(): boolean; stopCompletion(): Promise; startTimeout(): boolean; stopTimeout(): Promise; startCancellation(): boolean; stopCancellation(): Promise; } export interface ManualPrimaryRuntimeActivationOptions { load(): Promise; create(policy: RuntimeRolloutPolicy): ManualPrimaryActivationStack; install(router: ManualPrimaryExecutionRouter): () => void; audit(record: ManualPrimaryActivationAudit): void | Promise; receipt?: ManualPrimaryRuntimeReceiptLifecycle; } export interface ManualPrimaryRuntimeActivationResult { load: RuntimeRolloutLoadResult; active: boolean; recovery?: PrimaryRunStartupSummary; stop(): Promise; } const NOOP_STOP = async (): Promise => 'drained'; async function stopLifecycles( stack: ManualPrimaryActivationStack, started: { completion: boolean; timeout: boolean; cancellation: boolean }, ): Promise { let result: PrimaryCancellationStopResult = 'drained'; let firstError: unknown; if (started.timeout) { try { if ((await stack.stopTimeout()) === 'timed_out') result = 'timed_out'; } catch (error) { firstError = error; } } if (started.cancellation) { try { if ((await stack.stopCancellation()) === 'timed_out') { result = 'timed_out'; } } catch (error) { firstError ??= error; } } if (started.completion) { try { if ((await stack.stopCompletion()) === 'timed_out') { result = 'timed_out'; } } catch (error) { firstError ??= error; } } if (firstError !== undefined) throw firstError; return result; } function assertSafeRecovery(summary: PrimaryRunStartupSummary): void { if ( summary.remaining || summary.stopReason !== 'complete' || summary.skipped > 0 || summary.ambiguous > 0 || summary.failed > 0 ) { throw new Error('Primary startup reconciliation did not converge safely'); } } function recoveryAudit(summary: PrimaryRunStartupSummary) { return { scanned: summary.scanned, verifiedRunning: summary.verifiedRunning, recoveredRunning: summary.recoveredRunning, completedFromReceipt: summary.completedFromReceipt, quarantinedReceipts: summary.quarantinedReceipts, publishGraceWaits: summary.publishGraceWaits, markedLost: summary.markedLost, }; } export async function activateManualPrimaryRuntime( options: ManualPrimaryRuntimeActivationOptions, ): Promise { const load = await options.load(); const shouldActivate = load.status === 'accepted' && load.policy.modeFor('manual') === 'primary'; if (!shouldActivate) { await options.audit({ ...load.audit, activation: 'not_activated' }); return { load, active: false, stop: NOOP_STOP }; } let stack: ManualPrimaryActivationStack | undefined; let dispose: (() => void) | undefined; let completionStarted = false; let timeoutStarted = false; let cancellationStarted = false; try { await options.audit({ ...load.audit, activation: 'selected' }); stack = options.create(load.policy); const recovery = await stack.reconcile(); assertSafeRecovery(recovery); await options.audit({ ...load.audit, activation: 'reconciled', recovery: recoveryAudit(recovery), }); completionStarted = stack.startCompletion(); if (!completionStarted) { throw new Error('Primary completion lifecycle did not start'); } timeoutStarted = stack.startTimeout(); if (!timeoutStarted) { throw new Error('Primary timeout lifecycle did not start'); } cancellationStarted = stack.startCancellation(); if (!cancellationStarted) { throw new Error('Primary cancellation lifecycle did not start'); } dispose = options.install(stack.router); await options.receipt?.activated(load.audit); await options.audit({ ...load.audit, activation: 'activated', recovery: recoveryAudit(recovery), }); let stopPromise: Promise | undefined; return { load, active: true, recovery, async stop() { stopPromise ??= (async () => { let receiptError: unknown; try { await options.receipt?.stopping(); } catch (error) { receiptError = error; } dispose?.(); let result: PrimaryCancellationStopResult = 'drained'; let lifecycleError: unknown; try { result = await stopLifecycles(stack!, { completion: completionStarted, timeout: timeoutStarted, cancellation: cancellationStarted, }); } catch (error) { lifecycleError = error; } if (receiptError === undefined && lifecycleError === undefined) { try { await options.receipt?.stopped(); } catch (error) { receiptError = error; } } if (receiptError !== undefined || lifecycleError !== undefined) { try { await options.receipt?.failed(); } catch { // Preserve the first stop failure; a non-active receipt is best effort. } throw receiptError ?? lifecycleError; } try { await options.audit({ ...load.audit, activation: 'stopped', recovery: recoveryAudit(recovery), }); } catch { // Cleanup must not be reversed by a diagnostic failure. } return result; })(); return stopPromise; }, }; } catch (error) { dispose?.(); if (stack && (completionStarted || timeoutStarted || cancellationStarted)) { try { await stopLifecycles(stack, { completion: completionStarted, timeout: timeoutStarted, cancellation: cancellationStarted, }); } catch { // Preserve the activation error after best-effort cleanup. } } try { await options.receipt?.failed(); } catch { // Preserve the activation failure; liveness checks still reject stale state. } try { await options.audit({ ...load.audit, activation: 'failed' }); } catch { // Preserve the activation error while ownership remains uninstalled. } throw error; } }