Verification is the whole job now
Producing code got cheap. Knowing whether it's right did not. Everything downstream follows from that asymmetry.
Here is the single fact that explains most of what has happened to software engineering in the last two years:
Generation got roughly two orders of magnitude cheaper. Verification did not get cheaper at all.
Everything else — the review bottleneck, the arguments about junior hiring, the sudden importance of tests, the unease people cannot articulate about agent-written code — is downstream of that asymmetry.
why verification did not get cheaper#
You might expect it to. Surely a model can check code as well as it can write it?
It can, sort of, and not in the way that matters. Three problems:
The checker has the same blind spots as the writer. A model that does not know your system produced code with an assumption baked in. The same model reviewing it holds the same assumption and does not see it. Independent errors can be filtered by voting; correlated errors cannot.
Verification requires knowing what correct means. That is a property of your domain, your users, your obligations — not of the code. A model can verify that code does what it says. It cannot verify that what it says is what you needed, because that information was never written down anywhere.
Confidence is decoupled from correctness. Generated code is fluent. Fluency is the signal humans use to assess competence, and it has been severed from correctness. Reviewing text that reads well but is subtly wrong is much harder than reviewing text that reads badly, and everyone underestimates this.
what this changes#
Tests stop being a chore and become the primary artifact. If verification is the constraint, then anything that makes verification automatic is worth enormous investment. A test suite is executable verification. It was always valuable; it is now the thing that determines your throughput.
The practical implication: write tests first, review those carefully, and let the implementation be cheap. Invert the effort. The specification is the part you have to get right; the code is increasingly a derived artifact.
Type systems get a promotion. Every constraint the compiler can check is a constraint you do not have to verify by reading. Languages with expressive type systems and strong static guarantees are worth more than they were, because they convert human verification into machine verification.
I have watched teams that were ambivalent about strict TypeScript become evangelists in the space of a year, and the reason is always the same: it catches the class of error that agent-written code produces most often.
Small diffs become non-negotiable. Verification cost scales superlinearly with diff size, because the number of interactions you have to reason about grows faster than the lines. A machine can produce a 2,000-line change effortlessly. Accepting it is not a favor to anyone.
Property-based testing gets its moment. If you can state an invariant, you can verify a very large input space cheaply. Invariants are exactly the kind of thing that a human should specify and a machine should check. This technique has been niche for twenty years and it is the right shape for this moment.
Observability becomes a verification tool. If you cannot verify everything before deploy, you verify in production: feature flags, canaries, and metrics that detect wrongness quickly. Fast detection is a substitute for perfect pre-verification, and it is often a better investment.
the skill that matters#
The engineers getting genuine leverage out of these tools all share one trait, and it is not prompting.
It is that they can look at a plausible-looking piece of code and say "that retry loop will hammer the upstream on a 429" or "that will deadlock under concurrent writes" or "that assumes the list is sorted and nothing sorts it."
That skill comes from having debugged those exact failures. It does not come from reading about them.
Which produces the uncomfortable question everybody is circling: the traditional way to acquire it was to write a lot of code badly and then fix it. If that apprenticeship is being automated away, what replaces it?
the answer I have, which is partial#
Deliberately do the hard part yourself sometimes.
Not out of nostalgia. Because the judgment is the product, and the judgment is built by doing. If you delegate every debugging session, you will be worse at debugging in two years, and debugging is the thing you are being paid for now.
Pick the gnarliest bug of the week and do it by hand. Read the code the agent wrote in the module you own, all of it, once a month. Write the tricky concurrency code yourself and let the machine do the CRUD.
That is not a workflow recommendation for efficiency. It is a training regimen, and treating it as one is the honest framing.
— Dom, January 8, 2026