We were in a dev meeting, sharing work-in-progress. I’d built a SQL generator for SCD2 merges — the kind of thing you write once and reuse across a dozen tables. It worked. The demo ran clean. The output looked right.
Then a colleague asked a simple question:
“What happens if you get a row with a start date earlier than the last known start date for that key?”
I paused. I didn’t know.
Not “I’d have to check the code” didn’t know. More like: I couldn’t reason about it at all. I couldn’t tell you whether my own generator would insert it correctly, corrupt the validity intervals, or silently overwrite the latest version. The code was mine. The behavior at the edges wasn’t.
The diagnosis
Here’s the thing — I hadn’t written bad code. The generator was clean, it followed my conventions, it handled the nominal case correctly. If you’d reviewed it, you’d have signed off on it too.
The problem wasn’t the code. It was that I’d delegated a whole class of behavior without realizing I’d delegated anything.
I’d asked an AI to build the happy path. It built the happy path. Beautifully. And somewhere in that smooth, well-structured output, the question of backdated rows just… never came up. Not from me, not from the model. The edge case fell into a gap between what I designed and what I read.
I call this implicit delegation: the behavior you handed off without deciding to.
You own the design. You own the intent. But there’s a second kind of ownership — owning what the thing actually does at the boundaries — and that one doesn’t come for free. With AI in the loop, it’s easy to think you have it when you don’t.
Why AI makes this worse
Implicit delegation isn’t new. You do it every time you pull in a library without reading its edge-case docs, or paste a snippet from Stack Overflow that “works.” You delegated. You just didn’t read the fine print.
But AI amplifies it, and the mechanism is worth being honest about.
When you copy a stranger’s snippet, there’s friction. It doesn’t match your style. The variable names are wrong. You have to massage it in, and that act of massaging forces you to read it.
AI removes that friction. With a decent CLAUDE.md, the model writes in your style. It respects your conventions. It integrates cleanly. The output looks exactly like something you’d have written — which means the one natural alarm bell, “I didn’t write this myself,” never rings.
That’s not a reason to stop using it. I went back to Claude Code precisely because of that speed and that consistency. But it means the safety signal you’d normally rely on is gone, and you have to replace it with something deliberate.
What actually caught it
It wasn’t luck. It was a colleague with fresh eyes asking a question I hadn’t asked myself. That’s the whole point of sharing work before it ships — peer review is built to surface exactly this.
But I don’t want to depend on someone else finding my blind spots in a meeting. So I added a step that happens before anyone else looks.
I went back to Claude — not to understand the code, but to audit its behavioral coverage. Rubber duck mode: walk through the generator, enumerate the inputs it might receive, and for each one, state what it does. Out-of-order start dates. Duplicate keys in the same batch. Nulls in the business key. A close-out with an end date earlier than the start.
For each case we went through the same loop: what does the current code do here, and is that what we want? Some cases were already handled. Several weren’t. We covered them.
Notice what that session was and wasn’t. It wasn’t me finally reading the SQL line by line and achieving enlightenment. It was me making the delegation explicit — turning a vague “it works” into a concrete map of inputs and behaviors. It’s the same draft → review → constrain loop I use to shape AI code in the first place, applied this time to behavioral coverage instead of the code itself. The AI was fast at generating the input space. I was the one deciding what correct meant for each entry.
That’s the division of labor I actually want. The model carries exploration speed and integration consistency. I carry the design, the invariants, and the final call. The failure in that dev meeting wasn’t that I’d used AI — it was that I hadn’t drawn that line on purpose.
The rule
This connects straight back to Fail Fast or Corrupt Silently — except the system corrupting silently here isn’t the pipeline. It’s your own understanding of what you shipped.
So before you merge AI-generated code on anything that matters, ask yourself one thing: can I list the three most dangerous inputs this could receive, and say what happens for each?
If you can, you’ve made the delegation explicit. If you can’t, you haven’t finished — you’ve just stopped early.
Because your blind spots surface before production or after. A question in a dev meeting, a rubber duck session — these are the cheap options. The other one isn’t.