The single most annoying thing about coding with an AI assistant is that it keeps context between sessions about as well as a goldfish. You spend an afternoon with Claude Code working through a gnarly refactor — you settle on an approach, reject two others for good reasons, agree on a naming convention. Close the terminal. Come back three days later, and the assistant is a blank slate. It re-suggests the exact approach you already rejected, because it has no idea that conversation ever happened.
People call this context rot, and it’s not a bug you can patch away. Each session is a fresh process with a fresh context window. What you need is a way to keep context between sessions — real persistent memory that survives across sessions — and the good news is you can build it in layers. This post is the pattern I actually run, described so you can replicate it with whatever tools you like.
Why a bigger context window doesn’t fix losing context between sessions
The obvious guess is “just use a model with a bigger context window.” That helps within a session — you can hold more of the codebase in view at once — but it does nothing across sessions. When the process restarts, that giant window starts empty again. You’d have to re-paste your entire history every morning, which is both expensive and something you’ll stop doing by Wednesday.
The other half of the problem is that raw history isn’t the same as recall. Even if you could stuff three months of transcripts into a prompt, the assistant would be drowning, not remembering. What you actually want is retrieval: the ability to ask “what did we decide about the auth flow back in May?” and get back the two paragraphs that matter, not the haystack they’re buried in.
So the real fix is two things working together: durable storage of what matters, and cheap retrieval of the right slice at the right moment. I break that into three layers.
Layer 1: A versioned file index for durable facts
The base layer is the least clever and the most reliable: a plain markdown file, versioned in git, that loads at the start of every session.
Claude Code reads a CLAUDE.md (and a small memory index alongside it) automatically when a session starts. So I keep a short, curated file of durable facts — the things that should be true across every session, forever, until I change them:
- Decisions that are settled (“we use Bun, not npm; here’s why”).
- Preferences (“branch first, never commit straight to main”).
- Conventions (“Spanish is the default locale; English lives under
/en/”). - Hard rules (“never add a
Co-Authored-Bytrailer to commits”).
The discipline is to keep it short and curated, not a dumping ground. This file is loaded into every session, so every line costs context on every future run. If it grows into a wall of text, the assistant skims it and you’re back where you started. I treat it like a README for the agent: the ten things it must never forget, and nothing else.
Because it lives in git, it’s reviewable, diffable, and rolls back like any other file. When a decision changes, I edit the line and the change is in the history. This is the same instinct behind validating a blog post before you publish it — the durable stuff belongs in version control where you can see it change, not in a chat log that evaporates.
Layer 2: A semantic second brain for old decisions
The file index is great for the ten things that are always true. It’s useless for the thousand things that were true once — the reasoning behind a decision from six weeks ago, the dead end you explored last month, the reason a config value is set to exactly that number.
That’s what the second brain is for. The idea: take your codebase plus your past session notes and index them with embeddings, so you can query them in natural language. Not keyword grep — semantic search. You ask “how did we end up handling rate limits?” and it finds the relevant notes and code even if none of them contain the literal string “rate limit.”
I use a tool called gbrain for this, but the pattern is what matters, and it has three parts:
- Embed everything worth remembering — source files, and short notes you write at the end of meaningful sessions (“decided X because Y; rejected Z”).
- Query it in natural language — retrieval that ranks by meaning, so a question phrased nothing like the original note still finds it.
- Expose it to the agent over MCP so it can search its own memory mid-task, without you playing librarian.
That third point is the one that changes how it feels to work. MCP (the Model Context Protocol) is just a standard way to hand an assistant a set of tools it can call on its own. Wire your second brain in as one of those tools, and Claude Code can pause in the middle of a task, decide it needs to know what you concluded about something last month, query the brain itself, and keep going. You’re no longer the memory — the agent retrieves from its own history.
You don’t have to use my exact stack. Any embedding-based store you can query in natural language and expose over MCP will do. What earns its place is the combination: retrieval beyond keyword search, over your whole history, callable by the agent without you in the loop. The same “build the plumbing once, let it compound” instinct shows up all over this site — it’s exactly how I think about the Astro SEO setup most portfolios skip: the unglamorous foundation is the part that pays off for years.
Layer 3: Session pointers to close the loop
The file index holds durable facts. The second brain holds old decisions. The last gap is the most mundane one: when I sit back down, where exactly did I leave off?
That’s what a session pointer solves. At the end of a session I flush a small pointer — nothing dramatic, just the current state:
- The branch I was on.
- The working directory.
- The last few commits.
- The state of the working tree (staged, unstaged, untracked).
Then a start-hook injects that pointer at the beginning of the next session: here’s where you left off. And crucially, the very first thing I do is orient from git — git log, git status, git diff, open PRs — before touching anything. The pointer tells the assistant which drawer to open; git tells it what’s actually inside right now.
This layer is cheap and pays off immediately. Without it, every session starts with five minutes of “wait, what was I doing?” With it, the assistant opens already knowing the branch, the recent work, and the uncommitted changes — and reorients itself from the live repo instead of from a stale summary.
The angle that makes this current: native memory isn’t semantic recall
Here’s the part worth sitting with, because it’s changed recently. Modern agents — Claude Code included — now ship native memory: they can persist notes across sessions on their own. So a fair question is whether all of the above is still necessary.
It is, because these are different jobs:
- Native memory is best for the live thread — the working set of the current effort, carried forward a little so you don’t repeat yourself session to session.
- The file index is best for durable facts — the settled decisions and rules you want reviewed in git and loaded verbatim every single time, not summarized by the model’s discretion.
- The semantic brain is best for old decisions — retrieval across months of history that no fixed-size memory can hold, ranked by meaning rather than recency.
Native memory ≠ semantic recall over your whole history. One is a short, evolving scratchpad; the other is searchable long-term memory. The move isn’t to pick one — it’s to layer them. Let native memory carry the live thread, let the file index anchor the durable facts, and let the second brain answer “what did we decide about X, way back when.” Each layer covers what the others can’t.
The takeaway
You will never make context rot disappear — every session is still a fresh process. What you can do is make it not matter, by giving the assistant somewhere durable to keep context between sessions and a cheap way to retrieve the right slice on demand.
Start with the layer that costs almost nothing: a short, curated, git-versioned file of durable facts that loads at the start of every session. Add session pointers so each session opens knowing where the last one stopped. Then, when your history grows past what any file can hold, add a semantic brain so the agent can search its own past in natural language. Three layers, each doing the one job it’s actually good at — and an assistant that finally remembers why you made the decisions you made.