Apache Maka History Compaction and Context Budget Policy Explained

Apache Maka uses a two-tier system to manage conversation history: automatic history compaction with checkpoint-based recovery and per-session token budgets enforced at the UI layer.

Maka, an open-source AI conversation platform, implements sophisticated memory management to handle unbounded chat transcripts without degrading performance. The history compaction mechanism archives older conversation segments while preserving reconstructability, and the context budget policy places hard limits on token consumption per session. Both systems are integrated across the UI (packages/ui) and storage (packages/storage) layers.

How History Compaction Works in Maka

Maka's history compaction operates on the long-term memory (LTM) store, automatically reducing in-memory footprint while maintaining the ability to rebuild full conversation context when needed.

Compaction Triggers and Checkpoints

When the storage layer receives a compaction request with trigger = 'compaction', it writes a compaction checkpoint that marks the boundary between retained and archived history. The checkpoint ID (compactionCheckpointId) is stored with operation metadata, allowing subsequent reads to locate the correct history slice.

In packages/storage/src/sqlite-long-term-memory-store.ts, the compaction logic:

  • Persists checkpoint references per session
  • Enables incremental reconstruction of trimmed transcripts
  • Coordinates with the schema defined in sqlite-long-term-memory-schema.ts

Handling Compaction Failures

Not all compaction attempts succeed. When policy violations occur—such as missing checkpoints or concurrent modification conflicts—the system records a compaction policy denial in memory_compaction_policy_denials. The UI surfaces these failures through the error key context_compaction_failed_open, defined in packages/ui/src/materialize.ts:

// From materialize.ts - fallback copy when compaction context cannot be opened
export const COPY_CONTEXT_COMPACTION_FAILED_OPEN = 'context_compaction_failed_open';

This string renders a user-facing message explaining that the conversation context could not be reconstructed due to compaction.

UI History Management

The composer layer maintains a bounded in-memory history separate from LTM compaction. In packages/ui/src/composer-helpers.ts:

// Maximum entries kept for arrow-key navigation
export const COMPOSER_HISTORY_MAX_ENTRIES = 50;

// Append with automatic truncation
export function rememberComposerHistoryEntry(
  entries: ComposerHistoryEntry[],
  entry: ComposerHistoryEntry
): ComposerHistoryEntry[] {
  const updated = [...entries, entry];
  // Oldest entries drop off when exceeding 50
  return updated.slice(-COMPOSER_HISTORY_MAX_ENTRIES);
}

The reconcileHistorySync function merges this bounded history with localStorage, handling three states:

  • Empty persisted state: Resets navigation index to -1
  • Null persisted state (read failure): Preserves in-memory entries
  • Valid persisted state: Replaces current history with stored version

Context Budget Policy Implementation

While compaction manages storage bounds, context budgets enforce runtime token limits that prevent prompt overflow.

Budget Definition and Display

Each session (and constituent skills) may declare a token budget. The UI renders this as a usage chip showing "spent / budget" format. In packages/ui/src/session-context-layer.tsx, the display logic follows this pattern:

/** When present (a budget exists), the chip shows spent / budget. */
interface SessionContextLayerProps {
  budget?: {
    spent: number;
    limit: number;
  };
}

The chip appears conditionally—only when a budget is configured for the current session context.

Budget Enforcement Flow

  1. Token accounting: The runtime deducts generated tokens from budget.spent after each model turn
  2. Threshold checking: Before initiating a new generation, the system verifies sufficient headroom exists
  3. UI gating: When spent >= limit, interactive elements (continue buttons, send actions) disable until budget refresh

Interaction with Compaction

Budget exhaustion can trigger preventive compaction. The telemetry system tracks these decisions:

// From telemetry-file-schema.ts - compaction decision tracking
interface CompactionDecisions {
  budgetForced: number;      // Compactions triggered by budget limits
  storageForced: number;     // Compactions triggered by storage pressure
  policyDenied: number;      // Failed compaction attempts
}

Operators monitor budgetForced versus storageForced ratios to tune budget allocations.

Practical Integration Example

import { 
  rememberComposerHistoryEntry,
  navigateComposerHistory,
  reconcileHistorySync 
} from '@maka/ui/composer-helpers';

// 1. Initialize with persisted history or empty array
let history = reconcileHistorySync([], localStorage.getItem('composerHistory'));

// 2. User submits prompt - append with automatic 50-entry limit
history = rememberComposerHistoryEntry(history, {
  role: 'user',
  content: userInput,
  timestamp: Date.now()
});

// 3. Arrow-up navigation retrieves previous entry
const { value } = navigateComposerHistory(
  { entries: history, index: -1, savedDraft: '' },
  'previous',
  currentDraft
);

// 4. Storage layer handles compaction independently
//    Budget exhaustion may trigger automatic checkpointing

Key Source Files Reference

Component Path Responsibility
Composer history helpers packages/ui/src/composer-helpers.ts 50-entry bounded history, navigation, localStorage reconciliation
Budget UI layer packages/ui/src/session-context-layer.tsx Token usage chip, budget presence detection
Compaction storage packages/storage/src/sqlite-long-term-memory-store.ts Checkpoint persistence, LTM operations
Compaction schema packages/storage/src/sqlite-long-term-memory-schema.ts memory_compaction_policy_denials table structure
Telemetry packages/storage/src/telemetry-file-schema.ts compactionDecisions counter definitions
Error handling packages/ui/src/materialize.ts context_compaction_failed_open copy constants

Summary

  • History compaction archives older transcripts via checkpoint IDs stored in SQLite, with COMPOSER_HISTORY_MAX_ENTRIES = 50 bounding the active navigation history
  • Context budgets enforce per-session token limits rendered as "spent / budget" chips in session-context-layer.tsx
  • Failure modes are logged to memory_compaction_policy_denials and surfaced through materialize.ts error keys
  • Telemetry integration enables monitoring of budget-forced versus storage-forced compaction decisions

Frequently Asked Questions

How does Maka decide when to compact history?

Maka compacts history when storage receives an explicit compaction trigger or when context budget limits would be exceeded. The sqlite-long-term-memory-store.ts module writes a compactionCheckpointId marking the archive boundary, while telemetry tracks whether compactions are budget-forced or storage-forced.

What happens if I navigate backward through history after compaction?

The in-memory history retained for navigation—capped at 50 entries in composer-helpers.ts—remains available for arrow-key traversal. Older entries beyond the checkpoint require reconstruction from LTM storage; if that fails, the UI displays context_compaction_failed_open from materialize.ts.

Can context budgets be configured per skill rather than per session?

Yes. The session-context-layer.tsx component receives budget data through props, and the underlying system supports skill-level budget declarations. Each skill's token consumption aggregates to the session total shown in the budget chip.

Where are compaction policy violations recorded?

Failed compaction attempts are written to the memory_compaction_policy_denials table defined in sqlite-long-term-memory-schema.ts. This schema enables debugging of checkpoint conflicts and policy enforcement gaps without interrupting user sessions.

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 →