Skip to content

Agent memory — typed entries that survive every session

Scorecard question: How do you use auto-memory / persisted memory? Max-score answer: I deliberately use memory types (user / feedback / project / reference) and prune stale entries.

Memory is the only mechanism in an agent stack that survives across sessions for free. Every other context lever costs tokens or attention: CLAUDE.md is loaded on every turn whether you need it or not; plan files have to be re-read; rules in Cursor get clipped when context fills; conversation history is summarised away by compaction the moment a session passes the model’s window. Memory is the exception — a persistent typed store the agent writes to itself between turns, that the next session reads back automatically before the user types. Used right, every later conversation starts ahead of where the previous one ended. Used carelessly, it bloats into a noisy attic where stale “we use jest” notes contradict the new vitest setup and the agent confidently does the wrong thing for months. The gap between “I let auto-memory happen to me” and “I deliberately steer what lives in memory and prune what doesn’t” is the single biggest predictor in Q5 of whether your fifth session on a codebase feels like your first or like a senior engineer’s tenth. The discipline is small: four memory types to understand, one weekly review, a few slash commands. Very few developers actually do it — most sit at 0–1 pts, either ignoring memory or treating it as a black box.

A max-score Q5 setup is deliberate, typed, and pruned. When something useful surfaces in a session — a preference you’ve expressed three times, feedback you keep giving, a project decision just made, a reference URL the agent keeps re-discovering — you steer it into memory with the right type. You don’t let auto-memory choose for you; you confirm or correct the type when the agent proposes a write, and you reject session noise. Weekly (or after every meaningful milestone), you skim ~/.claude/memories/, delete entries that no longer hold, edit drifted ones, and promote project-level entries to user-level when they belong cross-repo. You can name the four types from muscle memory and tell a colleague which one a snippet belongs to in under five seconds.

The four types, with concrete examples of what belongs in each:

  • User memory — facts about you that should follow you across every project. “Primary language is TypeScript; treat Python as secondary.” “Senior backend engineer learning Rust; frame Rust against the Go equivalent.” “Prefer functional composition over class hierarchies.” Smallest of the four (5–15 entries) but most leveraged — it shapes how every future session talks to you.
  • Feedback memory — how the agent should work for you, accumulated from corrections. “Don’t summarise what you just did at the end of messages.” “Always run the test suite before declaring done.” “When proposing a refactor, include the rollback plan in the same message.” Each entry is a correction you no longer have to give.
  • Project memory — state, decisions, and constraints of this project now. “Migrating from Polar.sh subscriptions to BetterAuth + Polar webhook bridge, Phase 8/10.” “Drizzle schema lives in src/lib/db/schema.ts; don’t duplicate in scripts/schema.sql.” “Paywall logic is intentionally vanilla JS at /public/paywall-inline.js.” Ages fastest; most likely to be stale on next review.
  • Reference memory — pointers to where information lives in external systems. “Pipeline bugs tracked in Linear project WND-INGEST.” “Grafana latency board at grafana.internal/d/api-latency.” “Polar webhook docs: polar.sh/docs/integrate/webhooks.” Your “external brain” — small entries that save re-discovering the same URL every session.

The lower tiers are easy to spot. 0 pts (“I don’t use memory”): auto-memory is disabled or you’ve never opened the directory; every session starts cold. 1 pt (“I let it happen automatically”): auto-memory is on, you’ve never reviewed it, and you don’t know what type any of your entries have. 2 pts (“I write the occasional entry”): you sometimes nudge the agent with #memorise this, but you don’t think in types and you don’t prune. 3 pts (max): four types are second nature, weekly prune is on the calendar, stale entries are rare, and the agent’s first turn on a fresh session demonstrably reflects what came before.

Persistent typed memory is a Claude Code feature today. Cursor has rules-only (no auto-memory typing). Codex has session compaction (memory-shaped, but not the same thing). Knowing which tool gives you what determines what discipline you can build.

Claude Code typed memory (user / feedback / project / reference)

Section titled “Claude Code typed memory (user / feedback / project / reference)”

Claude Code is the only mainstream agent tool with first-class typed auto-memory in 2026. As Claude works, it writes memory entries to itself between turns with a metadata.type field — one of user, feedback, project, or reference — and the next session reads them back before the first user turn. The system prompt instructs Claude to choose the right type and refresh, not duplicate, when an entry covers the new fact. Memory files live under ~/.claude/memories/ (and a per-project equivalent for project-typed entries). You can edit them in $EDITOR, delete entries, write by hand, or force a write with #remember this: <fact> / “save this as a feedback memory.” The four types, recapped with what each is for:

  • user — durable facts about you that should follow you across projects. Role, expertise level, languages, preferences for how Claude should explain things. Cross-project by intent.
  • feedback — corrections and meta-instructions about how Claude should work for you. Things you’ve told it more than once. Cross-project by intent.
  • project — current state and active decisions for this codebase. Ages fast; needs frequent review.
  • reference — pointers to external systems (Linear project codes, dashboards, doc URLs, runbooks). Cheap, long-lived, low risk of staleness.

A known sharp edge as of May 2026 (GitHub issue #58840): user and feedback memories — cross-project by definition — are still written into a per-project directory by default, so they don’t automatically carry between repos. The workaround until routing-by-type ships is to manually copy or symlink them into your global ~/.claude/memories/. Watch the issue; it’s high-traffic and likely to be fixed soon.

Cursor in 2026 still has no auto-memory in the Claude-Code sense. What it has is rules — Markdown files (.cursor/rules/*.md) injected into the agent’s context on every relevant turn. Rules are user-authored, not agent-written; no “the agent learned this and saved it.” Rules can approximate user and feedback memory if you discipline yourself to write them down — “always TypeScript, never any” can live in style.md — but can’t approximate project memory (state changes too fast for hand-edited rules) or reference memory (no agent-driven URL store). Pragmatic Cursor pattern: rules for durable things (your user and feedback slots), accept that you’ll repeat yourself on project-state.

Codex CLI has no persistent memory of any kind in 2026. What it has instead is session compaction: when the context window fills, the agent summarises earlier turns so the session can continue. Compaction is helpful within a session, but the moment the session ends, the summary is gone. If Codex CLI is your primary tool and you want anything memory-shaped, hand-roll it: an AGENTS.md at repo root you treat as project memory, a personal ~/.codex/AGENTS.md you treat as user memory, and the discipline to update both. Clunkier than typed memory, but better than nothing.

Whatever tool you use, pruning matters more than writing. Stale entries are worse than no memory: an out-of-date “we use jest” will actively mislead the agent for months after you’ve switched to vitest. Minimum discipline: weekly prune — open the directory, skim, delete or update. Better discipline: event-driven — after every milestone (phase shipped, stack swapped, refactor merged), do a targeted prune of project-typed entries related to it. Best discipline pairs both — weekly skim plus milestone-driven targeted prune — and treats user and feedback as semi-permanent (review monthly).

Step-by-step: building a memory discipline

Section titled “Step-by-step: building a memory discipline”
  1. Confirm your tool’s memory model and where it lives. For Claude Code: ls ~/.claude/memories/ and ls .claude/memories/ (per-project). For Cursor: ls .cursor/rules/. For Codex CLI: check whether you have an AGENTS.md at repo root and a personal one. You can’t manage what you can’t see; step zero is opening the directory and reading what’s there.
  2. Audit what’s already in there. Read every existing memory entry or rule. For each, decide: which of the four types does this belong to (user, feedback, project, reference)? Is it still true? Is it actionable, or is it noise the agent saved during a long session? On a typical first audit, 30–50% of entries will be either misclassified or stale. Delete the stale ones, retype the misclassified ones, and you’ve already moved from 1 pt to 2 pt.
  3. Adopt the four-type vocabulary. Print the four types on a sticky note for one week. Every time you give the agent a correction or express a preference, ask yourself “which type is this?” before the next message. After a week you’ll be sorting in your head without thinking.
  4. Steer writes deliberately. When the agent proposes a memory write — or when you want to force one — say the type out loud. “Save this as a feedback memory: don’t summarise at the end of messages.” “Save this as a reference: Linear project for ingest bugs is WND-INGEST.” “Save this as a project memory: paywall logic stays in vanilla JS.” The explicit type forces a clean entry and trains your reflex.
  5. Promote user-level entries out of the project directory. If you’re on Claude Code, and you notice that a user or feedback entry is sitting in a per-project memory folder, move it (or copy it) to ~/.claude/memories/ so it follows you everywhere. Until issue #58840 is fixed, this is manual. Doing it once a week takes 30 seconds and is the single highest-leverage habit in this whole guide.
  6. Schedule the weekly prune. Put a 10-minute slot on your calendar — Friday afternoon works well — labelled “memory prune.” Open the directory. Skim every project entry: still true? Still relevant? Delete or update. Skim reference entries: URL still valid? Project code still in use? Skim user and feedback once a month, lightly. The goal is not zero entries — it’s fresh entries.
  7. Run a milestone-driven prune at every phase boundary. When you ship a phase, swap a stack, or merge a major refactor, do a targeted prune of project-typed entries that touched the change. The example from this repo: when Phase 7 of the Polar migration finished and the legacy subscription endpoints were removed, any project memory that referenced those endpoints had to go in the same commit.
  8. Verify the first turn of every new session. Open a fresh Claude Code session in your project. Ask “what do you remember about this project?” or “summarise the relevant memories before I start.” If the first turn reflects what came before — current phase, active conventions, your preferences — your memory is healthy. If it’s vague, contradictory, or wrong, you have a prune to do.
  • Memory bloat. Left unchecked, auto-memory writes an entry every time you mildly emphasise a preference. Symptom: hundreds of overlapping entries, contradictory advice. Fix: prune weekly, and merge near-duplicates into single canonical entries.
  • Stale entries that contradict reality. You migrated from jest to vitest six months ago, but a project memory still says “we use jest” and the agent keeps writing jest matchers. Fix: milestone-driven prune (step 7) — any stack change triggers a targeted memory sweep.
  • Recording the wrong things. Session-specific minutiae get saved as durable preferences. “Currently debugging the Polar webhook” is session state, not memory. Fix: ask “will this matter in a month?” before confirming a write.
  • Wrong-type writes. A user-level preference saved as project memory dies on repo switch; a project-state note saved as user memory follows you everywhere it shouldn’t. Fix: step 5 — promote misfiled entries, and confirm type at write time (step 4).
  • Treating memory as a black box. The agent saved it, the agent reads it, no one looks inside. Fix: open the directory. It’s flat-file Markdown/JSON; reading takes minutes.
  • Cross-tool inconsistency. Switching between Claude Code (typed), Cursor (rules), Codex (compaction-only) means entries don’t carry. Fix: pick one tool as your memory-of-record (Claude Code in 2026); treat the others as best-effort approximations.
  • You can list the four memory types from memory and give an example of each tied to your actual work.
  • ls ~/.claude/memories/ (or your tool’s equivalent) returns a non-empty, fresh-looking directory you’ve touched in the last 7 days.
  • A weekly memory-prune slot is on your calendar; you can show the last one you completed.
  • After a milestone (phase shipped, stack swapped), you remember to prune project-typed entries within the same week.
  • A fresh session in a familiar project’s first turn reflects what came before — current phase, conventions, your preferences — without you having to remind it.
  • user- and feedback-typed entries that should follow you everywhere actually do (you’ve moved them out of per-project folders into ~/.claude/memories/ while issue #58840 stands).
  • You can point to at least one feedback memory that demonstrably removed a recurring correction from your sessions.
  • Stale entries are rare; when you find one, it’s an exception, not the norm.