Let me tell you a story about probability.
You have a fair coin and plan to toss it 100 times. Expecting around 50 heads is reasonable — mathematically proven, even.
Now you toss it 40 times and get 15 heads, 25 tails — a deficit of 10 heads, from nothing but randomness.
Here’s what people quietly assume: the coin will compensate. The next tosses will lean toward heads to restore the balance.
That instinct — that the coin is “due” — is the gambler’s fallacy, and gamblers have lost money to it for a century.
The next toss is still 50/50. So is the one after. The coin has no memory of your deficit. The average never pulls you back to the line — it is not a correcting force, it’s an accounting convention.
You cannot rely on probability to guide you back to stability inside a process that has already deteriorated.

Now Replace “Coin” With “Codebase”
That, roughly, is what happens when you vibe-code with AI and skip the good old, not-so-shiny engineering underneath.
The tools are genuinely remarkable. Ask for a working demo and you’ll get one. That part is real.
Then you complicate it.
You add a feature. You modify a behaviour. You try to sustain the thing over months rather than an afternoon. And you discover that maintainability has almost nothing to do with how fast the code was produced. It depends on whether the architecture was coherent, the decisions consistent with one another, and the business domain actually modelled rather than approximated.
Every small choice can deviate a little from the reality the code is meant to describe — each one insignificant and fully defensible in isolation. And like the coin’s, these deviations do not cancel. They accumulate.
The Price of Every Subsequent Change
Once the incoherence exists, you pay interest on it with every change. Call it technical debt — but with AI it shows up in the process and the product far more visibly than when code was written by hand.
It is created by perfectly normal work:
- Someone shipped a fix that quietly ignored the assumptions the rest of the system relies on.
- Someone approximated the domain instead of modelling it.
- Someone missed the idea behind an interface and broke its encapsulation.
And so each of these changes might be a matchstick. Each one works. Each one ships.
Eventually many systems end up held together by matchsticks.
Anyone who has worked in software long enough has been inside one. What’s easy to forget is why it didn’t collapse sooner.
The Limit That Just Disappeared
For decades, what saved these systems was friction.
Matchsticks went in slowly. A human had to understand enough of the surrounding code to place one, and that understanding cost time — not a good brake, an accidental one, but a brake nonetheless. Incoherence accumulated at human speed.
That limit is now gone.
AI taken off the shelf does not remove the existing matchsticks. It removes the cost of inserting them.
Which leads to the sentence I’d like you to sit with:
If your system is built on matchsticks, adding AI to it will not make it coherent next year. It will make it a larger pile of matchsticks, much faster.
What the Tools Actually Give You
The argument is not that these tools are weak. It’s the opposite.
Ask a good model for a first version and you can trust what comes back, the way you trust a fair coin to land near 50/50. The baseline is predictable, and today it is high.
But a model is a coin in a second sense: it averages toward the patterns you put in front of it, with a little randomness each time. Point it at your codebase and it reproduces what’s already there — faithfully, tirelessly, fast. Left alone, it makes the existing code more like itself. And its nudges don’t average out: an unmanaged model walks a system downhill one defensible step at a time, faster than any human hand.
So coherence isn’t what the model lacks. It will hold a system perfectly consistent — including consistently bad. A pile of matchsticks is a pattern too, and the model extends it without hesitation.
What it can’t supply is the direction of that coherence — which shape to converge on. That doesn’t live in the code; it lives in your head, until you build the thing that carries it to the AI model.
That thing is the harness around the tool, and it is two jobs:
- Systematise the process — so the model checks against the right code every time, instead of comparing well once and guessing the next three.
- Point the direction — so a weak codebase gets pulled, change by change, toward the shape you want, instead of just more faithfully weak.
Do both and even a shaky system improves under the tool. Do neither and the pile grows faster. That isn’t a setting you switch on. It’s engineering work that has to be deliberately done.
Here is what that looks like when we run it. Every change an agent produces goes out as an ordinary pull request, and the whole team reviews it like anyone else’s work. But the comments do double duty. When a reviewer writes “we don’t reach across this module boundary,” that sentence doesn’t just fix one change — it becomes a rule in the harness, checked against every change that follows. A retrospective after every change, not every two weeks.
Those rules always existed. They lived in people’s heads and travelled by review comment, one head to another, written down nowhere. Now they accumulate — and when a new rule contradicts one already recorded, that collision is an architectural decision surfacing: to be made once, in the open, instead of twice, differently, in two corners of the codebase.
Look again at the chart at the top. The drift happens because every deviation quietly becomes the new baseline, and nothing pulls the process back toward the line. This loop is the correcting force the coin never had. Each deviation gets pointed back at the same target, and each correction improves not only the code but the process that produces the next change — compound interest, finally working in your favour.
It also quietly widens what “your system” means: not just the code and how its components talk to each other, but the process that governs them.
What This Actually Asks of Us
Not “don’t use AI.” That would be silly, and wrong.
It asks for something less comfortable than a tool purchase.
Restoring architectural coherence is a conscious decision — about what the system is supposed to model, which assumptions are load-bearing, which matchsticks come out before anything new goes in, and who is accountable for the shape of the whole rather than the correctness of the parts.
The tools will not make that decision for you. They will execute whichever decision you have already made — faithfully, tirelessly, fast — including the one you made by not deciding.
If you want to know which decision you’ve made so far, three checks will answer it on Monday morning:
- Where does the architecture live? If it’s in a wiki that was written once, updated never, and sits where your tools can’t reach it, then as far as the AI is concerned it doesn’t exist. Documentation that lives with the code — and changes in the same pull request — is the version the model actually reads.
- How does a new engineer land? If someone can build, run, and usefully change the system from what is written down, an agent can too. If they first have to ask fifteen people how it works, you already know how the model fills that gap: it guesses.
- Ask the model what your assumptions are. Have it read the codebase and list the assumptions it considers load-bearing. Then take that list to your team and count the ones nobody knew were in there. Every one of those is a rule the AI is already following. Nobody chose it.
What the harness consists of in practice — the conventions, the constraints, the checks — is the next piece. None of it ships with the subscription. All of it starts as a decision.
The coin does not correct itself.
Neither will the codebase.
What’s the most expensive matchstick you’ve ever had to remove?