Article
A founder builds a product over a few weekends with an AI coding tool. It works. Customers arrive. Then, on a schedule that has become predictable, it starts to break. We have now audited enough of these codebases to say what breaks and roughly when, which means most of it can be prevented before the customers arrive.
Week one: the secrets
API keys in the source, committed on day one, because the tool put them where the tutorial did. Sometimes the repository is public. This is the first thing we check and the first thing we fix, by rotating every key and moving them to a vault. If you do nothing else after reading this, search your repository for the string "sk-".
Week two: authorisation
The login works. What does not work is the check that the logged-in user is allowed to see the record they asked for. Generated code is very good at authentication and very bad at authorisation, because the first is a pattern and the second is a policy. Any endpoint that takes an ID is suspect until proven otherwise. The fix is a single place where ownership is enforced, usually a base query or a database policy, instead of a check the tool remembered on some endpoints.
Month one: the data
Fields stored as strings that should be numbers or dates. Money as floating point. No constraints, so the same email exists three times. No migrations, so nobody knows how the production schema differs from the code. These are silent until a report is wrong or a payment is off by a cent, and they are the most expensive class to fix late because they require migrating data, not just changing code. We wrote about the underlying decisions in the three architecture decisions that are expensive to reverse.
Month two: the duplicated logic
The tool implemented the same rule in four places, slightly differently each time, because each time it was asked in a different conversation. A discount calculated one way in the cart and another at checkout. Fixing a bug in one copy leaves the others. The refactor is to find each rule and give it one home, which is slow but mechanical.
Month three: the tests that test nothing
There is a test folder, and the tests pass. They pass because they assert whatever the code currently does, including the bugs. Real tests describe intended behaviour; these describe existing behaviour. We replace them with a small set that covers the paths that would hurt the business, written by a person, and delete the rest.
Month four: the dependencies
Dozens of packages, several doing the same job, some unmaintained, a few with published vulnerabilities. The tool added whatever solved the immediate problem. Pruning takes a day and removes real exposure.
Month six: nobody can change it
The product still works, mostly, but every change takes longer than the last and breaks something unrelated. This is the compound interest on everything above, and it is when most people call us. It is fixable, and it is much cheaper to fix at month one.
What to do about it
If you are building with AI tools now, put the five review gates in place before you have customers; they prevent nearly everything on this list. If you already have the codebase and the customers, an audit is a week, produces a ranked list with a cost against each item, and you decide what to do with it. The codebase is almost always worth keeping. The order of fixes is the thing to get right.