Skip to content

Claude Code Memory

On March 31, 2026, Anthropic accidentally shipped a source map in the @anthropic-ai/claude-code npm package. The file contained roughly 512,000 lines of TypeScript, including the full memory and context-management architecture. Anthropic confirmed it was a packaging mistake, not a breach. The leak is useful not for the code itself, but for what it reveals about how a multi-billion-dollar coding agent is engineered.

The headline finding: Claude Code is roughly 1.6% AI decision logic and 98.4% deterministic infrastructure — permissions, context management, tool routing, and recovery. Memory is not a feature; it is the harness.

KrokiKroki

From three layers to eleven subsystems

Public summaries often called Claude Code's memory a three-layer architecture. The leaked code showed at least eleven interacting subsystems. They map cleanly onto the four CoALA memory types:

  • Procedural: modular system prompt, tool descriptions, behavior rules.
  • Semantic: MEMORY.md index, CLAUDE.md hierarchy, project and user notes.
  • Episodic: background extraction agent that records lessons from each turn.
  • Working: assembled context window, session notes, recent history.

Seven memory layers in the leaked code

While public summaries described three layers, a source-code analysis of the leaked build organizes the memory system into seven layers [luyao618, 2026]:

Layer Storage Lifetime Responsibility
CLAUDE.md Project / user / managed / local directories Permanent Human-authored static instructions
Auto Memory (memdir) ~/.claude/projects/<slug>/memory/ Cross-session Automatically extracted persistent knowledge
Background Extract Memories Same memdir Cross-session Background worker extracts candidate memories from transcript
Session Memory ~/.claude/projects/<slug>/<sessionId>/session-memory/summary.md Single session Structured notes for current session
Agent Memory Three scope directories Cross-session Dedicated memory for a specific agent
Relevant Memories Attached on demand Per-turn Recalled and injected as attachments
Auto Dream Writes back to memdir / Agent memory Idle consolidation Deduplicate, rewrite, and compress memories

These layers address memory at different timescales and granularities; the earlier "eleven subsystems" framing counts internal services such as compaction, tool routing, and permission checks.

How the context window is built

The prompt is divided into two zones:

  1. Static zone at the top. Behavior rules, style, and tool instructions. Shared across requests and globally cached.
  2. Dynamic zone below. MEMORY.md, CLAUDE.md, environment, language, compact summary, conversation history, tool results, and memory attachments.

This order is deliberate. Static instructions live at the top; dynamic memory lives at the bottom. The model pays most attention to the start and end of the context, so the conversation history sits in the middle — the least attended region.

CLAUDE.md: four-level instruction hierarchy

Instructions are loaded from four levels, closer directories taking priority:

  1. Managed (/etc/)
  2. User (~/.claude/)
  3. Project (CLAUDE.md, .claude/rules/)
  4. Local (CLAUDE.local.md, gitignored)

Priority is implemented by position, not by conditional code. The project-level file is loaded last, so it appears near the end of the context where the model attends more. The combined instructions are memoized per session and capped at about 40,000 characters.

How CLAUDE.md is discovered and loaded

The loader is more subtle than "read the nearest file" [luyao618, 2026]:

  1. It walks upward from the current working directory to the filesystem root, collecting candidate files.
  2. It loads them from root downward so the closest directory is loaded last.
  3. Later content has higher priority because the model attends more to the end of the context (recency bias).
  4. @path includes allow modular rules; they are guarded by cycle detection, depth limits, and a text-extension allowlist.
  5. The combined result is memoized per session and capped at about 40,000 characters.

This is why a project-level CLAUDE.md beats a user-level one: it physically appears later in the prompt.

MEMORY.md: a file-based memory index

Long-term memory is stored as plain Markdown files, organized into four subtypes:

  • user — role, goals, preferences.
  • feedback — confirmed errors and validated approaches.
  • project — current work, decisions, patterns.
  • reference — pointers to external systems and files.

The entry point is MEMORY.md, an index of up to 200 lines (~25 KB). Each line is a short label with a one-phrase description linking to a separate topic file. The index contains addresses, not data. A cheap auxiliary model scans the index in the background and selects up to five relevant files to attach to the context. This prefetch is non-blocking; if it fails or is slow, the request proceeds without it.

Two paths for loading the memory index

The leaked build gates MEMORY.md injection behind a feature flag (tengu_moth_copse) [luyao618, 2026]:

  • Traditional path: the ~200-line MEMORY.md index is injected into the user context at every turn.
  • New path: the index is not injected; instead, a background prefetcher selects relevant topic files and injects them as attachments.

Both paths cap the index at ~25 KB and instruct the model to treat memories as hints, not facts, and to verify against real code before acting.

Background extraction: an agent for memory

After each final response, Claude Code spawns a separate, restricted background agent whose only job is to extract lessons. It sees the full conversation but focuses on messages since the last extraction. It can read code but may only write to the memory directory. A cursor tracks the last processed message, so failures retry the same messages without loss.

This is episodic memory in production: action, context, result, lesson — with at-least-once semantics and hard iteration limits to prevent runaway loops.

Session and team memory

  • Session memory is a per-session note file of decisions, changed files, and observed patterns. It is a reflection, not a log.
  • Team memory synchronizes notes across Cowork or SDK users working together.

Both run in the background so they do not block the main response.

Five layers of context compaction

Before every model call, the context goes through up to five compaction stages, cheapest first:

  1. Skip already summarized messages.
  2. Offload oversized tool results to disk. Large results are truncated to a preview plus a path to the full file.
  3. Drop oldest messages.
  4. Micro-compact. If the KV cache is alive, evict specific keys via API without invalidating the whole cache.
  5. Auto-compact. A heavy background summarization; stops after three consecutive failures.

The overriding principle is protect the KV cache. Mutating the middle of a sent context invalidates the cache and multiplies cost. Claude Code either mutates only when the cache is already stale, or asks the provider to evict specific keys without killing the whole prefix.

Limits and failure modes

Independent analyses of the leak point to five structural limits [Milvus, 2026]:

Limit Consequence Mitigation
200-line MEMORY.md cap Old notes are pushed out by new ones Periodically archive or compress the index; keep only active pointers
Grep-only memory search Semantic drift ("port conflicts" vs. "docker-compose mapping") yields misses Add a semantic/BM25 hybrid search layer or external memsearch-style index
Summary-only storage The reasoning path that produced a decision is lost Store short decision traces, not just conclusions
Layer stacking CLAUDE.md → Auto Memory → Auto Dream → KAIROS adds complexity without replacing the local-file foundation Keep the storage primitive simple and exportable
No portability Memory is locked to one agent and one machine Adopt a shared Markdown-based memory format or external memory service

These limits are trade-offs for simplicity and privacy, not oversights.

Lessons for building agents

The leaked architecture confirms the central thesis of this series: intelligence lives in the system around the model, not in the model itself. The engineering questions that matter are:

  • What to remember.
  • When to deliver it.
  • How much to spend.
  • When to stop and compact.
  • How to observe every decision.
  • How to verify memory before acting on it.

Deeper dive: lessons from Claude Code's memory pipeline

Recent analyses of both the accidentally shipped source and the documented surface confirm that Claude Code treats memory as a file-system-backed state pipeline rather than a database-backed store [Vectorize, 2026; Novela, 2026]. Auto Memory writes candidate notes into ~/.claude/projects/<slug>/memory/ as Markdown; a foreground MEMORY.md index is always loaded up to 200 lines or 25 KB, while detailed topic files are read on demand by standard file tools. This separates addressability from retrieval: the model always sees the index, but only pays for full topic files when it decides to read them. The loading of CLAUDE.md uses a four-level hierarchy (managed, user, project, local) discovered by walking up the working directory, with @path imports and .claude/rules/*.md providing path-scoped modularity [Vectorize, 2026].

The pipeline's second half is compaction and consolidation. Because Claude Code runs as a single-user, single-process CLI, it deliberately avoids a database; state lives in an in-memory STATE singleton, JSON/JSONL files, and Markdown, with compaction keeping sessions inside token budgets [Novela, 2026]. The Auto Dream integration invokes Anthropic's Dreams primitive during idle periods, reading a single memory store plus 1–100 recent session transcripts and producing a rewritten store: duplicates merged, contradictions resolved, stale entries replaced [Vectorize, 2026]. Dreams, however, is per-store: it does not reconcile across repositories, agents, or users, leaving a cross-project semantic gap that the native system acknowledges [Vectorize, 2026].

The practical lesson is that the architecture optimizes for continuity and cache stability, not perfect recall. Prompt-cache latches never flip back once set, settings merge through a priority stack, and compaction trades detail for the ability to keep the session alive [Novela, 2026]. The following stages capture the production memory lifecycle:

Stage Trigger Storage Responsibility
Capture After each turn (Auto Memory) ~/.claude/projects/<slug>/memory/*.md Write candidate lessons as Markdown
Index Session start MEMORY.md (≤200 lines / 25 KB) Provide an addressable table of contents
Recall Per turn Topic files via file tools Read relevant details on demand
Consolidate Idle (Auto Dream / Dreams) Same memory directory Merge, deduplicate, and refresh the store
Compact Context budget exceeded In-memory summary + JSONL Summarize or drop older messages

This confirms the pattern seen in the leaked build: the hard engineering is not the model call, but the deterministic orchestration of what to keep, when to load it, and how much to spend.

References

  • Shou, C. (discovery) and community analyses. "Dive into Claude Code." VILA-Lab. https://github.com/VILA-Lab/Dive-into-Claude-Code
  • Nafiz, A. "How Claude Code Actually Remembers Things." https://ahammadnafiz.github.io/posts/How-Claude-Code-Actually-Remembers-Things/
  • luyao618. "Claude Code Source Study — Memory Subsystem Overview." 2026. https://github.com/luyao618/Claude-Code-Source-Study/blob/main/docs-en/31-memory-subsystem-overview.md
  • Milvus. "Claude Code Memory System Explained: 4 Layers, 5 Limits, and a Fix." 2026. https://milvus.io/blog/claude-code-memory-memsearch.md
  • Vectorize. "Claude Code Memory: Complete Guide to Persistence." 2026. https://vectorize.io/articles/claude-code-memory
  • Novela. "Claude Code Deep Dive Part 6: How Claude Code Memory Is Designed." 2026. https://interwater.biz/blog/2026-04-06-claude-code-memory-architecture?lang=en