🌏 中文版
At 11:44 UTC on 23 July 2026, Robert C. Martin (Uncle Bob) posted a 533-character reply that has since drawn 4.18 million views, 16.6k likes, 11.4k bookmarks, and 530 replies. The author of Clean Code says he no longer reads code.
But nearly every retelling drops one thing: it was a reply, not a manifesto. To read it correctly you have to see who he was replying to.
▍He was answering one person's anxiety, not opening a debate
The day before, Ori Pomerantz posted this (161k views, 227 replies):
I am trying to use Claude to help me write something, but I just don't feel comfortable letting it edit my files. Does anybody else feel the same? If I am responsible for code, I NEED to understand it, psychologically if for no other reason.
Started programming in 1983. Old?
In plain terms: I'm accountable for this code, so I have to understand it — if only because I can't get comfortable otherwise. That closing "Started programming in 1983. Old?" is self-deprecating, and it's also a real question: am I just out of date?
Here is how Uncle Bob's full reply opens:
I'm significantly older than you. I started coding in the late 60s. My current strategy is to not read any of the code written by my agents. That's the only way I can take advantage of their productivity. What I do instead is to surround the agents with extreme constraints. Unit tests, gherkin tests, QA procedures, quality metrics, mutation testing, test coverage, and a plethora of others. In the end, I have very high confidence in the code they produce because they've had to run the gauntlet of all of my constraints and tests.
That first sentence answers "Old?" — you're not too old, I'm much older, and I don't read it.
The context changes what the post is. Ori asked a psychological question: I need to understand it to feel okay. Uncle Bob's answer isn't "understanding doesn't matter" — it's swapping out the source of that confidence:
Confidence used to come from I read it. His now comes from that last clause — they've had to run the gauntlet — the code cleared every gate he built.
Put differently, the post answers "how do I sleep at night without reading it," not "none of you should read it." Compressed for circulation into "the Clean Code author stopped reading code," the subject silently changed from him to everyone — and that meaning isn't in the original.
▍Unpacking the list
He names six classes of constraint in a single breath, but they don't carry equal weight:
| What he wrote | What it actually verifies |
|---|---|
| Unit tests | Whether behavior is correct — the basic one, and the one he says he most often uses alone |
| Gherkin tests | Pins acceptance criteria to concrete examples, and must stay in natural language |
| QA procedures | Manual, UI-driven inspection |
| Quality metrics | Coverage, dependency structure, cyclomatic complexity, module sizes |
| Mutation testing | Break the code, see whether tests scream |
| Test coverage | Which paths were executed |
Mutation testing is the pivotal one, because it's the only item that answers "who verifies the tests?" — which is exactly what most of the replies under that post kept asking. The implementation and the tests come from the same agent, so both can be wrong in the same direction. What does green actually prove?
And his real mechanism is stranger than the word in that tweet suggests.
▍The gauntlet isn't an abstraction — he open-sourced the spec
This gauntlet has an implementation spec. You don't have to guess from tweets.
Uncle Bob put it on GitHub as Acceptance-Pipeline-Specification, described as a portable acceptance-test pipeline that AI agents can install into projects. One line from the README covers what it does:
turns Gherkin feature files into JSON IR, generates executable acceptance test entry points, runs those tests, and uses acceptance mutation to check whether example data is actually connected to the application under test
It defines two flows. The normal run: feature file → Gherkin parser → JSON IR → optional IR-DRY checker → entrypoint generator → generated test entry points → project test runner.
The mutation run: feature file → parser → base JSON IR → entrypoint generator → Gherkin mutator alters the IR → runner adapter evaluates the mutated IR → mutation report.
The tooling splits in two: portable pieces (gherkin-parser, gherkin-ir-dry-checker, gherkin-mutator, shipped as Babashka tasks or Go binaries) and project-specific pieces (entrypoint generator, acceptance runtime, step handlers, runner adapter). The IR-DRY checker's job is to flag repeated, near-duplicate, and possible-synonym step text so agents can normalize and prune the Gherkin.
▍The most commonly mangled point: he isn't mutating the code
Ordinary mutation testing means quietly breaking the production code and seeing whether the tests scream. Uncle Bob does use that too — mutation testing is on his April list.
But the signature mechanism in this pipeline is something else: acceptance mutation. The README is blunt about it:
The normal run proves that the project satisfies the feature. The mutation run checks whether the acceptance tests fail when important example values change.
What gets mutated is the example data in the Gherkin, not the code. Change a key value and the acceptance test should go red. If it stays green, that test isn't wired to the application under test at all.
The distinction matters because it directly answers the nastiest version of "who verifies the tests?" — a test that is well written, richly asserted, and shows good coverage, but is actually exercising a mock or its own fabricated data. Breaking the production code won't catch that: the line you broke is one the test never reaches. Breaking the example data will.
One honest caveat: the README contains no threshold numbers — no required mutation score, no coverage percentage. He has given two in his posts, though, and both are severe. That's the next section.
▍He said it himself: you don't need all of it every time
The 7/23 post lists six classes of constraint side by side, which reads like a standard process. His 7/2 post three weeks earlier says the opposite — and it drew 21.5k views, 1/194 of the viral one:
I've been pushing very hard on overloading with tests. Gherkin test unit test QA test mutation test gherkin mutation test. It's easy to make the AI's do these things. But just because we can do them doesn't mean we actually should.
Lots of times I just use unit tests and crap evaluation. That seems to work pretty well. For larger projects I can imagine that gherkin testing is pretty useful and so is QA testing. I'm checking that now.
Three things there: most of the time he uses unit tests plus crap evaluation, and it "seems to work pretty well"; on Gherkin and QA his phrasing is "I can imagine," a guess rather than a conclusion; and the closing "I'm checking that now" means he is still verifying whether the heavy kit earns its keep.
Note that "crap" there isn't an adjective. CRAP (Change Risk Anti-Patterns) is a real metric, defined by crap4j as cyclomatic complexity multiplied against test coverage:
CRAP(m) = comp(m)² × (1 − cov(m))³ + comp(m)
The lower the coverage and the higher the complexity, the faster the score climbs. The conventional threshold, from the Google Testing Blog, is 30 — above 30 a method counts as "CRAPpy." Remember that 30.
So the list isn't a menu, it's a toolbox. Even he is still picking his moments, and he said outright that being able to do these things doesn't mean you should. Anyone copying the six items from 7/23 as standard process is copying the part he'd said three weeks earlier isn't always necessary.
▍He does look — "I spot check the code"
"not read any of the code" is a claim he doesn't hold to in his own 6/1 post. That one lays out the entire pipeline: four agents, with human involvement tapering off at each stage.
| Stage | Who does it | His involvement |
|---|---|---|
| Informal specs | He hand-writes them | Throughout |
| Convert to harder specs, split into tasks | agent | "I review these." |
| specifier agent: task → Gherkin, prune it | agent | "I spot check the Gherkin." |
| coder agent: acceptance tests → unit tests → code | agent | None |
| refactorer agent: push crap to 6 or below, cut duplication, write property tests | agent | None |
| architect agent: run language mutation over uncovered sections and kill all survivors, then Gherkin mutation killing those survivors, then the full suite | agent | None |
| Output | — | "I spot check the code." |
That last line matters: he spot checks the code. "Reads none of it" is the rhetoric of the tweet, not his actual process. The real line isn't read/don't-read, it's how densely — he writes the specs word by word, reviews the hardened specs, spot checks the Gherkin and the code, and lets the middle three agents run untouched.
The previous section said the README carries no thresholds. This post supplies two, both harsher than convention:
- crap ≤ 6: the conventional threshold is 30, so he demands one-fifth of it
- kill all survivors: no surviving mutants tolerated, which is to say a perfect score
He names the cost too: "Raw computer power is the limiting factor. Those mutation tests are CPU intensive." The bottleneck in this gauntlet isn't people, it's CPU.
▍A side correction: this isn't a position he adopted on 7/23
Plenty of retellings frame it as Uncle Bob suddenly changing. Walk his own timeline and the pipeline has been built in public for five months; 7/23 is just the post that happened to get seen:
| Date | What happened |
|---|---|
| 2026/3/7 | Announced Gherkin as his primary behavioral specification tool, requiring it stay natural language with no code-level artifacts |
| 2026/4/14 | "I don't review code written by agents." He measures coverage, dependency structure, cyclomatic complexity, module sizes instead |
| 2026/5/13 | Proposed Gherkin mutation: Gherkin to JSON, mutator alters the IR, expect the test to fail |
| 2026/5/22 | Described two modes: the full-constraint swarm is "very productive and safe, but slower than raw vibe coding" |
| 2026/6/1 | Published the full pipeline, including "I review these." |
| 2026/7/2 | You don't need every layer every time — "I'm checking that now" |
| 2026/7/23 | The reply to Ori Pomerantz, 4.18M views |
The April version states it more plainly than July:
The code itself I leave to the AI. Humans are slow at code. To get productivity we humans need to disengage from code and manage from a higher level.
"Humans are slow at code" is his actual argument. The 7/23 post went off not because it said anything new, but because it landed on a named person asking whether he was too old-fashioned.
▍The strongest objection isn't from trolls — it's Grady Booch
In the April round of this discussion, Grady Booch (co-author of UML) gave a rebuttal that names specific categories:
Unlike Bob, I review all code generated by agents. Test coverage and similar metrics will give me confidence of functionality, but they offer me no confidence whatsoever that those agents have not introduced vulnerabilities, that they have not introduced dead code that will diminish understandability in the future, that they have missed factorizations that would have significant impact upon performance.
He added: "Trust but verify. As an experienced developer, I know the smell of what is good and what is not. And no agent has either the experience or the context to know those things." His closing line is aimed squarely at Uncle Bob:
If you want to be sloppy and fast then I suggest you proceed with Bob's advice.
The value here isn't the sentiment, it's the three categories metrics can't see:
- Security vulnerabilities: tests verify that behavior is correct, not that no extra door was opened
- Dead code: doesn't affect functionality, doesn't affect coverage, but permanently taxes everyone's comprehension afterward
- Missed refactorings: it runs, it's just slow — performance problems don't turn tests red
All three share a property: they are completely invisible along the "functionally correct" axis. And Uncle Bob's gauntlet measures almost nothing but functional correctness.
▍Where this approach actually hits its ceiling
Harder to handle than Booch's three items is this: the gauntlet verifies the spec, not the intent.
Acceptance mutation can catch "the test is too weak." It cannot catch "the acceptance criteria are wrong." If the examples in your Gherkin encode a misunderstanding of the business rule, the whole pipeline will very efficiently — with beautiful coverage and a high mutation score — verify the wrong thing.
And it fails more invisibly than a human would, because every light is green.
Which is why his spec-review step isn't optional; it's the load-bearing wall. He only spot checks the code, and a spot check isn't a gate — the gates all sit at the spec end. The specs are the one link in this system with no automated check protecting it.
▍The point is who designs the gauntlet
Everyone argued about whether to read code and skipped the question: who designed that gauntlet?
Uncle Bob can afford not to read code because the person who designed his gauntlet has been a programmer since 1970 (he says late 60s in the tweet) and is 73 this year. Where to place a check, which values are worth mutating, which boundaries the Gherkin examples need to cover, what the IR-DRY checker should treat as synonymous — all of that judgment comes from having read a lot of bad code and fixed a lot of bad tests.
What he did was write decades of judgment into the verification layer first, and only then look away. And he's teaching it: cleancoders has a Clean AI: Agentic Discipline series, and O'Reilly runs an AI Agents for Clean Code live course. He isn't telling people to stop reading code — he's selling how to design the gauntlet.
An engineer three years in who copies the "don't read the code" conclusion gets the risk and nothing else, because they can't yet design a gauntlet worth trusting.
The conclusion fits in one shareable line. The gauntlet doesn't.
▍Back to the original question
What Ori Pomerantz asked was: I'm accountable for this code, so psychologically I need to understand it — is that just old-fashioned?
Going by the original, Uncle Bob's answer isn't "you don't need to understand it." It's "what you need isn't having read it, it's having grounds to believe it" — and you build those grounds yourself. His version is six classes of gate plus reviewing the specs personally. If you don't have that apparatus, Ori's discomfort is the correct response, not an outdated one.
The point isn't picking a side. It's that the scarce skill has moved from writing fast to designing verification — the same conclusion Loop Engineering reaches from a different direction when it identifies verification cost as the real bottleneck.
Before deciding whether to stop reading code like Uncle Bob, do two things:
- Run mutation testing against your code. See what fraction your suite catches when production code is broken.
- Run Uncle Bob's kind of mutation against your acceptance criteria. Take a few end-to-end tests, change the key input values inside them, and see whether the tests go red. If they stay green, those tests aren't wired to your system.
The second is done far less often, and usually looks worse. For rigorously measuring whether a change actually improved anything, see how to compare agent behavior before and after a change.
References
- Uncle Bob, 2026/7/23: not reading agent code, surrounding agents with constraints
- Ori Pomerantz, 2026/7/22: the original question being replied to
- Uncle Bob, 2026/4/14: measuring metrics instead of reviewing code
- Uncle Bob, 2026/3/7: Gherkin as the primary behavioral specification tool
- Uncle Bob, 2026/5/13: how Gherkin mutation works
- Uncle Bob, 2026/5/22: trade-offs between swarm mode and single-agent mode
- Uncle Bob, 2026/6/1: the full pipeline, including "I review these"
- Uncle Bob, 2026/7/2: you don't need every test layer every time
- unclebob/Acceptance-Pipeline-Specification (GitHub)
- Crap4j FAQ: definition and formula for the CRAP metric
- Google Testing Blog: This Code is CRAP (source of the threshold of 30)
- Uncle Bob vs. Grady Booch: Rethinking Code Reviews in the Age of AI
- Grady Booch (Wikipedia)
- Robert C. Martin (Wikipedia)
- Clean AI: Agentic Discipline series (cleancoders)
- AI Agents for Clean Code with Uncle Bob Martin (O'Reilly live course)
- Loop Engineering: When AI No Longer Needs Your Prompts
- Rigorously comparing agent behavior before and after a change
Loading...