Vibe Coding Gets You to 80%. Here's What Gets You the Rest.
- 4 days ago
- 12 min read

Vibe coding, the practice of prompting AI to build features rapidly, iterating by feel rather than by formal specification, is genuinely extraordinary for exploration. You move fast, ideas become prototypes in hours, and the first 80% of almost anything comes together with a speed that still surprises me. I use it. Most people building seriously with AI do.
But there’s a wall at 80%. And after years of building systems before AI, and the last several specifically navigating the transition to AI-assisted development, I’ve come to understand that wall more precisely than I’d like.
The remaining 20% of any non-trivial system, edge cases, reliability under real usage, integration complexity, performance, and security, is where the real work begins. That ratio isn’t new. What’s new is how fast AI gets you to that wall, and how much is waiting on the other side of it when you arrive with unclear foundations.
AI hasn’t changed the nature of the problem. It’s changed the stakes. When a human builds from unclear requirements, they compensate, pause, ask questions, and apply judgment. When AI builds from unclear requirements, it does something far more dangerous: it produces complete-looking, confident output that hides its mistakes behind a finished appearance.
I’ve watched teams generate entire features in hours, only to have them thrown away in days.
Not because the AI failed. Because the thinking behind the prompt did.
AI makes the first 80% faster than ever. Which means it also makes unclear thinking more expensive than ever.
The Real Problem: Specification Debt
This isn’t a new problem. And it isn’t the AI’s fault.
The root cause is something I’ve watched accumulate silently across every team I’ve worked with, in every technology era I’ve built through. I call it specification debt, the gap between what a system is supposed to do and what has actually been clearly defined.
We’ve been carrying it for years. We just never had a reason to confront it this directly.
Waterfall tried to close that gap with heavy upfront documentation. It couldn’t keep pace with how fast requirements change in the real world. Many teams reacted by stripping documentation to its minimum viable form, which improved speed but often normalized ambiguity as an acceptable default.
User stories became the industry standard. In experienced teams, they often evolved well: groomed with technical guidance, enriched with acceptance criteria, and sharpened through conversation between product and engineering. At their best, they do close many of the gaps.
But even a well-groomed story was written to communicate intent to a human, someone who brings context, asks questions during implementation, and notices when something feels off. That same story, handed to an AI coding agent, is a different proposition entirely.
The agent works from what is written, not from the unwritten context around it. It wasn’t in the room when the team resolved that edge case over Slack. It can’t sense when something feels architecturally wrong. It executes on what’s written, and fills everything that isn’t written with its best inference.
That gap, between clear enough for a human and precise enough for an AI agent, is where specification debt lives in modern development. And it’s significantly wider than most teams realize.
In practice, teams have always filled those gaps somewhere. In Slack threads. In someone’s head. Across hallway conversations that never got written down. Or worse, directly inside the code itself, invisible to everyone who comes after.
That works, until it doesn’t. What you end up with isn’t a system built on shared understanding. It’s a system built on accumulated assumptions, and the older it gets, the more fragile those assumptions become.
Now add AI to that picture.
A senior developer, seeing a vague requirement, will pause, push back, and apply years of pattern recognition to what isn’t being said. AI does not do that consistently, and it does not own the consequences when those assumptions are wrong. It takes your assumptions, executes them faithfully, and returns output that looks exactly like what you asked for, which is precisely the problem when what you asked for wasn’t fully thought through.
The result isn’t a few bugs. Its entire features, built at speed, that are wrong in exactly the way your requirements were wrong. AI didn’t create this problem. It just made the cost of it impossible to ignore.
Clarity Before Execution
To be clear about what this is and isn’t: not a new methodology, not a return to 200-page requirements documents. What I’m describing is a working principle that emerged from repeatedly hitting the same problems and learning what actually resolved them.
Before anything gets built, the thinking has to be done.
This is where I start every piece of work, not by asking AI to build, but by asking it to think with me. Before a single line of code gets written, I use AI as a thinking partner: stress-testing the idea, surfacing edge cases I haven’t considered, challenging assumptions, and pressure-testing the approach against constraints I might have glossed over. This is where the collective knowledge of those models earns its place, not in generating code, but in sharpening the thinking that will eventually drive it.
From there, the spec gets built the same way, collaboratively, in conversation with AI. Not dictated to it, and not written manually in isolation. The AI brings depth, pattern recognition, and the kind of systematic thinking that comes from having processed more software decisions than any single person could accumulate in a lifetime. My role in that conversation is to guide it, push back where something doesn’t reflect the intent, and own every final decision.
AI can think with you, draft with you, reason through tradeoffs, and increasingly act on your behalf. What it cannot do is know what you actually intend, or be accountable for what gets built. That part stays with you.
The more capable AI becomes at reasoning and acting autonomously, the more important it is that the human has been clear about intent upfront. Autonomous execution without clear direction doesn’t become safer as AI gets smarter. It becomes faster, which means the cost of unclear thinking compounds even more quickly.
A few other shifts happened when I started working this way that are worth naming:
Spec before code, not alongside it, not after it. The act of building the spec, collaboratively with AI, is where the gaps surface.
The spec becomes the source of truth. Not the code. Not tribal knowledge. Not the Slack thread from three sprints ago.
Specs are built to be executed by AI, not archived by humans. Traditional documentation often fails because it was written for humans to read and interpret, and humans drift, forget, and fill gaps with their own judgment. What I’m describing is fundamentally different in both purpose and format.
These specs are written for AI coding agents to execute on. Every section, every constraint, every acceptance criterion is structured with that in mind, not as a narrative for a human reader, but as a precise, unambiguous instruction set for an AI that will take it literally. The prompts are deliberate. The boundaries are explicit. The expected outputs are defined.
This changes how you write them. Ambiguity that a human might charitably interpret in the right direction will be executed by an AI in whatever direction the gap allows. Vagueness that might survive a human review will produce confidently wrong code at the other end of an agent session.
When a spec is written well for an AI coding agent, it doesn’t just guide the implementation; it constrains it. The agent isn’t making judgment calls. It’s executing a clear instruction set that was built, reviewed, and finalized by a human who understood exactly what they were asking for.
That’s the difference between documentation and a spec designed for AI execution. One gets read. The other gets run.
Ambiguity is a blocker, not a detail. This was the biggest mindset shift for me, and the hardest one to hold under pressure. The default on most teams is to tolerate ambiguity and resolve it during implementation. I’ve stopped doing that. Every unclear requirement is a future inconsistency waiting to be generated at scale. Clarity isn’t overhead anymore. In an AI-assisted workflow, it’s the primary form of leverage you have.
Where Most Conversations Stop, And Where the Real Work Begins
Most discussions about working spec-first end around here.
The argument makes sense. The principles are sound. People nod along. And then they go back to their existing workflow because nobody answered the most important question:
How do you actually make this work, especially when AI is in the loop?
In practice, here’s what usually happens. You start with good intentions. You write a few specs. You ask the AI to follow them. And for a while, it works.
Then reality kicks in.
The AI drifts off-track. Scope starts expanding in ways you didn’t anticipate. Context gets messy across sessions. Something breaks, and the fastest fix is to make it directly in the code. And within a few cycles, the spec is already behind the implementation, which means it’s already stopped being the source of truth.
The problem was never the idea of working spec-first. The problem is the absence of an execution model that actually holds under real conditions, with real deadlines, real scope changes, and an AI that will confidently fill every gap you leave open.
That’s what took me the longest to figure out. And it’s what I’ll get into next.

How I Actually Make This Work
What I’m about to describe isn’t a prescribed process. It’s a working model that evolved through iteration, some of it deliberate, most of it in response to things breaking in ways I didn’t anticipate. I’m sharing it because it’s what works for me, and because the underlying principles might be useful regardless of how you adapt them to your own context.
The core insight that changed everything was this: the problem with AI-assisted development isn’t the AI. It’s the absence of structure around how humans and AI work together.
AI is extraordinarily good at execution. It is not good at defining what should be executed. That’s the human’s job. And once I stopped expecting AI to fill that gap, and started building a workflow that made the boundary explicit, everything else followed.
Work in slices, not features.
The first structural change I made was breaking work into small, isolated pieces rather than building large features end-to-end. Each slice has its own spec, clear acceptance criteria, and defined boundaries. More importantly, one slice gets one focused AI session. That constraint turns out to be critical.
Long AI sessions degrade in ways that aren’t always obvious until the damage is done. Earlier decisions get quietly overridden. Contradictions appear between components. The system drifts toward inconsistency, and by the time you notice, you’re debugging something that was never going to hold together because the context that should have constrained it got lost several prompts back.
Keeping each session scoped to a single slice keeps the context clean, the output predictable, and the system coherent across its parts. If I can’t define the boundaries of a slice clearly enough to constrain a single AI session, that’s a signal the spec isn’t ready; not a reason to start building anyway.
Plan before code. Every time. No exceptions.
Every session starts the same way, regardless of how clear the spec feels or how much pressure there is to move fast. Read the system spec and the slice spec, have AI generate an implementation plan, and review and approve that plan before a single line of code is written.
This feels like overhead until you’ve experienced what happens without it. Once AI starts generating code, it moves fast, and the cost of correcting direction grows with every line it produces. Five minutes reviewing a plan is worth an hour of untangling code that went wrong way with complete confidence.
The plan review is also where I catch the gaps I missed in the spec. Which brings me to the next point.
The spec is where you go when something is wrong.
When something breaks, or behaves unexpectedly, or doesn’t match what I intended, my first move is back to the spec, not into the codebase.
This took discipline to build as a habit. The instinct, especially under pressure, is always to fix the code. It’s faster in the moment. But if the spec doesn’t reflect the correct behavior, the next AI agent session will reintroduce the same problem. You’re not fixing anything. You’re just resetting the clock.
The order that works for me: update the spec first, adjust the acceptance criteria or tests second, then update the code. And when I say update the spec, I mean rewrite the instruction, not a note about what went wrong, not a comment explaining the bug, but a precise, updated directive that tells the agent exactly what the correct behavior is, in language unambiguous enough to execute on.
In that sequence, the correction propagates correctly through the system. In any other sequence, you’re patching symptoms while the root cause stays encoded in the instruction set.
Specs live in the repository, not outside it.
This is one of the most practically important decisions in the entire workflow, and one of the easiest to get wrong.
Specs don’t live in Confluence. They don’t live in Notion, a shared drive, or a folder someone has to remember to sync. They live in the GitHub repository, alongside the code they govern, committed and version-controlled with the same discipline as the implementation itself.
Every spec change is a commit. Every commit tells a story, not just what changed in the code, but what changed in the instruction that drove it. Pull requests carry both the updated spec and the updated implementation together. The history is traceable, reviewable, and permanent. There’s no drift between what the system does and what the spec says it should do, because they’re updated in the same moment, in the same place.
For AI agents, this changes everything about session quality. Every new session starts with access to the full, current, version-controlled spec, not just what you remember to paste into the prompt, but the complete instruction set for that slice and the broader system. The agent isn’t working from fragments or a conversation you half-remember from last week. It’s reading from the same source of truth that produced every previous output.
For humans, the value compounds over time. New team members can clone the repository and immediately have access not just to the code but also to the reasoning behind it. Decisions are visible in the specs, not buried in someone’s head or lost in a Slack thread from six months ago. Code reviews become richer, and reviewers can see whether the implementation actually matches the instruction, not just whether the code looks right in isolation.
When specs live alongside the code, they stop being documentation. They become the persistent memory of the system, for every agent that works on it, and for every human who comes after you.
What this changed in practice.
After working this way consistently, a few things shifted that I didn’t fully anticipate.
AI output became more consistent, not because the AI improved, but because the inputs did. Rework went down noticeably. Onboarding got easier because the reasoning behind decisions lived in the specs rather than in people’s heads or buried in commit history. New team members could understand not just what the system did, but why it was built the way it was.
Most significantly, I stopped spending energy managing the AI and started spending it directing it. That’s a different relationship with the tool, and a more productive one. The AI operates within boundaries that have been defined, reviewed, and thought through. It’s not filling gaps with its best guess. It’s executing against a clear instruction set.
That shift, from managing to directing, is what the workflow is really about.
A Broader Point Worth Acknowledging
The most significant thing AI has done for this industry isn’t making developers faster. It’s changed who gets to build at all.
Product managers, designers, domain experts, founders, people who wouldn’t traditionally have called themselves builders are taking ideas from concept to deployed product with a speed and independence that simply wasn’t possible before. It’s real, it’s already here, and the implications are still unfolding.
But here’s what I’ve also observed: the spec-first discipline matters even more in that context, not less.
AI carries the collective knowledge of thousands of the world’s best engineers and decades of accumulated software thinking. For someone without a technical background, that’s not a small thing; that’s access to a level of depth and experience that simply wasn’t available before. The AI genuinely does serve as a capable, knowledgeable technical partner.
What it misses, though, is this: even the most capable engineer, human or AI, builds the wrong thing when the brief is unclear. Knowledge doesn’t compensate for direction. Pattern recognition doesn’t activate without something precise to pattern-match against. The AI’s extraordinary capability responds to what it’s given, it executes brilliantly against a clear instruction set and just as confidently against a vague one. The difference in output between those two scenarios is significant. And it’s entirely determined by the quality of thinking the human brings before the agent session starts.
That’s the part that can’t be delegated. Not because AI isn’t capable, but because intent can only come from the person who knows what they’re actually trying to build.
This isn’t about whether you have an engineering background. It’s about the quality of the conversation you’re having with the most capable collaborator most of us have ever worked with. Spec-first thinking isn’t a barrier to entry. It isn’t a workaround for AI’s limitations. It’s how anyone, regardless of background, actually unlocks what AI can do.
The Real Shift
There’s a version of this story where the takeaway is: write better specs and your AI problems go away. That’s not what I’m saying.
What I’ve come to understand is that the tools we use always expose the weakest part of our process. Every technology cycle does this. AI is doing it now, at a speed and scale that makes the exposure impossible to ignore.
The weakest part of most development processes isn’t the code. It’s the thinking that precedes it.
Vibe coding is a natural response to having extraordinarily capable tools at your fingertips. The impulse to move fast and build immediately is completely understandable, and for exploration, prototyping, and getting to a proof of concept, it’s often exactly the right approach.
But there’s a point where speed without clarity stops being an asset and becomes a liability. Where the confidence of the output begins to mask the ambiguity of the input. Where what felt like momentum turns out to have been drift.
That’s the line I’ve learned to watch for.
Working spec-first didn’t slow me down. It changed where I spend my thinking, earlier in the process, before the cost of unclear thinking gets multiplied across the generated code. The velocity on the other side of that shift is cleaner, more predictable, and significantly easier to sustain.
AI is going to keep getting better at execution. That makes the quality of what we ask it to execute more important, not less. The builders who understand that early, who invest in clarity before they invest in speed, aren’t just going to ship faster.
They’re going to build things that hold.




Comments