DEV Community

Cover image for Why I no longer read code (much)
Egor Kraev
Egor Kraev

Posted on

Why I no longer read code (much)

One of the big divides of 2026 among people who are responsible for producing code (whatever their title) is whether reading (or at least skimming) every bit of actual code produced by the agent is a good idea.

Some vehemently argue for that, citing the atrophying of mental muscles if one doesn’t, dependence on Anthropic, architectural erosion of the codebase, feeling responsible for the code they ship, and other sound reasons; others are happy with their automated code-producing and -reviewing setup and rejoice in the increased productivity it brings.

I come down strongly on the latter side at the moment. To explain why, it’s best to first walk you through my code-generating workflow first.

This consists of four stages, each materialized as skills and helper scripts, each ran in a new clean session. The first stage is planning: I brain-dump every detail of what I know about what I want to achieve, goals, implementation details, anything I can think of that relates to the task. Claude (using Fable) then interviews me about it, focussing on design decisions, corner cases, and gotchas.

It shows to me the resulting plan and once I’m happy sends that to Codex for review. It then validates the points brought up by Codex (typically accepting most but not all, explaining to me why for those it refuses, and asking for my decision on those it deems borderline).

The result of that stage is a full set of OpenSpec artefacts for the change, reviewed by Codex and formally validated by the OpenSpec machinery. At this point I reset the session and start the test-writing phase.

In the test-writing phase (ran by Fable 5 or Opus-4.8, as are the following stages, chosen depending on task complexity) Claude writes tests (which the OpenSpec delta in changes/specs/spec.md makes easy to both plan and verify) and then has the tests reviewed by Codex, again folding in all valid feedback.

After that I reset the session again and start the implementation phase. The goals and design are available to the agent from the OpenSpec artefacts, and the tests are already written. At the end of this phase, the agent asks for my permission to push and PR (GitHub is not touched until this moment).

In contrast to the planning phase, which is very interactive, the test-writing and implementation phases typically require no involvement from me, unless they run into a gotcha they need my judgement to resolve.

Once the PR has been created, I reset the session again and run a review loop. At each iteration, I check CI results of course, plus review feedback from Codex, Sonar, CodeRabbit, and some deterministic scripts enforcing internal conventions (such as imports at the top only and a maximum inline-comment-to-source-code-ratio).

Once feedback has been collected from all the sources, it’s triaged by Claude Code. This phase is more interactive than the previous two, mostly because I need to decide whether some of the issues uncovered by the reviews deserve a follow-up issue, should be handled on the spot, or can just be dismissed.

All the triaged results are addressed by Claude Code and the result pushed. This goes on until every single gate returns no issues. Then the openspec artefacts are archived in the same branch, and the result merged.

I believe that as far as gotchas, corner cases, and code validity is concerned, the resulting code is far more reliable than the code I wrote by hand ever was. This doesn’t mean it needs no involvement from me - after the workflow is done, it’s still imporant to kick the tires so to speak, that is to try using the code for the purpose for which it was written - but that doesn’t require my reading the code either.

I’m not claiming the result is perfect - but let’s be honest, the code I wrote by hand in the olden days wasn’t perfect either, though perhaps with different failure modes. Certainly this flow has pointed out (and then addressed) more corner cases and choices that I hadn’t thought about when formulating the task, than I can count.

One important challenge that the above process doesn NOT address is architectural erosion - even if every single PR is sound, over time they might well add up to unmaintainable spaghetti code (also known as the lava flow or lava layer anti-pattern). At the moment, I deal with that by doing periodic interactive reviews and refactors as separate PRs, formulating high-level principles I expect the code to comply with, and using Fable to analyze current code against the principles and plan towards alignment - it’s perfectly able to reason at that level of abstraction if that’s what it’s asked to do.

In the long term that does not seem like a sufficiently clean or reproducible approach (well, spelling out and enforcing principles does, but relying on ad hoc Fable analyses to make them stick doesn’t), so I’m now looking at firstly, a setup using a combination of arc42 and LikeC4 to automatically maintain, and enforce against the source code, a high-level representation of the architecture; and secondly, a principles-first design - I’ll report on how that works out, in a later post.

Fundamentally, I find using agents to code not that different from running a team - you have to set up the right processes, and then trust them to get the right result, and keep adjusting the processes to address every new failure mode you come across.

I do realize not reading code is anathema to many - so explain to me why!

Top comments (0)