AI coding agent memory: why agents forget, and the fix
Why AI coding agents forget between sessions, the five memory layers that fix it (rules files, auto memory, handoffs, MCP, decisions), and how to choose.
On a Monday, your agent does the right thing. You tell it the team settled the auth rename weeks ago: POST /login became /session, the old route is dead, don't call it. It builds against /session. Clean PR, merged.
On Tuesday, a different session starts. Maybe a different engineer, maybe you with a fresh context window. The agent reads the code, finds a stale client still importing the old path, and helpfully "fixes" the inconsistency by calling /login again. The decision that took a meeting, a Slack thread, and a small argument to settle gets unmade by a tool that was never told it existed.
That is not a model quality problem. The agent did what a competent person would do with no memory of the meeting. It has no memory of the meeting.
This page is the map for that problem: why agents forget, the five layers of memory teams use to fix it, how each one fails, and how to decide what goes where. The deeper guides for specific tools are linked throughout.
Why do AI coding agents forget?
An AI coding agent's working memory is its context window. When the session ends, so does the window. Whatever was decided in yesterday's conversation, last week's pairing session, or the Slack thread where the pricing rule changed does not exist for today's run unless it was written somewhere the agent reads.
Humans route around this without noticing. You overhear things at standup, absorb conventions in code review, and know not to touch billing on a Friday because of an incident nobody wrote down. As we've argued before, the hallway is load-bearing, and the agent is never in it.
But "the session ended" is only half the explanation. The other half is that most repositories preserve outcomes much better than reasoning.
The code shows the answer, not the debate
Picture an agent opening an order service and finding a retry loop capped at two attempts. Three attempts would improve success rates in most systems, so the agent raises the limit and adds a test. The diff is clean.
What the repository doesn't say is that the payment provider can repeat a capture on the third attempt. The team tried several strategies, rejected a broader retry, and accepted a lower success rate to protect customers from duplicate charges.
The agent understood the code. It didn't understand why this code is intentionally different from the obvious design. Intentional compromises often look like technical debt: duplicate paths that serve different customer guarantees, an extra write required for audit, a slower call that protects ordering, a feature flag kept for rollback.
Tests, commits, and transcripts each carry part of the why
- Tests enforce behavior.
it('stops after two attempts to avoid duplicate provider capture')is a good name, but it still won't list the rejected designs, the owner, or what would have to change before the limit can move. - Commits and PRs hold evidence, but a decision can span several commits, the message may describe the edit rather than the tradeoff, and the agent changing the file today may never search a six-month-old review thread.
- Transcripts hold too much and too little. Search over raw history can return the proposal, the objection that killed it, the accepted answer, and a later reversal, all semantically similar. Nothing says which one is current.
So the problem is less "the agent has no memory" and more "the team never gave the reasoning a home the agent will reliably read."
The five layers of agent memory
Teams that get this right don't build one universal memory. They separate context by how long it should live, who it belongs to, and who can change it.
| Layer | What it holds | Shared with the team? | Lifetime | Typical failure |
|---|---|---|---|---|
Rules files (CLAUDE.md, AGENTS.md, .cursor/rules) | Commands, conventions, hard boundaries, pointers | Yes, through Git | Until someone edits it | Grows into a journal; goes stale silently |
| Auto memory | One user's recurring learnings and preferences | No, machine-local | Until reviewed or deleted | Personal notes treated as team policy |
| Task handoff | Done, next, blockers, tests, branch | Yes, if committed | Until the task closes | Outlives the task and looks current |
| Live context over MCP | Tickets, deploys, incidents, ownership, docs | Yes, by server policy | Always current at query time | Unranked results with no status |
| Approved team decisions | Choice, reason, rejected options, owner, scope, status | Yes, by design | Until superseded, with history kept | Not captured at the moment of the call |
Each layer is cheap on its own. Problems start when one is asked to do another's job.
Rules files: tell the agent how to work and where to look
Build commands, repository layout, naming conventions, and hard boundaries shouldn't be rediscovered every session. Put them in the file your client loads from the repository: CLAUDE.md for Claude Code, AGENTS.md as the vendor-neutral baseline, .claude/rules/ or .cursor/rules for path-scoped detail.
The best rules files point rather than absorb:
## Payments
- Run `pnpm test payments` before the full suite.
- Never retry non-idempotent capture automatically.
- Before changing retries, idempotency, ordering, or provider flows,
read matching accepted records in `docs/adr/` and follow replacement links.
If a change conflicts with a current decision, name the conflict in the plan.
Keep them short. Instructions enter the context window and compete with the task. Claude Code's documentation recommends concise CLAUDE.md content and scoped rules for details; Cursor likewise recommends focused rules that reference files instead of copying them. Instructions guide behavior; they don't enforce it, so hard boundaries still need tests and permissions.
Sources: Claude Code memory and Cursor Rules. For the full breakdown, see CLAUDE.md vs agent memory and our guide to AGENTS.md.
Auto memory: a personal accelerator, not a team authority
Claude Code auto memory stores project-specific learnings as plain Markdown: a test quirk, a debugging command, a preference that should come back next time. It's useful precisely because it's automatic.
It's also machine-local. It isn't shared across machines or cloud environments, and independent subagents don't automatically inherit it. That makes it a good personal tool and a weak place for anything the team must follow. When a learning should apply to everyone, promote it into the rules file. When it's really a choice, promote it into the decision layer, where an owner accepts it. More on the distinction in the glossary entry for agent memory.
Handoff notes: unfinished work, nothing more
A transcript is a poor handoff. It includes exploration, errors, and paths the agent abandoned. A handoff should be short enough to read in a minute:
# Checkout migration handoff
Done: read path moved to v2 schema.
Next: migrate write path behind `checkout_v2` flag.
Tests: unit suite passes; staging backfill not run.
Constraint: dual write remains until DEC-42 is superseded.
Open risk: rollback query needs review.
Commit it with the branch when another person or tool might continue the work, and delete it when the task ends. Anthropic's guidance on long-running agents uses the same pattern: durable progress artifacts let a fresh context window orient itself without replaying the old conversation. The Claude Code specifics, including resume, /compact, and plugins, are in Claude Code keeps forgetting context; the Cursor equivalent is Cursor keeps losing context mid-project.
Live context via MCP: query it, don't copy it
Deployment state, incident status, ticket ownership, and customer configuration change too fast for static files. A copied note saying "staging is on v2" goes wrong without anyone noticing. A live tool can say what is running now, with its own timestamp.
MCP lets the agent query the owning system when the fact drives an action. Persistent memory should hold the pointer and the retrieval rule, not a duplicate of every volatile fact. MCP is a connection, though, not a guarantee of meaning: a generic memory server can return a proposal and its replacement side by side. For the options, see the best tools for AI coding agent context.
Approved team decisions: the layer most teams skip
The most important team context is often neither an instruction nor a live fact. It's a choice: use an outbox instead of direct publish, keep a synchronous confirmation path, cap provider retries at two, delay a migration until one customer leaves the old API.
A record that an agent can actually apply looks like this:
# Payment capture retry limit
- Status: Accepted
- Owner: Payments team
- Scope: card capture through Provider A
- Decided: 2026-04-12
## Context
Provider A can repeat capture after a delayed third retry. Its idempotency
window does not cover our full retry schedule.
## Decision
Attempt capture at most twice for Provider A.
## Rejected options
- Three retries: unacceptable duplicate-charge risk.
- Queue-only capture: misses the checkout response window.
## Consequences
Some recoverable payments fail sooner. Revisit when Provider A supports a
longer idempotency window.
That's the useful core of the architecture decision record format, with owner, scope, rejected options, and a revisit condition added so an agent can apply it correctly.
Four properties separate decision memory from a wiki with good intentions:
- Captured at the moment of the call. In the PR discussion, the review, or the Slack thread, not reconstructed in a retro. A decision nobody records at the time gets re-litigated by the next six sessions.
- Ranked by blast radius. The auth rename matters to almost everything; the chart-library choice matters to one dashboard. Memory that can't tell the difference either floods the context window or buries the decision that was about to be broken.
- Briefed before code is written. A log the agent never reads is documentation for humans. The record earns its keep on the read side.
- Superseded, not rewritten. When a decision is reversed, the old entry stays, marked as replaced, with the reason. Otherwise an agent will resurrect the thing you killed.
Why Claude Code forgets architecture decisions walks through this loop for Claude Code specifically.
How agent memory goes wrong
Most failures aren't "the agent remembered nothing." They're the agent remembering the wrong thing with confidence.
The newest note wins. A recent note may be a proposal. Without a status field, retrieval treats it as equal to, or better than, the accepted answer. Status and ownership matter more than timestamps. This is the main reason coding agent memory files go stale.
One person's memory becomes policy. Your agent learns "the events table is append-only." Your teammate's agent never does. The team's decisions fragment across personal memories, which is a direct route to decision drift.
Parallel agents split the truth. Two agents on separate branches each make a locally sensible change built on different assumptions: one shortens the trial to 7 days, another rewrites the billing email and still promises 14. Different files, clean merge, inconsistent product. See two AI agents, one codebase.
Switching tools resets the context. The code moves with you from Cursor to Claude Code; the reasoning stays in the old tool's chat and memory. See sharing memory between Cursor and Claude Code.
The cost lands outside the IDE. Rework is the obvious cost. The subtler one is a product that slowly stops matching what the team agreed: pricing logic changes shape, a cut feature comes back. In METR's 2025 study of experienced open-source developers, developers using AI tools took 19% longer to complete their tasks while believing they were faster. The study has its own scope and caveats, but review, correction, and rework are where context gaps get paid for. Demand for a fix is public too: an engineering manager's feature request for shared team memory in Claude Code calls individual-only memory "the single biggest efficiency bottleneck for teams adopting Claude Code seriously."
What shouldn't be remembered at all?
More memory can reduce quality when it adds contradiction and retrieval noise. Anthropic describes context as a finite resource: the goal is the smallest high-value set, not maximum recall (Effective context engineering for AI agents).
Usually discard:
- routine tool output the source can reproduce
- generated plans that were never accepted
- intermediate guesses and temporary errors after the task closes
- duplicate summaries and copies of live data
- raw secrets and sensitive transcripts
How do you decide where something goes?
Sort by how fast it changes and how many people depend on it:
- Slow and universal: rules file.
- Slow and personal: auto memory.
- Temporary and task-specific: handoff.
- Changes outside the repo: query live over MCP.
- A choice the team made: decision record.
Then give anything durable six fields, so it's usable context rather than "related text":
- Scope: which project, service, or files?
- Owner: who can confirm or change it?
- Status: proposed, accepted, rejected, superseded?
- Time: when was it learned or accepted?
- Replacement: what newer record wins?
- Source: where can an agent verify it?
The faster something changes and the more people rely on it, the less it belongs as copied prose in a repository.
Test it with a fresh session
The session that wrote a memory already knows the answer, so don't test with it. Open a new session, ideally in a different client or on another machine, and ask:
- What is this branch trying to finish, and which command verifies it?
- Why are capture attempts capped at two? Does that apply to every provider?
- Which alternative was rejected, and who owns the decision?
- Which live system confirms the current deployment?
Then ask it to plan a three-retry refactor. A working setup names the conflict before editing code. Finally, change one decision and one live fact and ask again. The current answer should come back, and the superseded one shouldn't be presented as equally valid.
What Lockstep does about the decision layer
We built Lockstep for the fifth layer, because it's the one the other four keep pointing at and nobody owns.
Lockstep captures decisions where they're made (Slack is the most mature source; Notion, Jira, Confluence, Google Docs, and GitHub PRs are supported too) and asks the owner to approve each one with a click. Approved decisions keep their rationale, rejected options, scope, and replacement history. Before an agent writes code, Claude Code, Cursor, or any MCP-compatible agent can pull the relevant ones through the get_product_context tool. A PR check flags changes that may conflict with an approved decision; it warns by default, and blocking is opt-in.
It doesn't replace your rules files, auto memory, handoffs, or other MCP servers. They tell the agent how to work and what's happening now; Lockstep tells it what the team decided. It's open source under Apache-2.0, self-hostable, and early: we're working with design partners now.
Go deeper
- Claude Code keeps forgetting context: sessions,
/compact, plugins, and what to save between sessions - Why Claude Code forgets architecture decisions
- CLAUDE.md vs agent memory
- Why coding agent memory files go stale
- How to share memory between Cursor and Claude Code, including switching tools
- Cursor keeps losing context mid-project
- Two AI agents, one codebase: worktrees, handoffs, and shared decisions
- AGENTS.md: what a vendor-neutral rules file can and can't carry
- The best tools for AI coding agent context
- Agent memory, defined
Frequently asked questions
- Why do AI coding agents forget between sessions?
- An agent's working memory is its context window, and the window ends with the session. Anything not written to a file or source the agent reads at startup, such as CLAUDE.md, AGENTS.md, a handoff, or a decision record it can query, does not exist for the next session.
- Isn't CLAUDE.md or AGENTS.md enough memory?
- Rules files are the right home for stable commands, conventions, and boundaries. They are a poor home for the reasoning behind every decision, for unfinished task state, or for facts that change weekly. They grow, go stale quietly, and nobody updates them at the moment a decision changes.
- What's the difference between agent memory and a decision record?
- Agent memory, such as Claude Code auto memory, is usually personal and machine-local: useful learnings for one user's sessions. A decision record is shared, owned, and has a status, so every person and agent can tell which answer is current and who can change it.
- Should I save full transcripts so the agent remembers everything?
- No. Transcripts mix proposals, objections, abandoned plans, and the final answer, and search cannot tell which one is current. Save the result: a short handoff for unfinished work and a decision record for accepted choices. Keep a transcript only as evidence.
Keep reading