How Maka Handles Context Compaction and History Pruning: A Two-Step Projection System
Maka reduces LLM context usage through a deterministic two-step process—selecting a safe prefix of immutable events and building a durable checkpoint—while preserving replayability and auditability.
Maka implements context compaction and history pruning to keep conversation history within provider token limits without sacrificing the ability to reconstruct, audit, or replay sessions. This article examines the runtime mechanisms, source file locations, and practical usage patterns based on the actual implementation in apache/maka.
The Two-Step Compaction Architecture
Maka's compaction system operates as a projection layer over an immutable ledger of RuntimeEvent records. Rather than mutating history, it creates a checkpoint that summarizes a safe prefix of events, then projects future requests from that checkpoint plus remaining uncovered events.
Step 1: Selecting a Safe Compaction Prefix
The selectSafeCompactionPrefix function in [packages/runtime/src/history-compaction.ts](https://github.com/apache/maka/blob/main/packages/runtime/src/history-compaction.ts) scans the event ledger to identify the largest contiguous prefix that can be safely summarized.
This function enforces structural safety invariants:
- No split streaming snapshots — partial snapshots are excluded from the prefix
- No split pinned events — pinned messages remain intact
- No orphaned tool calls — the
toolPairSpanshelper ensures tool-call/result pairs are never separated
The algorithm preserves a configurable tail of uncovered events to maintain conversational continuity. This deterministic selection guarantees that the remaining ledger remains immutable and replayable even after compaction.
Step 2: Building a Compact Checkpoint
Once a safe prefix is selected, buildHistoryCompactCheckpoint in [packages/runtime/src/history-compact-checkpoint.ts](https://github.com/apache/maka/blob/main/packages/runtime/src/history-compact-checkpoint.ts) constructs a durable checkpoint containing:
- Coverage bounds of the selected prefix
- A source digest for integrity verification
- V2: a text summary generated by a summarizer model
- V3: provider-native state (for compatible LLM providers)
The checkpoint is stored as an AgentRun event and referenced by future turns through the ContextCompactionOutcome type defined in [packages/core/src/events.ts](https://github.com/apache/maka/blob/main/packages/core/src/events.ts).
Automatic Triggering and Token Estimation
Compaction occurs automatically when the runtime detects an impending context overflow. The estimateNextRequestTokens function predicts token usage for the upcoming provider call. If this exceeds the model's configured high-water mark (exceedsHighWater), compaction is triggered before the request is built.
import { RuntimeKernel } from '@maka/runtime';
// Compaction happens automatically during normal operation
// when token estimates exceed thresholds
await kernel.processTurn({
sessionId: 'my-session-id',
messages: newMessages,
// The runtime internally calls:
// 1. estimateNextRequestTokens()
// 2. selectSafeCompactionPrefix() if needed
// 3. buildHistoryCompactCheckpoint() to create projection
});
Fail-Open Behavior and Context Budget Exhaustion
Maka implements defensive degradation when compaction cannot produce a valid result. If the summarizer returns empty output, or if the input still exceeds budget after prefix selection, the system follows a fail-open path:
- The turn is marked with
context_compaction_failed_open - The original, uncompacted history is sent to the provider
- The session ends with
context_budget_exhausted
This behavior ensures that user requests are not silently dropped, while clearly signaling that the conversation has reached architectural limits.
History Pruning Through Deterministic Omission
History pruning uses the same safe-prefix algorithm as compaction. When tool-call/result pairs exceed the available context budget, Maka may:
- Omit older tool-result payloads
- Replace them with a fixed omission marker
- Preserve the call/response relationship for audit purposes
This approach maintains ledger integrity without requiring speculative edits. The pruned events remain reconstructible from earlier checkpoints in the event stream.
Practical Usage Examples
Manual Session Compaction (Desktop Command)
Trigger compaction explicitly using the sessions:compact command:
import { RuntimeKernel } from '@maka/runtime';
await kernel.compactSession({
sessionId: 'my-session-id',
// Optional: force a specific checkpoint ID
// checkpointId: 'checkpoint-123',
});
This creates a new Turn/Run, executes the two-step compaction process, and attaches the outcome to ContextCompactionOutcome.
Inspecting Compaction Outcomes
Examine compaction results from completed turns:
import { readTurn } from '@maka/runtime-host';
const turn = await readTurn('session-42', 'turn-7');
if (turn.contextCompactionOutcome) {
console.log('Compaction result:', turn.contextCompactionOutcome);
// Possible values:
// { kind: 'compacted', checkpointId: string }
// { kind: 'failed', reason: 'context_budget_exhausted' }
}
The TurnSnapshot type in [packages/runtime-host/src/protocol/turn.ts](https://github.com/apache/maka/blob/main/packages/runtime-host/src/protocol/turn.ts) defines this structure.
Rendering Compaction Notices in the UI
Display user-friendly compaction events:
import { contextCompactionNotice } from '@maka/desktop/app-shell-context-compaction';
function onCompaction(outcome: ContextCompactionOutcome) {
const notice = contextCompactionNotice(outcome, uiLocale);
presentTerminal(sessionId, notice);
}
The helper in [apps/desktop/src/renderer/app-shell-context-compaction.ts](https://github.com/apache/maka/blob/main/apps/desktop/src/renderer/app-shell-context-compaction.ts) formats outcomes for terminal presentation.
Key Source Files and Architecture References
| File | Purpose | Location |
|---|---|---|
history-compaction.ts |
Safe-prefix selection, token estimation, high-water checks | packages/runtime/src/history-compaction.ts |
history-compact-checkpoint.ts |
Checkpoint construction, validation, serialization (V2/V3) | packages/runtime/src/history-compact-checkpoint.ts |
events.ts |
ContextCompactionOutcome type definition |
packages/core/src/events.ts |
turn.ts |
Turn snapshot protocol including compaction outcomes | packages/runtime-host/src/protocol/turn.ts |
app-shell-context-compaction.tsx |
UI notice rendering for compaction events | apps/desktop/src/renderer/app-shell-context-compaction.ts |
ARCHITECTURE.md |
High-level compaction node in backend architecture | Repository root |
llm-compaction-events-log-projection-draft.md |
Detailed projection model and fail-open design | docs/architecture/ |
Summary
- Two-step projection: Maka compacts context through
selectSafeCompactionPrefix(safe prefix selection) andbuildHistoryCompactCheckpoint(checkpoint construction) - Immutable ledger: All operations preserve event immutability and replayability
- Automatic triggering: Token estimation via
estimateNextRequestTokensdrives compaction decisions - Fail-open safety: Invalid compactions fall back to uncompacted history with explicit failure markers
- Deterministic pruning: Tool pairs and structural boundaries are respected during history reduction
- Provider flexibility: V2 text summaries and V3 native states accommodate different LLM capabilities
Frequently Asked Questions
What triggers context compaction in Maka?
Maka triggers compaction when estimateNextRequestTokens predicts that the next provider call would exceed the model's configured high-water mark. This automatic check runs before each turn, ensuring proactive rather than reactive context management.
Can I manually force compaction without waiting for automatic triggers?
Yes. Use kernel.compactSession({ sessionId }) from @maka/runtime or invoke the desktop command sessions:compact. This creates a new checkpoint immediately, useful for long-running sessions where you want to guarantee available context headroom.
What happens if the summarizer fails to produce valid output?
Maka follows a fail-open path: the turn receives context_compaction_failed_open, the original uncompacted history is sent to the provider, and the session terminates with context_budget_exhausted. This guarantees user visibility into the failure while preventing silent data loss.
Does history pruning break the ability to replay or audit sessions?
No. Pruning operates on the same safe-prefix algorithm as compaction, using deterministic rules that preserve structural integrity. Omitted tool results are replaced with fixed markers, and checkpoints maintain source digests. The full event ledger—including compaction events—remains immutable and reconstructible.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →