Brownfield first, and why greenfield advice misleads
Almost every account of agentic development you will read describes a new codebase with no history. Your codebase has history, and that changes which advice applies.
Read enough writing about agentic development and you notice something about the examples. They are always a fresh repository. Someone starts a new service, writes a specification, points an agent at it, and reports back that the whole thing came together in an afternoon.
Those accounts are usually honest. They are also nearly useless to the person reading them, because the person reading them has a nine-year-old codebase with two ORMs in it, a module everyone is afraid of, four hundred tickets in a backlog nobody has groomed since the last reorg, and a deployment process with a manual step in the middle that exists for a reason no living employee can fully articulate.
The gap between those two situations is not a matter of degree. It is a difference in which problems dominate, and therefore in which advice is load-bearing. Greenfield advice optimises for the wrong constraint.
What greenfield quietly assumes
Every greenfield success story rests on a set of conditions that are true precisely once, at the start of a project, and never again.
The specification is complete because the system is small. You can hold a new service in your head. The acceptance criteria you write are complete relative to a system with no hidden behaviour, no undocumented consumers and no five-year-old bug that three downstream teams now depend on. As soon as a system has history, its real specification includes a large body of behaviour nobody has ever written down, and criteria written in ignorance of that body are confidently incomplete.
There is no existing backlog to reconcile. Greenfield starts with an empty tracker. Every ticket in it was written this month, by people who are currently in the room, in a shared style. Nobody has to deal with the four hundred inherited tickets that describe intentions from two strategies ago.
There are no conventions to reconcile because there are no conventions yet. Branch naming, commit message format, review policy, ticket linking: on a new project you decide these once and everyone follows them. On an old one, you have three conventions that all half-exist, an era of history that used none of them, and a senior engineer who invented the second one and is not thrilled about your third.
Nothing is load-bearing yet. A wrong ticket transition on a project with no customers costs you nothing. The same event on a system that finance uses to close the month is a different sort of afternoon.
Change any one of those and the advice built on it stops holding. Change all four, which is what “we have an existing product” means, and you need a genuinely different approach.
Why brownfield is the better place to start anyway
Given all of that, the instinct is to pilot on the newest, cleanest service you have. I think this is a mistake, for three reasons.
The clean service will not convince anybody. If you demonstrate that ground truth reconciliation works beautifully on a six-week-old repository with immaculate conventions, the response from every engineer watching will be, correctly, “yes, but that is not our problem.” You will have proved the easy case and then have to prove the real one anyway, in a second pilot, with less political capital than you started with. You may as well prove the hard case first.
The value is proportional to the mess. On a clean service where everyone follows convention and the board is roughly accurate, the reconciliation layer produces a modest improvement. On a messy one where a fifth of merged work is unlinked and the board lags by four days, the same layer produces something people notice within a week. The return is not evenly distributed and it concentrates where the disorder is.
Brownfield problems are discoverable, not fatal. This is the part people get wrong. The mess in an old codebase feels like an obstacle, but almost all of it is legible from source control. Inconsistent branch naming shows up in a week of shadow logs. Tickets that describe five changes at once show up in the granularity bucket of your disagreement taxonomy. A manual QA gate shows up as a systematic pattern of “would have marked done, was not actually done.” None of these are subtle. They surface fast, and each one is a finite piece of work.
The thing that would actually kill a brownfield pilot is if the mess were invisible. It is not. It is written into the commit history in full.
Piloting on the clean service
- Works beautifully, convinces nobody
- "That is not our real codebase"
- Value is modest because the board is already roughly right
- Proves nothing about the hard case
Piloting on the messy one
- Worse first week, credible result
- Value is proportional to the mess
- Objections are answered by the pilot itself
- The mess is legible in commit history
The backlog problem, and the honest answer to it
The most common objection to brownfield goes like this: our acceptance criteria are terrible across four hundred tickets, rewriting all of them is impossible, so we cannot start.
The premise is right and the conclusion is wrong. Three things resolve it.
You do not need the whole backlog. You need the next six weeks. Anything further out will be rewritten, reprioritised or deleted before an agent ever reads it. Rewriting it now is work you will throw away. Fix criteria on the work in flight and the work about to be in flight, and let the rest sit.
You can measure criteria quality before you fix it. An existing backlog can be scored for whether its acceptance criteria are actually evaluable, ticket by ticket, without anyone reading four hundred tickets by hand. That is exactly the capability that makes brownfield viable: you get a map of where the criteria are unusable, so you can spend the rewriting effort on the twenty percent of tickets that are both bad and imminent rather than spreading it evenly over everything.
Reconciliation and criteria quality are separable. This matters and it is frequently missed. Reading ground truth from source control and updating the record does not require good acceptance criteria at all. It requires a link between a change and a ticket. You can get the status accuracy benefit on a backlog full of vague tickets, immediately, and improve criteria as a parallel track that pays off later when you start gating on them. Treating these as one project is what makes the whole thing look impossible.
A sequence that works on an old codebase
Concretely, if you are starting on a system with real history, this is the order.
One: pick the highest-traffic repository, not the cleanest. Where the commits are is where the signal is.
Two: audit conventions before you audit code. Spend an hour with the last three hundred merged pull requests and answer: what fraction reference a ticket, where does the reference live (branch, title, commit, description), and how many distinct formats are in use? This hour is the single highest-value hour in the whole brownfield transition, because linking rate is the ceiling on everything else.
Three: fix the convention going forward, not backwards. Do not backfill history. Agree one reference format, enforce it in whatever lightweight way your platform allows, and accept that everything before today is a different era. You are trying to get the next six months right.
Four: shadow mode, and expect a worse first week than a greenfield pilot would have. This is not failure. Your first-week disagreement rate on an old codebase will be materially higher, and most of it will be convention gaps rather than inference errors. Sort them into the categories, fix the ones that are yours, and watch the rate fall across the second week. That fall is the most persuasive thing in the whole pilot, and greenfield never gets to show it because it started at ninety-something percent.
Five: score the backlog, then rewrite the intersection of bad and imminent. Not all bad criteria. The bad ones that are also close.
Six: enable the additive actions first. Linking and evidence comments before status transitions, on a brownfield codebase especially, because the value of a correct link on a system where a fifth of work is unlinked is immediate and the risk is near zero.
Seven: model the out-of-band steps explicitly. Every old system has at least one: a manual QA sign-off, a staged rollout, a release train, a change approval board. Find them during shadow mode and encode them, rather than discovering them when a ticket gets marked done three days before the change was actually deployed.
The legacy module everyone avoids
One specific brownfield situation deserves its own note, because it is nearly universal and it interacts badly with agents.
Every long-lived codebase has a region that people route around: undocumented, under-tested, high-blast-radius, understood by one person who may or may not still work there. Human developers handle it with fear, which is an effective safety mechanism. They go slowly, they ask, they test more than usual.
An agent has no fear. It reads the code, forms a plausible model, and produces a confident change. In the region of your codebase where the tests are thinnest, you now have the fastest generation and the weakest verification, which is exactly the wrong pairing.
The practical response is not to ban agents from it. It is to make the criteria bar higher there than elsewhere and to keep human review mandatory in that path regardless of confidence. Whatever threshold you set globally, this region gets a stricter one. If your tooling lets you set per-path rules, this is the first place to use them, and if it does not, a written team rule works nearly as well because everyone already knows which directory it is.
The region of the codebase everyone routes around is the region with the thinnest tests, the least documentation and the highest blast radius. Human developers avoid it out of well-calibrated fear. An agent has no fear.
So the fastest generation in your system now points at the place with the weakest verification. Raise the criteria bar there and keep human review mandatory regardless of confidence.
Where this breaks down
I have argued brownfield-first fairly hard, so let me argue the other side properly.
Some brownfield codebases genuinely cannot support this. If the work does not land in source control in a legible way, no amount of sequencing helps. A system maintained through a vendor’s admin console, a data platform configured through a UI, a mainframe integration where the real change happens in a process outside your repositories: in all of these, ground truth is thin and the reconciliation layer has little to read. Brownfield-first assumes brownfield means old-and-messy, not invisible. If your legacy estate is invisible to source control, the honest answer is that this whole approach has limited purchase there, and you should pilot somewhere else and be candid about why.
The convention audit can return a number that stops the project. If your linking rate is under about a third, you are not looking at a tooling exercise, you are looking at a behaviour change that has to land first. That is a months-long piece of work involving habits, and pretending it is a two-week setup task will produce a failed pilot that gets blamed on the tool. In that situation the correct move is to fix the linking convention as its own initiative, prove the rate has moved, and start the pilot after.
Brownfield pilots take longer and look worse, and that has a political cost. Everything in this article optimises for a credible result rather than a fast one. If your organisational reality is that you get one demo to keep the funding, a greenfield pilot that produces a clean number in three weeks may be the pragmatic choice even though it proves less. I do not love that trade but I recognise it, and it is better made consciously than discovered in retrospect.
And “fix criteria only six weeks out” leaves a permanent debt. The rolling-window approach is right for getting started, and it does mean that a chunk of your backlog remains unevaluable indefinitely. If your planning horizon is genuinely long, if you commit to roadmap items two quarters ahead and expect agents to work from them, the rolling window is insufficient and you will need a real backlog remediation effort at some point. Start with the window. Do not pretend it is the end state.
The takeaway
Almost all published advice about agentic development describes a codebase with no history, and history is the thing that makes your situation hard. Pilot on the messy, high-traffic, load-bearing repository, because that is where the value concentrates, that is what your engineers will accept as a real test, and the mess is legible from commit history rather than hidden.
Audit the linking convention before anything else, fix it forwards rather than backwards, separate reconciliation from criteria quality so you can get one without waiting for the other, and rewrite only the criteria that are both bad and imminent.
The next piece goes deeper on that last separation, and makes what I think is the most important sequencing argument in this entire series: criteria before automation, every time, without exception, even when the automation is available today and the criteria work is tedious.