When vibe coding creates brittleness debt

Vibe coding is fast. You sit down, describe what you want to AI agents, iterate against what they produce, ship things at a pace that traditional engineering can't match. The speed is genuine. The strategy works.

The hidden cost is brittleness debt. Each thing you ship was generated by AI against a prompt that lived in your head at the time. The prompt isn't documented. The decisions the AI made aren't captured. The assumptions built into each piece aren't explicit. The system grows. The cumulative invisible context accumulates.

Then small changes start breaking unrelated things. Adding a feature triggers a regression in something that should be unrelated. Fixing a bug introduces a different bug elsewhere. The system has become fragile in ways nobody can debug because the relevant context exists only in the heads of whoever was vibe coding at each moment, and those moments are gone.

This is brittleness debt. It's the cousin of technical debt that vibe coding produces specifically and that traditional engineering processes were designed to prevent. Knowing the shape it takes is the first step to either preventing it or addressing it after it's accumulated.

What brittleness debt is

Brittleness debt is the cumulative consequence of building software without externalizing the architectural context. Every meaningful decision exists in someone's head. The decisions interact in ways that are obvious to the person who made them at the time and invisible to anyone (including their future self) who didn't.

The debt is invisible because nothing in the code looks wrong. The code is functional. Tests (if they exist) pass. The system runs. The brittleness emerges only when changes happen, because changes interact with the invisible context, and the interactions produce unexpected outcomes.

Traditional engineering practice tries to prevent this through specifications, code review, documentation, tests. The practices feel like overhead. They're actually the externalization that prevents brittleness from accumulating. Vibe coding skips these practices to gain speed, and pays the cost in brittleness later.

The cost isn't immediate. Brittleness debt can compound for months before any visible symptom. By the time symptoms appear, the debt is large.

The four shapes brittleness debt takes

Shape one: implicit dependencies between components. Two parts of the system depend on each other in ways that aren't documented or visible. Changing one breaks the other in a way nobody predicted. The debug requires understanding both parts, which the operator may not have anymore.

The accumulating cause: each component was built quickly. The integration between them was implicit (this part calls that part, that part expects this format, nobody wrote it down). Over time, the system has dozens of these implicit dependencies, and changes ripple through them unpredictably.

Shape two: undocumented assumptions in the data layer. Code that reads or writes data assumes specific properties of the data. The assumptions aren't enforced anywhere. When data violates the assumptions (because the schema changed, because an edge case emerged, because a vendor returned something unexpected), the code fails in ways that look like code bugs but are actually assumption violations.

The accumulating cause: each piece of data-handling code was written against the data as it existed at the time. The properties of the data weren't captured. As data evolved, the code's assumptions silently became wrong.

Shape three: invisible business logic embedded in implementation. Decisions about how the business should work got encoded in code without being captured as business decisions. The code reflects the decisions; the decisions aren't documented anywhere else. When the business needs to change the rules, the code is the only artifact that knows what the rules are.

The accumulating cause: each business decision was made in the moment of building. "Let's handle this case this way" became code without becoming documentation. The business logic is now distributed across the codebase in ways that resist coherent change.

Shape four: workaround pyramids. Each problem that emerged got a workaround. The workarounds work for the immediate problem and create small new constraints. New problems get workarounds that interact with the existing workarounds. Over time, the workaround pyramid has its own internal logic that nobody fully understands.

The accumulating cause: each workaround was reasonable in isolation. The cumulative effect is a system whose behavior depends on the specific interaction of many small workarounds, and changing any of them risks breaking the others.

How to detect brittleness debt before it's catastrophic

The early signals are subtle but consistent:

Confidence in changes drops. You used to make changes without much worry. Now you hesitate. You're not sure what the change might affect. The hesitation is your intuition telling you the system has become unpredictable.

Reproduction of bugs becomes harder. Bug reports come in. You can't reproduce them in development. The bugs occur in production under specific conditions you can't recreate. The unreproducible-bug pattern is brittleness signaling itself.

Feature requests get longer estimates. You used to estimate features in hours. Now you estimate in days because you're not sure what you'll discover. The growing estimate reflects growing uncertainty about the system's behavior.

Old features start breaking spontaneously. Something that was working stops working for no obvious reason. Investigation reveals that an unrelated change two weeks ago had a side effect nobody anticipated. The side-effect pattern is the debt manifesting.

When two or more of these signals appear, the system has accumulated meaningful brittleness debt. The signals are diagnostic; the next question is whether to keep adding to the debt, pause to pay it down, or invest in fundamental restructuring.

The discipline that prevents accumulation

The discipline that prevents brittleness debt is the same shape as the discipline that addresses technical debt: externalize the architectural context as you build, not after.

In practice, this means: write the specification before generating each piece. Capture the decisions you're making and why. Document the assumptions that the code depends on. Make the implicit relationships explicit. Test the invariants that should hold.

This is the SpecMesh discipline I run on my own builds. The same vibe-coding speed, with the externalization that prevents brittleness from accumulating. The speed doesn't suffer meaningfully; the debt simply doesn't accrue.

The discipline takes maybe 20% additional time per build cycle. It saves dramatically more time over the life of the system because the changes don't keep breaking unrelated things. The math is consistent in favor of the discipline.

What to do if you've already accumulated brittleness debt

If you're past the prevention point and the debt is real, the options are:

Stabilize first, then evolve. Pause feature work. Address the debt deliberately: write specifications for the existing system, capture the architectural decisions, document the implicit dependencies, externalize the business logic. This is paid-down debt rather than continued accumulation. The pause feels expensive; the cost of continuing accumulation is higher.

Rebuild incrementally. Identify the most brittleness-laden parts of the system. Rebuild them with the discipline in place. Each rebuild is smaller than a full rewrite and produces a clean section. Over time, the system shifts from brittle to specified.

Full rewrite. When the debt has accumulated past the point of incremental address, sometimes a clean rewrite is the right answer. The rebuild should use the discipline from the start: specifications, captured decisions, explicit relationships, tests for invariants. The new system shouldn't accumulate the same debt.

Which option fits depends on how much debt has accumulated, how critical the system is, and how much runway you have for stabilization work. None of them are easy; all of them are better than continuing to accumulate.

The honest tradeoff

Vibe coding without specification is genuinely faster for short bursts. The speed is real. The cost is brittleness debt that accumulates and eventually consumes the speed advantage.

Vibe coding with specification is slightly slower per cycle and dramatically faster over months. The discipline costs upfront and saves continuously.

If you're building something throwaway, raw vibe coding is fine. If you're building something that has to grow, the discipline pays back. The choice should be made deliberately based on the system's expected lifespan, not by defaulting to the faster-per-cycle option.

If you're seeing the early signals of brittleness debt in your current vibe-coded system, the discipline is still available. Adding it now prevents the debt from getting worse, and gives you a path to address what's already accumulated.


Got a vibe-coded system that's starting to show brittleness debt signals? Send the system description, the symptoms you're seeing, and how the build has been done so far. VibeKoded can scope the prototype, build the MVP, or hand off the production app. → Work with VibeKoded