Yeah I agree - I think code written by AI is not substantially worse or better than code written in the old-fashioned way ...
And, as the AI coding tools (models, skills, harnesses, etc etc) have gotten better, so has the code they generate - while I doubt the same can be said about 'human-written' code ...
I think we'll reach a point (if we haven't even, already) where AI writes better (more solid, thorough etc) code ...
I honestly think (based on experience working with Claude Code) that AI is generally better at managing lots of complexity, and managing huge amounts of details, and overlooks fewer issues and edge cases - almost unlimited mental capacity, and huge amounts of facts and knowledge stashed away in those 'frontier' models ...
Still, and always, needs human judgement though - both at the "input" end (asking for the right stuff to be built), and the "output" end (reviewing what has been produced)!
Thanks leob! I also agree on your last point. It's really about how we judge the inputs and outputs. I am less certain about the "better" part – it might be able to capture more edge cases, but only a human can tell you which of those edge cases matter to you and your business. So I think we are more aligned than we think 🙂
We're 90% aligned (I think) - but, the number of (often pretty obscure) edge cases that some of these tools are able to find is pretty astonishing - potential security holes, race conditions, etc - things you'd be hard-pressed to find manually, because it's often like "needles in haystacks" ...
But (and here's where we certainly agree) - judging if all of those edge cases matter is best left to human judgement - because what I also noticed is that dealing with ALL of those rare edge cases can sometimes add a LOT of complexity to the code (i.e. make it harder to read and understand) ...
So it's still about making the right tradeoffs ...
Agreed and you raise a great point about complexity. Every unique edge case adds lines of code and complexity to the code base.... The agent will find the needle but it is up to us humans to evaluate whether the needle's marginal benefit is worth the overhead. Great discussion, leob 🙂
Yeah that's the point, it's able to find the most weird and obscure stuff, but when it's marginal I'd often say let's avoid the added complexity ... tradeoffs!
This framing landed for me — the problem usually isn't who wrote the code, it's how much of it there is to hold in your head. Simplicity is my first review pass: if a workflow needs 200 lines where 50 would do, I rewrite before I extend. The fancy version isn't more capable — it's just more places for Sunday-me to find surprises. Minimal isn't a style preference for me anymore; it's risk control.
Fair point about the 2019 code. Most of us have opened an old repository and wondered who wrote it before checking the blame. The difference you name at the end is the one that matters, though, and Reid put it well in the comments: with human spaghetti there is usually someone who remembers why the strange patch exists. With generated code, nobody ever built that mental map, so the context has to live somewhere other than a person.
That shifts the question from "is this code clean" to "can someone who was not there change it safely". Small units, tests on the boundaries, and a short written note on why a decision was made do more for that than style rules.
At Ascendra Ventures we hand over every build with that in mind, because the client team inherits the code without having been in the room. The handover is judged on whether someone new can make a change and know it worked, not on how the code reads.
Do you think the review bottleneck Reid described is the bigger maintenance risk now, more than the quality of the code itself?
"A person can explain their code, and the model cannot" is the real delta, and it's worth pulling apart from code quality entirely. Unmaintainable has always meant one thing: nobody can say what the code is for, which constraints it encodes, and which alternatives were rejected. Human legacy code has that disease too - we just used to be able to interrogate the author, until they left, and then it was archaeology anyway.
Which makes the fix the same for both authors, and it isn't cleaner code: capture the rationale at write time, while it still exists. The intent, the constraints, the "don't touch this because" - as an artifact that ships with the module. AI code makes the missing artifact obvious because there was never a human who knew; human code hides the same absence behind a name in git blame. The codebase that can answer "why is this here" without a seance is maintainable, regardless of who or what typed it.
The 2019 code story is the part I recognized most. I have opened old code and wondered who wrote it before checking the blame, and that is exactly why the mirror argument lands. What I took from Reid's point, and your reply, is that the review bottleneck is the practical risk: a clean 400 line diff that passes tests can be merged in two minutes while hiding assumptions about retries and state cleanup. Small units and boundary tests feel like the right response, because they force that review cost up front instead of during an outage.
AI testing storyteller. Writing the 36 Stratagems series — ancient Chinese military tactics meet modern AI system meltdowns. 16yr QA → building AI test framework.
Honestly, I haven’t written much actual code since AI became widely available. My prompt these days is simple: I don’t care what language or structure you use, just give me the working result. Hahaha🤣
Hahaha, honest answer! 😄 That prompt works well until the day it breaks. Then someone must read what the model wrote. That is the day I worry about....
AI testing storyteller. Writing the 36 Stratagems series — ancient Chinese military tactics meet modern AI system meltdowns. 16yr QA → building AI test framework.
AI testing storyteller. Writing the 36 Stratagems series — ancient Chinese military tactics meet modern AI system meltdowns. 16yr QA → building AI test framework.
Building Scarab Diagnostic Suite: proprietary diagnostics for software drift, boundary failures and repo-truth drift. Support open-source work: https://github.com/sponsors/scarab-systems
This really resonates with what we've been exploring at Scarab Diagnostics.
I think the article touches on something much bigger than whether AI writes maintainable code. The entire pre-AI era of computing has left us with an extraordinary technological inheritance, but also decades of accumulated patches, architectural drift, redundant structures, changing requirements, and decisions that only make sense within their original context.
And yet, buried within that complexity is the genuine ingenuity of the developers who established the foundations of modern computing. That intelligence is worth preserving. The question is whether we also need to preserve every detour taken along the way.
At Scarab, we're asking a different question about AI adoption: Are we approaching the integration of AI into existing software systems from the wrong direction?
Right now, we're handing AI agents enormous, often internally inconsistent codebases and expecting them to reconstruct decades of context, understand every historical decision, preserve every dependency, and somehow innovate on top of it all.
But how much of that complexity is actually essential to the system's functioning, and how much is simply accumulated noise?
Our work explores the idea of system coherence: mechanically establishing the fundamental relationships, behaviors, and constraints that make a system function, identifying where architectural drift has introduced inconsistencies, and distinguishing what genuinely needs to be preserved from what can be reconciled or modernized.
The goal isn't to discard legacy software or the principles of good software design. It's quite the opposite: to preserve the best of human engineering while making existing systems intelligible and usable by AI.
What if, instead of asking AI to figure out the entire history of a system, we gave it a verified, coherent baseline and scoped context from which to work?
Perhaps the next major advancement in AI-assisted development won't come solely from making models better at interpreting our accumulated complexity, but from making our software environments better prepared for AI.
A technologist working in automation. Here I write up what I actually learn building tools, engineering AI agents, and keeping systems running, along with the workflows and habits that stick.
That last distinction is where the maintenance trouble starts. Human spaghetti code is frustrating to inherit, though someone on the team usually carries the context behind a weird patch or a hacky workaround until they leave. Model-generated code arrives without anyone having built that mental map on day one.
The bigger problem in practice is review throughput. A developer can skim and merge a 400-line generated diff in two minutes when the syntax looks clean and the unit tests pass, missing implicit assumptions about retries, state cleanup, or error paths. Keeping generated changes scoped to small modules with explicit boundary tests forces that review cost up front instead of six months later during an outage.
Thanks for chiming in, Reid. I think you said what I wanted to say much better than I did. By “a person can explain their code” I meant “someone carries the context”.
The point you brought up that I didn’t mention was that when a change has a clean diff and passes all tests, you can merge it quickly with false confidence.
Using small units and testing the boundaries is a good strategy, and one that pushes the cost of failure to the early stages when it is cheap.
We're a place where coders share, stay up-to-date and grow their careers.
Yeah I agree - I think code written by AI is not substantially worse or better than code written in the old-fashioned way ...
And, as the AI coding tools (models, skills, harnesses, etc etc) have gotten better, so has the code they generate - while I doubt the same can be said about 'human-written' code ...
I think we'll reach a point (if we haven't even, already) where AI writes better (more solid, thorough etc) code ...
I honestly think (based on experience working with Claude Code) that AI is generally better at managing lots of complexity, and managing huge amounts of details, and overlooks fewer issues and edge cases - almost unlimited mental capacity, and huge amounts of facts and knowledge stashed away in those 'frontier' models ...
Still, and always, needs human judgement though - both at the "input" end (asking for the right stuff to be built), and the "output" end (reviewing what has been produced)!
Thanks leob! I also agree on your last point. It's really about how we judge the inputs and outputs. I am less certain about the "better" part – it might be able to capture more edge cases, but only a human can tell you which of those edge cases matter to you and your business. So I think we are more aligned than we think 🙂
We're 90% aligned (I think) - but, the number of (often pretty obscure) edge cases that some of these tools are able to find is pretty astonishing - potential security holes, race conditions, etc - things you'd be hard-pressed to find manually, because it's often like "needles in haystacks" ...
But (and here's where we certainly agree) - judging if all of those edge cases matter is best left to human judgement - because what I also noticed is that dealing with ALL of those rare edge cases can sometimes add a LOT of complexity to the code (i.e. make it harder to read and understand) ...
So it's still about making the right tradeoffs ...
Agreed and you raise a great point about complexity. Every unique edge case adds lines of code and complexity to the code base.... The agent will find the needle but it is up to us humans to evaluate whether the needle's marginal benefit is worth the overhead. Great discussion, leob 🙂
Yeah that's the point, it's able to find the most weird and obscure stuff, but when it's marginal I'd often say let's avoid the added complexity ... tradeoffs!
This framing landed for me — the problem usually isn't who wrote the code, it's how much of it there is to hold in your head. Simplicity is my first review pass: if a workflow needs 200 lines where 50 would do, I rewrite before I extend. The fancy version isn't more capable — it's just more places for Sunday-me to find surprises. Minimal isn't a style preference for me anymore; it's risk control.
Thank you. "Minimal as risk control" is what I mean. I also agree with your advice to refactor, not elaborate.
The more complex version puts even more things on the future reader's plate.
Same thing with file size caps. It forces you to ask the question up front.
Fair point about the 2019 code. Most of us have opened an old repository and wondered who wrote it before checking the blame. The difference you name at the end is the one that matters, though, and Reid put it well in the comments: with human spaghetti there is usually someone who remembers why the strange patch exists. With generated code, nobody ever built that mental map, so the context has to live somewhere other than a person.
That shifts the question from "is this code clean" to "can someone who was not there change it safely". Small units, tests on the boundaries, and a short written note on why a decision was made do more for that than style rules.
At Ascendra Ventures we hand over every build with that in mind, because the client team inherits the code without having been in the room. The handover is judged on whether someone new can make a change and know it worked, not on how the code reads.
Do you think the review bottleneck Reid described is the bigger maintenance risk now, more than the quality of the code itself?
"A person can explain their code, and the model cannot" is the real delta, and it's worth pulling apart from code quality entirely. Unmaintainable has always meant one thing: nobody can say what the code is for, which constraints it encodes, and which alternatives were rejected. Human legacy code has that disease too - we just used to be able to interrogate the author, until they left, and then it was archaeology anyway.
Which makes the fix the same for both authors, and it isn't cleaner code: capture the rationale at write time, while it still exists. The intent, the constraints, the "don't touch this because" - as an artifact that ships with the module. AI code makes the missing artifact obvious because there was never a human who knew; human code hides the same absence behind a name in git blame. The codebase that can answer "why is this here" without a seance is maintainable, regardless of who or what typed it.
The 2019 code story is the part I recognized most. I have opened old code and wondered who wrote it before checking the blame, and that is exactly why the mirror argument lands. What I took from Reid's point, and your reply, is that the review bottleneck is the practical risk: a clean 400 line diff that passes tests can be merged in two minutes while hiding assumptions about retries and state cleanup. Small units and boundary tests feel like the right response, because they force that review cost up front instead of during an outage.
Honestly, I haven’t written much actual code since AI became widely available. My prompt these days is simple: I don’t care what language or structure you use, just give me the working result. Hahaha🤣
Hahaha, honest answer! 😄 That prompt works well until the day it breaks. Then someone must read what the model wrote. That is the day I worry about....
That would be the ideal case. Here’s the more realistic plan: I just get a stronger model to audit it instead, hahaha.🤣
i don't trust any code i didn't read
which is a problem because i didn't read most of my code 🤣
Haha, the classic dev paradox! I don’t trust my own old code either, let alone AI‑generated ones 🤣
This really resonates with what we've been exploring at Scarab Diagnostics.
I think the article touches on something much bigger than whether AI writes maintainable code. The entire pre-AI era of computing has left us with an extraordinary technological inheritance, but also decades of accumulated patches, architectural drift, redundant structures, changing requirements, and decisions that only make sense within their original context.
And yet, buried within that complexity is the genuine ingenuity of the developers who established the foundations of modern computing. That intelligence is worth preserving. The question is whether we also need to preserve every detour taken along the way.
At Scarab, we're asking a different question about AI adoption: Are we approaching the integration of AI into existing software systems from the wrong direction?
Right now, we're handing AI agents enormous, often internally inconsistent codebases and expecting them to reconstruct decades of context, understand every historical decision, preserve every dependency, and somehow innovate on top of it all.
But how much of that complexity is actually essential to the system's functioning, and how much is simply accumulated noise?
Our work explores the idea of system coherence: mechanically establishing the fundamental relationships, behaviors, and constraints that make a system function, identifying where architectural drift has introduced inconsistencies, and distinguishing what genuinely needs to be preserved from what can be reconciled or modernized.
The goal isn't to discard legacy software or the principles of good software design. It's quite the opposite: to preserve the best of human engineering while making existing systems intelligible and usable by AI.
What if, instead of asking AI to figure out the entire history of a system, we gave it a verified, coherent baseline and scoped context from which to work?
Perhaps the next major advancement in AI-assisted development won't come solely from making models better at interpreting our accumulated complexity, but from making our software environments better prepared for AI.
That's the question I think we should be asking.
That last distinction is where the maintenance trouble starts. Human spaghetti code is frustrating to inherit, though someone on the team usually carries the context behind a weird patch or a hacky workaround until they leave. Model-generated code arrives without anyone having built that mental map on day one.
The bigger problem in practice is review throughput. A developer can skim and merge a 400-line generated diff in two minutes when the syntax looks clean and the unit tests pass, missing implicit assumptions about retries, state cleanup, or error paths. Keeping generated changes scoped to small modules with explicit boundary tests forces that review cost up front instead of six months later during an outage.
Thanks for chiming in, Reid. I think you said what I wanted to say much better than I did. By “a person can explain their code” I meant “someone carries the context”.
The point you brought up that I didn’t mention was that when a change has a clean diff and passes all tests, you can merge it quickly with false confidence.
Using small units and testing the boundaries is a good strategy, and one that pushes the cost of failure to the early stages when it is cheap.