Disclosure: this article was drafted with an AI assistant (Claude). #ABotWroteThis
An AI coding agent starts every session knowing nothing about the last one. That one fact explains most of the "the agent contradicts itself" complaints. It is not a bad model. It has no memory, and you are the only thing connecting session 1 to session 5.
Here is a setup that moves that memory out of your head and into files the agent reads. It is three small files, one short prompt, and one rule for risky work.
The two failures
Context loss. You open a new session and retype the project background from memory. You drop a constraint without noticing, so the output is wrong in a way you only discover later.
Reopened decisions. Picture a pricing page. You settled on three tiers after thinking it through. A fresh session sees an unfinished page, proposes two tiers, and has no way to know why you chose three. You either re-argue it or accept the regression.
Both come from the same place: the reasoning behind the project lives in your head or in a chat that is now closed.
The fix: three layers
| Layer | Holds | Changes |
|---|---|---|
| Master prompt | What is true about the project: what it is, who it is for, constraints | Rarely |
| Scaffold files | What has been decided and where the work stands | Every session |
| Session line | What to do today | Every session |
The master prompt is the stable background you paste or reference at the start. The session line is one sentence: the scope for today, plus "read PROGRESS.md first". The middle layer is where most of the value is, so the rest of this article covers it.
CLAUDE.md: thin, stable, surprising
Claude Code reads CLAUDE.md automatically at the start of a session, so every line in it is read every time. That is the reason to keep it short. Put in it only the conventions that differ from the agent's defaults.
# 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.
(Harbor Lane is a made-up example project.)
Good entries are surprises: a generated file, an unusual tool, a rule about public copy. Bad entries restate defaults ("write clean code") or hold things that change ("we are working on the webhook"). If a line only repeats what the agent would do anyway, delete it. A rule of thumb is to stay around 40 lines.
DECISIONS.md: decision, why, alternatives, revisit-if
Every real decision gets 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 does a job:
- Why lets a future session judge edge cases instead of guessing.
- Alternatives considered stops the same options being proposed again.
- Revisit if names the evidence that would justify reopening the choice.
Never delete an entry. When you reverse a decision, add a new one that supersedes it and mark the old one Superseded by D-NNN. The history is the point.
PROGRESS.md: written for a session that remembers nothing
This file answers three questions: where are we, what is blocked, what is 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:
- The next action is one concrete step, not a theme.
- A phase is done only when its gate passes, not when the work feels finished.
- Update the file at the end of every session, before stopping.
A gate for risky work: plan, approve, build
For anything that touches money, customer data, going public, or deletion, split the work into three steps:
- Plan. The agent writes 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 change.
- Build. The agent builds against the approved plan and reports any deviation.
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 detail matters here: 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 is not written down, treat it as not given. And approving a plan is not approving going live.
The open-and-close routine
Open: paste the master prompt, then add the session line (scope, "read PROGRESS.md first", and the gate if there is one).
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 did not verify.
Reading is reliable; remembering is not. Five minutes of closing routine saves the time you would otherwise spend reconstructing context next time.
Try it in 15 minutes
- Create
CLAUDE.mdwith your commands and only the conventions that surprise a newcomer. - Create
DECISIONS.mdand write down the last three decisions you would hate to re-argue, with the reason for each. - Create
PROGRESS.mdwith a status board, one next action, and a blocked list. - Next session, start with: "Read
PROGRESS.mdandDECISIONS.mdfirst, then do X."
If a decision keeps coming back, the entry is missing its "why" or its "revisit if". What does your agent keep reopening?
Top comments (0)