
Between the last commit of September 5 and the morning of September 15, 2026, 1,177 commits landed on the main branch of our monorepo. Together they added 260,771 lines and removed 862,973 (our git log for those nine days, lockfiles and archived code excluded). For every line we wrote, we deleted 3.3.
Agents did much of that work. 558 of the 1,177 commits carry an agent's co-author trailer (our git log for the same nine days), and that is a floor, because not every agent we run signs its commits that way. That is the lesson. Agents bias toward adding: given a task, an agent writes a new module, a new flag, a sibling endpoint. Over months that sprawl becomes the product's bug surface. The fix we landed on is to make deletion the default verb and to make every new thing justify itself in the pull request that adds it.
Nine days on main
Most of the deleting happened in two days. On September 10, main lost 432,843 lines, and on September 11 another 333,094 (our git log, end-of-day snapshots of main). Those were whole seams going at once: a directory, its tests, its docs, and every import that pointed into it. The other days were slower work, a route here and a flag there, each with its own pull request.
Where the lines came from
The two largest deletions were decisions we made once. A directory of consumer agents we no longer sell was 280,365 lines. The agent framework and UI kit built for the old desktop app were another 261,311. Nobody was going to extend either again, so we removed them whole instead of letting them rot in place.
The smaller bars teach more. In the same nine days the API lost 113,115 lines while gaining 55,244, and the CLI lost 87,219 while gaining 15,820 (our git log). That was live code. Much of it had been added by agents finishing a task, and each piece came with its own tests, docs and callers.
Sprawl is one reasonable commit at a time
From February 1 to September 13, 2026, our main branch took 11,756 commits. Once the conventional-commit prefix (fix(api):, refactor:, chore:) is stripped, the subjects of 577 of them begin with remove, delete, drop, kill, retire or prune (our git log). Reading them back, the same shapes repeat: dead modules, the same endpoint served twice, types with one caller, three hand-maintained lists of the agents we support that had to be kept in step, and registry rows for routes that no longer existed.
No single commit was wrong. An agent sees the task and the files it opened. Adding a sibling is the locally safe move, because it cannot break callers the agent never read. Finding the thing that already does the job means reading code nobody asked it to read. So each change adds a new thing instead of extending the one that exists, and each new thing brings its own bugs, its own tests, and its own copy of a decision already made somewhere else. When the decision changes, the fix lands in one copy and the other two become the next bug report.
GitClear sees the same pattern at a much larger scale. Its analysis of 211 million changed lines found that moved code, the signature of refactoring and reuse, fell from 25% of changed lines in 2021 to under 10% in 2024, and that 2024 was the first year copy/pasted lines outnumbered moved ones (GitClear code-quality report, 2025; DevClass, February 20, 2025). Their data covers code completion with a person at the keyboard. Our agents ran whole tasks with nobody watching each edit.
Deleting finds bugs too
One pull request on September 10 retired 50 API endpoints from a list. Before merging, the agent doing the work ran our API reference generator on the old tree and the new one. The old tree had 307 endpoints. The new one had 256, one fewer than the plan allowed.
Diffing the two endpoint sets found the cause. Deleting the whole email router had also taken POST /api/v1/emails/webhook, the live webhook our email provider calls, which was never on the list. On paper the list matched. The router-level delete took one more route with it. The agent restored that route as a one-route router, counted again, got 257, and diffed again to confirm the removed set was exactly the 50 on the list.
The rule we took from it: verify a deletion against a measured baseline, never against the plan. A deletion is a change like any other, and it gets the same proof.
The rule we wrote down
On September 13 we added a section called "Extend, don't add" to the instructions every agent in this repository reads before it writes code. It starts from the default answer to "where does this go?": an existing function, type, route, table, flag or module. Adding a new one is the exception, and the pull request has to argue for it.
The argument has a fixed shape. Every pull request description lists, under New surface, each new exported symbol, type, route, table or column, config key, environment variable, CLI flag, module and dependency it introduces. For each one it names the existing thing the author tried to extend and the one concrete reason that thing could not carry the change. An empty list is the goal. A pull request with new surface and no list is not reviewable, and reviewers block it.
This works on agents for a plain reason. An agent follows an explicit procedure well, and it will search under three names if the instructions say to. The list also moves the cost of adding to where a person can see it. I argued in Agents Are Eating the Org Chart that review is the rate that bounds what agents can ship; a pull request that says "New surface: none" is one a reviewer can read in a minute.
What I can't claim yet. Lines are a crude measure. The 862,973 include docs and tests, and the first nine days took the cheapest deletions, the seams nobody used. The rule is four days old, and I have no before-and-after bug count. What I can say is that the product kept shipping through all of it: the engine and the console grew while the rest shrank.
Where Rush fits
We build Rush Cloud, and it returns work in the shape this rule asks for. A request starts an agent in an isolated cloud sandbox. When a one-shot run pushes code, the result is one pull request with checks, plus the full trajectory of what the agent did, so a reviewer can see what it read before it wrote anything and judge whether the new surface was needed. When a run pushes work without its pull request, it ends as needs_review. The same cost-of-failure reasoning from Every Agent Demo Hides the Same Number applies: review is where an agent's output becomes something you can merge.
Our agents did what we asked. The first thing we ask them now is to find what already does the job.


