Coding agents have become genuinely good at the part that used to be slow. Ask for a feature and you get a working one. The failure has moved — it is no longer whether the code works, it is whether the change was allowed to happen at all.
The agent can read the code. It cannot read the decision.
An agent working in your repository has excellent access to one thing: what the code currently does. It can trace a function, find every caller, follow a type. That is real, and it is why the code it writes usually runs.
What is nowhere in the repository is the reasoning. Why this is out of scope. Which rule must stay true no matter what. Which of two similar-looking approaches was already tried and rejected. That information lived in a conversation, or in someone's head, and the agent has neither.
So it does the reasonable thing, which is to infer intent from the code it can see. Most of the time the inference is right. When it is wrong, it is wrong confidently and in a way that looks finished.
An agent given a ticket has the ticket. An agent given the plan has the product.
Two different jobs, usually confused for one
There are two kinds of context an agent needs, and mixing them is why context files get long and stop working.
The first is the brief for one change: what this change touches, what it must not break, how you will check it. That is per-task, it is written fresh every time, and it is thrown away afterwards. I have written up that packet in detail already — the dependency check before a change covers it, and this note deliberately does not repeat it.
The second is the product itself: the decisions that were true before this task and will be true after it. That is what this note is about, and it is the part almost nobody writes down, because it never feels urgent on any particular day.
The sorting question
Would this still be true if the current task were cancelled?Yes means it belongs in the durable file. No means it belongs in the request. Almost every mistake in a context file is a sentence that answers no and got written down anyway.
The durable half is not something you should have to invent for the agent. It is the boundary, the invariants, the non-goals, the dependency map and the open decisions that a build-ready plan already contains. If the plan exists, this is a copying exercise. If writing it feels like original work, the decisions were never actually made — and that, not the file, is the thing to fix.
A task brief describes a change. Durable context describes what the change is not allowed to do.
Where to put it so it is actually read
Context that lives in a chat message is gone next session. Context that lives in a document nobody references is decoration. The only reliable place is the repository itself, in the file the tool loads by convention.
Every major agent has one — a markdown file at the project root that is read at the start of a session. The exact filename differs per tool and changes often enough that it is worth checking the current docs rather than trusting a blog post, including this one. What does not change is the shape of what belongs in it.
Version control is the point, not the convenience. A rule in the repo is reviewed like code, changes with a commit that explains why, and survives the session it was written in. A rule in a chat message survives nothing.
The failure nobody plans for
A stale rule is worse than a missing one, because it gets followed.A missing rule produces a question. A rule that was true six months ago produces confident, consistent, wrong work. Keep the file short enough that you will actually reread it, and delete lines the moment the decision behind them changes.
What not to include
The instinct is to write everything down. Resist it: the file competes for attention with the actual task, and padding it lowers the odds that the important lines land.
- Descriptions of what the code does. The agent can read the code faster and more accurately than your summary, which starts going stale the day you write it.
- Style rules a formatter enforces. If a tool can check it, let the tool check it.
- Ticket-level detail. That belongs in the request, phrased as a constraint rather than an errand. In the repo it becomes historical noise within a week.
- Aspirations. “We value clean code” tells an agent nothing it can act on. A named invariant does.
How to tell whether it worked
The measure is not whether the agent completed the task. It nearly always completes the task. The measure is what it did with a request that was underspecified.
Give it something the plan does not fully answer and watch. With good context it comes back with a question, points at the open decision, or names the invariant that makes the request ambiguous. With poor context it picks an interpretation and builds it, and you find out three files later — the exact situation where an agent should stop and ask.
That is also the honest reason to write the plan down at all. It is not that agents cannot build without it. It is that the cost of a wrong assumption is now paid at machine speed, across more files, in less time than it takes to notice — which is why it pays to see what breaks before you build rather than after.
Reader response
Was this field note useful?
Next in the path
The file is written. Now phrase the request.
Read how to write the constraintField notes by email
Thanks, you're on the list. ✓
Email signup did not go through. Please try again.
A short note when there is something worth sharing. No spam.
