The first feature arrives in an afternoon and it is genuinely good. The second takes a day. The fourth takes a week, and nobody can quite say why.
That curve is the interest payment. AI writes code fast, and speed is real — but some of what it produces is borrowed against the future, and the repayment schedule is steep and quiet.
Why AI codebases get harder rather than easier
Normal codebases get easier for a while. Patterns settle, the shape becomes obvious, and the tenth feature is quicker than the third because you are building on decisions already made.
AI-generated code often inverts this, for a specific reason: each generation is a fresh start. The model has your prompt and whatever context it was given. It does not carry an opinion about how this codebase does things, because it does not have one. So it solves each problem well and locally, in its own idiom.
Ten features later you have ten idioms. Three ways of handling errors, four of talking to the database, two date formats. Everything works. Nothing agrees. And every new change now requires understanding which of the several conventions applies here.
The second-feature problem
The tell is the second feature that touches the same area. The first was fast. The second requires someone to read the first, and reading unfamiliar code that follows no consistent convention is slower than writing it.
Worse, changes stop being local. Because there is no shared way of doing things, a change in one place has no predictable effect elsewhere — so every modification carries a small chance of breaking something unrelated, and the cost of that uncertainty falls on every future change, forever.
This is what technical debt actually is. Not bad code. Code whose cost is deferred.
Concrete smells to check for
You can assess this without being able to read code. Ask an engineer to look for these and report what they find:
Repeated logic. The same rule implemented in three places, slightly differently. When the rule changes, two of the three get missed.
Inconsistent error handling. Some paths raise, some return nothing, some log and continue. This is where silent data loss lives.
No shared vocabulary. The same real-world thing called three names in three files. A reliable signal that the parts were generated separately.
Tests that only cover the happy path. Very common in generated code, because the prompt asked for something that works, and tests were written to demonstrate exactly that.
Comments explaining what rather than why. Generated comments describe the line beneath them. The expensive missing knowledge is why the decision was made, and no model can supply that because it never knew.
Who actually pays
Not the person who generated it. They shipped fast and it worked.
The payer is whoever maintains it — often the same person six months later, by then unable to remember which parts were considered and which were accepted. Then it is the next hire, whose ramp-up doubles. Then it is the customer, when a change that should have been small breaks something that should have been unrelated.
And eventually it is the buyer's technical due diligence, which is the most expensive place to find out.
What to do about it
Not stop using AI — that would trade a real gain for a manageable problem. Instead: decide the conventions first and hold generated code to them. One way of handling errors. One data access pattern. One vocabulary. Review for consistency, not just correctness.
That means someone senior reading the output with the question "does this match how we do things here?" rather than "does this work?". It is the single highest-leverage habit available to a team building with AI, and it costs minutes per change instead of weeks per quarter.
If you have been shipping fast for a while and the curve has started bending upward, a Reality Check maps what is actually there — in writing, in a week.
This is the part we do — the crossing from a demo to a system that survives production.