Verifying the Verifier

Sep 6, 2026 · 8 min read

You can't fully verify something you built, because you already believe it works.

@williamtranqa

Developers shouldn’t test their own code. Every QA person learns that in their first few months on the job. It’s not that developers are lazy or careless. They’re just too close to their own work to see it straight. I’ve believed that for my whole career, and nothing I’ve seen since has given me a reason to stop believing it.

Then AI started writing the code too, and I watched the exact same problem show up again, just a lot faster, and wearing a much more convincing disguise.

The old rule

Ask anyone who’s worked in QA and they’ll tell you the same thing. A developer testing their own work isn’t stupid. They’re just too close to it. They already know what the feature is supposed to do, so when they check it, they’re mostly checking that it does the thing they meant, not hunting for the ways it could be wrong.

That’s why QA exists as its own job instead of a box a developer ticks on their own ticket. Someone with actual distance from the work looks at it fresh, with no attachment to how hard it was to build or how good it’s supposed to be. Not because that person is smarter. Just because they didn’t build it.

Telling a developer to “just be more careful” was never a real fix for this. It doesn’t matter how conscientious someone is. If you already believe your own work is right, that belief quietly decides what you bother looking for and what you don’t even think to check.

I’ve sat across from plenty of developers who were genuinely good at their jobs and still missed things in their own code that a fresh pair of eyes caught in minutes. Not because they didn’t care. They cared a lot, that was usually the problem. Caring about a feature and being the right person to find its flaws turned out to be two different skills, and having one didn’t guarantee the other.

What happened when I built this with AI

I built this exact website using Claude Code. I was moving fast, describing the design I wanted and letting it write most of the implementation, tests included. It even spun up a local server so I could click through and see everything working.

Every time I asked for a change, it went off, made the edit, and came back with some version of “tested, 700 tests passed.” Curl commands, visual checks, all sorts of things bundled into that one number. I didn’t actually know what most of those tests checked. I just saw 700 passed, thought “cool,” and moved on. The number felt like proof, so I trusted it.

Then I asked for one small thing, a one-liner of a request: add a breadcrumb trail above the blog posts. Simple, low-risk, the kind of change that shouldn’t touch anything else. It made the change, ran its own visual check as part of that same 700, and told me everything looked fine. It didn’t. One of the characters in the breadcrumb was rendering enormous, completely out of proportion with everything around it, the kind of thing you’d catch in under a second just glancing at the page. I caught it in under a second. The AI that had supposedly just visually checked that exact element didn’t.

I’ve seen the same thing happen with OpenAI Codex, on a completely separate project. Different tool, different codebase, same story: confident report, tests passing, and something obviously off that I only found because I looked myself instead of taking its word for it. Two different companies, two different models trained by two different teams, and they both fell into the exact same trap the moment I asked them to mark their own homework.

That’s the part that actually stuck with me. It wasn’t a Claude Code quirk or a Codex quirk. It was the same failure mode wearing two different logos.

Why this keeps happening

Once you see it, it makes sense. If you build something, you already believe it works, that’s just how building anything goes. It doesn’t matter whether the thing doing the building is a person or a model. Asking an AI to check its own work is like asking a developer who just spent all week on a feature to go find their own bugs in it. Most of the time they’ll do a decent job. But they’re checking against what they meant to build, not against what’s actually there, and those two things quietly drift apart without anyone noticing.

The AI doesn’t get tired or defensive about it the way a person might. But it has the exact same blind spot, and because it can run a “test everything, 700 pass” pass in seconds instead of hours, that blind spot moves a lot faster than it used to.

A developer with a deadline still has to physically sit down and write each test, which at least gives a bad assumption some time to be noticed before it ships. An AI does the same thing in the time it takes you to read its reply. Same blind spot, none of the friction that used to slow it down enough for someone to catch it.

What this means for QA

Right now, a developer can use AI to write the code, then use that same AI, or a second one, to review and verify it. On paper it looks like the testing problem is solved. Two systems, one checking the other.

But if both systems trust their own patterns the same way, that’s not independent verification. That’s the same blind spot checking itself twice and calling it a second opinion.

This is where QA doesn’t get replaced. It gets more necessary, and what the job actually is shifts under it. Writing test cases isn’t the scarce skill anymore, plenty of tools will spit those out on request. Knowing what to be suspicious of is. Knowing which “looks fine, tests passed” needs a second look anyway, and which one genuinely doesn’t. That instinct doesn’t come from a clever prompt. It comes from watching things sail through review for years and break in production regardless. Trusting an AI’s word as a substitute for that instinct doesn’t remove the risk, it just moves it further down the line to wherever the bug actually shows up.

What actually changes day to day

None of this means throw away the AI-run tests. It means stop treating “tests passed” as a fact and start treating it as a claim, the same way you’d treat a developer telling you “yeah, I checked it” before handing you a build. Ask what actually ran. Ask what a failure would even have looked like. If the answer’s vague, that’s the same old signal, it just came from a model instead of a person this time.

The other change is where you put your own attention. Don’t spread it evenly across everything the AI touched, you don’t have the hours, and it earns that trust on the easy 90% of the work. Spend your attention on the parts most likely to hide this exact blind spot: anything visual, anything the AI has to judge rather than just check against a clear pass or fail, and anything that changed on a second or third pass after a tweak. That’s exactly where my breadcrumb bug was hiding, a small, late, visual change to something already marked “done.”

I still let AI run its own tests. I’d be slower and worse at this if I didn’t. I just don’t let “tested, all passed” end the conversation anymore. It starts it. If I can’t tell you what a failure would have looked like, I haven’t actually verified anything, I’ve just been told a nice story by something that wanted to believe it too.

The line doesn’t move, it just gets redrawn

This was never really about developers specifically. It’s about distance. You can’t fully verify something you built, because you already believe it works. That’s not a flaw in your character, it’s just what happens when you’re the one who built it.

AI has the exact same problem now, just running at a speed no single developer was ever tested at. It writes fast, it reviews fast, and when you let it mark its own homework end to end, it’s confidently wrong at that same speed. Someone still has to be the outside eye, the one with enough distance to see what’s actually there instead of what’s expected to be there. For now, that’s still us.

Comments

Loading comments…

Leave a comment