How do you keep work context across Claude Code sessions?
Short answer
CLAUDE.md is for standing rules that should be read every time, not for one job's purpose, decisions, and acceptance criteria. Mix the two and the file grows until the rules that matter get skimmed past.
Every new session starts with "where were we?"
The next morning we opened a new session to continue the day before. The first thing we typed was "how far did we get yesterday?". Of course it has no idea. Only we know, and we have already forgotten the details.
Right after a /clear it is the same. We have explained the same decision twice more often than we would like. "We dropped that approach, here is why", written out again for a different session. Nothing moves while we are typing it.
What we call context is really two things. One is coding conventions, the framework in use, quirks of the environment, operations that must never be run. That has a long shelf life. The other is what this particular job is for, what we decided, and what counts as done. That expires when the job ships.
CLAUDE.md is a good home for the first kind, precisely because it gets read every time. The trouble starts when the second kind goes in there. Nothing removes it when the job is over, so the file grows. Ours went past two hundred lines once and the rules that mattered started getting skimmed past. We now split it at roughly two hundred lines.
What we tried first
In the order we tried them. We still use some of these.
At first we added everything to CLAUDE.md. It is guaranteed to be read and costs nothing to write. But warnings about finished work stay behind. Read it a while later and there are lines cautioning you about a function that no longer exists. Nobody prunes it. We did not.
Next, writing a handoff.md when we stopped for the day and having the next session read it. This helped a lot and we still do it. The problem is that three jobs running side by side still share one file. Split it per job and you lose track of which one is current.
We also pasted whole transcripts from the previous session. That is the most accurate option. It is also long. The decision that matters is two lines out of a hundred, and sometimes those two lines are the ones that get skimmed. Also, pasting it every time is just tedious.
Compacting helps while you are extending the same session. It does nothing for tomorrow, and nothing at all when you cross clients, which we do constantly: decide in ChatGPT, implement in Claude Code.
We use the client's memory feature too. Durable facts fit there nicely: how we like things written, traps in our environment. But we never wanted to put a specific job's acceptance criteria in it. Once per-job material goes in, we inherit the work of deleting memories of finished jobs. And it only reads back inside that one client.
Where each one ran out
Every file-based option is blind to what state a job is in right now, and clearing out the finished ones is our own handwork. Every transcript-based option holds the whole job and never leaves the session. The client's memory only reads back inside that client.
What we wanted sat between the two: one job's purpose, decisions, and acceptance criteria attached to the job itself, fetchable by number from any client.
What this looks like for us
Our cards are not finished when we create them. Most start as a single line of title. The purpose, the background, and the acceptance criteria get added later, while we talk it through with a chat AI. Days when we have the energy to write a clean spec up front are rare.
In practice we say, mid-conversation, "write what we just decided onto that card". The reasoning goes in with it. We never write the minutes ourselves. This might be the operation we use most.
The payoff arrives weeks later. Coming back to something that had stalled, we can ask the AI what we were talking about on that one, and have it read the attached material too. Instead of reconstructing it from memory and explaining it again, we have it read first and then we start.
It feels like explaining the same decision twice has mostly stopped. What remains is the case where we decided something and forgot to have it written down. That one is on us and the mechanism does not catch it.
How we designed it in Dazbench
What we wanted was for the purpose of a job, the decisions behind it, and the definition of done to live on the job itself. And to reach all of it with one number, identically, from any client. Not in a session's memory, and not in our heads.
- One job, one card. Each card gets a number like dz51.
- A card carries the purpose, the background and decisions, and the acceptance criteria. None of it has to be complete up front. Mid-conversation, "write what we just decided onto dz51" is enough.
- A new session opens with one sentence: "read dz51". The body and the criteria come back as written. No transcript pasting.
- The project itself carries a goal, a current state, and background. Ask where the project stands and the project details come back together with its open cards. Standing rules stay in CLAUDE.md; this holds where things currently stand.
- Specs and requirement docs go on as attachments. Anything the AI produced can be attached as it is, and a later session reads the attachment directly. Nobody goes digging through chat history.
- Acceptance criteria are ticked off one item at a time. How far the work got stays on the card, so cutting a session short does not lose the place.
- A card can only be completed after a person approves; the AI never decides that on its own. Evidence is stored with it, so what the call to finish was based on can be read later.
We do not have the AI keep card bodies short. We did once look at trimming the background to save tokens on every fetch. Measured, a card body runs in the seven-hundred-token range, so there were no savings worth having, and the trimmed version pushed design decisions the wrong way: the round trips spent re-investigating more than doubled. So the full text goes across.
What actually changed
The first exchange of a new session went from "how far did we get" to "read dz51". The time we spent writing explanations is gone.
/clear stopped being scary. The context lives outside the session, so when one clogs up we can throw it away.
Repeating the same explanation between the AI that thinks and the AI that builds happens less. Decide in ChatGPT, hand Claude Code the number.
The parts that are not solved, plainly. A decision only survives if somebody writes it down. We have the AI do it, but anything we forget to ask for is gone. A card is not a transcript, so the fine-grained back and forth is not kept; when that matters it becomes an attachment. Project-wide rules are still CLAUDE.md's job and there is no reason to move them onto cards. And as cards pile up, finding which card holds what becomes its own chore: search matches literal words, not meaning.
FAQ
- Do you still need CLAUDE.md?
- Yes. Coding conventions, environment quirks, and operations that must never be run have to be read every time, and CLAUDE.md is the right place for that. What moved out is one job's purpose, decisions, and acceptance criteria. Mixing things with different lifespans in one file makes it grow until the rules that matter get skimmed past.
- How is this different from pasting the previous transcript?
- A transcript has everything in it, which is exactly why the decisions are buried in a long history. A card holds only the purpose, the decisions, and the criteria, and it comes back in one call. A transcript also only reaches whoever you pasted it to, while a card reads back by number from any client.
- How much should you write on a card?
- We gave up on keeping them short. A card body runs in the seven-hundred-token range, trimming it barely changed the cost, and the trimmed version made the AI spend more round trips re-investigating things. Writing down why you decided something pays for itself.
Related
Other articles
Tips