
Robert Grazioli
Date
Reading time
3 Min Read
Topic
Engineering
AI has made it possible to build software faster than ever. It has also made it possible to ship software you don’t understand.
That tradeoff is fine when you’re building a proof of concept, testing an idea, or trying to get something in front of a customer before lunch. In those cases, speed is the point. Generate the whole thing. Break it. Throw it away. Learn something.
But the standard changes when the work becomes customer-facing.
Mitchell Hashimoto recently described a useful standard for AI-assisted work: the “whiteboard defense”.
I should be able to pull you aside at any moment and ask you to explain any customer-facing system you’ve shipped. You should be able to clearly explain how it works and defend the decisions you made.
I don’t expect line-level familiarity with the code. I don’t care if you remember the exact function name, the shape of every API response, or the implementation detail an AI tool generated. You may never have written the code yourself.
But if I ask why you chose X instead of Y, what happens when an actor behaves maliciously, what data structure you used, or where the system is likely to fail, you should have an answer.
If you can’t explain it on a whiteboard, you probably shouldn’t ship it.
The abstraction isn’t the problem
We’ve always built software on top of things we don’t fully understand.
Most engineers couldn’t explain every part of the operating system their application runs on. Most product teams couldn’t rebuild the database, framework, cloud platform, or payment processor underneath their product. Abstraction is how software gets made.
AI is another abstraction. A very useful one.
The problem is not that an AI wrote the code. The problem is when no one owns the decisions inside it.
Generated code can look correct, pass a test, and still introduce assumptions the team never intended to make. It can choose a convenient architecture that becomes painful at scale. It can handle the expected path beautifully and ignore the strange, adversarial, or simply human ways customers will use the product.
That isn’t an AI problem. It’s an accountability problem.
Understanding is part of the deliverable
When we ship customer-facing software, the output isn’t just working code.
The output is a team that understands:
What the system is supposed to do
How information moves through it
Which decisions were deliberate
What assumptions it depends on
Where it will break
How we’ll know when it breaks
That understanding is what lets you maintain the product, respond to an incident, make the next decision, and explain the tradeoffs to a customer.
Without it, you don’t really own the product. You’re renting an outcome you happened to generate.
This is especially important because customer-facing systems accumulate responsibility. A prototype can disappear. A product has users, data, expectations, edge cases, support requests, and consequences. Once people depend on it, “the AI wrote it” stops being an interesting explanation.
The standard should change with the stakes
I don’t want teams slowing down every experiment to perform an architectural review. That would defeat the point.
For PoCs, demos, internal experiments, and disposable tests: speed over quality. Generate 100% of it and understand none of it if that is the fastest way to answer the question.
For customer-facing work: use the same tools, move just as aggressively, but earn the right to ship.
That means reviewing the architecture, tracing the important flows, testing the failure modes, and challenging the assumptions. It means being able to describe what was generated in your own words. It means treating AI as leverage, not authority.
The whiteboard defense is intentionally simple. It doesn’t require a new process, a lengthy document, or an AI governance committee. It only requires someone to own what happens after the software leaves the laptop.
Before shipping, pull the team aside and ask:
What happens from the moment the customer takes an action?
Where does their data go?
What did we optimize for?
What did we knowingly trade away?
How could this be abused?
What happens when a dependency fails?
Where are we least confident?
If the answers are clear, ship it.
If they aren’t, the work isn’t done.
Inspired by Mitchell Hashimoto’s “whiteboard defense”.

