# LLM Compaction in Apache Maka: How It Manages Context Windows Without Losing History

> Discover LLM Compaction in Apache Maka, a projection technique that compresses chat history for limited context windows without losing critical information. Learn how Maka maintains auditability.

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

---

**LLM Compaction in Maka is a projection mechanism that creates compressed checkpoints of chat history when the Runtime Events Log exceeds the model's context window, replacing old events with a lossy summary while keeping the original log immutable for auditability.**

When building long-running AI sessions, every conversation, tool call, and diagnostic output gets appended to Maka's **Runtime Events Log**. As this log grows, it eventually bumps against the model's token limit. Rather than deleting or truncating history, Maka implements **LLM Compaction**—a deterministic, auditable compression system that projects a smaller, semantically coherent view to the model while preserving every original event for debugging and replay.

## What Is LLM Compaction

**LLM Compaction** is the process of folding a prefix of the Runtime Events Log into a compact checkpoint that can substitute for the original events in subsequent model requests. The checkpoint contains either a text summary generated by an LLM or a provider-native compact state (like OpenAI Codex's remote compaction). The key insight: this is a **projection**, not a mutation. The original events remain untouched; only what the model sees changes.

This design serves three goals:

- **Bounded context**: The model never receives more tokens than its window allows
- **Auditability**: Every event remains available for replay and debugging
- **Fail-open safety**: If compaction fails, the system falls back to the full log

## Core Architecture Components

Maka's compaction system spans several modules in `packages/runtime/src/`. Here's how the pieces fit together.

### Runtime Events Log

The **Runtime Events Log** is the canonical, append-only source of truth for all session activity—user messages, model completions, tool calls and results, and internal diagnostics. It lives implicitly across the runtime but is manipulated through the APIs in [`runtime-event.ts`](https://github.com/apache/maka/blob/main/runtime-event.ts).

### Safe Prefix Selection

Before any summarization happens, `selectSafeCompactionPrefix` in [`history-compaction.ts`](https://github.com/apache/maka/blob/main/history-compaction.ts) determines which contiguous prefix can be safely folded. This calculation respects:

- `reserveTailEvents`: Keeps recent events untouched
- `isPinned` flags: Prevents certain events from being compacted
- Tool call/result pairs: Never splits a pending tool operation

If no safe prefix exists, the compaction aborts with **fail-open semantics**—the original log proceeds to the model unchanged.

### Compaction Policy

When should compaction trigger? [`context-budget-policy.ts`](https://github.com/apache/maka/blob/main/context-budget-policy.ts) implements the **Compaction Policy** that watches for:

- Manual requests (`sessions:compact` command)
- Pre-turn capacity breaches
- Active-turn overflow during generation
- Provider-side context-length rejections

### Summarizer

The **Summarizer** ([`history-compact-summarizer.ts`](https://github.com/apache/maka/blob/main/history-compact-summarizer.ts)) transforms the selected prefix into a compact representation. Two modes exist:

| Mode | Implementation | Output |
|------|---------------|--------|
| Text-based LLM | Default `defaultSummarizer` | Plain text summary |
| Provider-native | [`openai-codex-history-compactor.ts`](https://github.com/apache/maka/blob/main/openai-codex-history-compactor.ts) | `openai.compaction` part |

### HistoryCompactCheckpoint

A **`HistoryCompactCheckpoint`** ([`history-compact-checkpoint.ts`](https://github.com/apache/maka/blob/main/history-compact-checkpoint.ts)) is the durable artifact created by compaction. It stores:

- **Coverage metadata**: Event count, SHA-256 digest of covered events, boundary ID
- **Compacted content**: Text summary or provider-native state
- **Lineage**: Optional `previousCheckpointId` for checkpoint chains

### Projection and Replay

When building the next provider request, [`ai-sdk-backend.ts`](https://github.com/apache/maka/blob/main/ai-sdk-backend.ts) runs the **prior-messages pipeline**:

1. Load the latest compatible checkpoint
2. Validate its `sourceDigest` against the immutable log
3. Materialize either a synthetic text checkpoint event or inject the provider-native state
4. Append the raw tail events (events newer than the checkpoint coverage)

The model receives this projected view seamlessly.

## How LLM Compaction Works: Step by Step

The compaction flow in [`history-compaction.ts`](https://github.com/apache/maka/blob/main/history-compaction.ts) follows seven deterministic stages:

1. **Trigger detection** — A `Compact` command arrives from policy or user action. No events are modified.

2. **Safe-prefix calculation** — `selectSafeCompactionPrefix` scans the ordered events, respecting constraints. Returns a boundary or fails open.

3. **Summarization** — The prefix (plus any newly folded events) passes to the configured `HistoryCompactionSummarizer`.

4. **Checkpoint construction** — `buildHistoryCompactCheckpoint` assembles the `HistoryCompactCheckpoint` with metadata, content, and lineage.

5. **Durable write** — The checkpoint persists atomically alongside an `AgentRunEvent` of type `history_compact_checkpoint_recorded`.

6. **Projection for next request** — The prior-messages pipeline validates and materializes the checkpoint, combining it with tail events.

7. **Auditability and replay** — Original events remain immutable. Debuggers can replay the full log; future compactions can fold further.

Every step through checkpoint construction is **pure and side-effect-free**. The runtime—not the LLM—retains authority over what gets projected, when it's used, and how it's validated.

## Working with LLM Compaction: Code Examples

### Manual Compaction from the Desktop Client

Trigger compaction programmatically via `RuntimeKernel.compactSession`:

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

await RuntimeKernel.compactSession({
  sessionId: 'abcd-1234',
  phase: 'standalone',          // Manual fold, not mid-turn
  orderedEvents: runtimeEvents, // Full ordered RuntimeEvent array
  summarize: async ({ coveredRuntimeEvents }) => {
    // Use default LLM text summarizer
    return await defaultSummarizer(coveredRuntimeEvents);
  },
});

```

This delegates to `planHistoryCompaction` in [`history-compaction.ts`](https://github.com/apache/maka/blob/main/history-compaction.ts), which orchestrates prefix selection, summarization, and checkpoint persistence.

### Programmatic Compaction in Custom Backends

For finer control, call `planHistoryCompaction` directly:

```typescript
import { planHistoryCompaction } from '@maka/runtime';
import { defaultSummarizer } from '@maka/runtime/ai-sdk-compaction';

const result = await planHistoryCompaction({
  sessionId: 'sess-001',
  phase: 'mid_turn',
  orderedEvents,
  headAnchor: { runtimeEventId: curEvent.id, turnId: curEvent.turnId },
  reserveTailEvents: 1,
  summarize: defaultSummarizer,
});

if (result.decision === 'compacted') {
  console.log('New checkpoint:', result.checkpoint.checkpointId);
  console.log('Token reduction:', result.tokensBefore - result.tokensAfter);
}

```

The result reports the checkpoint, replacement events, and token estimates.

### Inspecting Checkpoint Projections

Debug what the model will actually see:

```typescript
import { applyRuntimeEventHistoryCompact } from '@maka/runtime';

const replay = applyRuntimeEventHistoryCompact(
  runtimeEvents,
  { enabled: true, checkpoint: latestCheckpoint },
);

console.log('Effective events count:', replay.events.length);
console.log('First projected event:', replay.events[0]?.type);

```

`applyRuntimeEventHistoryCompact` validates the checkpoint's `sourceDigest` against the log before returning the projected list.

## Key Source Files

| File | Purpose |
|------|---------|
| [`packages/runtime/src/history-compaction.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/history-compaction.ts) | Safe-prefix selection, planning logic, fail-open handling |
| [`packages/runtime/src/history-compact-checkpoint.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/history-compact-checkpoint.ts) | Checkpoint schema, coverage validation, replay materialization |
| [`packages/runtime/src/history-compact-summarizer.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/history-compact-summarizer.ts) | Default LLM summarizer, prompt templates, repair logic |
| [`packages/runtime/src/openai-codex-history-compactor.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/openai-codex-history-compactor.ts) | Provider-native compaction for OpenAI Codex |
| [`packages/runtime/src/ai-sdk-backend.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/ai-sdk-backend.ts) | Prior-messages pipeline, checkpoint loading, request building |
| [`packages/runtime/src/context-budget-policy.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/context-budget-policy.ts) | Trigger conditions, capacity management, policy defaults |
| [`packages/runtime/src/runtime-kernel.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/runtime-kernel.ts) | Public `compactSession` API |

For the architectural narrative, see [`docs/architecture/llm-compaction-events-log-projection-draft.md`](https://github.com/apache/maka/blob/main/docs/architecture/llm-compaction-events-log-projection-draft.md).

## Summary

- **LLM Compaction in Maka** creates lossy, auditable checkpoints that project compressed history to models without destroying the original log
- The **Runtime Events Log** remains immutable; only the **view sent to the model** changes
- **[`history-compaction.ts`](https://github.com/apache/maka/blob/main/history-compaction.ts)** implements safe-prefix selection with fail-open semantics
- Checkpoints carry **SHA-256 digests** (`sourceDigest`) enabling validation and replay
- Two summarizer modes: **text-based LLM prompts** and **provider-native compaction**
- The system is **pure until durable write**, with the runtime—not the LLM—controlling all authority

## Frequently Asked Questions

### What triggers LLM Compaction in Maka?

**Compaction triggers from four sources**, all configured in [`context-budget-policy.ts`](https://github.com/apache/maka/blob/main/context-budget-policy.ts): manual commands like `sessions:compact`, pre-turn capacity checks that estimate token counts before generation, active-turn overflow when generation exceeds the context window, and provider-side rejections for context-length violations. The trigger itself never modifies events—it only emits a `Compact` command for the planner.

### Does LLM Compaction delete or lose my conversation history?

**No. History is never deleted.** The original Runtime Events Log stays append-only and immutable. Compaction creates a **projection**—a derived view that substitutes a checkpoint for old events **only in what the model sees**. Debuggers and future operations can always replay the complete log using `applyRuntimeEventHistoryCompact` or direct event inspection.

### What happens if the summarizer fails during compaction?

**The system fails open.** If summarization throws, checkpoint validation fails, or the durable write doesn't complete, [`history-compaction.ts`](https://github.com/apache/maka/blob/main/history-compaction.ts) abandons the compaction attempt. The original ordered events proceed to the model unchanged. This guarantees that a buggy summarizer or transient error won't break session continuity.

### Can I use provider-native compaction instead of LLM summarization?

**Yes.** Maka supports pluggable summarizers. The default `defaultSummarizer` in [`history-compact-summarizer.ts`](https://github.com/apache/maka/blob/main/history-compact-summarizer.ts) uses text prompts, but [`openai-codex-history-compactor.ts`](https://github.com/apache/maka/blob/main/openai-codex-history-compactor.ts) implements provider-native compaction that produces `openai.compaction` parts. Configure your summarizer in the `compactSession` or `planHistoryCompaction` call's `summarize` parameter.