Context is the bottleneck
Model capability keeps improving and tokens keep getting cheaper. What stays hard is telling an agent which of the things already in the repo is the one the team considers correct.
Here is a shape we keep running into, in our repos and in everyone else's. An agent is asked for a feature that turns a raw string into a category the product understands, so it writes a parser. The parser is typed and tested and sensible about the odd inputs. It is also the second one in the repo. The first has sat a few directories away for months, and the two agree on common inputs and drift apart at the edges. Nothing crashes, no test goes red, and two parts of the product begin describing the same thing differently.
Read that diff on its own and you approve it. The code is better than what a hurried person writes at the end of a day, so the model was not the weak link. Nobody told the agent the first parser existed, and nothing in the repo would have led it there: no naming convention pointing at it, nothing that made the existing answer easier to find than a new one.
Where the binding constraint sits depends on what you are building; for plenty of teams it is judgment, or the willingness to delete things. Inside an agentic build loop it is context. Model capability and token prices move on a schedule set outside the team, and so far both have moved in the builder's favour. What does not improve on its own is the curated subset of everything true about a system that a particular task requires, assembled and put in front of the agent before it opens a file.
Locally correct, globally wrong
The failure has two common shapes and both look like competence. The first is the one above: the agent builds what the codebase already has, because building is cheaper than finding, and it rarely stops at one duplicate. Utilities like that accumulate in any repo with a few years on it, added by people who each knew better and could not find the one already sitting there. The second shape survives review, which makes it worse, because the agent matches a convention the codebase abandoned months ago. Retired patterns do not delete themselves. The old files are still there, still outnumbering the new ones, laid down in strata that look identical from the inside, and a pattern matcher reading the repo cold has no way to tell which layer is current.
A bigger window does not solve this by itself. A brief that names twelve files says those twelve matter; the same brief with the whole repo pasted in leaves the model to work out which twelve those are, which is the failure the brief was meant to prevent. Every wrong inclusion dilutes the right ones, and the first parser stays invisible inside a window that contains it.
Some of this is a tooling problem with tooling answers, and retrieval has improved. An agent that can grep the repo and follow imports outward recovers a real share of what a hand-assembled brief used to supply, and on a well-named codebase it finds the existing parser without being told. We are planning on that improving further, not on it stalling.
Search finds what exists. What it cannot do is adjudicate: it cannot tell you which of two working implementations this codebase considers correct, or that the pattern in forty files is the one we stopped using in March while the three-file version is the replacement. Both are present and both compile. The distinction is a judgment somebody made, and unless that judgment was written down by someone who held it, there is nothing to retrieve. Better search will turn up both parsers, and neither of them says which one the team decided on.
Decisions nobody wrote down
Module boundaries get argued over in review, and a compiler complains when they slip. Where the choice between the two parsers is recorded, and how long it takes something starting cold to find it, has never been anyone's job. Until recently the only readers were people, and people work around a repo that is hard to read without ever reporting it as a problem.
Humans absorb conventions the informal way, in review or from the one engineer who remembers why the retry lives where it does. Conventions that live only in someone's head were always a liability, usually billed when that person leaves. Agents change the timing: an agent begins every session cold and will not wander over to ask. It also works fast enough that an unwritten rule gets violated across a dozen files before anyone notices the pattern, and the same rule produces the same mistake at the start of the next session. A line saying a value is parsed in exactly one place, and here is that place, changes the diff an agent produces.
core/derive/ the place raw inputs become categories. add here.
core/analysis/ whole-archive pass. pure functions; no network inside.
legacy/ui-v1/ superseded layout. still compiles. copy nothing from it.Legibility becomes leverage
Documentation has always lost the internal argument to shipping in our own planning, and for a defensible reason: the return was deferred and diffuse. That return has moved into the same week as the work. A repo that can explain itself gets a correct change out of an agent on the first pass.
The gap shows up most clearly in what a diff communicates. A human reviewer reads absence: the fact that you did not touch the cache layer says you considered it and decided it was fine. An agent reads only what is present, so a rule the team never stated is not a rule its codebase has.
- One canonical doc per repo that states decisions, not one that re-describes the code.
- Scope the brief to a subsystem rather than the whole repo.
- Name things so search lands on them, then record which of the two findable versions is current.
- Write down what a diff cannot carry: the alternative we rejected, and the thing not to do.
None of this hardens into something that sits still. Discoverability is an operating property of a codebase, in the same family as build time or how often the suite flakes: it degrades with every merge that adds a file and states nothing, and it improves only when someone spends the twenty minutes. The measure we use is how long it takes something arriving cold to find the answer the repo already contains, whether that is an agent or one of us back from three weeks on another product.
More from the notebook →