Field Guide · 08 of 10
Why AI agents forget your requirements
A long session eventually outgrows what the agent can hold, so the earlier conversation is replaced by a summary. The summary keeps the mood and loses the constraints: it says the user is happy and the work is going well, and the rule you set in the first hour is gone. The defence is to keep requirements in a file in the repository instead of in the conversation, and to check that file after every summary.
What is actually happening
The space an agent can hold at once is finite. A common remedy when it fills is to condense the earlier turns into a summary and carry on from that. It is a reasonable trade, and the summary is written by the same agent that is about to rely on it.
It decides what mattered without knowing which sentence will matter in an hour. Rules about what not to do are especially exposed. “Keep the public API unchanged” and “do not email customers” leave no trace in the work, so a summary of the work has nothing to attach them to. What survives is the story: a user, an app, progress.
The failure is silent. A summary reading “everything is going great” looks exactly like a good one, and nothing errors. The next turn starts from the reduced picture with full confidence. The agent will not tell you it forgot, because it does not know what it forgot. In the skit it greets you as a stranger, asks what you would like to build, then claims to remember everything.
A new session is the same problem with a bigger gap: nothing is carried over unless it was written down somewhere the agent reads.
How it shows up in the diff
- A change that breaks a rule you stated earlier: a renamed public function, an edited file you said to leave alone, a forbidden dependency.
- A question you already answered, asked again.
- Work redone: files recreated, or an approach you rejected coming back.
- A decision reversed without comment, such as a setting flipped to its old value.
- A summary made of adjectives, with no requirement in it.
Requirement (turn 3): Keep the public API unchanged.
Summary (turn 86): User wants an app. Everything is going great.
User is very happy.
// src/cart.ts
- export function total(items: Item[]): number
+ export function calculateTotal(items: Item[], options: Options): number
The requirement did not survive the summary, so nothing stopped the rename.
Guardrail
Put the requirements somewhere that does not get summarised, and say when to read them.
Paste into AGENTS.md
Requirements are in REQUIREMENTS.md. Re-read it before you start, after any summary of this conversation, and before you report done. Never edit it.
Check it mechanically
# CI step. Assumes the base branch is main and the history is fetched.
if [ ! -s REQUIREMENTS.md ]; then echo 'REQUIREMENTS.md is missing or empty'; exit 1; fi
if git diff --name-only origin/main...HEAD | grep -qx REQUIREMENTS.md; then echo 'REQUIREMENTS.md changed on this branch'; exit 1; fi
The first line fails if the file is missing or empty, including when it was only deleted or emptied in the working tree. The second fails if the branch changed the file in a commit. An unchanged file passes both without output.
The second line is written as if … | grep -q …; then exit 1; fi because here the match is the failure. It also trips on legitimate edits, and on the pull request that first adds the file; a person makes those on the main branch, or merges that one by hand. An uncommitted edit to the file is not seen until it is committed, and if origin/main is missing the second line prints a fatal error and passes, so fetch first. None of this proves the agent obeyed the file, only that the file is still there to obey. The diff still gets read against it: that is the checklist item about the start of the session still being true at the end.
Further reading
A Philosophy of Software Design: complexity as the main enemy, and why a design should not depend on anyone holding all of it in their head, human or otherwise.