A year ago, Andrej Karpathy gave the world a phrase and it spread like fire: _vibe coding_. You know the practice even if you avoided the term. You describe what you want in natural language, the AI writes the code, you run it, you nudge it, you ship it. You don't fully understand every line. That's fine. It works.
It worked, anyway.
The teams who enthusiastically vibe-coded through 2025 are now hitting something I'd describe as the maintenance wall. Not a catastrophic failure—something quieter and more insidious. The codebase keeps growing, but each new feature takes a little longer than the last. Each bug fix breaks something adjacent. The original developer—or the original session—is long gone, and the context went with it.
The AI that was so useful twelve months ago is now staring at a codebase full of decisions it doesn't understand, because nobody wrote down _why_.
What Vibe Coding Actually Is
Let me be precise, because the term gets used sloppily.
Vibe coding, at its best, is _intention-led development_: you describe the outcome you want, and you let the AI figure out the implementation. It's genuinely productive. For prototypes, for MVPs, for exploratory work where the goal is to find out if an idea is viable—it's arguably the best workflow we've ever had.
At its worst, it's _context-free generation_: you ship code you can't explain, into a system you only partially understand, with no record of why.
The distinction matters, because the failure mode isn't the AI's fault. AI does exactly what it's asked. The failure mode is _context evaporation_—the silent loss of all the reasoning that produced the code.
When a human developer makes a decision—uses this library instead of that one, structures the data this way rather than that way, ships the simple version now and defers the complex version—that reasoning lives somewhere. Ideally in documentation. Practically, in their head. When they leave, the reasoning leaves too.
With AI-generated code, the reasoning never fully existed in a form anyone captured. The developer's "vibe" was the context. And vibes aren't searchable.
The Maintenance Wall, Precisely
Here's what the maintenance wall actually looks like in practice.
Symptom one: The AI hallucinates your conventions.
You've been on this project for eight months. There's a particular way you handle errors. A particular pattern for async operations. A naming convention that evolved organically. A senior engineer on your team would absorb these within a week.
A new AI session doesn't have a week. It has your codebase and whatever context you provide. If you didn't document the conventions, the AI will invent plausible ones—and they'll be wrong. Not obviously wrong. Subtly inconsistent.
Symptom two: Nobody can explain the decision.
Six months ago, you vibe-coded a rate limiting solution. It works. Then you need to change it—add a new tier, adjust the logic. You ask the AI to modify it. The AI dutifully modifies it. Something breaks. You can't quite figure out why, because the original implementation is opaque. You fix the break, but you're not confident. Another ticket opens.
This is context debt. Like technical debt, it compounds. Unlike technical debt, it's invisible until it bites you.
Symptom three: The codebase resists extension.
The original vibe-coded system had a shape that made sense _at the time_. That shape was implicit—it lived in the developer's intuition. As the system grew, new features were added around it. Now the shape is locked in, unexplained, and everything new has to contort around it.
When you ask the AI to add a feature, it struggles. Not because it isn't capable—because it's working without the architectural reasoning that produced the current structure. It's like asking someone to extend a building without knowing which walls are load-bearing.
The Context Evaporation Problem
Here's the root cause: in vibe coding, the context lives in the developer's head.
When you describe what you want to an AI, you're drawing on a mental model that the AI can't see. You know that this service is eventually-consistent. You know that the external API has a ten-second timeout that's bitten you before. You know that the CEO will want to query this data in a specific way. These constraints shape your "vibe"—but they never get written down.
The AI produces code that satisfies the stated requirement. It doesn't produce code that satisfies the unstated constraints—because it doesn't know about them.
The output looks right. It passes the tests you wrote. It ships.
Three months later, you hit the ten-second timeout. Or the CEO wants the query that wasn't anticipated. Or the eventual-consistency assumption breaks a user flow.
And now you're debugging a system where the reasoning is gone.
What Comes After
The solution isn't to stop using AI. That suggestion is barely worth dismissing.
The solution isn't to write more code manually either. Manual code doesn't solve the context evaporation problem—humans forget too, and they have worse memory than AI.
The solution is to treat context as the primary artifact.
Code is generated. Context is authored.
When you start a new piece of work, the most valuable thing you can create is not the first working implementation. It's a clear statement of:
- What you're building and why
- What constraints apply (performance, security, compatibility, business logic)
- What alternatives you considered and why you rejected them
- What "success" looks like in concrete terms
This sounds like documentation. It is, but with a crucial difference: it's _decision-oriented_, not _description-oriented_. Most documentation describes what code does. Context documentation explains why the code is the way it is.
When this context exists—when it's structured, persistent, and accessible—AI can work on a codebase indefinitely. New sessions don't start from zero. They start with everything the previous sessions learned. The AI can explain any decision. A new engineer can understand the system in days, not months.
The Compound Effect of Context
I wrote yesterday about the compound agent—how AI knowledge can accumulate across sessions if you build the right infrastructure. Context-driven development is the same principle applied to codebases.
Each session that produces good context makes the next session more effective. Each decision that gets documented removes a future investigation. Each constraint that gets written down prevents a future bug.
The teams who do this well look almost magical to outsiders. Their AI seems to "understand" their codebase. It writes code that fits their patterns. It avoids their antipatterns. It remembers their architecture decisions.
It's not magic. The AI is reading context that previous sessions left behind.
Compare this to the vibe-coded codebase at month eight: where every AI session has to rediscover the shape of the system, re-ask the same questions, make the same mistakes that were already made. Where the codebase is technically functional but architecturally opaque.
The Shift in Practice
What does this look like in the workflow?
Before you start a task: Write a context document. Not a spec—a _context_. Two paragraphs. What's the problem? What constraints matter? What would make this wrong? This isn't overhead. It's the input that makes the AI's output trustworthy.
During a task: When the AI makes a significant decision—chooses an approach, structures data a particular way—ask it to explain the choice. Capture the explanation. It takes thirty seconds. It's worth thirty hours later.
After a task: Extract the learnings. What didn't work? What was the trap? What would a new person need to know to maintain this? Add it to your knowledge layer. Not a wiki that nobody reads—a searchable, persistent store that AI can access in future sessions.
Can you hand this code to an AI with no prior context and have it make a correct change on the
first try? If yes, you have good context. If no, you have context debt.
This workflow sounds like more work. In my experience, it's less. The time spent writing context is returned tenfold in the time not spent debugging mysterious failures, re-explaining the system to new sessions, or fixing changes that broke adjacent functionality.
Vibe Coding Was Right About One Thing
The vibe coders were right that the old way—writing every line, understanding every implementation, being the master of every dependency—is no longer necessary or desirable. The abstraction ceiling has genuinely risen.
The mistake was thinking that rising above implementation details meant rising above decision-making. It doesn't. The decision-making got _more_ important, not less.
When you're writing every line, the implementation and the decision are fused. The code is evidence of the thinking. When AI writes the code, the thinking and the implementation separate. The code is just output. The thinking has to live somewhere else.
Context-driven development is the recognition that we need new artifacts for new workflows. Not less documentation—different documentation. Oriented toward decisions, not descriptions. Persistent and searchable, not static and forgotten. Structured for AI consumption, not just human consumption.
The vibe only gets you so far. After that, what carries you is context.
The Test
Here's the test I now apply to every piece of work:
_If I came back to this codebase in six months, with no memory of building it, could an AI work effectively on it immediately?_
If yes, the context is good. If no, there's context debt.
Vibe coding fails this test by construction. The context lives in the vibe—in the developer's state of mind during the session. That state doesn't persist.
The teams that will win the next phase of AI-assisted development aren't the ones with the best AI tools. Those are commodities now. They're the teams who built context infrastructure—who made their AI sessions compound instead of reset.
The vibe was a good start.
Now build the thing that lasts.