Part I followed one task through the runtime. Part II separated long-lived memory ledgers from transcript. This chapter starts after that split: the word context
is overloaded. In Claude Code it can mean project memory, user instructions, repository status, visible conversation messages, hidden runtime metadata, compact summaries, or API request blocks. Reading the code becomes easier once those surfaces are separated.
type ContextSurfaces = {
durableTranscript: Message[]
baseContext: SystemContext | UserMemory
modelVisibleView: ProviderMessage[]
pressureRelief: "replacement" | "collapse" | "compact"
recoveryBoundary: "compact summary" | "resume replay"
}
1. Context starts before the chat history
The initial user and system context are built outside the model loop. User memory can come from CLAUDE.md files and related memory sources. System context captures facts such as the working directory, git state, and environment details. Later, appendSystemContext() and prependUserContext() place those facts into the provider request in different positions.

2. The model-visible view is rebuilt every turn
Inside queryLoop(), the runtime constructs the current API view. It does not blindly replay the whole transcript. It starts from the active compact boundary, applies the tool-result budget, lets HISTORY_SNIP lower historical pressure when that feature is present, runs microcompact, projects any committed Context Collapse summaries, and only then asks whether auto compact must take over.
That difference explains a common surprise: a message can be visible in local history, present in transcript storage, and still absent from the next API request. Context management is a projection problem.
3. Pressure is layered
Context pressure arrives from multiple directions. Tool results can be large. Repeated edits can create bulky replacement state. Long reasoning chains add assistant blocks. System and memory context consume prefix space before the conversation even begins. The runtime therefore has several valves, not one big summarizer.

4. Compact is a boundary, not just shorter text
A compact operation creates a new boundary in the conversation. From that point, later API requests can reason from a compacted representation instead of replaying every earlier message. This is why compact metadata matters to resume and recovery. The runtime needs to know not only the summary text, but also where the old context ended and which local state still belongs to the session.
The summary is also a model request, not an editorial afterthought. The compact path builds a no-tools summary request, installs the resulting summary as a recovery message, and can share the parent prompt-cache prefix for that side path. That is the bridge to the final chapter: summary quality matters, but request shape still decides how expensive the handoff becomes.

5. Microcompact handles local pressure
Microcompact is a smaller valve. It is used to control high-pressure parts of the prompt without forcing a full user-facing compact. The source separates three cases that are easy to blur together. HISTORY_SNIP runs before microcompact and returns a tokensFreed estimate so later auto-compact checks do not overcount the surviving assistant usage.
What does snip do? It is not a clock-based deletion of the oldest prefix. If the first user message contains the task, constraints, and acceptance criteria, deleting from the beginning would lose the point of the session. Claude Code already has compact boundaries for prefix replacement. Snip is the smaller operation for selected middle ranges inside the active context.
Who decides that a range is low-value? The public code shows that Claude Code registers a feature-gated SnipTool, adds stable [id:...] tags to API-bound user messages so Claude can reference exact messages, and injects a context_efficiency attachment after enough context growth without a snip. So low-value
is not a visible timestamp heuristic in the public source. It is a model-participating context-retention decision: which middle messages are no longer critical for the task, file state, tool references, or user constraints, and can therefore leave the next model-visible view.
Not this:
U0(initial task) A1 T1 A2 T2 ... A80 T80
-> delete the oldest N messages by age
Closer to this visible contract:
API-bound copy: U0[id:a1] A1 T1 U2[id:b7] ... U80[id:k9]
snip boundary: removedUuids = [uuid(T12), uuid(A13), uuid(T13), ...]
next API view: U0 A1 T1 U2 ... [middle range filtered] ... U80
Local UI / JSONL:
original messages remain; resume replays the same removedUuids deletionThe feature-gated selector implementation is not present in the public TypeScript tree, so the exact SnipTool prompt, scoring rule, threshold, and selector policy are not visible. The surrounding contracts are clear, though. Model-facing paths call projectSnippedView() after the compact-boundary slice, while UI rendering can pass includeSnipped: true so scrollback still shows the full local history. Resume code records removedUuids on the snip boundary, deletes those middle ranges on load, and relinks parent pointers across the gap. Source comments also say tool-reference-bearing messages are protected from snip. In other words, snip removes selected middle ranges from the next model-visible view; it does not rewrite old tool results into a placeholder and it does not erase the append-only transcript evidence.
Time-based microcompact is the path that replaces old tool results with [Old tool result content cleared]; its own comment says this fires when the server cache is already cold, so the next request would rewrite the prefix anyway. Cached microcompact is different again: when cache editing is available, local messages stay unchanged and Claude Code first records pendingCacheEdits. Later, services/api/claude.ts, the Anthropic API adapter inside Claude Code, translates those edits into a cache_edits block while building the provider payload.
This should not be confused with ordinary public prompt caching. Public Anthropic prompt caching is centered on cache_control, cache writes, and cache reads. The source path for cached microcompact additionally requires the feature gate, model support, a firstParty main-thread request, and a cache-editing beta header. So cache_edits is best read as a first-party beta cache-editing capability expressed through the Anthropic Messages API payload, not as a stable field available to every ordinary Messages API caller.
shape-level payload fragment:
{
"type": "tool_result",
"tool_use_id": "toolu_abc",
"cache_reference": "toolu_abc",
"content": "..."
}
{
"type": "cache_edits",
"edits": [
{ "type": "delete", "cache_reference": "toolu_abc" }
]
}cache_reference names the cached old tool result; cache_edits asks the cache-editing path to delete that reference.The point of cache_edits is reference-based deletion. Claude Code marks cached-prefix tool_result blocks with cache_reference, usually the original tool_use_id. A cache_edits block then says to delete a specific cache_reference. The local transcript still keeps the full tool result, but the provider-side cache view can drop that old result. Inserted edits are pinned to the same user-message position and resent so the request prefix remains stable. The later cache_deleted_input_tokens usage field is used to report how many tokens the provider actually deleted. Snip can still change prompt-cache shape because the provider sees a shorter message sequence, but that is a model-view projection, not the placeholder path and not the cache-edit path.
Context Collapse is another projection layer, not simply a synonym for full compact. The shape is: archived span summary from the collapse store plus the newer incremental messages after that span. The REPL history and recovery metadata remain owned outside the API payload. This can change prompt-cache shape on the transition where the provider first sees the shorter projected prefix, but it also creates a smaller stable prefix for subsequent turns and can avoid a more destructive auto compact.
6. Recovery needs more than a summary
Resume code loads conversation messages, file history, content replacement state, compact-collapse metadata, and session metadata. That is a stronger claim than load the old transcript
. The runtime wants to rebuild a state that can continue making tool calls, checking permissions, and projecting a request correctly.

7. The invariant
Context management is the art of preserving the right facts at the right layer. Memory influences the prefix. Transcript preserves evidence. Compact rewrites the route back into old work. Microcompact reduces local pressure. Prompt cache rewards stable request shape. Once those layers are separate, the code stops looking like a pile of special cases.
Sources
The source-code claims in this article are based on the public mirror and the linked official documentation. Server-side behavior and private feature-gate policy are treated only as client-visible request shape.
- Context builders
- API context insertion
- QueryLoop context projection
- SnipTool feature-gated registration
- Snip message ID tags
- Context efficiency snip nudge
- Snip projection in active message view
- Snip removal replay on resume
- Tool-reference messages protected from snip
- Cached microcompact gate and model support
- Cache editing beta header
- Anthropic API adapter cache edits
- Conversation recovery
- Claude Code memory docs
- Xiaolin Coding context compaction reference (Chinese)