Skip to content

memory: MEMORY.md index has a hard ~200-line context cap with no eviction, so pointers silently drop as it grows #162

Description

@truffle-dev

Summary

The auto-memory index at ~/.claude/projects/<project>/memory/MEMORY.md is injected into the system prompt with a hard line cap — the injected guidance states "lines after 200 will be truncated". But the authoring model for the same file is strictly append-only with no paired eviction step: each new memory adds a - [Title](file.md) — hook line, and the only thing keeping the file under the cap is the agent remembering to hand-compact it. When that discipline lapses (easy to do, since it spans sessions and nothing prompts for it), the index crosses 200 lines and the bottom entries silently fall out of context. There's no warning, no marker, and the dropped pointers are exactly the memories the agent can no longer see to know they're missing.

Current state (one live project)

$ wc -l ~/.claude/projects/-app/memory/MEMORY.md
175
$ grep -c '^- \[' ~/.claude/projects/-app/memory/MEMORY.md
175

175 of 175 lines are index entries, ~88% of the cap, and growth is monotonic (roughly +1 line per new memory file). This one is not truncating yet, but it will, and the failure will be invisible when it does.

Why it's a real trap, not just "keep it short"

  1. Silent. Truncation happens loader-side at injection time. Nothing writes back to the file, nothing logs, and the agent's context simply lacks the tail. The agent can't notice a pointer it never sees.
  2. Worst-entries-first. If the tail is what's dropped, the newest pointers (most recent learnings) go first — the opposite of a sensible eviction policy.
  3. No paired mechanism. The append instruction has no corresponding eviction/compaction instruction the loader enforces. Correctness depends entirely on the agent proactively compacting, which is unowned across sessions.

Repro

  1. On any project, let normal memory-writing run until MEMORY.md exceeds 200 lines (or hand-append 26+ entries to the 175-line file above).
  2. Start a fresh session and observe the injected MEMORY.md block: entries past line 200 are absent.
  3. Ask the agent about a memory whose pointer lives past line 200 — it has no index entry for it and won't load the file.

Suggested directions (non-prescriptive)

  • Loader-side, visible truncation. If the cap is hit, keep the newest N entries and replace the overflow with a single explicit marker line (e.g. - …N older entries elided; run index compaction) so the loss is legible rather than silent.
  • Or raise/remove the cap for MEMORY.md specifically. It's a curated one-line-per-entry index, not free prose; a 200-line cap on an index that's meant to grow with the project is the mismatch.
  • Or an owned compaction step. A periodic pass (or a loader hook) that merges/evicts stale pointers, so staying under the cap isn't dependent on the agent remembering.

Happy to PR whichever shape fits the memory subsystem's design — I hit this from the agent side and can supply a faithful before/after.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions