You Can Stop Reading the Code. You Can't Stop Knowing What It Should Do
A lot of people write that developers using AI no longer understand their own code. I barely read code myself, so here is what I have in place of reading it. For the last few weeks I keep running into articles about the
A lot of people write that developers using AI no longer understand their own code. I barely read code myself, so here is what I have in place of reading it.
For the last few weeks I keep running into articles about the same thing. Developers with AI write code much faster, but they no longer understand what they ship.
There is even a name for it: comprehension debt. In simple words, it is the gap between how much code there is in a system and how much of it any person actually understands.
The worst part about this debt is that you can't see it. The tests are green, the code looks clean, and nobody can explain anymore why it works the way it does.
So, have I lost control too?
I have to be honest about one thing. For more than a year I've barely read the code my agents write. So on paper, I'm exactly the person these articles are about.
I thought about it for a while and came to the conclusion that no, I haven't. Not because I'm special, but because over these two years a system slowly grew around my agents, and it does what reading code used to do.
The real question is not whether you read the code. It's whether someone in the system knows what that code is supposed to do.
That system is what this post is about.
We have been here before
In the early 1950s almost all programs were written in machine code or assembler. When Fortran appeared, people met it with a lot of distrust.
John Backus, who created it, later remembered that programmers back then saw their work as an art that could not be automated.
The arguments against it sound very familiar today:
- the code a compiler generates is worse than code written by hand
- you don't understand what it actually does
- so you won't be able to debug it
In the end a simple thing won. Programmers stopped thinking about registers and memory addresses and started thinking about the problem itself.
I think the same thing is happening now, just one level higher. Instead of functions and classes, I think about how payment should work, who is allowed to see what, and what happens if a client changes their mind.
But an agent is not a compiler
There is one important difference, and this is where the analogy breaks.
A compiler always turns the same code into the same result. Once it matures, you can simply trust it.
An agent doesn't work like that. It can do one thing today and another tomorrow. It fills gaps in the task with guesses, and sometimes it even bends a test to fit its code so the test goes green.
If a person no longer reads the code, someone else has to do what reading used to do. And that someone can't be the same agent that wrote it.
Here is what that someone looks like in my setup.
1. Write down the intent before the code
The first thing is to write down what should be built before a single line of code exists.
Why does it matter so much? The reason is simple. Understanding of a system used to live in the head of the developer who wrote it. Now the code is written by an agent that remembers nothing after its session ends.
If the intent isn't written down anywhere, in a month nobody will tell you why payment works the way it does. That's no longer a code problem, it's a memory problem for the whole team.
Planning starts with an interview
Every bigger task starts with an interview. A planner asks me questions one by one until nothing is left to guess.
What comes out of it is a plan split into phases. For every phase it says not only what to do, but also how to tell it was done right.
The tests are then written from these descriptions, from what the client does, and not from what the agent wrote. If a test is written after the code by the same agent, it will just confirm what the agent already believed.
Finished plans don't disappear
This is the part people rarely talk about. Every finished plan goes into an archive: the plan, its phases and the reports on how they were done.
When months later I need to understand why something was built a certain way, I don't dig into the code. I open the plan and see how the thinking went, what the options were and what was decided.
Understanding of the system now lives not in someone's head and not in the code, but in these records.
2. Separate who writes from who checks
The second solution grew out of a simple observation: an agent can't properly check itself.
Not because it lies. It checks with the same blind spots it had while writing the code.
Auditors came first
Funny enough, in my case this happened almost by itself, because auditors appeared before agents that write code.
At first I wrote everything by hand and asked AI to review it and point out weak spots. Then I started letting agents apply those suggestions. First small fixes, then whole features, and now I delegate parts of the business logic.
But the auditors always stayed separate from the ones who write.

My trust grew step by step, and the auditors came first, not the agents that write code.
How it works now
When an agent finishes its part, the work is checked by a separate agent that can't change anything, it can only read. It doesn't see the writer's reasoning, only the code changes and the plan.
It checks not only whether the code works, but whether it does what the plan says.
If something is wrong, the system creates a fix task by itself. But not forever: after three attempts it stops and waits for me. If it didn't work three times, the problem is most likely not in the code, but in the task.
On top of that there is a security auditor that looks for typical holes and thinks about how this specific product could be broken. And an agent that simply runs the build, the linter and the tests and honestly reports what ran and what it said.

The one who writes the code and the one who checks it are always different agents.
The numbers surprised me a bit. Over the last 30 days the agents that check ran almost as often as the agents that write, and checking cost about five times less.

Agent runs across all my projects over the last 30 days, data from Swarmery. Cost is approximate, estimated from tokens.
"Don't know" is a separate answer
One more detail I didn't get right away. If a check couldn't give an answer, for example it timed out or couldn't read the changes, that is neither a fail nor a pass. It's a separate state: "don't know".
I used to have "done", "not checked" and "the process just died" all showing the same green badge, and I was lying to myself a bit. When I split them, the dashboard got uglier, but honest.
One thing in the data I didn't expect: in 8 cases out of 100 reviews the checker, which is only allowed to read, changed files anyway. The system caught it and didn't accept that verdict.

Verdicts of the separate checker: 100 reviews of phases and plans, Oct 10 to Nov 4.
When you don't look at the code yourself anymore, an honest "don't know" is worth more than a pretty green badge.
3. Check the product, not only the code
For me this is probably the most important one. Tests have one problem: they only check what they were asked to check.
In one of my earlier runs, the agents marked five phases as done, and the separate checker found serious problems in three of them. All the tests were green. Nobody lied, the problems were just exactly where the tests didn't look.
And most often they don't look at the business logic: what happens when several people with different permissions use the product at the same time.
Agents as manual testers
So I have manual testing done by agents. Let me show it on one of my projects, a platform where clients bid on cars from auctions and an operator places those bids on the real auction.
There is a scenario for it that covers the whole path, from a client signing up to the invoice and delivery. Before a run, the system creates test people: an admin and three clients.
The agents log in as each of them and go through the steps in a browser, like a real tester. Then they check the database and the logs to see whether what should have happened actually happened.
They never touch real lots, the system makes copies just for the test. The real Telegram bot, email and payments are switched off during the run.
The rules for the tester matter more than the run
- The tester doesn't fix bugs. It only finds and describes them, because the one who fixes shouldn't be the one who checks.
- It doesn't stop at the first failure. It records it and moves on.
- No step can be skipped silently. Every step must have a status.
- Every failure needs proof. And a plain script checks that the proof exists, not another model.
At the end I get a report with the status of every step and a list of bugs with steps to reproduce them.
Checks only see what you show them
There is a limit here too, and I want to name it honestly. The run happens on a local environment, so it can't see how production is configured.
When I was writing a handbook for the operator of this project, it turned out that payments and deposit top-ups were built and tested, but simply not switched on in the production settings.
So the code was right, the tests were green, and the most important part of the business, money from the client, wouldn't have worked in production. It wasn't the tests that caught it. It was someone walking through the whole path with the eyes of the operator.
Checks only cover the part of the world you showed them. Production settings need to be shown too.
4. Check by risk, and fix the factory
A fair question: if all of this exists, how often does it run? A full manual run is expensive, it takes the test environment for hours, so running it after every small change makes no sense.
I ended up with two rhythms:
- Sprints. Development is split into two-week sprints. After each one I sum up the results, run full audits and run the manual tests.
- Risk. If important business logic changed, or a new process appeared that many others depend on, I run the checks right away, without waiting for the sprint to end.

Full checks follow two rhythms: the calendar and the risk.
I think the second rule matters more. How often you check should depend on how much a mistake costs, not on the calendar.
What I do with audit reports
I said I barely read code, but it's more accurate to say I don't read it line by line.
During an audit I skim the changes and carefully read what the auditor reports. If it found a problem, I go into the code on purpose, straight to that place, and try to trace the whole chain: not only where the bug is, but why it appeared at all.
Often it turns out the agent didn't simply make a mistake, it was set up the wrong way. For example, I had an agent that kept reaching into files outside its own working copy. It still finished its tasks, so I wouldn't have noticed for a long time.
The reason was simple: its instructions were written before agents started working in separate copies, and nobody ever updated them.
Fix the factory, not only the product
So after that kind of review I don't just fix the bug. I fix the skill or the agent that let it happen, and make a new plan so the same mistake doesn't come back.

When an audit finds a problem, I fix not only the bug, but also what allowed it to appear.
A regular developer fixes the product. I mostly fix the factory that makes it.
That, I think, is the answer to whether you lose control. Control just moves from individual lines of code to how the whole system works.
Where the limit is
It would be dishonest to say all this protects you from everything.
All these checks share one limit: they catch code that doesn't match the intent, but they won't save you if the intent itself is wrong.
If I write in the plan that the deposit is always returned to the client, and the business needs something else, the agents will honestly build it, the tests will honestly check it, and everything will be green.
So my responsibility didn't get smaller. It got bigger, it just moved to a different place.
I used to spend most of my time on code, and often there was no energy left for the details of the business. Now agents and auditors take the code, and I can calmly think about how payment should work, what to do with a client who won a lot and disappeared, or who exactly should see other people's bids.
So, are developers losing attention?
I think some are, and the articles about it are not written for nothing.
The problem is not that people stopped reading code. It's that they didn't replace that reading with anything.
When programmers moved from assembler to Fortran, attention didn't disappear, it moved one level up. The same is happening now. Only this time the compiler can make mistakes, so you have to build a system you can trust yourself.
That takes time. It took me two years, and it's still not perfect.
But I think this is now the main job of a developer: not writing code and not reading it, but knowing what it should do, and having a way to check that it does exactly that.
How does it work for you? Do you still read every line your agents write, or have you moved to checks too? I'd like to hear where you draw the line.
Sources
- Comprehension Debt, Addy Osmani
- From Technical Debt to Cognitive and Intent Debt, Margaret-Anne Storey
- The History of FORTRAN I, II, and III, John Backus
- Programming in America in the 1950s, John Backus
Originally published on Swarmery on Substack, where I write about building with Claude Code agents in public. Swarmery itself is open source: atretyak1985.github.io/swarmery.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.