The Bar for a Legacy Codebase Is No Worse Than Today
Strict gates are fine greenfield. On a codebase you inherited, they get disabled by day two, unless grandfathering makes the line honest instead of a demo.
Point a strict architecture gate at a codebase someone else wrote five years ago, and you get a wall of red before you have finished reading the first screen. External reviewers who look at this product keep landing on the same spot: the enforcement story sounds great for a new project, but you cannot point it at a large, untested legacy codebase and expect anything but a wall of violations. That objection was correct. There was no honest answer to it, until now.
A Gate You Turn Off on Day Two Was Never Enforcement
Here is what actually happens when a team installs a strict gate on a codebase that predates the project. The first run floods the terminal with violations, most of them sitting in files nobody on the current team wrote and nobody has time to fix this week. The gate blocks the next commit. Then the one after that. By day two, someone quietly removes the pre-commit hook, or comments out the CI step, and nobody mentions it in standup.
The first time this happened to me, I had dropped a strict gate onto a repository three years older than the project sitting on top of it. The terminal filled with red before I had scrolled past the first file. The team kept the intention and lost the tool: for weeks afterward, everyone still believed the gate was protecting them.
That is the actual cost of enforcement a team disables. It costs more than never installing anything at all, because the afternoon spent setting it up is gone, and so is the following month of trusting a check that was not there. A gate a team turns off by day two never protected anything, no matter how official installing it felt.
The Bar Isn't Clean. It's No Worse Than Today.
The fix here is a different question, and answering it is what lets the gate survive contact with a real codebase. On a new project, every file was written under the rule, so whether a file violates it is the right test for all of them. On a codebase you inherited, most files predate the rule, and holding them to tomorrow's standard just rebuilds the wall that gets the gate disabled.
For a legacy codebase, the test that matters shifts from whether an inherited file is clean to whether today's change made it worse. Existing debt gets a line drawn under it: it cannot get worse, but nobody has to fix it before they can merge anything else. New code, the code written after the gate goes on, gets held to the real standard. Grandfathering existing debt is the mechanism that lets enforcement survive contact with a codebase that already had debt in it before you arrived.
The setup wizard now has an architecture step built around that distinction. It seeds from a preset instead of asking you to write rules against a blank file. Before anything is decided, it runs a read-only violation pre-scan, so you see the true state of the repository against the proposed rules before you commit to any of them. It offers to grandfather existing debt with hold-the-line carve-outs, and it lets you set each gate to enforce, warn, or off, independently:
architecture:
gates:
file_size:
mode: enforce # new code, no exceptions
cyclomatic_complexity:
mode: warn # visible, not blocking, while the team catches up
god_object:
mode: off # not yet; revisit once the split lands
None of that requires touching the offending files first: the pre-scan tells you where the debt actually is, and the carve-out tells the gate to stop counting it against you. The gate still runs, and it still blocks a new violation from landing in a file that was already flagged, or spreading into one that was not.
wizard --edit re-opens the wizard against a config you already wrote, pre-populated from your current settings instead of starting over. It shows the delta between what you have and what it is proposing, side by side, so a rule you tightened on purpose six months ago does not silently reset to the preset default. And it writes the change back through a merge that preserves your comments, rather than a flat rewrite that erases them. The config file gets to stay a document you maintain instead of a generated artifact you are afraid to touch.
Where the Line Still Has to Be Yours
None of this decides where the line goes. The wizard shows you the state of the repository and gives you three settings per gate. It does not tell you which one is correct for your team, and it does not fix a single violation on your behalf. The pre-scan is read-only on purpose. Setting every gate to enforce on a repo you have not scanned yet just rebuilds the wall from a different door. Setting every gate to off because the pre-scan was uncomfortable is how these tools die quietly again, just with an extra step in front of it.
So scan before you decide anything. Draw the carve-out around the debt that is actually there, no more and no less. And come back to wizard --edit once the repository has actually improved, because the line you drew on day one is not the line you should still be defending a year later.