# What Does a Turn Represent in Maka's Session Architecture

> Understand what a Turn represents in Apache Maka's session architecture. Learn how this immutable unit captures the entire agent-runtime interaction cycle, from input to completion.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: internals
- Published: 2026-09-08

---

**A Turn in Apache Maka is the fundamental, immutable unit of work that captures a complete interaction cycle between the agent and runtime, from initial user input through all model-generated messages, tool calls, permission decisions, and side-effects until the runtime marks it as ended.**

In Apache Maka's session architecture, understanding what a Turn represents is essential for building reliable agentic applications. A Turn encapsulates an entire logical interaction as an append-only segment of the Runtime Event Log, ensuring that every step—from initial prompt to final output—remains replayable and auditable. This design pattern allows the UI to render coherent conversation blocks while maintaining an immutable single source of truth in the underlying data layer.

## The Turn as a Fundamental Unit of Work

Maka treats the **Turn** as the atomic boundary for agentic interactions. Unlike simple message passing, a Turn groups all related events into a single, coherent transaction that spans the full lifecycle of a request.

When a user submits input, the runtime creates a Turn that persists until the model finishes reasoning, executes any requested tools, resolves permissions, and generates final outputs. This architecture enables the UI to display complex multi-step interactions—such as "model speaks → runs a command → asks permission → you approve → result → edit → turn ends"—as a single visual block, as illustrated in the project README.

## Turn Lifecycle and Event Flow

The Turn lifecycle follows a strict protocol defined in [`packages/runtime-host/src/protocol/turn.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/turn.ts). Each phase corresponds to specific input types that transition the Turn through distinct states.

### Turn Start with TurnStartInput

A Turn begins when the runtime receives a `TurnStartInput` payload. According to the source code in [`packages/runtime-host/src/protocol/turn.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/turn.ts) (lines 53-59), this input initializes the Turn context and assigns a unique `turnId` that tags all subsequent events.

```typescript
import { RuntimeHostClient } from '@maka/runtime-host';
const client = new RuntimeHostClient();
await client.sendTurnStart({ 
  sessionId: 's1', 
  turnId: 't1', 
  text: 'Summarize repo' 
});

```

### Runtime Events and Event Tagging

During the active phase, the runtime generates `RuntimeEvent` objects for every model message, tool call, permission decision, and file change. Each event carries the same `turnId`, creating an immutable audit trail in the Runtime Event Log. The `TurnLedger`—implemented in `scripts/computer-use/direct-runtime-ledger.mjs`—provides in-memory filtering to group these events by `turnId` for efficient session management.

### Turn End with TurnStopInput

The runtime finalizes the Turn by emitting a `TurnStopInput`, defined at lines 86-90 of [`turn.ts`](https://github.com/apache/maka/blob/main/turn.ts). This marker completes the interaction cycle and makes the transcript viewable for UI rendering.

```typescript
await client.sendTurnStop({ sessionId: 's1', turnId: 't1' });

```

## Internal Data Structures

Maka implements the Turn concept through several specialized data structures that handle persistence, UI projection, and session state:

- **`TurnStartInput` / `TurnStopInput`** – API protocol messages in [`packages/runtime-host/src/protocol/turn.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/turn.ts) that define the Turn boundaries.
- **`TurnRecord`** – The persistent representation stored in the SQLite runtime database (`runtime.sqlite`), defined in [`packages/core/src/session.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session.ts).
- **`TurnViewModel`** – A UI-friendly model used by React renderers, constructed in [`packages/ui/src/materialize.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/materialize.ts) (lines 404-412).
- **`TurnLedger`** – An in-memory ledger that efficiently filters and groups events by `turnId`, located in `scripts/computer-use/direct-runtime-ledger.mjs`.

## Practical Code Examples

### Submitting Messages Within a Turn

Once a Turn is active, you submit messages using the `turnId` to maintain context. The message payload structure is defined in [`packages/runtime-host/src/protocol/message.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/message.ts) (lines 93-100).

```typescript
await client.sendMessage({
  sessionId: 's1',
  turnId: 't1',
  content: { 
    role: 'user', 
    text: 'What does a Turn represent?' 
  },
});

```

### Rendering Turns in the UI

The UI materializes Turns using `TurnViewModel` objects created by functions like `materializeTurns` and `projectTranscriptRows` in [`packages/ui/src/transcript-projection.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/transcript-projection.ts). React components consume these models to render complete interaction blocks.

```typescript
import { TurnViewModel } from '@maka/ui';

function TurnPanel({ turn }: { turn: TurnViewModel }) {
  return (
    <div className="turn">
      <div className="turn-header">{turn.label}</div>
      <div className="turn-body">{turn.content}</div>
    </div>
  );
}

```

## Key Source Files and Their Roles

| File | Role |
|------|------|
| [`packages/runtime-host/src/protocol/turn.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/turn.ts) | Defines protocol messages (`TurnStartInput`, `TurnStopInput`) for Turn lifecycle management. |
| [`packages/core/src/session.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session.ts) | Persists Turn data via `TurnRecord` and `TurnStateMessage` in the SQLite runtime database. |
| [`packages/ui/src/materialize.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/materialize.ts) | Builds UI-ready `TurnViewModel` objects from raw RuntimeEvents for React rendering. |
| `scripts/computer-use/direct-runtime-ledger.mjs` | Implements in-memory event grouping by `turnId` for session-specific queries. |
| [`README.md`](https://github.com/apache/maka/blob/main/README.md) (lines 39-42) | Provides visual documentation of the Turn lifecycle in the product interface. |

## Summary

- A **Turn** represents the complete interaction cycle in Maka's session architecture, from user input through all model-generated events to final completion.
- The **Runtime Event Log** treats Turns as immutable, append-only segments identified by unique `turnId` values.
- **TurnStartInput** and **TurnStopInput** in [`packages/runtime-host/src/protocol/turn.ts`](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/turn.ts) define the protocol boundaries for initiating and finalizing Turns.
- **TurnRecord** in [`packages/core/src/session.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session.ts) provides persistent SQLite storage, while **TurnViewModel** in [`packages/ui/src/materialize.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/materialize.ts) enables UI rendering.
- All UI components project the immutable log into transcripts using functions like `materializeTurns` and `projectTranscriptRows`.

## Frequently Asked Questions

### How does a Turn differ from a Session in Maka?

A **Session** represents the long-running container for user interactions, persisting across multiple Turns and maintaining state such as conversation history and file system context. A **Turn** is a bounded unit of work within that Session, isolating a single logical interaction from start to finish. While a Session may contain many Turns over time, each Turn encapsulates one complete request-response cycle with its own immutable event log segment.

### Can a Turn span multiple user messages?

No, a Turn represents a single logical interaction initiated by one user input (or automated trigger). While the model within a Turn may generate multiple messages, tool calls, and permission requests, the Turn itself begins with one `TurnStartInput` and concludes with one `TurnStopInput`. Subsequent user inputs initiate new Turns with distinct `turnId` values, ensuring clear separation between interaction cycles in the `TurnLedger`.

### How does the UI render Turns from the event log?

The UI materializes Turns by querying the immutable Runtime Event Log and projecting events through `materializeTurns` and `projectTranscriptRows` in [`packages/ui/src/transcript-projection.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/transcript-projection.ts). These functions filter `RuntimeEvent` objects by `turnId` and construct `TurnViewModel` instances. React components then render these view models as coherent blocks, displaying the full sequence of model messages, tool executions, and results as a single visual unit despite comprising multiple underlying events.

### Are Turn events mutable after the Turn ends?

No, Turn events are strictly immutable. Once the runtime emits a `TurnStopInput`, the events tagged with that `turnId` become permanent entries in the SQLite-backed Runtime Event Log. This immutability serves as the "single source of truth," enabling deterministic replay, accurate auditing, and consistent rendering across different UI surfaces (desktop, TUI, or CLI) without risk of data corruption or state drift.