I build analytics with AI now. I describe a metric, an agent writes the SQL or the dbt model, and a few seconds later there's a number on the screen. The speed is real, and I'm not giving it back. But fast and correct are two different things, and nothing about a clean-looking query tells you which one you got. A query can be well-formatted, pass a linter, pass its tests, survive a glance in review, and still return the wrong number. Fluency is exactly what makes that hard to see.
The cost of being wrong isn't symmetric, either. A slow query wastes a minute. A wrong number that reaches a stakeholder gets repeated in a meeting, lands in a board deck, and becomes the basis for a decision. By the time anyone notices, the damage is already upstream of the dashboard. So the thing I most wanted wasn't faster generation. It was a way to stop a wrong number before it left the building.
So I built a gate. The idea is simple. Between the AI's output and the person who trusts it, you put a chokepoint that fails loudly. For every important question, you write down the answer you've verified by hand, the real number, derived from the raw data, before you let any generated SQL near it. Then the gate runs the generated query, compares its answer to the verified one, and blocks the commit if they disagree. Not "warns." Blocks: non-zero exit, a clear reason, at commit time and in CI. Wrong output shouldn't be merely detectable. It should be stopped.
I got it working. The suite was green: dozens of cases, every headline number reconciled against the raw data, negative tests proving the checker could actually tell a wrong answer from a right one. The demo did the exact thing I'd built it for. Ask for net revenue, and a correct query returns $1,585 and is allowed through. Feed it a fluent hallucination that quietly answers with gross revenue instead ($1,672, off by exactly the $87 of returned orders that net is supposed to exclude), and the gate blocks it. It looked airtight.
Then I did the one thing the whole method is built on. I handed the gate to an independent adversarial review whose only job was to break it.
It found the gap in about a page.
The finding was this. My gate was testing the wrong boundary. The verified answers were written as SQL that read straight from the raw tables, and my golden queries hit those same raw tables directly. But the kit doesn't ship raw tables. It ships dbt models: the staging, intermediate, and mart layers that turn raw rows into governed business concepts like "net revenue." The gate proved my golden SQL was right. It never once checked that the models I actually ship were right. A broken mart, the precise thing a stakeholder's dashboard reads from, would have passed the gate clean.
Sit with that, because it's the whole point. I had built a tool to catch "looks right but isn't true," and the tool was itself looking right while not being true. Everything was green. The numbers all reconciled. A green suite is a small dopamine hit, and I had been taking it as proof. Underneath, the structure was quietly checking something adjacent to the thing it promised to check. The green suite wasn't lying. It was answering a question I hadn't noticed I was asking. There's a detail I find almost funny in hindsight. The audit couldn't even build the dbt project in its sandbox, so it rebuilt an equivalent database from the raw files and ran my real scoring code against that. The one layer it couldn't exercise was the dbt build, which was precisely the layer the gap was hiding in.
This is the failure mode I keep coming back to. It isn't the dramatic, obvious bug. It's the plausible one: the query that runs, the check that's green, the wall that looks straight until you hold a plumbline against it and find it's been leaning the whole time. Your eye doesn't catch it. Only the reference does.
So I fixed it, and the fix wasn't clever, which is how I knew it was right. I added golden cases that select from the built marts instead of the raw tables. Now the gate builds the dbt project and scores the shipped models (mart_net_revenue, mart_customer_orders) against hand-verified answers. To prove it actually closed the gap, I broke a mart on purpose. I deleted the single line in mart_net_revenue that excludes returned and return-pending orders, and ran the gate. The mart-level case blocked immediately. The model now returned $1,672 where net should have been $1,585, off by that same $87, and the commit was refused. The old raw-level cases stayed green through all of it, blind to the break exactly as the audit said they'd be. Then I reverted the line and the gate opened. The broken mart is now a permanent test case. That specific mistake can't come back without something turning red.
I want to be precise about what I'm claiming, because this brand is built on not overclaiming. The gate compares answers, not derivations. A hardcoded literal would still pass it, which is why it's a human-review aid, not a proof of correctness. It catches the wrong number; it doesn't catch every possible sin. I'd rather tell you that plainly than imply it understands your query, because the moment a reliability tool starts overselling itself is the moment it becomes the thing it was built to guard against.
Here's the principle I took out of this, and it's the one I'd keep even if I threw away every line of the code. Verify before you trust, including your own tools. The same skepticism you apply to an AI's output applies to the thing checking the AI's output. Reliability isn't a state you arrive at and stamp "done." It's a practice you keep running, on everything, and especially on the part you're most confident in. The component I was proudest of was the one hiding the gap, and the only reason I know that is that I pointed the method at itself instead of assuming it was exempt.
That's what Plumbline is about. It isn't a promise that AI-built analytics will be perfect. They won't be, and anyone selling you that is selling the hallucination. The promise is narrower and more useful: a discipline, and a set of tools, for making AI output earn its way to a stakeholder. Govern the definition. Evaluate the answer, not the code. Put a gate between generation and the dashboard. And turn all of it on itself, regularly, because the checker is just more code, and more code is just more places to be confidently wrong.
I built a reliability gate that had a reliability gap. Finding it didn't make the gate less trustworthy. Finding it is the only reason the gate is trustworthy at all.