You know the release you schedule for Thursday night. Not because Thursday is convenient, but because if it breaks you have Friday to fix it before customers notice. One engineer has to be online. He's the only one who understands what the billing module does when a subscription is cancelled mid-cycle. Nobody has touched that file in eighteen months and nobody wants to be the first.
Then Meta announces Muse Code, an AI agent built to work across large codebases. And someone on your board - or your own head of product - asks the obvious question. Could this thing just go in and clean it up?
I understand the appeal. It's the cheapest possible answer to an expensive problem. It's also the fastest way I know to turn a slow, fragile system into a fast, fragile system.
What an agent on a large repo actually does
Strip away the marketing and these tools all work the same way. The agent indexes your repository. It builds some form of searchable map - embeddings, symbol graphs, call hierarchies, git history. When you give it a task, it retrieves the parts of the code it thinks are relevant, plans a change, edits files, and then tries to verify its own work by running your build and your tests.
Every step in that chain depends on your codebase, not on the model.
The retrieval step depends on whether your code is named and organised in a way that makes intent findable. The planning step depends on whether there's one obvious way to do things in your system, or five. The verification step depends entirely on whether your test suite actually fails when something breaks.
The model is the same model whether you point it at a clean service or a ten-year-old monolith. The output is not remotely the same. This is the part vendors skip, and I've written about the underlying limits before in The AI Context Window Problem.
Your codebase is the prompt
Think of your repository as the actual instruction set. The task you type is a footnote.
An agent works by finding precedent. It looks for how something similar was done elsewhere and follows that pattern. That's a reasonable strategy in a system with one clear pattern per problem. It's a disaster in a system with four.
Most legacy systems have accumulated layers. There's the original way permissions were checked. There's the way the team did it after the 2021 refactor. There's the way the contractor did it for the mobile API. There's the special case for enterprise customers that lives in a middleware nobody documented. All four are in the repo. All four look equally valid to a retrieval system.
The agent will find one of them. It has no way to know which one is the current standard, which one is deprecated, and which one is a landmine kept alive by a single client contract. So it picks the one that matches your query best in vector space and copies it. Now you have five patterns instead of four, and the newest one was added by something that can produce code faster than your team can read it.
Dead code makes this worse. Every unused function, every commented-out block, every "v2" directory that was abandoned halfway - that's all live signal to a retrieval system. Humans learn to ignore it. They know that utils_old.py is a graveyard. The agent doesn't. It reads it with the same confidence as your best module.
The bottleneck moves, it doesn't disappear
Here's the arithmetic that gets ignored in every AI coding pitch.
Writing code was never the constraint in a mature system. Understanding the consequences of a change was. Agents attack the part that was already cheap.
If an agent produces a change touching thirty files across four modules, someone has to decide whether it's safe. That review is slower than reviewing human work, because you can't ask the author what they were thinking. There's no thinking to interrogate. You have to reconstruct the reasoning from the diff itself.
So the queue backs up at review. Teams respond in one of two ways. Either they slow down and the promised velocity never appears, or they start approving things they don't fully understand. The second one is what usually happens, because someone senior promised a productivity number to the board.
That's how you get faster damage. Not bad code - plausible code. Code that reads well, passes the tests you have, and quietly changes behaviour in the path you never covered. I called this pattern out in Why 'AI Slop' Is the Red Flag Your Software Rescue Needs Now, and agents that operate at repo scale raise the stakes considerably.
There's a second-order effect worth naming. Human pull requests are small partly because humans are lazy. Nobody wants to refactor forty files by hand. That laziness was an accidental safety feature: it kept the blast radius of any single mistake small. Agents remove the friction, and with it the accidental limit on how much can go wrong at once.
The contrarian bit: don't start with a greenfield pilot
Standard advice says to trial AI agents on something low-risk. A new microservice. An internal tool. A greenfield project with no legacy baggage.
I think that's the least informative place you can possibly test. Greenfield code has no history, no hidden coupling, and no conflicting patterns. Of course the agent performs well. You learn nothing about the environment where you actually need the leverage, which is the old system that's eating 60% of your engineering budget.
The useful experiment is narrower and harder. Pick one real module in the legacy system - ideally one that's painful but not existential. Spend two weeks making just that module agent-ready. Then run the agent on it and measure.
That's a small, bounded investment with a clear answer at the end. It also tells you something the pilot never will: how much work it takes to make your system legible to a machine. Multiply that by the number of modules and you have a real budget, not a vendor's estimate.
What "agent-ready" actually means
Four things, in order of how much they matter.
1. Tests that fail for the right reasons
Coverage percentage is a vanity metric. What matters is whether a test suite catches a behaviour change on the paths where money and data move. Chasing 80% coverage across a legacy system is a year of work with unclear payoff. Writing characterisation tests around the six flows that would get you a call from a lawyer takes a couple of weeks.
Characterisation tests don't assert what the code should do. They lock in what it currently does, bugs included. That's the point - you're building a tripwire, not a specification.
# Lock in current behaviour before letting anything touch this. # We are not claiming this proration logic is correct. # We are claiming it must not change without a human deciding it should. def test_midcycle_cancellation_refund_is_unchanged(): sub = build_subscription(plan="pro", start="2026-01-01", price_cents=9900) result = cancel(sub, on="2026-01-18") assert result.refund_cents == 4620 # observed today assert result.access_until == "2026-01-18" assert result.invoice_status == "credited"
An agent that can run this suite has a real feedback loop. Without it, "the tests pass" means nothing.
2. Boundaries the machine can see
If your module boundaries only exist in an architecture diagram, they don't exist. Make them enforceable in tooling, so a violation fails the build instead of surviving code review.
// eslint.config.js — boundaries as a build failure, not a convention { "rules": { "no-restricted-imports": ["error", { "patterns": [{ "group": ["**/billing/internal/**"], "message": "Billing internals are private. Use billing/api." }] }] } }
This gives the agent a hard wall. It tries the shortcut, the build breaks, it corrects itself. That loop is worth more than any amount of documentation.
3. Machine-readable context, not prose docs
Most internal documentation is written for a new hire who will read it once. Agents need something different: current constraints, stated plainly, in a file that lives next to the code.
# AGENTS.md ## Canonical patterns - Auth: use `lib/auth/session.ts`. `legacy/authCheck.php` is deprecated and only kept alive for the on-prem client. Do not extend it. - DB access: repository classes only. No raw SQL outside `db/queries/`. ## Do not touch without a human decision - `billing/proration.py` — contractual behaviour, audited annually. - Any migration in `db/migrations/` older than 2024. ## Definition of done - `make verify` passes (lint + types + tests + boundary checks). - No new dependencies without approval.
That file is governance in a form a machine can act on. Policy that only lives in a Notion page or a slide deck is invisible to the thing writing your code - which is the argument I made in Your AI Agent Didn't Read the Handbook.
4. One command, one truthful signal
If bootstrapping the project takes three days of tribal knowledge, an agent can't verify anything it writes. It needs a single command that builds, checks types, runs tests, and enforces boundaries. If that command is green, you should be able to deploy. If it isn't, everything downstream is guesswork.
The measurement that keeps you honest
Track four numbers before you adopt an agent, and again ninety days after. How long a change takes from start to production. How often a deploy causes a problem. How long it takes to recover. How much rework each change generates.
If change failure rate goes up while lead time goes down, you haven't gained speed. You've moved cost from engineering into support, and it will show up in churn a quarter later. That's the trade nobody puts in the ROI slide.
Where this leaves you
Muse Code and the tools that follow it are real. Agents that reason across a whole repository will change how engineering teams work, and I'd rather be early than late. But an agent doesn't hold an opinion about quality. It reproduces whatever discipline it finds in your system, at a speed your team can't match.
If your codebase has clear boundaries, honest tests, and one obvious way to do things, an agent makes a strong team materially faster. If it doesn't, the agent will faithfully industrialise your mess.
Stabilise first. Improve second. Add AI last. The order isn't conservatism - it's the only sequence where you pay once.
Book a Free Rescue Call


