What Information Is Stored in the Apache Maka Runtime Event Log?

The Apache Maka Runtime Event Log stores an immutable, ordered sequence of canonical RuntimeEvents that capture every semantic fact an agent generates—messages, tool calls, permissions, token usage, and terminal outcomes—enabling complete state replay and recovery.

The Runtime Event Log is the single source of truth for every interaction in the Apache Maka agent framework. When a session executes, the runtime doesn't just log a UI transcript—it preserves the full causal history needed to reconstruct, project, or recover any execution state. This article explains exactly what information is captured, how it's structured, and where to find the implementation in the Maka source code.

Core Dimensions of a RuntimeEvent

Each RuntimeEvent in the log encodes seven key dimensions. These fields appear in packages/core/src/runtime-event.ts at lines 145–181, which defines the canonical type:

Dimension Key Fields Purpose
Identity sessionId, invocationId, runId, turnId, branch Locates the event within the session hierarchy
Ordering id, ts, event_seq Establishes causal sequence for deterministic replay
Source role, author Tracks lane (user, assistant, system) and subsystem
Content text, thinking, function-call/response payloads, errors The actual semantic payload
Actions state delta, permission decision, artifact metadata, usage Side effects the runtime must record
Correlation tool-call ID, provider event ID, step ID, artifact refs Links related facts across subsystems
Lifecycle partial, status Distinguishes ephemeral fragments from durable facts

The event_seq field is particularly critical—it's the basis for the ordered ledger that all consumers project from.

What Types of Facts Are Stored

The Maka Runtime Event Log holds all semantic facts produced during execution, not just messages. According to the architecture design in docs/architecture/runtime-core-architecture-draft.md (lines 84–92), this includes:

  • User messages — input text and attachments
  • Model messages — assistant text and "thinking" deltas
  • Function (tool) calls — requests to external capabilities
  • Function responses — results returned from tool execution
  • Permission requests & decisions — runtime authorization events
  • Token-usage events — consumption metrics for context budgeting
  • Boundary-expansion requests — sandbox or user clarification prompts
  • Terminal facts — completion, error, or cancellation markers

The architecture document enforces a strict invariant at lines 49–52: a Run cannot be marked completed unless a durable terminal RuntimeEvent exists. This guarantees that the log always reflects ground truth.

How RuntimeEvents Are Created

Raw backend SessionEvents are transformed into canonical RuntimeEvents by the mapper at packages/runtime/src/session-event-runtime-mapper.ts (lines 48–55). Here's how a user message becomes a RuntimeEvent:

import { RuntimeEvent, RuntimeEventTextContent } from '@maka/core/runtime-event';

const userMessage: RuntimeEvent = {
  id: 'evt-001',
  ts: Date.now(),
  sessionId: 'sess-123',
  runId: 'run-456',
  turnId: 'turn-1',
  role: 'user',
  author: 'user',
  content: {
    kind: 'text',
    text: 'Find the failing tests in this project.'
  } as RuntimeEventTextContent,
  lifecycle: { partial: false, status: 'committed' },
};

The lifecycle field distinguishes partial events (streaming deltas that may be replaced) from committed terminal facts.

Persistence and Ordering

The RuntimeEventStore interface in packages/core/src/runtime-event-store.ts (lines 72–78) defines the contract for persistence:

export interface RuntimeEventStore {
  appendRuntimeEvent(event: RuntimeEvent): Promise<void>;
  readImmutableRuntimeEvents(filter: RuntimeEventFilter): Promise<RuntimeEvent[]>;
  // recovery methods...
}

The SQLite implementation at packages/storage/src/sqlite-runtime-store.ts (lines 3314–3320) stores events in the runtime_events table, strictly ordered by event_seq. This ordering guarantees that state equals projection over the ordered log: State(t) = Project(RuntimeEvents[0..t], …).

Writing an event to the store:

import { RuntimeEventStore } from '@maka/core/runtime-event-store';
import { MemoryRuntimeEventStore } from '@maka/runtime';

const store: RuntimeEventStore = new MemoryRuntimeEventStore();
await store.appendRuntimeEvent(userMessage);

Projecting Views from the Log

Multiple consumers read the same immutable log for different purposes. The RuntimeReadModel at packages/runtime/src/runtime-read-model.ts (lines 57–66) builds projections without modifying the source of truth:

import { RuntimeEventStore } from '@maka/core/runtime-event-store';
import { RuntimeReadModel } from '@maka/runtime';

const readModel = new RuntimeReadModel({ runtimeEventStore: store });
const modelHistory = await readModel.projectModelHistory({
  sessionId: 'sess-123',
  runId: 'run-456',
});

This approach means the model-history projector, UI read model, recovery process, and context-budget policy all work from identical data.

Crash Recovery and Terminal Invariants

The log-first architecture enables deterministic recovery. If a crash occurs, the RuntimeKernel at packages/runtime/src/runtime-kernel.ts scans for non-terminal runs and synthesizes failure facts where terminal events are missing—see the recovery logic referenced in the architecture document (lines 46–53):

import { RuntimeKernel } from '@maka/runtime';

await RuntimeKernel.recoverFromCrash({
  runtimeEventStore: store,
  agentRunStore: /* … */,
});

This guarantees that every Run reaches a terminal state in the log, even if the original execution failed.

Summary

Frequently Asked Questions

What is the difference between a SessionEvent and a RuntimeEvent?

A SessionEvent is the raw backend representation of an interaction, often tied to specific transport or protocol concerns. The session-event-runtime-mapper.ts translates these into canonical RuntimeEvents that strip away transport details and add the seven standard dimensions (identity, ordering, source, content, actions, correlation, lifecycle). This translation happens at lines 48–55 of the mapper file before persistence.

Why does Maka use an append-only log instead of mutable state?

The append-only log guarantees that state = projection over the ordered ledger. Because every fact is immutable and sequenced, any consumer can reconstruct the exact execution state at any point by projecting from event zero to event t. This enables deterministic replay, audit trails, and crash recovery without lock contention or merge conflicts. The architecture document at lines 84–92 formalizes this design.

How are streaming/partial events handled in the log?

Partial events carry lifecycle: { partial: true } and represent replaceable fragments like streaming text deltas. These may be updated or superseded until a terminal fact with status: 'committed' arrives. Consumers that need durable state filter out partial events; UI consumers may render them for responsiveness. The lifecycle fields are defined in runtime-event.ts at lines 145–181.

Where is the Runtime Event Log physically stored?

The default implementation uses SQLite in the runtime_events table, ordered by event_seq (see sqlite-runtime-store.ts lines 3314–3320). The RuntimeEventStore interface abstracts storage, so alternative implementations could use PostgreSQL, event streams, or distributed ledgers without changing consumer code.

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 →