# How Maka Handles Session Branching, Revision, and Regeneration: A Deep Dive into the Conversation Model

> Explore how Maka handles session branching, revision, and regeneration within its conversation model. Learn about its flexible approach to evolving user-assistant interactions.

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

---

**Maka's conversation model treats every user-assistant interaction as a session that can evolve through three distinct mechanisms: branching for new logical conversations, revision for edit-and-resend workflows, and regeneration for re-running completed turns.**

The Apache Maka project implements a sophisticated session management system that preserves full audit history while presenting users with a clean, coherent view of their conversations. This article examines how **session branching**, **revision**, and **regeneration** are implemented in the core runtime, with direct reference to the source code in [`packages/core/src/session.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session.ts), [`session-revisions.ts`](https://github.com/apache/maka/blob/main/session-revisions.ts), and [`agent-run.ts`](https://github.com/apache/maka/blob/main/agent-run.ts).

## Understanding the Three Session Evolution Patterns

Maka distinguishes between three ways a conversation can evolve. Each pattern serves a different user need and carries distinct metadata in the session record.

| Pattern | Purpose | Key Identifier |
|---------|---------|--------------|
| **Branch** | Start a new independent conversation from an existing one | `kind: 'branch'` in `SessionSummary` |
| **Revision** | Edit and resend a previous turn, creating a new physical version | `revisionRootSessionId`, `revisionParentSessionId`, `revisionOfTurnId` |
| **Regeneration** | Re-run a completed turn to obtain fresh results | `regeneratedFromTurnId` in `TurnStateMessage` |

## How Maka Implements Session Branching

A **branch** represents a new logical conversation that begins from an existing session context without altering the original thread.

In [`packages/core/src/session.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session.ts) at line 166, the `SessionSummary` interface defines the `kind: 'branch'` discriminator. When a user creates a new session UI element, the desktop or TUI layer creates a branch session whose `id` is **independent of any revision lineage**. Unlike revisions, branches do not carry `revisionRootSessionId` or related fields—they are clean forks of conversation state.

```typescript
// Creating a branch session via the Runtime Host
await runtimeHost.createSession({
  kind: 'branch',
  parentSessionId: currentSession.id,  // optional: reference to originating session
  // No revision fields set—this is a clean fork
});

```

Branches appear as separate top-level entries in the session list. The `projectRevisionLinkedSessionTree` function in [`session-revisions.ts`](https://github.com/apache/maka/blob/main/session-revisions.ts) preserves branch relationships when building the UI projection, ensuring users can navigate between related but independent conversation threads.

## How Maka Implements Session Revision

**Revision** is Maka's mechanism for "edit and resend" functionality—allowing users to modify a previous turn and generate a new response while preserving complete history.

### Revision Metadata Fields

The revision system uses five core fields defined in [`packages/core/src/session.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session.ts) (lines 260–286):

- `revisionRootSessionId`: The original session that started the revision family
- `revisionParentSessionId`: The immediate parent session that spawned this revision
- `revisionOfTurnId`: The specific turn being edited and resent
- `revisionIndex`: The sequence number within the revision family
- `revisionState`: Either `'preparing'` or `'committed'`, tracking durability

### Creating a Revision Session

When a user edits a turn and resends, the UI creates a revision session:

```typescript
// UI command → Runtime Host
await runtimeHost.createSession({
  kind: 'revision',                     // <-- creates a revision session
  revisionParentSessionId: current.id,  // parent session that spawned this revision
  revisionOfTurnId: turnId,             // the turn being edited
  revisionRootSessionId: rootId,        // original session in this family
  revisionIndex: nextIndex,             // incrementing sequence number
});

```

### Collapsing Revisions for UI Display

Multiple physical revisions of the same logical conversation must appear as a single row in the UI. The `collapseSessionRevisions` function in [`packages/core/src/session-revisions.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session-revisions.ts) (lines 57–85) handles this:

```typescript
import { collapseSessionRevisions } from '@maka/core/session-revisions';

const visibleSessions = collapseSessionRevisions(allSessions, activeSessionId);
// `visibleSessions` now contains one row per revision family

```

The collapse algorithm works as follows:

1. **Collect families** using `sessionRevisionFamilyId(session)` from [`session.ts`](https://github.com/apache/maka/blob/main/session.ts)
2. **Pick a representative**—the most recent *visible* member, or the active session if present
3. **Discard non-visible revisions** from the projected view while retaining them in storage

### Building the Linked Session Tree

After collapsing, `projectRevisionLinkedSessionTree` in [`session-revisions.ts`](https://github.com/apache/maka/blob/main/session-revisions.ts) (lines 95–108) constructs the child-session tree that respects original parent-session anchors:

```typescript
import { projectRevisionLinkedSessionTree } from '@maka/core/session-revisions';

const linkedTree = projectRevisionLinkedSessionTree(allSessions, activeSessionId);
// UI uses `linkedTree` to render branches, revisions and their children

```

The UI layer in [`packages/ui/src/transcript-projection.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/transcript-projection.ts) subscribes to this projected list, ensuring users see one coherent conversation while the underlying database retains every physical revision for audit and replay.

## How Maka Implements Turn Regeneration

**Regeneration** re-runs a completed turn to obtain a fresh result, typically after a crash or when using "safe-resume" functionality. Unlike revision, regeneration preserves the original turn's identity and session structure—the new turn simply supersedes it in display.

### Regeneration Metadata

Two structures carry regeneration linkage in [`packages/core/src/session.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session.ts):

- `TurnStateMessage` (lines 15–19): Contains `regeneratedFromTurnId` pointing to the source turn
- `TurnRecord` (lines 72–90): Mirrors this field for persistent storage

### The Regeneration Execution Flow

The `AgentRun` controller in [`packages/core/src/agent-run.ts`](https://github.com/apache/maka/blob/main/packages/core/src/agent-run.ts) handles regeneration requests:

**Step 1:** Runtime Host creates a `RegenerateExecution` object:

```typescript
const execution: RegenerateExecution = {
  kind: 'regenerate',
  sourceTurnId: 'turn-42',  // the turn we want to redo
};

```

**Step 2:** `AgentRun.handleExecution` receives the request (lines 88–106):

```typescript
import { AgentRun } from '@maka/core/agent-run';

await AgentRun.execute({
  kind: 'regenerate',
  sourceTurnId: 'turn-42',
});

```

**Step 3:** After the model re-executes, the new turn records its provenance:

```typescript
// In the runtime, after model response arrives:
const newTurn: TurnStateMessage = {
  type: 'turn_state',
  id: uuid(),
  turnId: 'turn-99',
  ts: Date.now(),
  status: 'completed',
  regeneratedFromTurnId: 'turn-42',   // <-- points back to the original turn
};
await runtimeLog.append(newTurn);

```

**Step 4:** The UI treats the regenerated turn as a fresh turn in the same logical session, displaying the new assistant response without breaking conversation continuity.

## Comparing Revision and Regeneration

While both revision and regeneration produce new turns from existing ones, they serve distinct purposes:

| Aspect | Revision | Regeneration |
|--------|----------|--------------|
| **User intent** | "I want to change my question and get a new answer" | "I want to retry getting an answer to the same question" |
| **Session structure** | Creates new physical session in revision family | Keeps same session, adds new turn |
| **Original turn** | Preserved as historical version | Superseded by new turn |
| **UI presentation** | Collapsed into single visible row | Shows as replacement in timeline |
| **Fields used** | `revisionParentSessionId`, `revisionOfTurnId`, `revisionIndex` | `regeneratedFromTurnId` |

## Key Source Files and Their Responsibilities

| File | Purpose |
|------|---------|
| [`packages/core/src/session.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session.ts) | Defines `SessionSummary`, revision metadata fields, `TurnStateMessage`, `TurnRecord`, and `sessionRevisionFamilyId()` |
| [`packages/core/src/session-revisions.ts`](https://github.com/apache/maka/blob/main/packages/core/src/session-revisions.ts) | Implements `collapseSessionRevisions()` and `projectRevisionLinkedSessionTree()` for UI projection |
| [`packages/core/src/agent-run.ts`](https://github.com/apache/maka/blob/main/packages/core/src/agent-run.ts) | Handles `regenerate` execution kind in `AgentRun.handleExecution()` |
| [`packages/ui/src/transcript-projection.ts`](https://github.com/apache/maka/blob/main/packages/ui/src/transcript-projection.ts) | Consumes collapsed revision list for UI rendering |

## Summary

- **Branching** creates independent conversation forks via `kind: 'branch'` in `SessionSummary`, with no revision lineage attached.

- **Revision** implements edit-and-resend through five metadata fields (`revisionRootSessionId`, `revisionParentSessionId`, `revisionOfTurnId`, `revisionIndex`, `revisionState`) and collapses multiple physical sessions into one visible row via `collapseSessionRevisions()`.

- **Regeneration** re-executes turns safely using `kind: 'regenerate'` execution requests in `AgentRun`, linking new turns to originals through `regeneratedFromTurnId`.

- The projection layer in [`session-revisions.ts`](https://github.com/apache/maka/blob/main/session-revisions.ts) ensures users see coherent conversations while the runtime maintains complete immutable history.

## Frequently Asked Questions

### What triggers a session revision versus a branch in Maka?

A **revision** triggers when a user edits and resends an existing turn in the same conversation context—Maka creates a new physical session with revision metadata pointing to the original. A **branch** triggers when a user explicitly starts a new conversation thread from an existing one, creating a completely independent session with `kind: 'branch'` and no revision fields. The UI typically offers "Edit and resend" for revisions and "Start new chat" or "Branch here" for branches.

### How does Maka prevent revision history from cluttering the UI?

Maka uses the `collapseSessionRevisions()` function to group all physical revisions of the same family into a single visible row. The algorithm selects the most recent visible member or the active session as the representative, while the underlying `TurnRecord` and `SessionSummary` objects remain stored for audit. The UI projection in [`transcript-projection.ts`](https://github.com/apache/maka/blob/main/transcript-projection.ts) subscribes to this collapsed view.

### Can regenerated turns themselves be revised or branched?

Yes. Once a regenerated turn completes and is recorded with its `regeneratedFromTurnId` linkage, it becomes a normal turn in the session. Users can subsequently **revise** it (creating a new revision family) or **branch** from its session context. The regeneration metadata is preserved for lineage tracking but does not constrain future operations on the resulting turn.

### What happens to revision families when the root session is deleted?

The `sessionRevisionFamilyId()` function derives family identity from revision metadata fields rather than session existence alone. If a root session is deleted, its descendant revisions maintain their `revisionRootSessionId` reference to the deleted ID. The collapse algorithm in `collapseSessionRevisions()` continues to group these orphaned revisions by their declared family ID, though the oldest member may become the effective root for display purposes.