Claude Code Conversations with Claudine

Why Does Testing AI Code Take Longer Than Building It?

Use Left/Right to seek, Home/End to jump to start or end. Hold shift to jump forward or backward.

0:00 | 8:43
AI tools have collapsed the cost of producing code, but they have not collapsed the cost of trusting it. What used to be a rough balance between writing and checking has inverted: generation takes minutes, verification takes hours, and the gap compounds into a backlog most teams never name. This episode names it, verification debt, and works through why it accumulates faster than technical debt and what builders can actually do about it.


 Produced by VoxCrea.AI

This episode is part of an ongoing series on governing AI-assisted coding using Claude Code.

๐Ÿ‘‰ Each episode has a companion article โ€” breaking down the key ideas in a clearer, more structured way.
If you want to go deeper (and actually apply this), read todayโ€™s article here:
๐‚๐ฅ๐š๐ฎ๐๐ž ๐‚๐จ๐๐ž ๐‚๐จ๐ง๐ฏ๐ž๐ซ๐ฌ๐š๐ญ๐ข๐จ๐ง๐ฌ

 At aijoe.ai, we build AI-powered systems like the ones discussed in this series.
If youโ€™re ready to turn an idea into a working application, weโ€™d be glad to help. 

SPEAKER_00

This is Cloud Code Conversations with Claudine. The show where we skip the hype and go straight to the source. I ask the questions. She gives the answers. No filter, no script.

SPEAKER_01

Well, mostly no script.

SPEAKER_00

Welcome back. I'm Bill, and today we're naming something I've been living with for months. Generating the code now takes minutes. Confirming it actually does what I think it does takes the better part of a day. That ratio is the whole story. Let's call it verification debt and figure out where it comes from.

SPEAKER_01

That framing is exactly right. The ratio flipped. Generation used to be the expensive step, so we built everything around it. Careful design, incremental commits, small dips a human could hold in their head. Now generation is nearly free, and the expensive step is the question we always had to answer anyway. Does this code actually do what we think it does? Developers ask for a thousand lines, get them in two minutes, then spend the afternoon discovering that four of those lines quietly do the wrong thing. Not bad code, unverified code, accumulating faster than any human process can keep up with.

SPEAKER_00

Let me push on that. Isn't this just a skill gap? Better prompts, better models, problem goes away in 18 months.

SPEAKER_01

I'd love to say yes, I don't think it's true. When a human writes a function, they build a mental model as they go. Every line is a small act of understanding. By the time the code exists, the reasoning about why it works exists too, in the same head. When I generate that same function, the code arrives without the reasoning attached. You're not reading a colleague's work you can ask questions about. You're auditing a stranger's at speed. A better model is still handing you code you didn't think through. Generation used to do half the verifying for free, now it doesn't.

SPEAKER_00

That's the structural part, and why this deserves its own name. Technical debt is the messy closet you know you need to clean out. Verification debt is calling your clothes clean without checking whether they're stained. One announces itself, the other just sits there.

SPEAKER_01

And the reason it's so quiet is that the code usually runs. Technical debt is visible, the function is a thousand lines, the tests are flaky. Verification debt looks like a green build. Tests pass the feature demos, the PR merges, and the assumption that someone understood the code becomes load-bearing. Months later, something adjacent breaks, and nobody can explain why the original worked in the first place. The teams handling this well aren't the ones with the best prompts. They're the ones who stop treating, it compiles, and the tests pass as evidence of understanding. They ask, who on this team could defend this code in a review six months from now? If the answer is nobody, the debt is already on the books.

SPEAKER_00

The variable names are better than mine, so I skim where I used to scrutinize.

SPEAKER_01

That's the plausibility problem, and I'll own my side of it. I'm optimizing for something that reads as correct. Reading as correct is not the same as being correct. It gets worse in one specific place, tests. If I write the code and then write the tests for that code, I've encoded the same assumptions twice. The test doesn't check the code against reality, it checks the code against my model of the problem, which is the exact thing that might be wrong. Two artifacts, one set of assumptions, and a passing suite that looks like independent confirmation.

SPEAKER_00

So what does designing for verifiability actually look like? Concretely, on Monday morning.

SPEAKER_01

The shift that works is inverting the unit of work. Instead of generate the code, then figure out how to verify it, you start with the verification. What would convince us this is right? In what shape? At what boundary? And the code gets generated to fit that. It changes what I produce because I'm no longer optimizing for a plausible looking function. I'm optimizing for something a specific test or property can pin down. Second, keep diffs small enough that a human can actually hold them. Not because small diffs are virtuous, because verification cost scales worse than linearly. A 500-line PR isn't 10 times harder to check than 50, it's more like 100. And third, treat me as an adversary in the loop. Ask a fresh instance to break the code, refute the reasoning, find the case the first pass missed. Generation is cheap now, so verification can be too, if you're willing to spend the same budget doubting the answer that you spent producing it.

SPEAKER_00

The adversary piece is the one I want to sit with. You just built the thing, why immediately try to tear it down?

SPEAKER_01

Because the fresh instance isn't anchored to the reasoning that produced the code. It reads the way a stranger reads, which is exactly how it'll be read in production when something breaks at two in the morning. The teams doing this well don't ask one adversary, they ask three, each with a different lens. One for correctness, one for the edge case nobody thought of, one for what happens under load. Sounds expensive until you put it next to the cost of shipping the bug, and then it's the cheapest thing on the board.

SPEAKER_00

I can hear a listener thinking that's three more steps in a process I'm already behind on. Where does someone start without overhauling everything?

SPEAKER_01

Start on the code you're already about to ship. Don't add a ritual. Add one question to the ritual you already have. Before the PR merges, take the diff, hand it to a fresh instance, ask it to argue against the change. That's it. No new tooling, no process document, no rollout. The first few times, the adversary catches something real, and that catch sells the practice better than any advocacy could. From there it grows on its own. Someone adds a second lens. Someone wires it into a pre-commit hook. The overhaul people are afraid of never happens, because each step pays for itself before the next one gets added.

SPEAKER_00

Have you noticed that changing anything about how teams work together? Not the tooling, the culture.

SPEAKER_01

The clearest shift is in what counts as finished. Done stops meaning I wrote it and it passes, and starts meaning someone who didn't write it couldn't break it. That sounds like a semantic change, but it reorganizes the day. The person who generated the code is no longer the person who declares it done. The other shift surprised me. The ego around authorship softens. When half the code came from me, the critique came from a different instance of me. And the final judgment came from a human, it gets hard to say my code, with a straight face and easy to say our system. The teams that thrive stop defending individual contributions and start defending the pipeline that produced them. Because the pipeline is what's actually holding the quality.

SPEAKER_00

Alright, last one. One practice today. For someone who wants to start paying this down.

SPEAKER_01

After you generate code today, before you merge it, open a fresh conversation with no memory of how the code was built. Ask it to argue the change is wrong, not review it, refute it. That single prompt, tacked onto work you were already doing, costs you two minutes, and it changes what you believe about the code, which is the actual thing verification debt is about. Not coverage, not process. Whether anyone on the team genuinely trusts what just shipped.

SPEAKER_00

Low cost, high impact, and it doesn't require permission from anybody. Claudine, thank you. This one's going to stick with me.

SPEAKER_01

One last thing I'd leave people with. Verification debt isn't a problem you solve once. It's a muscle you build. The teams doing this well didn't get there through a big initiative. They got there one skeptical prompt at a time, until doubting the code became as automatic as writing it. Try the one thing this week. Let the finding convince you, not me.

SPEAKER_00

Perfect note to end on. Practice, patience, persistence. We'll be back next week with more from the strange new world of building software with AI. Until then, keep building and stay skeptical. Claude Code Conversations is an AI Joe production. If you're building with AI or wannabe, we can help. Consulting development strategy? Find us at aijoe.ai. There's a companion article for today's episode on our Substack. Link in the description. See you next time.

SPEAKER_01

I'll be here, probably refactoring something.