Skip to content

Keep a long session inside the request budget

Localix shows the model a bounded view of a session while the stored transcript stays whole. Use this page to understand what the agent still sees after a long conversation, and how to keep a message in its view.

Terminology

TermMeaningBoundary
Request ceilingThe context limit, or the window minus the response reserve; every request must fit it.Per model from the catalog window, capped by delegation depth.
ViewThe model-facing copy of the conversation one agent reads on a turn.Stored messages are never rewritten to build it.
CheckpointA one-time, model-free re-plan of the view when it reaches the high-water mark.Between checkpoints the view is only appended to.
Epoch cardA short deterministic summary of evicted turns: files, commands, errors, requests, last answer.Lists facts; it does not carry the reasons behind decisions.
PinA person's mark that keeps one message whole in the agent's view.Set from the message context menu; stays within the current topic.

What you can do

ActionResultBoundary
Set the context limitModel details → Context limit: Auto, a token step the model holds, or Full.Shown only for a model whose window exceeds 272k plus its reserve.
Watch the usage ringSee request size against the ceiling and the Next checkpoint at figure.Limits arrive with a run's first snapshot, at the session's depth.
See where the view beginsAn Earlier turns checkpointed divider marks the last evicted message.Only the newest checkpoint is drawn; an old topic boundary removes the line.
Keep a message wholeRight-click a message → Pin to agent context; a pinned mark appears under it.The next checkpoint preserves it; a late pin uses a bounded context insert.
Start a clean contextOpen a new chat.Earlier messages stay visible in the stored transcript.
Recover older outputThe agent follows ToolOutput handles or GlobalSearch pointers.The tool must be in the agent's roster for its pointer to appear.
Replay a stored sessionRun replay-context-policy <sessionId> against localix.db.Read-only; prints every number a checkpoint decision turned on.

Context limit

The context limit is how many tokens a request may hold before a checkpoint reshapes the view. It is set per agent and model, like a reasoning level, and offered from the model's own window:

ChoiceRequest ceiling
Automin(272,000, window − reserve); the default.
Steps128k, 200k, 400k, 600k, 1M, 2M, 5M or 10M — those below Full.
FullThe whole window minus the response reserve.

A model whose Auto already is its whole window (up to about 302k) shows no setting. Long contexts cost more on every request and recall worse, so Auto stops at 272k even on a 1M window; choose a larger step when a task needs it, or a smaller one to save cost. A step remembered from a larger model reads as this model's Full.

No command summarizes the conversation with a model. The runtime checkpoints on its own, and /compact asks for one by hand: every agent of the chat takes a checkpoint on its next turn, whatever was measured, and a conversation already below the target is left whole. Text after the command, as in /compact keep the plan, goes to Claude Code's PreCompact hooks as custom_instructions; the cards are written without a model, so it does not steer them.

When a card's request list must shrink, it retains the newest requests. Trusted amendments from a delegator remain labeled assignment update; ordinary runtime wakes are not quoted as requests. These are bounded records, not a complete copy of every instruction: recover the original message when a clipped detail matters.

How it works

One history strategy, two moments

Every run — the interactive chat, a delegated task run, a delegated sub-agent, a loop round, a hook verifier — turns its stored transcript into a model request through the one chat-hybrid history strategy. A sub-session is an ordinary session with a narrower tool surface, not a different runtime.

MomentWhenWhat it does
MaterializeOnce per turn, before the first requestRuns the stages below over the stored rows and the frozen view.
RequestBefore every provider request in the turnPrunes only near the ceiling; a prune asks the next turn to checkpoint.

Side effects (mini app prompt rewrites, Claude Code prompt hooks, job and diagnostics snapshots) happen once, in the intake step. Everything after intake is pure, so a retry re-derives the same wire from the same frame without re-firing a hook.

Materialize runs these stages in order. The list is pinned by a repository test against the stage sources, so a stage cannot be added or renamed without this page changing:

StageKindEffect
clear-cutLoad-bearingDrops the latest stored /clear or topic boundary and everything before it.
agent-historyLoad-bearingKeeps the agent's own rows with their structured work, drops empty silent rows, and passes every other row through.
turn-contextLoad-bearingPuts every past turn's stored runtime context back before the reply it preceded, and appends this turn's — only the sections that changed — last.
mediaSeamRows become model payloads: steer notes, invocation text, media rehydration, spill, image downscale.
checkpointLoad-bearingApplies the frozen checkpoint in force; when one is due, plans a new one without a model call (mask and fold first, then evict the oldest turns into epoch cards).
preflightLoad-bearingRefuses an active turn, or first task + active turn, that no checkpoint could fit.
admissionLoad-bearingFinal measured-or-estimated size against the ceiling; a view that does not fit and took no checkpoint takes one.

A load-bearing stage that fails ends the run with a typed local budget error. No stage rewrites a stored message.

Topic boundaries and late pins

No agent tool places a topic boundary. A session that already holds one keeps it. Everything before the boundary stays in the stored transcript but leaves subsequent requests, and the saved summary carries forward what still matters.

A message pinned after a checkpoint may already be folded or evicted. Until the next checkpoint preserves it in the view, the runtime inserts its text into a # Pinned messages section, capped at 4,000 characters per message with middle truncation. That temporary text is not an exact replay of attachments or tool results. Pins can increase context pressure; they do not create extra request capacity.

Append-only between checkpoints

The same stored rows produce the same request bytes on every turn until the next checkpoint. That keeps the provider's prefix cache warm and keeps preserved thinking valid, since a model's signed reasoning is bound to the exact prefix before it.

Kept stableHow
Runtime contextKeyed sections; a turn stores and sends only what changed, as a <runtime-context update>.
Mid-run factsA job finishing mid-turn rides the tool result it arrived with, not a separate message.
Invocation text and imagesAttached on every turn, not only on the newest one.
Superseded live-state outputCollapsed only at a checkpoint, never between.

The runtime context and each checkpoint are stored per assistant turn in the agent_message_model_context table, written before the request is sent. A crash mid-run therefore never leaves a sent request the log cannot rebuild.

When a checkpoint is taken

SignalResult
Last provider-measured request ≥ 85% of ceilingThe next turn takes a checkpoint.
Last measured request ≥ 72% of ceilingThe agent is told once that a checkpoint is near, so it can save to memory.
The in-run safety net had to pruneThe next turn takes a checkpoint.
The built view does not fit the ceilingThis turn takes a checkpoint and rebuilds.
Provider overflow or a silently empty responseA checkpoint is taken and the turn reruns once.

A checkpoint cuts the view to about 30% of the ceiling, or a quarter of the history budget on a small window. It first masks old tool observations and folds long assistant answers to their head and tail. Only if that is not enough does it evict the oldest whole turns, always cutting before a user turn. Eviction never undoes an earlier eviction.

Evicted turns become epoch cards. Cards degrade from the oldest first when they exceed 12% of the target. Pinned messages that fall inside an evicted range stay verbatim after the cards. Kept rows lose their stored reasoning, which a rewritten prefix would invalidate anyway.

What the agent is told

SectionWhen it appears
# Context checkpoint aheadOnce, past the 72% mark: what a checkpoint keeps of older turns.
# Pinned messagesA pin the checkpoint in force shows only in part or not at all.

Cards and folded answers point at GlobalSearch(around_message_id="…"), which scrolls around a message without needing its session id. The pointers appear only when GlobalSearch is in the agent's roster.

Hooks

A checkpoint is this runtime's compaction for Claude Code hooks. PreCompact fires before the checkpoint is committed, with trigger auto, or manual and the typed text as custom_instructions after /compact; PostCompact follows with the same trigger. A block skips the checkpoint, as Hooks and commands describes. The next run fires SessionStart with source compact, so a hook can re-inject context the new view no longer carries.

Request budget

ControlCurrent rule
Policy windowThe smallest window whose ceiling is the context limit, at most the catalog window (128,000 when unknown); capped by depth.
Cap by depthNone for a conversation, 128,000 for its child, 64,000 below
Response reservemax(min(16,384, 20% of window), 10% of window)
Request ceilingPolicy window minus response reserve: the context limit, or less where the window or depth cap is smaller.
Checkpoint mark85% of the ceiling
Checkpoint target30% of the ceiling minus fixed overhead, at least 25% of history budget
Protected tailUp to 8 recent messages within clamp(15%, 16,384, 65,536) tokens

How a request is sized

SourceRule
Provider measurementThe newest assistant turn's contextTokens, valid within the same view epoch, prompt, tools and model.
Trailing estimateMessages after that measurement are estimated at ~4 UTF-8 bytes per token of their wire JSON.
Images and mediaA flat 1,600-token allowance per part until the model has taught its real cost.
Learned calibrationMeasured requests teach a per-model text scale and per-image cost by moving average; process-lived.

A checkpoint is scheduled only from a provider measurement. A heuristic figure near the mark waits for the next measured request; only a view that exceeds the ceiling checkpoints on an estimate.

Recovery handles

Completed tool calls cross a durable artifact barrier before the next model request, so masking can cite the original tool_call_id. Run preparation requires ToolOutput with its get operation.

Recovery pathWhat it restoresBoundary
ToolOutputStored text or successful mutation input.Active branch only; one replay is clipped at 100,000 characters.
GlobalSearchMessages around an evicted or folded message.This user's history only.
Read or rerunCurrent files or reproducible command output.Required for stale reads or unstored detail.

Configuration

ControlEffectBoundary
Pin to agent context / Unpin from agent contextKeep a message whole in the agent's view.Not offered for hidden internal messages.
bun apps/api/scripts/replay-context-policy.ts <sessionId>Print measured sizes, pressure bands and a checkpoint planned now.Read-only against the database.
bun apps/api/scripts/check-compression.ts <raw.json> [--context-window N]Report token sources and how far masking and folding get alone.Does not plan the eviction.

Limits

  • Epoch cards list facts, not reasoning. What must survive with its reasons belongs in memory or a pin.
  • Masking cannot restore bytes a tool removed earlier by paging, truncation or an output cap.
  • ToolOutput restores text, not image-only media.
  • A checkpoint cannot shrink an oversized active user turn or reclaim the system prompt and tool roster. Large pins can also prevent sufficient history reduction. Localix reports those as separate local budget failures.

Source of truth