Agents don't fail at writing code. They fail at knowing what already exists.

Give a capable coding agent a clear task and it will write the code. That part is close to solved, and arguing about it is not interesting any more.

What it will also do, given the chance, is write code that already exists. A helper three directories away. A rule in the stylesheet that does the same job under a different name. A check the build already performs. Not because the model is careless, but because it cannot see the tree. It sees whatever was put in front of it, which is a slice, and it reasons confidently about the whole from that slice.

That is the obstacle to agentic development at real scale, and it is not a prompting problem.

Duplication does not announce itself

The version everyone expects is copy and paste: the same twenty lines in two files, which any clone detector finds. That one is easy and it is not the one that hurts.

The expensive version is two implementations of the same idea that share no text at all. Different names, different structure, the same job. A clone detector sees nothing. A test suite sees nothing, because both work. A code review sees nothing, because the reviewer is looking at one of them.

Here is one from this site, three days old at the time of writing. Two sections of the homepage are the same shape: a heading, a paragraph under it, a hairline between items. They were written a week apart and they became two separate sets of CSS rules. Both correct. Both tested, in the sense that the pages rendered. And they drifted, as two copies of anything drift: one had a 44 pixel margin and the other 40, one had 28 pixels of padding and the other 26.

Nobody could see it. What the owner of the site could see was that two sections "looked different from each other", which is an accurate report of a four pixel discrepancy that no review would catch and no test would fail. The fix was one rule set instead of two. The lesson is that the second one should never have been written, and the only thing that would have prevented it is someone checking whether the pattern already existed.

An agent is very good at writing the second rule set. It has no mechanism at all for asking whether the first one is already there.

Recall is not the same as knowing

The usual answer is more context: a bigger window, a retrieval step, an index of the repository. These help, and they do not solve it, for a reason worth being precise about.

Retrieval answers "what is similar to this query". The question that matters is "does a thing that does this job already exist, and if so, is it the canonical one". Those are different questions. The first is a similarity score. The second is a claim about the tree that can be right or wrong, and it needs evidence rather than confidence.

So the discipline I settled on is not about giving the agent more to read. It is about making the question answerable and making the answer citable.

Two roles that exist only for this

In the framework I run coding agents under, two of the crew do nothing but this, and neither is allowed to write code.

The first takes soundings. Its only job is to answer "does this exist" before anything is built, and its answer is constrained to four verdicts:

  • exists and is canonical, with the file and line, and who imports it
  • exists but is forked, with every implementation cited
  • does not exist, where a stub, a TODO or a document claiming it all count as not existing
  • inconclusive, which names the searches that were run and what would settle it

That fourth verdict is the one that makes the other three worth anything. Without it there is no way for the answer to be "I could not tell", so the pressure is always toward a confident wrong answer. An admission that the search failed is useful. A guess dressed as a finding is worse than silence.

The second looks for the duplication the clone detectors miss, and it is deliberately denied the tools to fix what it finds. It files the work and stops. That constraint is not caution for its own sake: the moment a role can both find and fix, its incentive shifts toward finding things it can fix, and the semantic cases are exactly the ones that are hard to fix and easy to skip.

The cost of getting it wrong is not the duplicate

A duplicated function is cheap. Two of them cost slightly more than one.

What is expensive is everything downstream. Both get maintained. A bug is fixed in one. A convention changes and reaches one. Someone reads the wrong one and copies its pattern, and now there are three. The cost compounds quietly and none of it shows up as a failure, which is why it runs for months.

The same week as the CSS example, a bulk edit in the same repository rewrote a set of color values into named tokens. It also rewrote them inside the token definitions, producing a property that referred to itself. CSS has no opinion about this. No parse error, no warning, a completely valid stylesheet that resolves to the wrong thing. The footer of a live site rendered dark navy text on a near black background, and stayed that way until someone opened it on a phone.

Both of those are the same failure in different clothing. Something existed, something else was written without checking, and nothing in the toolchain was capable of noticing.

What this actually asks of you

Nothing here is about models, and it will survive the next three of them.

Make existence a question with a citable answer. Not "is there something like this" but "does this exist, where, and is it the only one". If the answer cannot carry a file and a line, it is an opinion.

Let the answer be "I could not tell". The failure mode of every system that cannot say this is a confident wrong answer, and a confident wrong answer about what exists is how you get the second implementation.

Separate finding from fixing. Not because agents cannot be trusted with both, but because the role that can fix will drift toward finding fixable things.

Assume the gap is invisible. The duplication that matters does not look like duplication. It looks like two sections of a page that are slightly different from each other, and the only person who will notice is the one who has to look at it every day.

The thing worth internalizing is that none of this is a limitation of the agent. It is a property of working on a codebase larger than the window you are looking at it through, and every human engineer has the same problem. The difference is that a human who has been in the codebase for a year has a vague, unreliable, genuinely useful sense of what is already in there. An agent starts every session with none of it, and will start the next one with none of it either.

Build the thing that answers the question, or accept that you are going to keep writing the second implementation.