AI Can Write Code. Software Engineering Is Still a Human Responsibility.
As AI-assisted development becomes the default way software gets built, I've been thinking about a challenge that more and more teams are going to run into — not in the demo, but six months after the demo.
It's now entirely possible to build an application that appears to work well using primarily AI-generated code. The features ship. The UI looks polished. The tests pass. On the surface, everything is fine. But without careful architectural planning, real code reviews, and old-fashioned engineering discipline, that codebase can quietly become something nobody wants to touch.
The decay is invisible until it isn't
The dangerous thing about AI-generated codebases isn't that they're broken. It's that they're plausible. Every individual file looks reasonable. Every function has sensible names and passable structure. The rot only becomes visible when you zoom out — and most teams don't zoom out until something forces them to.
Here are the patterns I keep seeing, in my own projects and in codebases I've reviewed:
- ▸Similar logic implemented in multiple places. The AI didn't know a utility already existed three folders away, so it wrote a new one. And then another. Each is fine alone; together they guarantee that a future bug fix lands in one copy and misses the others.
- ▸Duplicate functionality spread across layers. Validation in the frontend, again in the API handler, again in the service — each version subtly different, because each was generated in a separate conversation with separate context.
- ▸Excessive abstraction that adds complexity without value. AI models have read a lot of enterprise code, and it shows. You ask for a feature and receive a factory, an interface, a strategy pattern, and a configuration object — for logic that has exactly one caller and always will.
- ▸Code that works but resists understanding. It passes the tests. It also takes forty minutes to trace why, because the control flow was optimized for generation, not for reading.
- ▸Inconsistent patterns across the application. Three modules, three error-handling styles, three ways of naming the same concept. Nothing is wrong; nothing is coherent.
The six-month test
Here's the standard I keep coming back to: the real test of software isn't whether it works today. It's whether another developer can confidently understand, maintain, and improve it six months later.
"Confidently" is the load-bearing word. A developer can technically modify any codebase. What decays in an undisciplined AI-generated codebase is confidence — the ability to make a change and know its blast radius. When developers lose that, they stop refactoring and start appending. Every fix becomes another layer of duct tape, because nobody is sure what the existing code depends on. That's the moment a codebase starts aging in dog years.
What makes the AI version of this dangerous is the timeline. Legacy rot used to take years — long enough for teams to see it coming and staff against it. An undisciplined AI-assisted project can reach the same state in a quarter, because code is being added at ten times the rate while comprehension is being added at the same old human speed. The gap between "how much code we have" and "how much code we understand" has never widened this fast.
None of this is an argument against AI
Let me be clear about what I'm not saying. AI is an incredible productivity multiplier — the biggest I've experienced in my career. It helps me move faster, explore alternative solutions in minutes instead of days, and eliminate whole categories of repetitive work. I use it daily and enthusiastically.
But AI-generated code still requires exactly the things it cannot provide for itself:
- ▸Human judgment about whether this solution belongs in this codebase, in this form.
- ▸Architectural thinking that spans conversations — the AI sees the file; you see the system.
- ▸A clear understanding of the business problem, because the model optimizes for the prompt it received, not for the problem the company actually has.
The review step matters more now, not less. When a human wrote the code, the act of writing forced at least one person to understand it deeply. When AI writes the code, that forcing function disappears — unless review recreates it deliberately.
What this means in practice
A few disciplines that have held up well on teams I've worked with:
- ▸Review AI code as skeptically as junior-developer code. It has the same failure profile: confident, fast, and unaware of the wider system. The politeness of the output is not evidence of its correctness.
- ▸Make conventions explicit and machine-readable. Coding standards that live in the repository get picked up by AI tools and enforced in generation, not just in review.
- ▸Refuse abstractions that don't pay rent today. The AI will happily build for imaginary futures. Deleting speculative flexibility is a code review superpower.
- ▸Own the architecture yourself. Use AI to implement the design. Don't let a thousand small generations become the design by accident.
The future belongs to engineers who do both
The future isn't AI replacing software engineers. The future is software engineers who know how to use AI effectively while continuing to apply the principles that made software maintainable long before AI arrived: good design, clear boundaries, testing, and relentless attention to code quality.
Writing code is becoming easier — dramatically, permanently easier. That's worth celebrating.
Building software that remains understandable, scalable, and maintainable over years and across teams? That's still the hard part. And right now, it's still ours.