Yesterday's session ruled out one library, agreed where a folder of shared code should live, and left a database change half finished. Today Claude Code opens cold. It proposes the ruled-out library, creates a second folder for the same thing, and cannot say which half of the change exists.
None of that was an accident or a bug. Those three decisions only ever existed inside a conversation, and a conversation is not a place things are kept.
The idea
A session's The working memory a model has for one conversation: every message, every file it read and every command output, all counted together. It is rebuilt from scratch each session, out of your instruction files plus whatever gets read along the way. is assembled fresh every time, so whatever the next session needs to know has to be readable from disk. Durable project memory is a small set of plain files that answer four questions: how this project works, what was decided and why, what is true right now, and what to do first on resuming. Everything else stays in the conversation and is allowed to disappear.
| Memory | The question it answers | Written by | Shape that works |
|---|---|---|---|
| Instructions | How does this project work? | You, deliberately | Short, specific, verifiable rules |
| Decisions | Why is it this way? | You, when a choice sticks | Date, choice, consequence |
| Progress | What is true right now? | Whoever finishes a session | Done, active, next |
| Handoff | Where do I start? | The session that stops | Entry file plus the check to run |
How it works
The instruction file is the one every tool has. Claude Code reads CLAUDE.md at
the start of every session; Cursor and several other agents read an equivalent,
commonly AGENTS.md. Anthropic's memory documentation describes two systems:
instruction files you write, and an automatic memory Claude Code keeps from your
corrections and preferences. Your instruction file loads at the start of the
session along with a short index of that automatic memory; the memory's detail is
filed by topic and fetched only when the topic comes up. Nothing here remembers
you. Something loads a file.
Loaded and obeyed are different states. The same documentation says these files are context rather than enforced configuration, with no guarantee of strict compliance, and that two contradicting instructions may be resolved arbitrarily. For something that must happen at a fixed moment every time, the documented answer is a A small script Claude Code runs automatically at a set moment, such as after every file edit. that runs as a script.
Length is the failure everyone walks into. Anthropic targets under 200 lines per instruction file and offers a test worth stealing for each line: would removing it cause a mistake? If not, cut it. That rules out anything the model can work out by reading the code.
One fact needs one owner. If the active task appears in a plan, a progress file and a README, the copies drift and a cold session cannot tell which is current.
What to do
-
Move a rule into
CLAUDE.mdthe second time you type it into chat, and delete one whenever you add one past about thirty lines. The file only works while it is short, so treat it as a fixed budget rather than a growing pile. A real one is smaller than people expect:markdown# CLAUDE.md Next.js 15 app, Postgres via Supabase. Run everything with pnpm. - Check: `pnpm build` and `pnpm test` before saying anything is done. - Money is stored in integer cents. Never floats. - Server-only code goes in src/server/. Never import it from a component. - Migrations are forward-only. Do not edit one that already ran. -
Record a decision when it changes what the next session should do, one file per decision under
docs/decisions/, named so the order is obvious (0007-email-provider.md). Write the consequence, not only the conclusion: "Chose Resend over SES, 2026-03-04. No AWS account needed. The free tier caps at 3,000 a month, so a launch spike will bill." -
Keep one file answering "what is true right now" and "where do I start", in the four lines the previous section showed. The discipline is writing them at the end of a session, while you still know them, rather than reconstructing them at the start of the next one.
Where it breaks
Written memory is a second project, and it rots. A stale file does more damage than a missing one, because it is read with the same trust as a true one. Do not keep routine conversation, raw command output, or facts the code already states. If you cannot name a decision the file would change, it is notes rather than memory.
Files also do not enforce anything. A rule in CLAUDE.md changes the odds, which
is why anything that has to be true every single time belongs in a hook, where it
runs as a script instead of being read as advice.