How Maka Recovers Session State on Startup After an Interruption

Maka recovers session state by querying SQLite for catalog projections and tool-recovery bundles, reconstructing the runtime operation graph, and re-hydrating UI virtualization layers to restore exact scroll positions and draft buffers.

When the Apache Maka application launches or relaunches after a crash, shutdown, or network outage, it rebuilds every active session from persistent storage using a deterministic three-stage pipeline. This session state recovery process ensures users resume exactly where they left off, including pending tool calls and unsent message drafts.

Stage 1: Loading Session Metadata from SQLite

The recovery process begins in the storage layer when the Electron main process opens the session.sqlite database and instantiates SQLiteSessionMetadataStore.

Querying Catalog Projections

The recoverCatalogProjections method in packages/storage/src/sqlite-session-metadata-store.ts executes a SELECT query against the session_catalog table to retrieve the most recent snapshot of each session's catalog data.

// packages/storage/src/sqlite-session-metadata-store.ts
async recoverCatalogProjections(): Promise<CatalogProjection[]> {
  const rows = await this.db.all(`
    SELECT session_id, catalog_json
    FROM session_catalog
    ORDER BY updated_at DESC
  `);
  return rows.map(r => ({
    sessionId: r.session_id,
    projection: JSON.parse(r.catalog_json),
  }));
}

This deserializes JSON-encoded catalog data into CatalogProjection objects containing the list of turns, tool calls, and system messages required to rebuild the session transcript.

Recovering Supervisor Wake Signals

Concurrently, recoverAgentGraphSupervisorWakes fetches pending "wake-up" signals that indicate supervisor operations awaiting completion. These signals ensure oversight processes resume monitoring the correct session states immediately after startup.

Stage 2: Re-Hydrating Runtime State

With raw metadata loaded, Maka reconstructs the runtime store in packages/storage/src/sqlite-runtime-store.ts that drives the execution engine.

Rebuilding Tool-Recovery Bundles

For sessions interrupted during tool execution (such as long-running LLM requests), SQLiteRuntimeStore.recoverAgentGraphSupervisorWakes restores tool-recovery bundles. These bundles contain ToolRecoveryDecisionFact objects that capture the decision context needed to either resume or abort the tool call without re-executing side effects.

Restoring Operation State Machines

The runtime store reconstructs the operation state machine for each pending tool, cycling through states from prepared through outcome_committed to either recovery_completed or parked. This deterministic state machine ensures interrupted operations continue exactly where they paused, avoiding duplicate executions or data corruption.

Stage 3: Initializing UI and Virtualization Layers

The front-end React hooks in packages/ui/src/ subscribe to restored session objects and rebuild the visual transcript state without layout thrashing.

Synchronizing Scroll Containers

The useChatScroll hook receives the recovered sessionId and re-syncs the virtual scroll tail. It references the restored TurnHeightIndex to calculate initial scroll position without forcing layout recalculations.

// packages/ui/src/use-chat-scroll.ts
export function useChatScroll(input: { sessionId?: string; scrollRef: RefObject<HTMLElement> }) {
  const sessionIdRef = useRef(input.sessionId);
  sessionIdRef.current = input.sessionId;

  useEffect(() => {
    if (!input.sessionId) return;
    const tail = turnHeightIndex.lookup(input.sessionId, layoutKey);
    // Apply restored tail position to scroll container
  }, [input.sessionId, input.scrollRef]);
}

Rebuilding Turn Height Indexes

The useTurnVirtualizer hook in packages/ui/src/use-turn-virtualizer.ts looks up stored turn heights via TurnHeightIndex to maintain exact scroll positioning. This prevents layout thrashing when rendering large restored transcripts.

Projecting the Final Transcript

Finally, transcriptProjection in packages/ui/src/transcript-projection.ts maps the stored turns into the visible transcript view, while the draft store loads any unsent draft message attached to the session key, ensuring the user's in-flight input is never lost.

Architectural Guarantees for Reliable Recovery

Maka's recovery pipeline relies on two core architectural principles to ensure data integrity.

Atomic Persistence – Every state transition (turn added, tool call started, decision recorded) is written to SQLite within a single transaction. This guarantees that the recovery path always sees a consistent snapshot, even if the interruption occurred mid-write.

Separation of Concerns – The storage package handles raw persistence in sqlite-session-metadata-store.ts and sqlite-runtime-store.ts, while the UI package manages rendering in use-chat-scroll.ts and use-turn-virtualizer.ts. This boundary allows each layer to reload only its owned components, simplifying the recovery logic.

Summary

  • SQLite Metadata Store queries catalog projections and supervisor wakes from session.sqlite via recoverCatalogProjections and recoverAgentGraphSupervisorWakes.
  • Runtime Store reconstructs tool-recovery bundles and operation state machines to resume interrupted tool calls without side effects.
  • UI Hooks restore virtualization state using useChatScroll and useTurnVirtualizer to maintain scroll position and draft buffers.
  • Atomic transactions ensure consistent recovery snapshots even after unexpected shutdowns.

Frequently Asked Questions

How does Maka prevent data loss during an unexpected crash?

Maka persists every meaningful state change to SQLite within atomic transactions. When the application restarts, SQLiteSessionMetadataStore loads the last consistent snapshot, ensuring no committed data is lost even if the crash occurred during a write operation.

What happens to incomplete tool calls when Maka restarts?

Interrupted tool calls are captured as tool-recovery bundles containing ToolRecoveryDecisionFact objects. The SQLiteRuntimeStore reconstructs these bundles and restores the operation state machine, allowing Maka to either resume the tool execution or mark it as failed based on the persisted decision context.

How does Maka restore the exact scroll position in the chat interface?

The UI layer uses useTurnVirtualizer to retrieve cached turn heights from TurnHeightIndex, while useChatScroll applies these measurements to the scroll container. This avoids expensive layout recalculations and restores the virtual scroll tail to its exact pre-interruption position.

Where is the session recovery logic implemented in the Maka codebase?

The core recovery logic resides in packages/storage/src/sqlite-session-metadata-store.ts for metadata loading and packages/storage/src/sqlite-runtime-store.ts for runtime reconstruction. UI restoration is handled in packages/ui/src/use-chat-scroll.ts and packages/ui/src/use-turn-virtualizer.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →