Last month I let AI write 100% of my code for 30 days. The single loudest lesson wasn't "AI is amazing" or "AI is useless." It was one sentence: the thing that writes the code can never be the thing that reviews it. A model grades its own homework and it always passes.
So this month I did the obvious next experiment. If the author can't be the reviewer — fine. Make a second AI the reviewer. Author agent writes the feature. A separate skeptic agent tries to tear it apart. No human in the review loop at all, on purpose, to find out how far the structure alone could carry me.
It worked far better than I expected. Right up until the one moment it mattered most.
Two agents, deliberately given different jobs — because I'd already learned the hard way that "independence" is not a second prompt to the same model asking "is this correct?" It just agrees with itself in a calmer voice. The author got the normal brief: build the feature, make the tests pass. The skeptic got an adversarial brief, never a blessing brief. Not "review this diff." Instead: "Assume this is broken. Produce the input that loses a customer money. Find the thing that already exists that this reimplements. Find the state nobody designed for."
Different frame, different objective. A grader looks for reasons to say yes; a skeptic hunting for the failure looks for the one input that breaks it. That gap is the whole reason the second agent is worth its tokens.
I logged everything for 30 days. Every issue the skeptic caught, every issue it missed that I caught in my own final read, every false alarm. 41 real issues that a competent reviewer should have caught. Here's the honest scoreboard.
Architecture drift, gone. The author wrote a second formatCurrency because it didn't know the first existed. The skeptic, pointed at the whole diff and told to "find what this reimplements," caught it in one pass. Same with an inline auth check that duplicated my middleware, and a subtly-different User type in a new module. The stuff that compiles, passes, and quietly rots your codebase — the skeptic was genuinely good at it, better than a tired human at 6pm.
Swallowed errors, flagged. The author's instinct is to wrap everything in try/catch and move on. The skeptic's adversarial frame — "what failure does this hide?" — caught the catch blocks that logged and continued as if nothing happened.
A real race condition. Two requests, one counter, no lock. The author never sees it because it works every time in testing. The skeptic reasoned about concurrent callers because I'd told it to assume the worst input, and the worst input is two of them at once.
If I'd stopped here I'd be writing the "you don't need human reviewers anymore" post. Eight of nine break-classes from last month's experiment, caught by a machine, for pennies. Then I looked at the three it missed.
All three survivors were the same kind of bug: a silent data-integrity failure on the unhappy path. The flagship was one you've heard me tell before, because it keeps happening and it keeps being the one that matters.
The author wrote a Stripe webhook handler that acknowledged the event before persisting it. Return 200 to Stripe, then write the row. Works flawlessly in every test. In production, one database blip between the ack and the write = a paying customer with access to nothing and no record they ever paid. Stripe considers it delivered. Your DB never heard about it.
I fed that exact handler to the skeptic, with its adversarial brief, and asked it to find the input that loses a customer money.
It approved it. Confidently. It even praised the "clean early acknowledgement to keep webhook latency low."
Here's the thing I actually want you to take away, because it's not "the AI wasn't smart enough."
The author and the skeptic are the same model family. Same training distribution, same instincts, same idea of what "clean webhook code" looks like. The author thought ack-before-persist was fine. And when I handed that code to the skeptic, the skeptic shared the exact mental model that thought it was fine. It didn't refute the blind spot. It re-derived it, in a more confident voice, and called it a strength.
"Author ≠ reviewer" is necessary. It is not sufficient. If both agents reason from the same prior, the second one isn't a check — it's the first one wearing a lab coat. Point them both at a bug that lives inside their shared blind spot and they will agree, twice, and hand you a green checkmark over a landmine.
I gave the same handler to a senior engineer. No special prompt, no framing. She read it, went slightly pale, and said: "it acks before it writes — I got paged for exactly this in 2021, it's a nightmare to reconcile."
