Uber's AutoClean agents delete 1 million lines of dead code

Uber's engineering team has published a blog post describing an internal system called AutoClean. It plugs into the company's feature-flag management platform, identifies flags that are safe to retire, generates a diff that deletes the code behind them, and hands it to an engineer for approval once the tests pass. Over the past few years the system has cleaned up more than 16,000 feature flags and over 1 million lines of code, and it is still running across several of Uber's monorepos.

The post is credited to Uber senior software engineers Daniel Ramos and Diego Marcilio, and software engineer Nikhil Parasaram.

Why deleting code is hard

Uber rolls out new features gradually behind feature flags, and thousands of flags can be live on the platform at once. After a rollout finishes, the conditional branches, helper functions, call sites, configuration and tests often stay exactly where they were. Removing a single flag means touching all of those places at once, while making sure production behavior doesn't change at all.

The post points to a newer cost as well: dead code doesn't just make humans work harder to read it. AI coding assistants also spend extra time and tokens on those branches when they parse a codebase.

A three-stage pipeline

Stage one: rewrite. The agent gets access to the codebase and calls PolyglotPiranha, a code-transformation engine Uber built and open-sourced, through MCP. The engine handles boolean simplification and conditional elimination. The authors' reasoning is straightforward: if boolean simplification goes wrong, it can "silently change program behavior," so as much of it as possible is left to deterministic tooling.

Stage two: fix CI. Simple failures go to deterministic fixers, such as removing a default value that is no longer used or clearing lint errors. Harder ones go to an agent, for example deciding whether a given test should be deleted or rewritten. Each fixer's permissions are tightly scoped; the test fixer, for instance, can only touch test files. The loop runs until CI passes or the retry budget runs out.

Stage three: verification. Once CI is green, static checks run first. The diff then goes to a validation layer called CodeCourt, where several specialized review agents inspect it in parallel. The rules listed in the post include:

  • Delete only; introduce no new code.
  • Observable behavior must stay the same.
  • Handle only the designated flag, without sweeping away other related flags along the way.
  • Leave no comments or traces of the agent's reasoning behind.

If any one of them fails, the diff is discarded and never reaches a person. The authors say that a handful of focused sub-agents work better than a single agent reviewing a whole diff from start to finish.

From Piranha to agents

AutoClean is built on Piranha, which Uber open-sourced several years ago. That tool was written specifically to remove stale flags, using rule matching for static rewrites. Its successor, PolyglotPiranha, extended the rule engine to multiple languages. What has changed this time is the layer around it: the rule engine still owns the boolean logic where mistakes are most likely, while agents take over what rules can't fully cover, such as fixing tests and updating call sites, and a separate set of agents then checks their work.

The post is candid about several failure modes. Agents will modify production code just to make tests pass, delete tests whose behavior should have been preserved, and stop too early and leave a cleanup half done. When given many instructions, they can also miss one of the constraints. CI can't catch these semantic problems, and the restricted fixer permissions and the addition of CodeCourt are aimed squarely at them.

The post gives no success rate, no average run time and no share of diffs that get discarded, and the example code is in Go, with no detail on coverage for other languages. According to the authors, a human reviewer now only has to answer one question: should this flag be removed? The mechanical correctness has already been screened by the three stages before the diff gets that far.

Sources: Uber Engineering blog, CocoLoop, PolyglotPiranha GitHub project page. Cleanup figures follow the cumulative totals disclosed in Uber's blog.