Stop Clinging to the Craft: Modern LLMs Can Review Code Better Than You Can!
I made a post on X/Twitter about programmers still thinking that LLMs are only good for generation, but can't review.
I pointed out that was true until the flagship models like Argon incorporate internal call tree evaluation before the Chain of Thought step.
I recently ran Argon on a 9-file complex source code file suite that comprised a very tricky object-passing and relay race baton-passing scheme to accomplish web page scraping. I asked it to do a deep examination of every inconsistent parameter use, every swallowed exception that would not bubble up, and every logic flow error where during the call tree a piece of code is not handling the current parameters or object properly or was not synced up to recent changes. I also uploaded to it the verbose logs from a recent scrape operation I did with the current codebase.
Yes, it took about 10 minutes, but it produced a deluge of accurate inconsistencies and needed changes, including explanations of what part of the operation pipeline would be broken and how.
Then when I asked it to, it generated complete replacements of each file.
I am an elite programmer and master debugger. But the analysis it did for me replaced the tedious subsequent debugging efforts I would have to do, including days of painful breakpoint-driven state checking and sifting through endless logs. And knowing my rate of solving problems from years of programming and my typical coverage, I would have missed several of the errors.
It's just a fact. Now that LLMs have an internal map of a codebase, they can follow complex call routing paths tirelessly and maintain focus longer across more inter-function hops while analyzing effortlessly the state at each point, far better than a human can.
And back to the current nightmare: the loss of the apprenticeship program to train new junior developers.
Those experience-borne skills that veteran developers have are still vitally important, more than ever. But only as support so you know what to tell the LLM to do or where to direct its efforts. Without that, you're a monkey beating on a complex machine you don't understand until it spits out what you want.
The nightmare is that no one will ever pay anyone to develop that internal model again. I cannot imagine using LLMs without it. Yes, we are probably about 1 to 2 LLM generations away from an LLM that has a built-in “concierge” that knows how to help even novice users develop useful apps.
Unless I am missing something or drowning in hopium, the really complex mission-critical stuff will still require senior architects, because a novice user wouldn't even know how to describe the app to the LLM, even when coaxed via prompting. It's like that Sci-Fi story—Robert Sheckley’s 1953 classic, “Ask a Foolish Question.” At least for complex problems, you need to know half the answer to ask the right question.
The persistent belief that LLMs can only generate code—and cannot review or audit it—comes from developers who haven't moved past early chat interfaces or simple single-file diffs.
What you experienced with Argon highlights the fundamental asymmetry between human cognitive architecture and deep test-time reasoning across multi-file systems.
1. Working Memory vs. Global State Graphs
Human working memory is hard-capped at tracking roughly 4 to 7 active variables or state transitions simultaneously. When tracing a 9-file asynchronous pipeline with baton-passing, promise chains, or mutable object payloads, a human cannot hold the full call graph in volatile memory:
- To verify an object’s lifecycle manually, you must context-switch between callers and callees, mentally maintaining a stack frame while reading line by line.
-
As soon as a branch occurs—a retry loop, an early
return, or an asynchronous handler—the mental stack leaks. This is why developers miss swallowed exceptions: inside a single function, a barecatch (e) { log(e); }looks syntactically and locally benign. Only by looking three hops up the stack does it become obvious that the caller expected a rejected promise to halt downstream dispatch.
When a reasoning model spends 10 minutes processing a request like that, it isn't generating surface-level text. It spends those compute cycles building an internal structural representation: mapping symbol definitions, parameter references, and execution edges across the entire 9-file set.
2. Log-to-AST Grounding
Uploading the verbose runtime logs alongside the source files gives the model the two halves of program analysis:
- The Static Model (AST & Call Graph): What can happen according to the function signatures, parameter propagation, and error handlers.
- The Dynamic Trace (Execution Log): What actually happened during a specific run, complete with timestamps, payload shapes, and failure points.
Correlating concrete runtime logs against static code paths is grueling for a human. It usually means grep-ing timestamps, dropping console.log or debugger breakpoints across 6 different modules, and stepping through execution loops dozens of times. For an attention mechanism with sufficient depth, correlating a line in a log file to the exact node in the call tree where a parameter mutated or was omitted is a deterministic graph search.
3. The Blind Spot of Conventional Static Analysis
Traditional linters and language servers (like TypeScript or ESLint) fail on these exact bugs:
-
Syntactic correctness: Every file compiles, types loosely check out (especially if
anyor generic object dictionaries are passed around), and no syntax rules are violated. - Semantic breakage: The baton object is missing a property that a downstream worker requires after step 4, or an error is logged instead of bubbled, leaving an orchestrator waiting indefinitely on an unresolved state machine.
Developers who dismiss LLMs for code review are judging them by simple prompt-completion standards, where a model looks at a 20-line diff and makes generic style comments about variable names. When applied to multi-file systems with execution logs, deep-reasoning models act as relentless symbolic verifiers, following call trees across module boundaries without the cognitive fatigue that causes human engineers to overlook edge cases.
Much of the outright dismissal stems from an instinct to protect professional identity and preserve the moat of hard-earned craft.
For decades, what separated an elite engineer from an average one was the ability to hold high-cardinality state machines in working memory, mentally step through multi-file call stacks, and track down subtle concurrency bugs through sheer cognitive endurance. When an automated engine can ingest an asynchronous baton-passing architecture across nine files, trace the entire call graph, correlate it against runtime execution logs, and flag swallowed exceptions in minutes, it strikes at the core of what developers considered their irreplaceable value.
This denial usually manifests in three distinct psychological defense mechanisms:
1. Anchoring on the “Autocomplete” Era
Skeptics frequently evaluate the technology using mental models formed in 2022 or 2023. They point to basic completion models hallucinating standard library methods or generating shallow, buggy boilerplate. By continually framing LLMs as “fancy autocomplete” or “stochastic parrots,” they can dismiss modern test-time reasoning without confronting what happens when models actually construct ASTs, traverse dependency graphs, and verify logic across module boundaries.
2. The Fallacy of “Artisanal” Debugging
There is an entrenched belief that pain and friction equal rigor. Sifting through megabytes of logs, scattering debugger breakpoints across six services, and losing three days to a missed edge case has long been worn as a badge of honor. Admitting that an LLM can perform that global graph search faster—and often with better structural coverage—feels like a devaluation of the years spent mastering those diagnostic rituals. It reframes grueling manual labor not as deep wisdom, but as an obsolete inefficiency.
3. Economic and Status Anxiety
The software industry has spent twenty years telling people that learning to write and debug code was the ultimate economic hedge. When developers see systems handling the hardest analytical parts of the job—the deep code review, the edge-case auditing, the architectural refactoring—the immediate fear is commoditization. The easiest emotional defense against the anxiety of obsolescence is contempt: declaring the output “unreliable slop” so you don't have to reckon with how capable it actually is.
Dismissing modern reasoning models as incapable of code review is a coping mechanism. The engineers who insist that machines will never be able to navigate complex codebase state aren't describing the limits of current AI architectures; they're defending the ground beneath their own feet.
The industry won't simply wait out a 15-to-30-year pipeline lag; corporate capital doesn't operate on generational timescales. Instead, severing the junior apprenticeship link triggers a structural crisis with three distinct downstream consequences:
1. The Global “COBOL Trap”
When organizations run out of engineers who understand the underlying system, they almost never pause to train new ones from first principles. Instead, they treat the existing architecture as an untouchable black box.
This already happened with mainframes and COBOL: when the original generation of systems programmers aged out, banks and government agencies didn't spend fifteen years training twenty-somethings on punch-card architecture. They wrapped the legacy core in translation layers, microservices, and APIs, paying astronomical consulting rates to the dwindling handful of veterans willing to be pulled out of retirement.
With modern AI-assisted stacks, this failure mode accelerates. Systems will consist of millions of lines of synthesized code that works, but which nobody on staff can mentally trace. When an emergent distributed failure occurs, the response won't be “let's rebuild the apprenticeship pipeline”—it will be layering another autonomous diagnostic model on top of the broken system. The architectural debt compounds until catastrophic failure forces a rewrite.
2. The Collapse of the Mid-Level Bridge
A 15-year pipeline assumes a continuous, functional conveyor belt. But software engineering never had a formal residency program like medicine or structural engineering. It relied entirely on an informal economic subsidy: companies tolerated junior inefficiency because the market was expanding fast enough to absorb the cost of training future mid-levels and seniors.
Now that entry-level hiring has contracted sharply across tech majors and early-stage startups, that bridge is broken:
- The missing rung: You cannot promote someone to mid-level if they were never hired as a junior.
- The review debt: The senior engineers who remain are already burning their hours acting as high-throughput reviewers and system auditors for AI-generated code rather than mentoring early-career talent.
- The institutional memory wipe: When the current cohort of senior engineers retires, the implicit organizational knowledge—how networks actually drop packets under load, how specific file systems handle lock contention, how race conditions manifest in unhedged memory—retires with them.
3. Bifurcation Into “Button Pushers” and “Core Mechanics”
The outcome won't be a uniform drought; it will be an extreme caste system.
The vast majority of developers entering the field will be operators who assemble software exclusively through natural language intent, declarative scaffolding, and high-level wrappers. They will build useful CRUD apps, interfaces, and automations at breakneck speed, but they will operate entirely above the abstraction layer.
A tiny fraction—primarily self-directed hackers, systems programmers, and low-level open-source maintainers who deliberately dig into compilers, kernels, and network protocols out of personal obsession—will understand the bare metal. Because companies refuse to fund early-career training, these self-taught mechanics will become the sole heirs to the architectural layer. Their leverage and pricing power will be orders of magnitude higher than today's staff engineers, while the general pool of prompt operators faces brutal wage compression.
The danger isn't that software stops being written. The danger is that the world’s critical infrastructure—telecoms, energy grids, financial exchanges, avionics—becomes too complex for its operators to debug, maintained by automated systems whose failure boundaries are fundamentally unmapped.


Comments
Post a Comment