import { createHash, randomUUID } from 'node:crypto';
import { generalizedErrorMessage } from '@maka/core';
import { emptyPlanSessionState } from '@maka/core';
import { isDeepResearchSession } from '@maka/core';
import { filterModelVisibleTaskLedgerTasks } from '@maka/core';
import {
  AgentGraphCoordinator,
  AgentGraphSupervisorWakeCoordinator,
  agentGraphIdForRootSession,
  BackendRegistry,
  buildToolsForAgentDefinition,
  buildHostCapabilitiesFromBinding,
  createLocalContinuationSafetyInspector,
  createConfiguredSubagentCatalog,
  createBuiltinSandboxManager,
  createFilesystemWorkerLaunchSpecProvider,
  FakeBackend,
  FilesystemWorkerClient,
  isOAuthEnrollmentProviderEnabled,
  isBuiltinFilesystemWorkerSandboxAvailable,
  loadLatestHistoryCompactCheckpointFromRunLedger,
  prepareSkillInvocationMessageFromInventory,
  RuntimeReadModel,
  routeWebSearchTools,
  renderAgentSwarmSupervisorWake,
  SessionManager,
  shouldWakeAgentSwarmSupervisor,
  SessionActivityRegistry,
  ShellRunProcessManager,
  type BackendFactory,
  type MakaTool,
  type RuntimeHostedRootAuthority,
} from '@maka/runtime';
import { createAgentGraphControlStore } from '@maka/storage/agent-graph-control-store';
import {
  createArtifactAttachmentResourceReader,
  createReadImageSnapshotter,
  openInteractiveArtifactStoreForWrite,
} from '@maka/storage/artifact-stores';
import { openInteractiveAutomationAuthorityForWrite } from '@maka/storage/automation-authority';
import { openInteractiveDeepResearchStoreForWrite } from '@maka/storage/deep-research-authority';
import { openInteractiveDailyReviewAuthorityForWrite } from '@maka/storage/daily-review-authority';
import { openInteractivePlanStoreForWrite } from '@maka/storage/plan-authority';
import {
  isSessionNotFoundError,
  openInteractiveExecutionStoresForWrite,
} from '@maka/storage/execution-stores';
import { createExternalSessionAdapterRegistry } from '@maka/storage/external-sessions';
import { createGitWorktreeChildExecutor } from '@maka/storage/git-worktree-child-executor';
import {
  type InteractiveLongTermMemoryWriter,
  openInteractiveLongTermMemoryStoreForWrite,
} from '@maka/storage/long-term-memory-store';
import { openInteractiveMemoryBundleStoreForWrite } from '@maka/storage/memory-bundle-store';
import { runWithStorageRootLease } from '@maka/storage/root-authority';
import { openInteractiveRuntimePolicyStoresForWrite } from '@maka/storage/runtime-policy-stores';
import { openInteractiveTaskLedgerStoreForWrite } from '@maka/storage/task-ledger-authority';
import { openInteractiveShellRunStoreForWrite } from '@maka/storage/shell-run-authority';
import { openInteractiveUsageStoresForWrite } from '@maka/storage/usage-stores';
import { resolveWorkspaceIdentity } from '@maka/storage/workspace-identity';
import {
  openManagedWorkspaceOwner,
  type ManagedWorkspaceFilesystemWorker,
  type ManagedWorkspaceOwner,
  type VerifiedGitRuntimeInput,
} from '@maka/storage/managed-workspace-owner';
import { CanonicalSessionProjectionReader } from './canonical-session-projection.js';
import {
  bindHostChildAgentBackend,
  createHostChildAgentToolComposition,
} from './child-agent-composition.js';
import { HostCanonicalPermissionOutcomeReader } from './canonical-permission-outcome-reader.js';
import { HostArtifactCoordinator } from './artifact-coordinator.js';
import { HostAgentGraphCoordinator } from './agent-graph-coordinator.js';
import { HostAutomationCoordinator } from './automation-coordinator.js';
import { recoverClientCapabilityOutcomes } from './client-capability-recovery.js';
import { HostConnectionEffectCoordinator } from './connection-effect-coordinator.js';
import { HostConfigurationChangeService } from './configuration-change-service.js';
import { HostSessionCatalogChangeService } from './session-catalog-change-service.js';
import { HostConfigurationCoordinator } from './configuration-coordinator.js';
import { HostClientCapabilityCoordinator } from './client-capability-coordinator.js';
import { HostDeepResearchCoordinator } from './deep-research-coordinator.js';
import { HostDailyReviewCoordinator } from './daily-review-coordinator.js';
import {
  createHostAiSdkBackend,
  createHostExecutionModelComposition,
} from './execution-model-composition.js';
import {
  createHostGoalEvaluator,
  createHostDailyReviewModel,
  createHostMemoryExtractionModel,
  createHostSessionEffectModel,
} from './execution-model-authority.js';
import { HostExecutionInspectCoordinator } from './execution-inspect-coordinator.js';
import { HostExternalSessionCoordinator } from './external-session-coordinator.js';
import { HostGoalCoordinator } from './goal-coordinator.js';
import type { RuntimeHostComposition, RuntimeHostCompositionContext } from './host-kernel.js';
import { HostInteractionCoordinator } from './interaction-coordinator.js';
import { migrateLegacyRuntimePolicy } from './legacy-runtime-policy-migration.js';
import { ensureBootstrapRuntimePolicy } from './bootstrap-runtime-policy.js';
import { HostMemoryCoordinator } from './memory-coordinator.js';
import { HostMemoryExtractionCoordinator } from './memory-extraction-coordinator.js';
import { MemoryExtractionSessionLane } from './memory-extraction-session-lane.js';
import { type HostMessageRootPort, HostMessageCoordinator } from './message-coordinator.js';
import { HostNetworkProxyCoordinator } from './network-proxy-coordinator.js';
import { HostOAuthExecutionAuthority } from './oauth-execution-authority.js';
import { HostOAuthCoordinator, type HostOAuthCoordinatorInput } from './oauth-coordinator.js';
import { HostPlanCoordinator } from './plan-coordinator.js';
import type { DomainOperationHandlerMap } from './operation-dispatcher.js';
import { RootAdmissionOwner } from './root-admission-owner.js';
import { RootTurnCoordinator } from './root-turn-coordinator.js';
import { RuntimePolicyActivationGate } from './runtime-policy-activation-gate.js';
import { notifySandboxBoundaryGraphWake } from './sandbox-boundary-graph-wake.js';
import { HostRuntimePolicyCoordinator } from './runtime-policy-coordinator.js';
import { HostRuntimeResourceCoordinator } from './runtime-resource-coordinator.js';
import { SessionAdmissionGate } from './session-admission-gate.js';
import { HostSessionCatalogCoordinator } from './session-catalog-coordinator.js';
import { HostSessionRetirementCoordinator } from './session-retirement-coordinator.js';
import { HostSessionRevisionCoordinator } from './session-revision-coordinator.js';
import { HostSessionEffectCoordinator } from './session-effect-coordinator.js';
import { SessionContinuityCoordinator } from './session-continuity-coordinator.js';
import { createSessionTranscriptReader } from './session-transcript-reader.js';
import { HostSkillCatalogCoordinator } from './skill-catalog-coordinator.js';
import { SkillCatalogRepository } from './skill-catalog-repository.js';
import { HostTaskLedgerCoordinator } from './task-ledger-coordinator.js';
import { HostUsagePricingCoordinator } from './usage-pricing-coordinator.js';
import { HostWebSearchCoordinator } from './web-search-coordinator.js';
import {
  createHostWebSearchService,
  createHostWebSearchToolFromService,
} from './web-search-tool.js';
import { createHostWebFetchService, createHostWebFetchToolFromService } from './web-fetch-tool.js';
import { createHostExecutionArtifactServices } from './execution-artifacts.js';
import {
  createRuntimeHostWorkspaceExecutionComposition,
  RuntimeHostWorkspaceExecutionError,
  type RuntimeHostWorkspaceExecutionComposition,
} from './workspace-execution-composition.js';

export interface ExecutionRuntimeHostComposition extends RuntimeHostComposition {
  readonly workspaceExecution: RuntimeHostWorkspaceExecutionComposition;
}

export interface CreateExecutionRuntimeHostCompositionOptions {
  readonly managedWorkspaceGitRuntime?: VerifiedGitRuntimeInput;
  readonly legacyConfigurationRoot?: string;
  readonly bootstrapRuntimePolicy?: boolean;
  readonly skillHomeDirectory?: string;
}

export interface ExecutionRuntimeHostCompositionDependencies {
  readonly primaryBackendFactory?: BackendFactory;
  readonly oauthAuthorization?: Pick<
    HostOAuthCoordinatorInput,
    'startCodexAuthorization' | 'pollCodexAuthorization' | 'exchangeCodexCode'
  >;
}

export function runtimeHostFilesystemWorkerRuntime(versions: {
  readonly electron?: string;
}): 'electron' | 'node' {
  return versions.electron ? 'electron' : 'node';
}

export async function createExecutionRuntimeHostComposition(
  context: RuntimeHostCompositionContext,
  options: CreateExecutionRuntimeHostCompositionOptions = {},
  dependencies: ExecutionRuntimeHostCompositionDependencies = {},
): Promise<ExecutionRuntimeHostComposition> {
  const stores = await openInteractiveExecutionStoresForWrite(context.owner.lease);
  let graphControlStore: ReturnType<typeof createAgentGraphControlStore> | undefined;
  let taskLedgerStore:
    | Awaited<ReturnType<typeof openInteractiveTaskLedgerStoreForWrite>>
    | undefined;
  let usageStores: Awaited<ReturnType<typeof openInteractiveUsageStoresForWrite>> | undefined;
  let artifactStore: Awaited<ReturnType<typeof openInteractiveArtifactStoreForWrite>> | undefined;
  let shellRunStore: Awaited<ReturnType<typeof openInteractiveShellRunStoreForWrite>> | undefined;
  let longTermMemoryStore: InteractiveLongTermMemoryWriter | undefined;
  let automationStore:
    | Awaited<ReturnType<typeof openInteractiveAutomationAuthorityForWrite>>
    | undefined;
  let planStore: Awaited<ReturnType<typeof openInteractivePlanStoreForWrite>> | undefined;
  let deepResearchStore:
    | Awaited<ReturnType<typeof openInteractiveDeepResearchStoreForWrite>>
    | undefined;
  let dailyReviewStore:
    | Awaited<ReturnType<typeof openInteractiveDailyReviewAuthorityForWrite>>
    | undefined;
  let graphClient: HostAgentGraphCoordinator | undefined;
  let sessionEffects: HostSessionEffectCoordinator | undefined;
  let memoryExtraction: HostMemoryExtractionCoordinator | undefined;
  let unsubscribeTaskLedger: (() => void) | undefined;
  let managedWorkspaceOwner: ManagedWorkspaceOwner | undefined;
  let workspaceExecution: RuntimeHostWorkspaceExecutionComposition | undefined;
  try {
    const runtimePolicyStores = await openInteractiveRuntimePolicyStoresForWrite(
      context.owner.lease,
    );
    await migrateLegacyRuntimePolicy({
      workspaceRoot: context.owner.capability.canonicalPath,
      ...(options.legacyConfigurationRoot
        ? { legacyConfigurationRoot: options.legacyConfigurationRoot }
        : {}),
      stores: runtimePolicyStores,
    });
    if (options.bootstrapRuntimePolicy !== false) {
      await ensureBootstrapRuntimePolicy({
        workspaceRoot: context.owner.capability.canonicalPath,
        stores: runtimePolicyStores,
        onDeferredError: (error) =>
          console.error(
            `[runtime-host] optional bootstrap target could not be configured: ${generalizedErrorMessage(error)}`,
          ),
      });
    }
    const oauthCredentials = new HostOAuthExecutionAuthority(runtimePolicyStores);
    const openedAutomationStore = await openInteractiveAutomationAuthorityForWrite(
      context.owner.lease,
    );
    automationStore = openedAutomationStore;
    const openedPlanStore = await openInteractivePlanStoreForWrite(context.owner.lease);
    planStore = openedPlanStore;
    const openedDeepResearchStore = await openInteractiveDeepResearchStoreForWrite(
      context.owner.lease,
    );
    deepResearchStore = openedDeepResearchStore;
    const openedDailyReviewStore = await openInteractiveDailyReviewAuthorityForWrite(
      context.owner.lease,
    );
    dailyReviewStore = openedDailyReviewStore;
    const memoryStore = await openInteractiveMemoryBundleStoreForWrite(context.owner.lease);
    longTermMemoryStore = await openInteractiveLongTermMemoryStoreForWrite(context.owner.lease);
    taskLedgerStore = await openInteractiveTaskLedgerStoreForWrite(context.owner.lease);
    const openedArtifactStore = await openInteractiveArtifactStoreForWrite(context.owner.lease);
    artifactStore = openedArtifactStore;
    const openedUsageStores = await openInteractiveUsageStoresForWrite(context.owner.lease);
    usageStores = openedUsageStores;
    const openedShellRunStore = await openInteractiveShellRunStoreForWrite(context.owner.lease);
    shellRunStore = openedShellRunStore;
    const worktreeChildExecutor = createGitWorktreeChildExecutor({
      storageRoot: context.owner.capability.canonicalPath,
    });
    await stores.messageReceiptStore.beginHostEpoch(context.hostEpoch);
    const backends = new BackendRegistry();
    backends.register('fake', (backendContext) => new FakeBackend(backendContext));
    const runtimePolicyActivation = new RuntimePolicyActivationGate();
    const runtimePolicy = new HostRuntimePolicyCoordinator(
      runtimePolicyStores,
      runtimePolicyActivation,
      applyRuntimePolicyMutationEffects,
    );
    const sessionAdmission = new SessionAdmissionGate();
    const memoryExtractionLane = new MemoryExtractionSessionLane();
    let runtimeResources: HostRuntimeResourceCoordinator | undefined;
    let continuity: SessionContinuityCoordinator | undefined;
    let manager: SessionManager | undefined;
    let graphCoordinator: AgentGraphCoordinator | undefined;
    let graphSupervisorWake: AgentGraphSupervisorWakeCoordinator | undefined;
    const graphWakeActivities = new SessionActivityRegistry();
    const shellRuns = new ShellRunProcessManager({
      store: openedShellRunStore,
      newId: randomUUID,
      now: Date.now,
      onShellRunUpdate: (update) => runtimeResources?.observeShellRunUpdate(update),
      onPtyData: (event) => {
        void continuity?.enqueueRuntimeResourcePtyData(event);
      },
    });
    const sandboxManager = createBuiltinSandboxManager();
    const filesystemWorkerLaunchSpecProvider =
      sandboxManager && isBuiltinFilesystemWorkerSandboxAvailable()
        ? createFilesystemWorkerLaunchSpecProvider({
            runtime: runtimeHostFilesystemWorkerRuntime({
              electron: process.versions.electron,
            }),
            platform: process.platform,
            resourceLocation: { kind: 'runtime' },
          })
        : undefined;
    const filesystemWorker =
      sandboxManager && filesystemWorkerLaunchSpecProvider
        ? new FilesystemWorkerClient({
            sandboxManager,
            getLaunchSpec: filesystemWorkerLaunchSpecProvider,
          })
        : undefined;
    const managedFilesystemWorker = filesystemWorker
      ? adaptManagedWorkspaceFilesystemWorker(filesystemWorker)
      : undefined;
    if (options.managedWorkspaceGitRuntime) {
      if (!managedFilesystemWorker) {
        throw new RuntimeHostWorkspaceExecutionError(
          'filesystem_worker_unavailable',
          'Managed workspace execution requires the sandboxed filesystem worker',
        );
      }
      managedWorkspaceOwner = await openManagedWorkspaceOwner({
        rootOwner: context.owner,
        gitRuntime: options.managedWorkspaceGitRuntime,
        filesystemWorker: managedFilesystemWorker,
      });
    }
    workspaceExecution = createRuntimeHostWorkspaceExecutionComposition({
      ...(managedFilesystemWorker ? { filesystemWorker: managedFilesystemWorker } : {}),
      ...(managedWorkspaceOwner ? { managedOwner: managedWorkspaceOwner } : {}),
    });
    const taskLedger = new HostTaskLedgerCoordinator(
      taskLedgerStore,
      sessionAdmission,
      stores.sessionStore,
    );
    runtimeResources = new HostRuntimeResourceCoordinator({
      manager: shellRuns,
      sessions: {
        listShellRunUpdates: (sessionId) =>
          requireSessionManager(manager).listShellRunUpdates(sessionId),
        getShellRunUpdate: (sessionId, ref) =>
          requireSessionManager(manager).getShellRunUpdate(sessionId, ref),
      },
      sessionHeaders: stores.sessionStore,
      sessionAdmission,
      acquireResidency: context.acquireResidency,
      requestDrain: context.requestDrain,
      onProjectionChanged: (update) =>
        requireContinuity(continuity).enqueueRuntimeResourceChanged(update),
    });
    const executionArtifacts = createHostExecutionArtifactServices({
      artifacts: openedArtifactStore,
      requestDrain: context.requestDrain,
    });
    const builtinTools = {
      shellRuns: runtimeResources,
      runtimeResources,
      attachmentResources: createArtifactAttachmentResourceReader({
        artifactStore: openedArtifactStore,
      }),
      backgroundTasks: runtimeResources,
      ptyControls: runtimeResources,
      snapshotImage: createReadImageSnapshotter(openedArtifactStore),
      ...(sandboxManager ? { sandboxManager } : {}),
      ...(filesystemWorker ? { filesystemWorker } : {}),
    };
    const webSearchService = createHostWebSearchService({
      policy: runtimePolicyStores.operations,
    });
    const webFetchService = createHostWebFetchService({
      policy: runtimePolicyStores.operations,
    });
    const hostTools = [
      createHostWebSearchToolFromService(webSearchService),
      createHostWebFetchToolFromService(webFetchService),
      ...runtimePolicy.modelTools,
    ];
    const childAgentTools = createHostChildAgentToolComposition({
      taskLedger,
      builtinTools,
      hostTools,
      worktreePatchWriteBackAvailable: true,
    });
    const openedGraphControlStore = createAgentGraphControlStore(
      context.owner.capability.canonicalPath,
    );
    graphControlStore = openedGraphControlStore;
    let resolveAvailableToolNames: ((sessionId: string) => Promise<string[]>) | undefined;
    let resolveNewSessionToolNames:
      | ((
          previewSessionId: string,
          collaborationMode: 'agent' | 'plan',
          initiatingConnectionId: string,
        ) => Promise<string[]>)
      | undefined;
    const skills = new HostSkillCatalogCoordinator(
      new SkillCatalogRepository({
        runWithRoot: (operation) =>
          runWithStorageRootLease(context.owner.lease, 'interactive', 'write', operation),
        ...(options.skillHomeDirectory ? { homeDirectory: options.skillHomeDirectory } : {}),
      }),
      async (input, connection) => {
        if (input.target.kind === 'session') {
          const sessionId = input.target.sessionId;
          const header = await stores.sessionStore.readHeaderSnapshot(sessionId);
          const preview = await requireClientCapabilities(
            clientCapabilities,
          ).runWithSessionBindingPreview(sessionId, connection.connectionId, () =>
            requireToolNameResolver(resolveAvailableToolNames)(sessionId),
          );
          if (!preview.ok) throw new Error(preview.message);
          return {
            projectRoot: header.cwd,
            host: buildHostCapabilitiesFromBinding(preview.value),
          };
        }
        const previewSessionId = `skill-catalog-preview:${connection.connectionId}`;
        return {
          projectRoot: input.target.context.projectRoot,
          host: buildHostCapabilitiesFromBinding(
            await requireNewSessionToolNameResolver(resolveNewSessionToolNames)(
              previewSessionId,
              input.target.collaborationMode,
              connection.connectionId,
            ),
          ),
        };
      },
    );
    const configurationChanges = new HostConfigurationChangeService();
    const sessionCatalogChanges = new HostSessionCatalogChangeService();
    let rootCoordinator: RootTurnCoordinator | undefined;
    let canonicalProjection: CanonicalSessionProjectionReader | undefined;
    let memory: HostMemoryCoordinator | undefined;
    let clientCapabilities: HostClientCapabilityCoordinator | undefined;
    let oauth: HostOAuthCoordinator | undefined;
    let automations: HostAutomationCoordinator | undefined;
    let goal: HostGoalCoordinator | undefined;
    let deepResearch: HostDeepResearchCoordinator | undefined;
    let dailyReview: HostDailyReviewCoordinator | undefined;
    const rootPort: HostMessageRootPort = {
      readSessionHeader: (sessionId) =>
        requireRootCoordinator(rootCoordinator).readSessionHeader(sessionId),
      readRootState: (sessionId) =>
        requireRootCoordinator(rootCoordinator).readRootState(sessionId),
      claimStopFence: (input, commitQueueFence, admission) =>
        requireRootCoordinator(rootCoordinator).claimStopFence(input, commitQueueFence, admission),
      startFromMessage: (input, admission) =>
        requireRootCoordinator(rootCoordinator).startFromMessage(input, admission),
      prepareMessage: (input) => requireRootCoordinator(rootCoordinator).prepareMessage(input),
      claimStop: (input, commitQueueFence, admission) =>
        requireRootCoordinator(rootCoordinator).claimStop(input, commitQueueFence, admission),
    };
    const messages = new HostMessageCoordinator({
      hostEpoch: context.hostEpoch,
      root: rootPort,
      durableProof: {
        readRootTurnSourceMessageReceipt: (sessionId, messageId) =>
          stores.agentRunStore.readRootTurnSourceMessageReceipt(sessionId, messageId),
        readImmutableSteeringMessageProof: (sessionId, messageId) =>
          stores.runtimeEventStore.readImmutableSteeringMessageProof(sessionId, messageId),
      },
      receipts: stores.messageReceiptStore,
      sessionAdmission,
      acquireResidency: context.acquireResidency,
      requestDrain: context.requestDrain,
      preflightSessionSnapshot: (sessionId, candidate) =>
        requireCanonicalProjection(canonicalProjection).fitsCandidate(sessionId, candidate),
      onProjectionChanged: (sessionId) =>
        requireContinuity(continuity).enqueueCanonicalRefresh(sessionId),
    });
    const rootAdmissionOwner = new RootAdmissionOwner(stores.agentRunStore);
    const canonicalProjectionReader = new CanonicalSessionProjectionReader({
      stores,
      rootAdmissions: rootAdmissionOwner,
      messages,
      readGoal: (sessionId) => requireGoal(goal).readProjection(sessionId),
    });
    canonicalProjection = canonicalProjectionReader;
    const canonicalPermissionOutcomes = new HostCanonicalPermissionOutcomeReader({
      store: stores.interactionStore,
    });
    continuity = new SessionContinuityCoordinator(
      context.hostEpoch,
      (sessionId) => canonicalProjectionReader.read(sessionId),
      sessionAdmission,
      context.requestDrain,
      createSessionTranscriptReader({ stores, canonicalPermissionOutcomes }),
      (sessionId) => sessionCatalogChanges.publish(sessionId),
    );
    const continuityCoordinator = continuity;
    unsubscribeTaskLedger = taskLedger.subscribe(({ sessionId }) =>
      continuityCoordinator.enqueueSessionDomainChanged(sessionId, 'task'),
    );
    deepResearch = new HostDeepResearchCoordinator({
      store: openedDeepResearchStore,
      artifacts: openedArtifactStore,
      sessions: stores.sessionStore,
      sessionAdmission,
      onProjectionChanged: (sessionId) =>
        continuityCoordinator.enqueueSessionDomainChanged(sessionId, 'deep_research'),
    });
    dailyReview = new HostDailyReviewCoordinator({
      store: openedDailyReviewStore,
      usage: openedUsageStores,
      sessions: stores.sessionStore,
      readRunEvents: (sessionId, runId) => stores.agentRunStore.readEvents(sessionId, runId),
      model: createHostDailyReviewModel({
        runtimePolicy: runtimePolicyStores,
        oauthCredentials,
        claudeDeviceId: context.owner.capability.rootId,
        usage: openedUsageStores,
        requestDrain: context.requestDrain,
      }),
      acquireResidency: context.acquireResidency,
      requestDrain: context.requestDrain,
    });
    let poisonFailure: Error | undefined;
    let draining = false;
    let recoveryTask: Promise<void> | undefined;
    let rootCloseTask: Promise<void> | undefined;
    let rootRecoveryCompleted = false;
    let closeTask: Promise<void> | undefined;
    let backendInvalidationPoisoned = false;
    const beginDrain = () => {
      if (draining) return;
      draining = true;
      workspaceExecution?.beginDrain();
      goal?.beginDrain();
      rootCoordinator?.beginDrain();
      runtimeResources?.beginDrain();
      automations?.beginDrain();
      dailyReview?.beginDrain();
      messages.beginDrain();
      interactions.beginDrain();
      connectionEffects.beginDrain();
      sessionEffects?.beginDrain();
      skills.beginDrain();
      memory?.beginDrain();
      memoryExtraction?.beginDrain();
      oauth?.beginDrain();
      clientCapabilities?.beginDrain();
    };
    const interactions = new HostInteractionCoordinator({
      store: stores.interactionStore,
      sandboxBoundaries: stores.sessionStore,
      sessionAdmission,
      sessions: stores.sessionStore,
      preflightSessionSnapshot: (sessionId, interactionProjection) =>
        canonicalProjectionReader.fitsCandidate(sessionId, {
          interactions: interactionProjection,
        }),
      refreshCanonicalContinuity: (sessionId, admission) =>
        continuityCoordinator.refreshCanonical(sessionId, admission),
      onPoison: (error) => {
        if (poisonFailure) return;
        poisonFailure = error;
        context.retainUntilProcessExit();
        beginDrain();
        context.requestDrain();
      },
      onSandboxBoundarySettled: (sessionId) =>
        notifySandboxBoundaryGraphWake(sessionId, stores.sessionStore, (rootSessionId) =>
          requireGraphSupervisorWake(graphSupervisorWake).notifyPermissionResponse(rootSessionId),
        ),
    });
    memory = new HostMemoryCoordinator({
      store: memoryStore,
      runtimePolicyStores,
      activation: runtimePolicyActivation,
      requestDrain: context.requestDrain,
    });
    memoryExtraction = new HostMemoryExtractionCoordinator({
      store: longTermMemoryStore,
      policy: runtimePolicyStores.runtimePolicy,
      sessions: {
        readHeader: (sessionId) => stores.sessionStore.readHeaderSnapshot(sessionId),
      },
      runtimeEvents: {
        readSessionRuntimeEventEntries: (sessionId) =>
          stores.runtimeEventStore.readSessionRuntimeEventEntries(sessionId),
      },
      historyCompaction: {
        readLatestCheckpoint: (sessionId) =>
          loadLatestHistoryCompactCheckpointFromRunLedger(stores.agentRunStore, sessionId),
      },
      model: createHostMemoryExtractionModel({
        runtimePolicy: runtimePolicyStores,
        oauthCredentials,
        claudeDeviceId: context.owner.capability.rootId,
        usage: openedUsageStores,
        requestDrain: context.requestDrain,
      }),
      lane: memoryExtractionLane,
      acquireResidency: context.acquireResidency,
    });
    backends.register(
      'ai-sdk',
      dependencies.primaryBackendFactory ??
        ((backendContext) =>
          createHostAiSdkBackend({
            context: backendContext,
            runtimePolicy: runtimePolicyStores,
            oauthCredentials,
            claudeDeviceId: context.owner.capability.rootId,
            skills,
            memory: requireMemory(memory),
            memoryExtraction,
            taskLedger,
            artifacts: openedArtifactStore,
            executionArtifacts,
            usage: openedUsageStores,
            clientCapabilities: requireClientCapabilities(clientCapabilities),
            automationTool: requireAutomationCoordinator(automations).modelTool,
            planStore: openedPlanStore,
            deepResearchTools: requireDeepResearch(deepResearch).toolsForSession(
              backendContext.sessionId,
            ),
            goalTools: requireGoal(goal).tools,
            builtinTools,
            hostTools,
            resolveRootTools: (sessionId) =>
              requireGraphCoordinator(graphCoordinator).toolsForSession(sessionId),
            parentAgentTools: childAgentTools.parentTools,
            childTools: childAgentTools.childTools,
            worktreePatchWriteBackAvailable: true,
            childAgents: bindHostChildAgentBackend(
              requireSessionManager(manager),
              backendContext.sessionId,
            ),
            runtimeCommitSink: stores.runtimeEventStore,
            requestDrain: context.requestDrain,
          })),
    );
    const runtimeAuthority: RuntimeHostedRootAuthority = {
      bindRun: (identity) => messages.bindRun(identity),
      executeRoot: (input) => requireRootCoordinator(rootCoordinator).executeRoot(input),
      stopRoot: (identity, input) =>
        requireRootCoordinator(rootCoordinator).stopRoot(identity, input),
      stopSession: (sessionId, input) =>
        requireRootCoordinator(rootCoordinator).stopSession(sessionId, input),
    };
    resolveAvailableToolNames = async (sessionId: string): Promise<string[]> => {
      const header = await stores.sessionStore.readHeaderSnapshot(sessionId);
      if (header.subagentRuntime) {
        if (!header.subagentParent) {
          throw new Error('Subagent runtime snapshot requires a linked child session');
        }
        const tools = buildToolsForAgentDefinition(childAgentTools.childTools, {
          id: header.subagentRuntime.agentId,
          permissionMode: header.permissionMode,
          tools: header.subagentRuntime.toolNames,
        });
        if (tools.length !== header.subagentRuntime.toolNames.length) {
          throw new Error('Subagent runtime tool snapshot is unavailable');
        }
        return tools.map((tool) => tool.name);
      }
      if (header.subagentParent) {
        throw new Error('Linked child session is missing its durable runtime snapshot');
      }
      const capabilitySnapshot =
        requireClientCapabilities(clientCapabilities).snapshotForSession(sessionId);
      try {
        const graphTools =
          await requireGraphCoordinator(graphCoordinator).toolsForSession(sessionId);
        const planState = await openedPlanStore.readState(sessionId);
        return createHostExecutionModelComposition({
          policy: runtimePolicyStores.runtimePolicy,
          skills,
          memory: requireMemory(memory),
          taskLedger,
          ...(capabilitySnapshot ? { clientCapabilities: capabilitySnapshot } : {}),
          builtinTools,
          hostTools: [...hostTools, ...graphTools],
          automationTool: requireAutomationCoordinator(automations).modelTool,
          goalTools: requireGoal(goal).tools,
          parentAgentTools: childAgentTools.parentTools,
          plan: {
            store: openedPlanStore,
            state: planState,
            mode: header.collaborationMode ?? 'agent',
          },
          ...(isDeepResearchSession(header.labels)
            ? {
                deepResearch: {
                  tools: requireDeepResearch(deepResearch).toolsForSession(sessionId),
                },
              }
            : {}),
        }).tools.map((tool) => tool.name);
      } finally {
        capabilitySnapshot?.release();
      }
    };
    resolveNewSessionToolNames = async (
      previewSessionId,
      collaborationMode,
      initiatingConnectionId,
    ) => {
      const preview = await requireClientCapabilities(
        clientCapabilities,
      ).runWithSessionBindingPreview(previewSessionId, initiatingConnectionId, async () => {
        const capabilitySnapshot =
          requireClientCapabilities(clientCapabilities).snapshotForSession(previewSessionId);
        try {
          return createHostExecutionModelComposition({
            policy: runtimePolicyStores.runtimePolicy,
            skills,
            memory: requireMemory(memory),
            taskLedger,
            ...(capabilitySnapshot ? { clientCapabilities: capabilitySnapshot } : {}),
            builtinTools,
            hostTools,
            automationTool: requireAutomationCoordinator(automations).modelTool,
            goalTools: requireGoal(goal).tools,
            parentAgentTools: childAgentTools.parentTools,
            plan: {
              store: openedPlanStore,
              state: emptyPlanSessionState(previewSessionId),
              mode: collaborationMode,
            },
          }).tools.map((tool) => tool.name);
        } finally {
          capabilitySnapshot?.release();
        }
      });
      if (!preview.ok) throw new Error(preview.message);
      return preview.value;
    };
    const sessionEffectCoordinator = new HostSessionEffectCoordinator({
      model: createHostSessionEffectModel({
        runtimePolicy: runtimePolicyStores,
        oauthCredentials,
        claudeDeviceId: context.owner.capability.rootId,
        usage: openedUsageStores,
        requestDrain: context.requestDrain,
      }),
      readModel: new RuntimeReadModel({
        runStore: stores.agentRunStore,
        runtimeEventStore: stores.runtimeEventStore,
        projectionCache: stores.sessionStore,
        canonicalPermissionOutcomes,
      }),
      artifacts: openedArtifactStore,
      sessions: stores.sessionStore,
      readSessionHeader: (sessionId) => stores.sessionStore.readHeaderSnapshot(sessionId),
      sessionAdmission,
      acquireResidency: context.acquireResidency,
      requestDrain: context.requestDrain,
    });
    sessionEffects = sessionEffectCoordinator;
    const resolveChildTools = async (sessionId: string): Promise<readonly MakaTool[]> => {
      const header = await stores.sessionStore.readHeader(sessionId);
      const [resolved, snapshot] = await Promise.all([
        runtimePolicyStores.operations.resolveExecutionConnection(header.llmConnectionSlug),
        runtimePolicyStores.runtimePolicy.getSnapshot(),
      ]);
      if (resolved.kind !== 'ready') {
        return childAgentTools.childTools.filter((tool) => tool.name !== 'WebSearch');
      }
      const { models, ...connection } = resolved.connection;
      return routeWebSearchTools({
        tools: childAgentTools.childTools,
        settings: snapshot.policy.webSearch,
        connection: {
          ...connection,
          defaultModel: header.model,
          ...(models ? { models: [...models] } : {}),
        },
        model: header.model,
        privacy: snapshot.policy.privacy,
      });
    };
    const subagentCatalog = createConfiguredSubagentCatalog({
      getPresets: async () =>
        (await runtimePolicyStores.runtimePolicy.getSnapshot()).policy.subagents.presets,
      getConnection: async (slug) =>
        (await runtimePolicyStores.connectionCatalog.getSnapshot()).connections.find(
          (connection) => connection.slug === slug,
        ) ?? null,
    });
    manager = new SessionManager({
      store: stores.sessionStore,
      runStore: stores.agentRunStore,
      runtimeEventStore: stores.runtimeEventStore,
      toolBoundaryProtocol: stores.runtimeEventStore.toolBoundaryProtocol,
      backends,
      subagentCatalog,
      newId: randomUUID,
      now: Date.now,
      safeBoundaryResumeEnabled: process.env.MAKA_RUNTIME_SAFE_BOUNDARY_RESUME === '1',
      generateSessionTitle: (input) => sessionEffectCoordinator.generateTitle(input),
      onSessionTitleChanged: (sessionId) =>
        continuityCoordinator.enqueueCanonicalRefresh(sessionId),
      inspectContinuationSafety: createLocalContinuationSafetyInspector({
        readSessionCwd: async (sessionId) =>
          (await stores.sessionStore.readHeaderSnapshot(sessionId)).cwd,
        resolveWorkspaceIdentity: async (cwd) => resolveWorkspaceIdentity({ path: cwd }),
        listAvailableToolNames: resolveAvailableToolNames,
        hasPendingBackgroundOperations: async (sessionId) => {
          const graph = requireGraphCoordinator(graphCoordinator);
          const graphWake = requireGraphSupervisorWake(graphSupervisorWake);
          const [resourcesLive, graphLive, descendantLive] = await Promise.all([
            runtimeResources!.hasLiveSessionResources(sessionId),
            graph.hasLiveSessionState(sessionId),
            hasLiveLinkedDescendantState(
              requireSessionManager(manager),
              stores.agentRunStore,
              sessionId,
              async (descendantSessionId) =>
                (await runtimeResources!.hasLiveSessionResources(descendantSessionId)) ||
                graph.hasLiveSessionState(descendantSessionId) ||
                graphWake.hasLiveSessionState(descendantSessionId),
            ),
          ]);
          return (
            resourcesLive || graphLive || graphWake.hasLiveSessionState(sessionId) || descendantLive
          );
        },
      }),
      runBackendActivation: (operation) => runtimePolicyActivation.runBackendActivation(operation),
      messageAuthority: runtimeAuthority,
      hostedAgentGraphExecution: {
        readAgentGraphIntentClaim: (graphId, intentId) =>
          openedGraphControlStore.readAgentGraphIntentClaim(graphId, intentId),
        readRootTurnAdmissionIdentity: async (sessionId, turnId) => {
          const admission = await stores.agentRunStore.readRootTurnAdmission(sessionId, turnId);
          return admission
            ? { runId: admission.runId, userMessageId: admission.userMessageId }
            : undefined;
        },
      },
      interactionAuthority: interactions,
      canonicalPermissionOutcomes,
      shellRuns,
      planStore: openedPlanStore,
      childTools: childAgentTools.childTools,
      resolveChildTools,
      worktreeChildExecutor,
      listArtifactsForTurn: (sessionId, turnId) =>
        openedArtifactStore.listTurnArtifacts(sessionId, turnId),
      publishChildWorkspacePatch: ({ sessionId, turnId, binding, patch }) =>
        openedArtifactStore.create({
          id: subagentWritebackArtifactId(sessionId, turnId),
          sessionId,
          turnId,
          name: 'workspace.patch',
          kind: 'diff',
          content: patch,
          mimeType: 'text/x-diff; charset=utf-8',
          source: 'subagent_writeback',
          summary: `Workspace changes relative to ${binding.baseCommit}.`,
        }),
      assertChildWorkspaceQuiescent: async (sessionId) => {
        if (await runtimeResources!.hasLiveSessionResources(sessionId)) {
          throw new Error(
            `Child Session ${sessionId} still owns live Runtime Resources; patch publication requires a quiescent workspace`,
          );
        }
      },
    });
    graphCoordinator = new AgentGraphCoordinator({
      sessionStore: stores.sessionStore,
      runStore: stores.agentRunStore,
      runtimeEventStore: stores.runtimeEventStore,
      controlStore: openedGraphControlStore,
      runtime: manager,
      newId: randomUUID,
      acquireResidency: () => context.acquireResidency(),
      onReconciliation: (rootSessionId, result) => {
        void requireGraphSupervisorWake(graphSupervisorWake).notify(rootSessionId, result);
      },
      onCheckpoint: (rootSessionId) => {
        void requireGraphSupervisorWake(graphSupervisorWake).notify(rootSessionId);
      },
    });
    graphClient = new HostAgentGraphCoordinator({
      authority: graphCoordinator,
      continuity: continuityCoordinator,
    });
    const observeBackendInvalidation = (completion: Promise<void>) => {
      void completion.catch(() => {
        backendInvalidationPoisoned = true;
        runtimePolicyActivation.poison();
        context.requestDrain();
      });
    };
    const registerBackendInvalidation = (): void => {
      observeBackendInvalidation(manager.refreshIdleBackends());
    };
    const registerConfigurationMutation = (): void => {
      configurationChanges.publish();
      registerBackendInvalidation();
    };
    clientCapabilities = new HostClientCapabilityCoordinator({
      activation: runtimePolicyActivation,
      onModelToolsChanged: registerBackendInvalidation,
    });
    oauth = new HostOAuthCoordinator({
      runtimePolicy: runtimePolicyStores,
      oauthCredentials,
      activation: runtimePolicyActivation,
      clientCapabilities,
      isProviderEnabled: isOAuthEnrollmentProviderEnabled,
      acquireResidency: context.acquireResidency,
      invalidateBackends: () => {
        configurationChanges.publish();
        return manager.refreshIdleBackends();
      },
      onFatal: (error) => {
        if (poisonFailure) return;
        poisonFailure = error;
        runtimePolicyActivation.poison();
        context.retainUntilProcessExit();
        beginDrain();
        context.requestDrain();
      },
      ...dependencies.oauthAuthorization,
    });
    const usagePricing = new HostUsagePricingCoordinator(
      openedUsageStores,
      context.requestDrain,
      runtimePolicyActivation,
      registerBackendInvalidation,
      // The authority read behind Usage read-model repair (#1679).
      (sessionId, runId) => stores.agentRunStore.readEvents(sessionId, runId),
    );
    const webSearch = new HostWebSearchCoordinator(webSearchService);
    const networkProxy = new HostNetworkProxyCoordinator(runtimePolicyStores.operations);
    const configuration = new HostConfigurationCoordinator(runtimePolicyStores.operations);
    const artifacts = new HostArtifactCoordinator(
      openedArtifactStore,
      context.requestDrain,
      sessionAdmission,
      stores.sessionStore,
    );
    rootCoordinator = new RootTurnCoordinator(
      manager,
      stores,
      sessionAdmission,
      rootAdmissionOwner,
      interactions,
      messages,
      continuityCoordinator,
      context.acquireResidency,
      context.requestDrain,
      clientCapabilities,
      () => requireGoal(goal),
      (admission) => requireAutomationCoordinator(automations).assertRecoveryAdmission(admission),
      artifacts,
      async ({ sessionId, text, skillIds }) => {
        const header = await stores.sessionStore.readHeaderSnapshot(sessionId);
        const [inventory, toolNames] = await Promise.all([
          skills.readCanonicalModelInventory({ projectRoot: header.cwd }),
          resolveAvailableToolNames(sessionId),
        ]);
        return prepareSkillInvocationMessageFromInventory({
          text,
          skillIds,
          inventory: inventory.inventory,
          host: buildHostCapabilitiesFromBinding(toolNames),
        });
      },
    );
    const coordinator = rootCoordinator;
    graphSupervisorWake = new AgentGraphSupervisorWakeCoordinator({
      activityRegistry: graphWakeActivities,
      wakeStore: openedGraphControlStore,
      readSnapshot: (rootSessionId) =>
        requireGraphCoordinator(graphCoordinator).getSnapshot(rootSessionId),
      startTurn: (sessionId, input, _activity, abortSignal, isCurrent) =>
        coordinator.runAgentGraphSupervisorTurn(sessionId, input, abortSignal, isCurrent),
      inspectAttempt: async (rootSessionId, attemptId, turnId) => {
        const runs = (await stores.agentRunStore.listSessionRuns(rootSessionId)).filter(
          (run) => run.agentGraphWakeAttemptId === attemptId && run.turnId === turnId,
        );
        if (runs.length > 1) {
          throw new Error(
            `Agent graph supervisor wake attempt ${attemptId} has multiple AgentRuns`,
          );
        }
        return runs[0]?.status ?? 'missing';
      },
      recoverContextOverflow: (rootSessionId, { abortSignal }) =>
        coordinator.recoverAgentGraphSupervisorContextOverflow(
          rootSessionId,
          randomUUID(),
          abortSignal,
        ),
      shouldWake: shouldWakeAgentSwarmSupervisor,
      renderWake: renderAgentSwarmSupervisorWake,
      newId: randomUUID,
      isSessionDeliverable: async (sessionId) => {
        try {
          const header = await stores.sessionStore.readHeaderSnapshot(sessionId);
          return !header.isArchived && header.status !== 'archived';
        } catch (error) {
          if (isSessionNotFoundError(error)) return false;
          throw error;
        }
      },
      acquireResidency: () => context.acquireResidency(),
      onError: () => context.requestDrain(),
    });
    automations = new HostAutomationCoordinator({
      store: openedAutomationStore,
      sessions: stores.sessionStore,
      runs: stores.agentRunStore,
      runtime: manager,
      root: { executeRoot: (input) => coordinator.executeRoot(input) },
      runtimePolicy: runtimePolicyStores,
      isSessionActive: (sessionId) => coordinator.readRootState(sessionId).kind !== 'idle',
      sessionAdmission,
      acquireResidency: context.acquireResidency,
      requestDrain: context.requestDrain,
    });
    goal = new HostGoalCoordinator({
      stores,
      sessionAdmission,
      evaluator: createHostGoalEvaluator({
        runtimePolicy: runtimePolicyStores,
        oauthCredentials,
        claudeDeviceId: context.owner.capability.rootId,
        usage: openedUsageStores,
        requestDrain: context.requestDrain,
        readSessionHeader: (sessionId) => stores.sessionStore.readHeaderSnapshot(sessionId),
      }),
      admitTurn: (sessionId, text, checkpoint, controlLease) =>
        coordinator.admitGoalTurn(sessionId, checkpoint, controlLease, text),
      listActionableTaskKeys: async (sessionId) => {
        const tasks = await taskLedger.list(sessionId, {
          includeTerminal: false,
          includeArchived: false,
          classifyResumeTrust: true,
        });
        return filterModelVisibleTaskLedgerTasks(tasks)
          .filter((task) => task.status === 'pending' || task.status === 'in_progress')
          .map((task) => task.key);
      },
      acquireResidency: context.acquireResidency,
      onProjectionChanged: (sessionId) => continuityCoordinator.enqueueCanonicalRefresh(sessionId),
    });
    async function applyRuntimePolicyMutationEffects(): Promise<void> {
      try {
        await requireMemory(memory).refreshAfterPolicyMutation();
      } catch (error) {
        context.requestDrain();
        throw error;
      }
      registerConfigurationMutation();
    }
    const connectionEffects = new HostConnectionEffectCoordinator({
      stores: runtimePolicyStores,
      activation: runtimePolicyActivation,
      oauthCredentials,
      onCommittedMutation: registerConfigurationMutation,
    });
    const sessionCatalog = new HostSessionCatalogCoordinator({
      stores: stores.sessionStore,
      runtimePolicy: runtimePolicyStores,
      manager,
      admission: sessionAdmission,
      continuity: continuityCoordinator,
      requestDrain: context.requestDrain,
    });
    const externalSessions = new HostExternalSessionCoordinator({
      adapters: createExternalSessionAdapterRegistry(),
      sessions: stores.sessionStore,
      resolveTarget: () => sessionCatalog.resolveExternalSessionImportTarget(),
      requestDrain: context.requestDrain,
    });
    const plans = new HostPlanCoordinator({
      store: openedPlanStore,
      sessions: stores.sessionStore,
      runtime: manager,
      sessionAdmission,
      isSessionActive: (sessionId) => coordinator.readRootState(sessionId).kind !== 'idle',
      refreshContinuity: (sessionId, lease) =>
        continuityCoordinator.refreshCanonical(sessionId, lease),
      onProjectionChanged: (sessionId) =>
        continuityCoordinator.enqueueSessionDomainChanged(sessionId, 'plan'),
      requestDrain: context.requestDrain,
      root: coordinator,
    });
    const executionInspect = new HostExecutionInspectCoordinator(stores);
    const sessionRevisions = new HostSessionRevisionCoordinator({
      stores,
      artifacts: openedArtifactStore,
      taskLedger: taskLedgerStore,
      manager,
      admission: sessionAdmission,
      continuity: continuityCoordinator,
      graph: requireGraphCoordinator(graphCoordinator),
      isSessionActive: (sessionId) => coordinator.readRootState(sessionId).kind !== 'idle',
      requestDrain: context.requestDrain,
    });
    const sessionRetirement = new HostSessionRetirementCoordinator({
      stores: stores.sessionStore,
      admission: sessionAdmission,
      root: coordinator,
      messages,
      interactions,
      goals: requireGoal(goal),
      automation: automations,
      resources: runtimeResources,
      sessionEffects: sessionEffectCoordinator,
      graph: requireGraphCoordinator(graphCoordinator),
      graphWake: requireGraphSupervisorWake(graphSupervisorWake),
      manager,
      capabilities: clientCapabilities,
      continuity: continuityCoordinator,
      artifacts: openedArtifactStore,
      taskLedger: taskLedgerStore,
      purgeOperationalState: async (sessionId) => {
        await stores.purgeConversationOperationalState(sessionId);
        await openedPlanStore.purgeSessionState(sessionId);
        await openedDeepResearchStore.purgeSessionState(sessionId);
      },
      purgeAgentGraphState: async (sessionId) => {
        await openedGraphControlStore.purgeAgentGraphControlState(
          agentGraphIdForRootSession(sessionId),
        );
      },
      worktrees: worktreeChildExecutor,
      requestDrain: context.requestDrain,
      memoryExtractionLane,
    });
    const handlers = {
      ...coordinator.handlers,
      ...requireGoal(goal).handlers,
      ...sessionCatalog.handlers,
      ...externalSessions.handlers,
      ...executionInspect.handlers,
      ...graphClient.handlers,
      ...sessionRevisions.handlers,
      ...sessionRetirement.handlers,
      ...messages.handlers,
      ...interactions.handlers,
      ...runtimePolicy.handlers,
      ...connectionEffects.handlers,
      ...sessionEffectCoordinator.handlers,
      ...continuityCoordinator.handlers,
      ...taskLedger.handlers,
      ...artifacts.handlers,
      ...skills.handlers,
      ...usagePricing.handlers,
      ...requireMemory(memory).handlers,
      ...oauth.handlers,
      ...clientCapabilities.handlers,
      ...runtimeResources.handlers,
      ...automations.handlers,
      ...plans.handlers,
      ...requireDeepResearch(deepResearch).handlers,
      ...requireDailyReview(dailyReview).handlers,
      ...webSearch.handlers,
      ...networkProxy.handlers,
      ...configuration.handlers,
    } satisfies DomainOperationHandlerMap;
    const recover = () => {
      recoveryTask ??= (async () => {
        await requireMemory(memory).recover();
        await skills.recover();
        await openedArtifactStore.recover();
        await sessionRetirement.recover();
        const sessions = await stores.sessionStore.listForRecovery();
        await worktreeChildExecutor.recover(
          sessions.flatMap((session) =>
            session.subagentWorkspace ? [session.subagentWorkspace] : [],
          ),
        );
        await sessionRevisions.recover();
        for (const session of sessions) {
          await stores.runtimeEventStore.repairImmutableSteeringMessageProofsForRecovery(
            session.id,
          );
        }
        await recoverClientCapabilityOutcomes(
          stores.runtimeEventStore,
          sessions.map((session) => session.id),
        );
        await requireAutomationCoordinator(automations).prepareRecovery();
        await coordinator.prepareRecovery();
        await interactions.recoverPendingAfterHostRestart();
        await manager.recoverInterruptedSessionsStrict(stores);
        await manager.recoverChildWorkspacePatches(
          sessions.flatMap((session) => (session.subagentWorkspace ? [session.id] : [])),
        );
        await coordinator.recover();
        rootRecoveryCompleted = true;
        await requireGraphSupervisorWake(graphSupervisorWake).recover();
        await requireGraphCoordinator(graphCoordinator).recover();
        await requireAutomationCoordinator(automations).recover();
        await requireDailyReview(dailyReview).recover();
        requireAutomationCoordinator(automations).start();
      })();
      return recoveryTask;
    };
    const close = () => {
      closeTask ??= (async () => {
        beginDrain();
        const errors: unknown[] = [];
        try {
          await recover();
        } catch (error) {
          errors.push(error);
        }
        try {
          await goal?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await connectionEffects.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await graphSupervisorWake?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          graphClient?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await graphCoordinator?.close();
        } catch (error) {
          errors.push(error);
        }
        if (rootRecoveryCompleted && !poisonFailure) {
          try {
            rootCloseTask ??= coordinator.close();
            await rootCloseTask;
          } catch (error) {
            errors.push(error);
          }
        }
        try {
          await automations?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await dailyReview?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await runtimeResources?.close();
        } catch (error) {
          errors.push(error);
        }
        // Host operations have already drained before composition.close().
        // Close the workspace execution owner before the kernel releases the
        // root owner, preserving tool operations -> managed owner -> root owner.
        try {
          await workspaceExecution?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await sessionEffects?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          deepResearch?.close();
        } catch (error) {
          errors.push(error);
        }
        if (!backendInvalidationPoisoned) {
          try {
            await manager.refreshIdleBackends();
          } catch (error) {
            errors.push(error);
          }
        }
        try {
          await messages.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await interactions.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          continuityCoordinator.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await skills.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await memoryExtraction?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await memory?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await oauth?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          longTermMemoryStore?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await clientCapabilities?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await openedUsageStores.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await sessionRetirement.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          openedGraphControlStore.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          openedArtifactStore.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          unsubscribeTaskLedger?.();
          taskLedgerStore?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          shellRunStore?.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          openedAutomationStore.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          openedPlanStore.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          openedDeepResearchStore.close();
        } catch (error) {
          errors.push(error);
        }
        try {
          await stores.sessionStore.close?.();
        } catch (error) {
          errors.push(error);
        }
        if (poisonFailure && !errors.includes(poisonFailure)) errors.push(poisonFailure);
        if (errors.length > 0) {
          throw new AggregateError(errors, 'Unable to close Runtime Host execution composition');
        }
      })();
      return closeTask;
    };
    return {
      handlers,
      workspaceExecution: requireWorkspaceExecution(workspaceExecution),
      continuity: continuityCoordinator,
      clientCapabilities,
      configurationChanges,
      sessionCatalogChanges,
      releaseConnection: (connectionId: string) => {
        artifacts.releaseConnection(connectionId);
        requireMemory(memory).releaseConnection(connectionId);
        clientCapabilities?.releaseConnection(connectionId);
        runtimeResources?.releaseConnection(connectionId);
      },
      beginDrain,
      recover,
      close,
    };
  } catch (error) {
    const errors: unknown[] = [error];
    try {
      await workspaceExecution?.close();
      if (!workspaceExecution) await managedWorkspaceOwner?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      await sessionEffects?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      dailyReviewStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      deepResearchStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      graphClient?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      graphControlStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      await usageStores?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      artifactStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      unsubscribeTaskLedger?.();
      taskLedgerStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      shellRunStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      await memoryExtraction?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      longTermMemoryStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      automationStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      planStore?.close();
    } catch (closeError) {
      errors.push(closeError);
    }
    try {
      await stores.sessionStore.close?.();
    } catch (closeError) {
      errors.push(closeError);
    }
    if (errors.length === 1) throw error;
    throw new AggregateError(errors, 'Unable to clean up Runtime Host execution composition');
  }
}

function requireRootCoordinator(coordinator: RootTurnCoordinator | undefined): RootTurnCoordinator {
  if (!coordinator) throw new Error('Runtime Host root coordinator is not composed');
  return coordinator;
}

function requireWorkspaceExecution(
  composition: RuntimeHostWorkspaceExecutionComposition | undefined,
): RuntimeHostWorkspaceExecutionComposition {
  if (!composition) throw new Error('Runtime Host workspace execution is not composed');
  return composition;
}

function adaptManagedWorkspaceFilesystemWorker(
  worker: Pick<FilesystemWorkerClient, 'execute'>,
): ManagedWorkspaceFilesystemWorker {
  return {
    async execute(input) {
      const result = await worker.execute(input);
      switch (result.kind) {
        case 'read':
        case 'read_image':
        case 'glob':
        case 'grep':
          return result;
        default:
          throw new RuntimeHostWorkspaceExecutionError(
            'workspace_operation_denied',
            `Read-only filesystem worker returned mutating result ${result.kind}`,
          );
      }
    },
  };
}

function subagentWritebackArtifactId(sessionId: string, turnId: string): string {
  const digest = createHash('sha256')
    .update('maka-subagent-writeback-v1\0')
    .update(sessionId)
    .update('\0')
    .update(turnId)
    .digest('hex')
    .slice(0, 32);
  return `subagent_writeback_${digest}`;
}

function requireContinuity(
  continuity: SessionContinuityCoordinator | undefined,
): SessionContinuityCoordinator {
  if (!continuity) throw new Error('Runtime Host continuity coordinator is not composed');
  return continuity;
}

function requireCanonicalProjection(
  projection: CanonicalSessionProjectionReader | undefined,
): CanonicalSessionProjectionReader {
  if (!projection) throw new Error('Runtime Host canonical projection is not composed');
  return projection;
}

function requireMemory(memory: HostMemoryCoordinator | undefined): HostMemoryCoordinator {
  if (!memory) throw new Error('Runtime Host Memory coordinator is not composed');
  return memory;
}

function requireClientCapabilities(
  coordinator: HostClientCapabilityCoordinator | undefined,
): HostClientCapabilityCoordinator {
  if (!coordinator) throw new Error('Runtime Host Client Capability coordinator is not composed');
  return coordinator;
}

function requireToolNameResolver(
  resolver: ((sessionId: string) => Promise<string[]>) | undefined,
): (sessionId: string) => Promise<string[]> {
  if (!resolver) throw new Error('Runtime Host Session tool resolver is not composed');
  return resolver;
}

function requireNewSessionToolNameResolver(
  resolver:
    | ((
        previewSessionId: string,
        collaborationMode: 'agent' | 'plan',
        initiatingConnectionId: string,
      ) => Promise<string[]>)
    | undefined,
): (
  previewSessionId: string,
  collaborationMode: 'agent' | 'plan',
  initiatingConnectionId: string,
) => Promise<string[]> {
  if (!resolver) throw new Error('Runtime Host new Session tool resolver is not composed');
  return resolver;
}

function requireAutomationCoordinator(
  coordinator: HostAutomationCoordinator | undefined,
): HostAutomationCoordinator {
  if (!coordinator) throw new Error('Runtime Host Automation coordinator is not composed');
  return coordinator;
}

function requireDeepResearch(
  coordinator: HostDeepResearchCoordinator | undefined,
): HostDeepResearchCoordinator {
  if (!coordinator) throw new Error('Runtime Host Deep Research coordinator is not composed');
  return coordinator;
}

function requireDailyReview(
  coordinator: HostDailyReviewCoordinator | undefined,
): HostDailyReviewCoordinator {
  if (!coordinator) throw new Error('Runtime Host Daily Review coordinator is not composed');
  return coordinator;
}

function requireSessionManager(manager: SessionManager | undefined): SessionManager {
  if (!manager) throw new Error('Runtime Host SessionManager is not composed');
  return manager;
}

function requireGraphCoordinator(
  coordinator: AgentGraphCoordinator | undefined,
): AgentGraphCoordinator {
  if (!coordinator) throw new Error('Runtime Host Agent Graph coordinator is not composed');
  return coordinator;
}

function requireGraphSupervisorWake(
  coordinator: AgentGraphSupervisorWakeCoordinator | undefined,
): AgentGraphSupervisorWakeCoordinator {
  if (!coordinator) {
    throw new Error('Runtime Host Agent Graph supervisor wake coordinator is not composed');
  }
  return coordinator;
}

function requireGoal(coordinator: HostGoalCoordinator | undefined): HostGoalCoordinator {
  if (!coordinator) throw new Error('Runtime Host Goal coordinator is not composed');
  return coordinator;
}

async function hasLiveLinkedDescendantState(
  manager: SessionManager,
  runStore: {
    listSessionRuns(sessionId: string): Promise<readonly { status: string }[]>;
  },
  rootSessionId: string,
  hasLiveSessionState: (sessionId: string) => Promise<boolean>,
): Promise<boolean> {
  const pending = [rootSessionId];
  const seen = new Set(pending);
  while (pending.length > 0) {
    const parentSessionId = pending.shift()!;
    const children = await manager.listChildSessions(parentSessionId);
    for (const child of children) {
      if (seen.has(child.id)) continue;
      seen.add(child.id);
      pending.push(child.id);
      const [runs, liveState] = await Promise.all([
        runStore.listSessionRuns(child.id),
        hasLiveSessionState(child.id),
      ]);
      if (liveState) return true;
      if (
        runs.some(
          (run) =>
            run.status === 'created' ||
            run.status === 'running' ||
            run.status === 'waiting_for_user',
        )
      ) {
        return true;
      }
    }
  }
  return false;
}
