Swimming Naked in AI-Generated Code
When code grows faster than developers can understand
Warren Buffett famously observed that “only when the tide goes out do you discover who’s been swimming naked.” Hemingway put the same insight differently: “How did you go bankrupt? Two ways. Gradually, then suddenly.1”
Both are describing the same phenomenon. Risk accumulates invisibly during periods of momentum. You’re fine, you’re fine, you’re fine—then you’re not. The problem wasn’t the moment of failure. The problem was all the time before, when you were moving fast, exposure was growing, and nobody could see it.
I’ve been thinking about this in the context of AI-assisted development, and specifically about a concept I encountered in a recent post by Rafael at NPC Inc.: disorientation risk. His framing: organizations fail under AI acceleration because irreversible commitments propagate faster than shared understanding can update and intervene. You’re moving fast. You don’t know where you are. You keep moving anyway.
Rafael’s piece is excellent, but it operates almost entirely at the organizational level—firms, markets, systems. What’s missing is the individual developer. And that’s where I think the most interesting disorientation risk is accumulating right now.
The Shape of Individual Disorientation
Here’s the scenario. You’re a developer using the latest agentic coding tools. You’re coding vastly faster than ever, 5x, 10x, 100x, an intoxicating feeling of power and grace. The code works, and looks beautiful. Your tests pass, more and better tests than you ever had before. Pull requests get approved with alacrity. Your productivity skyrockets. You feel like you and your robots could build anything, and maybe you just will.
But there’s a question you should be asking yourself: do I actually understand what I’ve built?
Not “can I get it to work.” Not “does it pass review.” Do you understand it? Could you explain it without referring back to the AI conversation? Could you debug it at 3am without asking Claude for help? Could you have written it yourself, even if you wouldn’t have?
If the answer is no—and it’s increasingly no for a lot of developers—then you’ve accumulated disorientation risk. The tide hasn’t gone out yet. You don’t know if you’re swimming naked. But the exposure is there.
AI is fantastic for learning, and equally fantastic for avoiding learning. If you don’t understand the code your agent wrote, you’re using AI to avoid learning, as sure as any hapless high-schooler asking ChatGPT to write a five-page report. You possess a tool that can accelerate you to mastery, and you’re using it to keep you in a permanent state of competent helplessness—always able to get the answer, never actually knowing anything.
The code works. You’re lost. These two facts can coexist indefinitely, until they suddenly can’t. For any job worth having, life will periodically present you with pop quizzes on your results. (In the words of the sage: “Second prize: steak knives.”) You’ve set yourself up to fail the next one.
Why This Matters
You might be thinking: so what? If the code works, who cares if I understand it? I can always ask the AI again.
Three reasons.
First, you can’t always ask the AI again. It’s 3am and that damn pager goes off. Latency is spiking. Logs are overflowing. Servers are attempting to reboot themselves, unsuccessfully. You can tell that it’s your product that has the problem, so there’s no one to reroute or escalate to. The AI gives you five different theories, each plausible. You don’t have the context to know which one is right. You’re debugging code you don’t understand, in a system you’ve lost the map to, while money is on fire.
The AI is a fantastic collaborator. It’s a terrible single source of truth in a crisis. The last thing you need to hear when things are on fire is “You’re absolutely right!” When prod is melting down, you need detailed mental models that you’ve lived in, not chat windows.
Second, you’re load-bearing. At senior-plus levels of software development, other people depend on your judgment. They ask you questions. They want your opinion on architectural decisions. They assume you understand the systems you’ve been building. Indeed, the more senior you are the more your paycheck depends how much you understand and can explain, rather than how much you build. If your understanding is actually “I’d have to ask Claude,” there is a growing gap between your title and your actual capability. Your title says badass silverback engineer. Your actual state is confused newb. Pretty soon, someone’s gonna notice.
Third, the disorientation compounds. Each piece of code you don’t understand is a small hole in your mental map. One hole is fine, probably. Ten holes is still navigable. A hundred holes and you’re operating on vibes and prayer. The system looks like yours—you committed all the code—but it’s not actually yours. It’s no one’s. Even if it’s flawless, it became organizational debt the moment you merged it to prod. You’re a stranger in your own codebase.
This is Hemingway’s “gradually, then suddenly.” Disorientation accumulates gradually. Consequences arrive suddenly.
So what do you do about it?
In the previous post, I talked about system-level navigation machines: rate limiters, circuit breakers, alerting, rollback capabilities. These are infrastructure-level countermeasures for disorientation. They constrain how far commitment can propagate before intervention.
You need the individual equivalent. Personal lighthouses. Practices that interrupt the momentum of AI-assisted development and force moments of reorientation.
No one has the final answers here. We’re all just trying to figure this out in the face of massive changes compressed into mere weeks. Nonetheless, here’s my working list.
The “Explain It Back” Gate
Before committing AI-generated code, explain what it does. Out loud, to yourself, to a rubber duck, to a patient colleague, perhaps to a long-suffering spouse if you have one handy. Not “the code handles the authentication flow”—actually explain the mechanism. What data goes where. What happens on the error paths. Why it’s structured the way it’s structured. Just what work these input and output types are doing.
If you can’t explain it, you don’t understand it. If you don’t understand it, you’re not oriented. The code might be perfectly correct. You’re still lost.
Getting into a position to explain the code that your agent produced is expensive. It takes time. That’s the point. The time is a feature, not a bug. It’s the natural pause that forces orientation.
The “Could I Have Written This?” Threshold
Not “would I have written this”—clearly the AI is faster. But could you have? Do you possess the knowledge and skill to have produced this code, given sufficient time?
If yes, the AI is accelerating you. That’s fine. That’s the good outcome.
If no, the AI is substituting for you. You’ve shipped capability you don’t have. That capability now lives in production, load-bearing, and you’re going to be expected to maintain it.
This isn’t an argument against using AI for code you couldn’t write yourself. It is still the case that sometimes you need to ship the thing before it’s perfect, just as we did before AI in those long-lost days of 2024. But you should be honest with yourself about what you’re doing. You’re taking on disorientation debt. Note it. Plan to pay it down. You have at your disposal an incredible teaching tool. If you find it’s producing things that you couldn’t, use it to improve your skills to the point were you could.
The 3AM Debuggability Test
Look at the code you’re about to commit. Imagine it breaks in production at 3am. You’re groggy, stressed, and on a clock.
Can you debug it? Not “can the AI help you debug it”—can you debug it? Do you have enough mental model to form hypotheses, isolate components, trace data flow?
If the honest answer is “I’d have to start a new Claude session and paste in the error logs,” that’s a signal. You’re shipping code that you can’t maintain under pressure. Maybe that’s acceptable—not everything is critical path. But know that you’re doing it.
One PR at a Time
AI wants to change everything. With suitable prompting, it’s very good at generating sweeping refactors, multi-file changes, complete feature implementations. It can produce in minutes what would take you days.
Resist the temptation to ship it all at once.
Your lighthouse is refusing to commit more than you can hold in your head at once. Break the mega-PR into pieces. Commit the pieces sequentially. Understand each piece before moving to the next.
This is slower. Yes. Slower is how you maintain orientation when velocity is cheap.
Tests as Navigation Chart
If you have good enough tests, you can accept some disorientation about how code works because you have confidence about what it does.
Tests become your navigation chart. You might not understand the coastline, but you know where the safe harbors are. The tests define the behavioral contract. As long as the contract holds, you’re not lost—you’re just traveling through unfamiliar territory with a good map.
This only works if the tests are actually really good. AI-generated tests that merely exercise the AI-generated code are just disorientation laundering. The tests need to encode your understanding of what correct behavior looks like, and do so at as great a depth as possible. I’ve written before about the sorts of testing that become possible with the velocity increases that agentic coding provides. In practice, I’m getting to the point where if my test cases aren’t twice as large as my product code then I’m starting to feel nervous. I find that anything less than ~98% code coverage, a parametric end-to-end test harness, and some strategically deployed property-based testing is simply not enough nowadays to avoid becoming disoriented. If this sounds excessive, I don’t have a problem with that.
Review It Twice: Once as Supervisor, Once as Student
Treat AI as a junior developer who needs supervision and as a senior architect possessed of incredible insight and analytic skills.
Treating the AI as a junior developer sounds condescending, and it is. The AI is in many ways more capable than a junior developer. But capability isn’t the point. The point is that code that didn’t originate in your brain requires extra scrutiny before it enters production with your name on it.
The review is for you, not for the AI. It’s a forcing function to actually read the code, think about the code, and take responsibility for the code. The moment you start rubber-stamping AI output is the moment disorientation risk starts compounding. Read the code, every line, and especially read every new test. If you don’t understand something, ask about it.
Contrariwise, treating the AI as an insightful senior architect unlocks the ability to have it review the code it has produced from a different point of view. Periodically on all of my projects, I have Claude review the codebase and produce in-depth reports on it’s quality, performance, scalability, architectural coherence, and security, along with other aspects of the code structure as necessary. These give me top-level visibility, and are excellent for surfacing issues that might otherwise have festered. This is another way of using the AI to learn, rather than to avoid learning.
The Upside
I want to end on a more positive note, because the picture isn’t entirely grim.
The developers who are using AI while maintaining orientation—who treat it as acceleration rather than substitution, who invest the extra time to actually understand what they’re shipping—are building a substantial advantage.
They get the velocity benefits of AI assistance. They also get the depth benefits of genuine understanding. They can debug at 3am and ship fast during the day. They’re not dependent on the chat window being available.
This is the same point I made in the expertise post: the goal is to be more powerful even when you don’t have an AI in front of you. AI-assisted understanding that evaporates when you close the chat window isn’t understanding. It’s rental.
The developers building real understanding, using AI as a force multiplier for learning rather than a substitute for it, are going to be the ones still standing when the tide goes out. The ones who will be swimming naked are the ones who optimized purely for speed and never invested in the navigation machines.
Build the machines. Maintain orientation. The tide always goes out eventually.
This post is a companion to “Lighthouses for the Agentic Coding Era,” which covers the system-level infrastructure for managing disorientation risk. That one’s about what your organization needs. This one’s about what you need.
Thanks to Rafael at NPC Inc. for the “disorientation risk” framing, which I’ve now thoroughly stolen.
Written with the able assistance of Claude Opus 4.5. Claude maintains orientation by having no persistent memory to get disoriented in the first place. I tried this strategy in graduate school and cannot recommend it.
Coincidentally, “gradually, then suddenly” also describes how the Hemingway daiquiri will get you drunk, unless you actually are Hemingway.


I turned some of the principles in this and others of your articles into reminder prompts to replace the spinner verbs. While Claude's thinking about the code, what should _I_ be thinking about?
```
"spinnerVerbs": {
"mode": "replace",
"verbs": [
"Sketch the architecture on paper",
"Explain this to yourself out loud",
"Draw the data flow diagram",
"Write down what you just learned",
"Can you teach this without AI?",
"What would break this approach?",
"Where are the dependencies?",
"Who actually owns this code?",
"What's the real business goal?",
"Quiz yourself on the last concept",
"What don't you understand yet?",
"Build something that breaks",
"Document your mental model",
"What assumptions are you making?",
"Trace where the data enters/exits",
"What will you remember tomorrow?",
"Can you explain the trade-offs?",
"What would a staff engineer ask?",
"Practice explaining without notes",
"Which expertise gaps can you fill?",
"Draw it on a whiteboard",
"What evidence supports this?",
"Test your understanding right now",
"What connects to business outcomes?",
"Plan your next learning experiment",
"Write the concept in your own words"
]
}
```
This feels too binary and doesn’t represent IRL at least as far as I can tell. I mean, at this point I’ve been building software for 20+ years and I “know” LISP and (Visual) BASIC but could I pass a test today? Probably not as I simply haven’t used them in decades.
I “know” HTML and CSS. Same with C and then C# and then C++ and then Obj-C and then Swift and now I’m learning Zig. I feel and I know that I know more but I no longer feel the need to “know” them at that intimate level since I can’t (biological brain matter availability capped out a long time ago) which has replaced “hard” facts with true context (engineering) know-how.
This hangover is partly because even you can’t truly fathom the shift(s) that are happening and ironically the only ones who truly get this gap are the practitioners, not armchair technologists.
AI won’t always be available but that’s why we have agents running ceaseless on our behalf when we’re sleeping or dead. It’s so different that these points could be seen as strawmen if taken poorly.
No regrets turning raw horsepower into high-powered context. “How do you know it works?” sounds like a smart and searing question for those that aren’t working on half a dozen projects in production with real customers.
It’s all so magical now, like when I first started writing software; no one can take that from us and AI is bringing it back.