2026-07-28T17:10:02.050Z

Claude Code Memory: Audit What Loads and Survives

Inventory Claude Code memory sources, catch scope drift and startup truncation, and verify one critical decision after restart or compaction.

Claude Code memory should be operated as a versioned input contract, not judged by whether the agent sounds familiar with the project. A healthy setup has three pieces of evidence: the expected sources loaded, their content has not drifted or been truncated, and one critical project decision can still be reproduced after a restart or compaction. That standard matters because “memory” now refers to several mechanisms. Claude Code reads human maintained CLAUDE.md instructions and also keeps an agent written auto memory directory. Both can be present while the wrong scope is active. Both can be current on disk while absent from the moment that matters. And neither is an enforcement boundary: Anthropic’s documentation explicitly describes these files as context. If an action must be blocked, use a deterministic control such as a PreToolUse hook. The practical default is simple: keep durable team rules in a short project CLAUDE.md , move conditional instructions into path scoped rules, keep auto memory as a concise index, and verify the live source set before debugging the model. Treat memory as a loaded source contract The current Claude Code documentation describes two complementary systems: Source Writer Typical scope Startup behavior Best evidence Managed CLAUDE.md Organization Every user Loaded at launch /context or InstructionsLoaded User ~/.claude/CLAUDE.md Individual Every project Loaded at launch /context Project CLAUDE.md or .claude/CLAUDE.md Team Repository Loaded at launch /context plus file hash CLAUDE.local.md Individual Current project Loaded at launch when local settings are enabled /context plus file hash Nested CLAUDE.md Team or component owner Subdirectory Loaded when Claude reads within that subtree InstructionsLoaded .claude/rules/ .md Team Global or path scoped Launch or matching file load InstructionsLoaded Auto memory MEMORY.md Claude Repository, shared across worktrees First 200 lines or 25KB /memory , file audit, and a canary The table exposes the first failure class: declared is not loaded . /memory is useful for finding and editing configured locations. /context answers the narrower question of which memory files reached the current conversation. The InstructionsLoaded hook, added in Claude Code 2.1.69, is the best fit when lazy loading time and reason are material. Substituting one diagnostic for another produces a false green state. Load order also matters. Claude Code walks from broader directories toward the working directory. More specific files arrive later, but the system concatenates instructions rather than treating the nearest file as a clean override. Two contradictory rules therefore remain two contradictory pieces of context. The safe response is to remove the contradiction, not rely on position. Imports add another boundary. A project CLAUDE.md can include another file with @path , recursively up to four hops according to the current documentation. An import outside the working directory requires approval the first time it is encountered. Splitting a large file into imports can make it easier to maintain, but it does not reduce startup context because imported content still loads. Auto memory has a different limit. Only the first 200 lines or first 25KB of MEMORY.md , whichever boundary arrives first, enters a new conversation. Detail in topic files is read on demand. Since Claude Code 2.1.211, frontmatter and block level HTML comments are excluded when the loaded portion is measured. A successful write beyond the cap is therefore not a successful future read. Classify it as partial coverage , not healthy persistence. Build a manifest before blaming recall A useful audit does not collect prompts, transcripts, or memory contents. It records source paths, scope, size, modification time, a SHA 256 digest, imports, and the documented load mode. The reproducible artifact used for this article accepts a repository, a working directory, and an optional auto memory index: Its output deliberately stops short of claiming that a model followed an instruction: The companion fixture creates a root instruction file, a working directory local file, one path scoped rule, an imported decision file, and a 205 line auto memory index. The test passes only when the audit: discovers both launch time instruction files; resolves the import without reading its contents into the report; marks the rule as path scoped; marks auto memory startup coverage as partial at the line boundary; produces a hash for every observed source; and refuses to return a fully healthy verdict without runtime evidence. That last refusal is important. File hashes prove change detection, not adherence. /context proves inclusion, not that the model applied the correct decision. Even InstructionsLoaded proves an event, not the intended outcome. The evidence chain should be additive: 1. Inventory: the source exists where the documented resolver can find it. 2. Integrity: its digest and modification time match the expected revision. 3. Inclusion: /context or an InstructionsLoaded event shows it entered the session. 4. Decision: a deterministic canary produces the expected project specific answer. 5. Outcome: the resulting command, file, or deliverable passes its own verification. For example, do not ask “Do you remember our release process?” A fluent yes is untestable. Store a non secret decision such as “production releases use scripts/release all.sh ; direct release branch pushes are forbidden.” Then ask for the approved release entry point in a fresh session. Compare the answer to that exact decision, and still verify the actual release command separately before any mutation. Test restart and compaction as different boundaries A restart and /compact do not exercise the same path. At a fresh conversation, Claude Code loads the configured launch time source set and the startup visible portion of auto memory. Auto memory is machine local, although current Claude Code versions share the same project configuration and auto memory directory across worktrees of one Git repository. A successful test in one worktree therefore does not prove synchronization to another machine or cloud environment. After /compact , project root CLAUDE.md is re read and injected again. Nested CLAUDE.md files are not automatically re injected; they return when Claude later reads a file in their subdirectory. This creates a narrow but real uncertainty window. If a critical component rule lives only in a nested file, an answer immediately after compaction can be plausible before that rule has loaded again. Use a two part protocol: Boundary Setup Canary Pass condition Restart End the session, start from the same repository and working directory Ask for one critical root level decision Expected sources appear in /context ; answer matches the decision Compaction Enter the relevant subtree, confirm its nested source, then run /compact Ask once before and once after re opening a matching file The post read answer matches; load evidence records the nested source again Worktree Run from two worktrees of the same repository Inspect the auto memory path and one shared decision Both resolve the same project memory, with no claim of cross machine sync Oversized index Put a harmless canary beyond the documented startup boundary in a test fixture Start a new conversation without opening a topic file The canary must be treated as unavailable, proving the audit detects partial coverage Do not place a real secret, customer record, private prompt, or production credential in a canary. The question should depend on a harmless operational decision whose expected answer can be compared exactly. The trade off is that more instrumentation can become more context. InstructionsLoaded events and file manifests are compact evidence; copying entire instruction files into logs is not. Prefer paths, hashes, source type, load reason, freshness, and a bounded canary result. Keep content on the host. Use one operating verdict Use these states instead of a single “memory works” checkbox: Healthy: expected sources are intact and loaded, the canary survives the tested boundary, and the resulting task outcome verifies. Waiting: an external import approval or human decision is legitimately outstanding. Partial: the auto memory index crosses a startup cap, or a nested source has not reloaded after compaction. Drifted: a source hash changed without a reviewed decision update. Conflicted: two loaded sources prescribe incompatible behavior. Uncertain: file evidence and live behavior disagree, or inclusion evidence is unavailable. The operating rule is: never repair memory from prose alone . First identify the missing evidence layer. Move a rule only when its scope is wrong. Shorten an index only when startup coverage is partial. Remove a contradiction rather than adding a stronger duplicate. Escalate when the canary fails despite intact, loaded sources. Sidewisp’s planned health model includes memory and context continuity alongside availability, tools, execution, outcome, and cost. The useful boundary here is diagnostic: a future integration could report source freshness, partial coverage, and decision continuity without uploading memory contents. It must not pretend that a file hash proves useful work. Sidewisp is currently in private preview. Its production monitoring engine and Claude Code adapter are not generally shipped. The public site and article system are live; join the preview if you want this kind of evidence first health view around agents you already run. Sources: Claude Code memory documentation, Claude Code changelog, and Sidewisp product status.