Why AI Coding Agents Contradict Themselves — and How a Three-File Memory System Fixes Context Loss

Externalize project memory with a three-layer file architecture to fix AI coding agents' cross-session amnesia.
The article argues that AI coding agents have no memory between sessions, which is the real cause of "agent contradicts itself" — not model limitations. It proposes a three-layer file architecture: a master prompt for stable background, scaffold files (CLAUDE.md / DECISIONS.md / PROGRESS.md) for project decisions and progress, and a session line for today's task. CLAUDE.md should be concise with only counterintuitive conventions; DECISIONS.md uses why, alternatives, and revisit conditions to prevent re-opening decisions; PROGRESS.md records status, blockers, and next actions. Risky work needs a plan–approve–build gate with written approval. Open/close routines minimize context rebuild cost.
The Root Cause: AI Coding Agents Have No Session Memory
Every time an AI coding agent starts a new session, it knows nothing about the previous one. This single fact explains most "agent contradicts itself" complaints — the problem isn't the model, it's that the model has no memory, and you are the only thread connecting session 1 to session 5.
The author points out two typical failure modes:
Context loss. You open a new session and re-type the project background from memory, but unknowingly drop a constraint. The output is wrong, and you don't find out until later.
Decision re-opening. Picture a pricing page. After careful deliberation, you settled on three tiers. A new session sees an unfinished page, proposes two tiers, and has no way of knowing why you chose three. You either re-argue the whole thing or accept a regression in functionality.
Both share the same root: the reasoning behind the project lives only in your head, or in a chat window that's already been closed.

AI coding agent refers to tools that can autonomously complete multi-step programming tasks under human instruction — Claude Code, Cursor Agent, GitHub Copilot Workspace, and the like. What separates them from traditional code completion is that they don't just fill in a line of code; they read files, run commands, modify multiple modules, and report back.
Session memory is one of the core limitations of these agents. Most run "statelessly" — each new session sees only the system prompt, the current input, and the files it actively reads. Conversation history from prior sessions, verbal constraints you gave, and preferences you clarified through repeated back-and-forth are not carried over automatically. The model may stay coherent within a single session, but cross-session continuity has to be provided by an external mechanism.
The key distinction here is: the model's reasoning ability and the agent's context are two different things. When you complain that "the agent got dumber today," what usually happened is that it's missing the context from yesterday's session that was never written down. Understanding this is what makes it possible to accept the necessity of "externalizing memory into files."
The Three-Layer File Architecture: Move Memory from Brain to Files
The core of the solution is to transfer memory from the human brain into files the agent can read. The author designed a three-layer structure:
| Layer | Content | Change Frequency |
|---|---|---|
| Master prompt | Project basics: what it is, who it's for, constraints | Rarely |
| Scaffold files | Decisions made and current progress | Every session |
| Session line | What to do today | Every session |
The master prompt is stable background info, pasted or referenced at the start. The session line is one sentence: today's scope, plus "read PROGRESS.md first." The middle layer is where the most value lies, and it's the focus of this article.
CLAUDE.md: Concise, Stable, and Surprising
Claude Code automatically reads CLAUDE.md at the start of each session, so every line in it gets read every time. That's why it has to stay short — only include conventions that differ from the agent's default behavior.
**Master prompt** here does not mean the system prompt from the model's training phase. It refers to the fixed text block you paste or reference at the start of each session that describes the project's basic facts. It can be a chunk of Markdown or a referenced file. Its role is to provide stable, low-churn background so the agent can build a worldview before diving into specific tasks.
**Scaffold files** are the working-memory layer between the two, typically including `CLAUDE.md`, `DECISIONS.md`, `PROGRESS.md`, and so on. They aren't the code itself, but like scaffolding supports, they determine whether the agent can operate under the right constraints.
**Session line** describes only what this session is supposed to do — usually one sentence is enough.
The design intent of these three layers is to **minimize the amount of information the agent reads each time while maximizing relevance**. The master prompt provides long-term constraints, the scaffold provides project memory, and the session line provides the current task. If any layer is missing, the agent is forced to fill the gap with guesswork — and guesswork is the breeding ground for "decision re-opening" and "constraint loss."
`CLAUDE.md` matters especially because Claude Code **automatically reads and injects it into context** at every session start. That means every line consumes precious context window and shapes the agent's default behavior.
Context windows are finite — even with long-context models, too much irrelevant information dilutes the agent's attention to key constraints and increases cost. So the principle for writing `CLAUDE.md` is the opposite of a regular doc: **not completeness, but precision**. Only write what "the agent would get wrong if not told" — for example, generated files must not be hand-edited, price identifiers must not be hard-coded, public copy carries legal risk, etc.
A rule of thumb of around 40 lines is a useful upper-bound signal: when you have to scroll to finish reading it, the part the agent actually remembers shrinks. Write too much and you might as well have written nothing.
```markdown
# Harbor Lane Tutoring
Marketing site and community bot for a one-person tutoring business.
## Commands
- Dev: `npm run dev` Test: `npm test` Lint: `npm run lint`
## Conventions that differ from defaults
- Public copy never promises grades, scores, or admissions.
- Price identifiers live in `config/prices.js`; never hard-code them.
- `src/lib/api-types.ts` is generated; never hand-edit it.
## Where state lives
- Status and next action: PROGRESS.md. Decisions: DECISIONS.md.
## Rules
- Plan, then wait for written approval, before touching payments or data.
- Never read or print .env* files. Reference secrets by variable name only.
- Run test and lint before declaring work done.
Good entries are the surprising ones: generated files, unusual tooling, rules about public copy. Bad entries merely restate defaults ("write clean code") or include things that change ("we're working on webhooks"). If a line just repeats what the agent would do anyway, delete it. The rule of thumb is to stay around 40 lines.
DECISIONS.md: Decision, Why, Alternatives, Revisit Conditions
Every real decision is recorded as a dated entry in a fixed format:
### D-004: Map payments to roles through a config table
- Date: 2026-03-11
- Decision: Price identifiers map to tier roles in config/prices.js.
- Why: Prices will change; the logic should not.
- Alternatives considered: hard-coded if/else on amount (breaks when prices
change); a database table (more machinery than three tiers justify).
- Revisit if: tiers exceed six, or non-developers need to edit them.
- Status: Active
Each field has a role:
- Why lets future sessions judge edge cases instead of guessing.
- Alternatives considered prevents the same options from being proposed again.
- Revisit if specifies what evidence would justify reopening the choice.
Never delete entries. When you overturn a decision, add a new one that supersedes it and mark the old entry as Superseded by D-NNN. The history itself is the point.
PROGRESS.md: Written for a Session with No Memory
This file answers three questions: where we are, what's blocked, and what's next.
## Status board
| Phase | State | Gate |
|---|---|---|
| 1. Website | In progress | npm test passes; pricing page renders |
| 2. Payment-to-access | Waiting on Phase 1 | Test-mode payment creates a role and channel |
## Next action
Wire the Standard tier payment link into the pricing card; run the render check.
## Blocked
- Live payment links: waiting on account verification.
Three habits keep it useful:
- Next action is a concrete step, not a topic.
- A phase is done only when its gate passes, not when the work feels done.
- Update the file at the end of every session, before you stop.
Gates for Risky Work: Plan, Approve, Build
For any work touching money, customer data, public releases, or deletions, split the work into three steps:
- Plan. The agent writes down what it will do, in what order, what it will touch, and what could go wrong. It builds nothing.
- Approve. You read the plan and reply in writing with what you approve and what you want changed.
- Build. The agent builds according to the approved plan and reports any deviations.
Today: the payment webhook handler. Plan first. List the files you will touch,
the events you will handle, and the failure cases. Wait for my approval.
One critical detail: an approval you gave in conversation does not exist for the next session. Record it in PROGRESS.md ("Phase 2 webhook plan: approved 2026-03-12 with one change, 7-day activation expiry"). If it isn't written down, treat it as never given. Approving a plan is not the same as approving a launch.
Gate is a term borrowed from engineering and project management: a clear checkpoint that must be passed before moving to the next phase. In AI agent collaboration, gates serve to separate irreversible operations from reversible exploration.
Agents are highly efficient when freewheeling, but once payments, data deletion, or public releases are involved, the cost of an error becomes asymmetric — a bad line of code can be reverted, but an accidental trigger of a live payment flow can cause real losses. So forcing this kind of work into a plan–approve–build structure is essentially trading process for controllability.
There's another easily overlooked detail: verbal approval within a session has no cross-session validity. The next session's agent can't see your prior conversation and will assume it isn't authorized. Writing approval into PROGRESS.md with a date effectively turns "authorization" into readable state instead of a one-off conversational act. This is the principle of "reading is more reliable than remembering" applied to risky scenarios.
Open and Close Routines
Open: Paste the master prompt, then add the session line (scope, "read PROGRESS.md first," and a gate if applicable).
Close: Have the agent update PROGRESS.md (status, next action, blockers). Any new decision gets a DECISIONS.md entry. Ask it to state what it changed and what it didn't verify.
Reading is reliable; memory is not. A five-minute close routine saves you the time of rebuilding context next time.
15-Minute Hands-On Practice
- Create
CLAUDE.mdwith your commands and the conventions only a newcomer would find surprising. - Create
DECISIONS.mdwith the last three decisions you least want to re-argue, plus the why for each. - Create
PROGRESS.mdwith a status board, one next action, and a blocked list. - At the start of the next session, say: "Read PROGRESS.md and DECISIONS.md first, then do X."
If a decision keeps coming back, it means the entry is missing its "why" or "revisit if." What decisions does your agent keep reopening?
One-line Summary
Externalize project memory through a three-layer file architecture to solve the cross-session amnesia of AI coding agents.
Paragraph Summary
The article points out that AI coding agents have no memory at the start of each new session, which is the root cause of "agent contradicts itself" — not a flaw in model capability. The author proposes a three-layer file architecture: a master prompt provides stable background, scaffold files (CLAUDE.md / DECISIONS.md / PROGRESS.md) carry project decisions and progress, and a session line states only today's task. CLAUDE.md should be concise and contain only counterintuitive conventions; DECISIONS.md uses "why, alternatives, revisit conditions" to prevent decisions from being re-opened; PROGRESS.md records status, blockers, and next actions for a memoryless session. Risky work involving money or data must go through a plan–approve–build gate, with approval recorded in writing. Combined with open and close routines, this minimizes the cost of rebuilding context.
Related articles

Chain of Thought Isn't Just for AI: How Humans Can Use CoT to Improve Thinking Quality
Chain of Thought isn't just a prompt trick for large models. Starting from a Hacker News discussion, this article analyzes why CoT works for human thinking too, breaks down actionable ways to transfer it, and highlights the key differences between human CoT and machine CoT.
Cloudflare Teams Up with OpenAI: Closi…
Cloudflare Teams Up with OpenAI: Closing the Loop from Vulnerability Discovery to Defense with AI
Cloudflare uses OpenAI Daybreak to investigate security vulnerabilities and generate reviewable remediation plans, while developers use Codex to boost coding efficiency and quality.

Orca Multi-Agent Orchestration in Practice: A Guide to Parallel Collaboration with Claude and Codex
Orca is Stable AI's free open-source agent workbench supporting 34 agents like Claude Code and Codex in parallel. Learn its Git worktree isolation, multi-model orchestration, and mobile management.