A project that worked last Tuesday and cannot be trusted by Friday has usually not suffered a disaster. It has drifted.
Nothing obviously broke. Each individual change was reasonable at the time. But somewhere in the middle you stopped being able to say, with confidence, what the software currently does — and once that is gone, everything after it becomes guesswork.
What drift actually is
Drift is the accumulation of change you have not verified and no longer fully understand.
It is worth being precise about that, because it is not the same as having bugs. A project with known defects is in a good position: you know what is wrong, you know what is right, and you can decide what to fix. A drifted project has neither. The defects and the working parts are mixed together, and you cannot tell which is which without going back through everything.
AI does not cause drift. It accelerates it, because the rate at which change can be produced is now much higher than the rate at which a person can review it.
The sequence
Drift follows a recognisable pattern, and the early steps look completely harmless.
It starts with a change you accept without checking properly. The output looked right, the page loaded, and you were in a hurry. Nothing bad happens — which is precisely the problem, because the lesson you take away is that checking was optional.
Then you build the next thing on top of it. The AI reads the current state of the code as context, including the part you did not verify, and produces something consistent with it. If the earlier change was subtly wrong, the new work is now subtly wrong too, and in a way that looks deliberate.
Then something misbehaves, and the correction touches more than you expected. You asked for a fix; you received a fix plus some tidying, or a rewritten function, or a changed assumption elsewhere. You skim it, it looks plausible, and you accept it because reading it properly would take longer than you have.
By this point you have stopped reading diffs in full. There are too many, they are too long, and most of them have been fine. So you start sampling instead of reading.
And then something is definitely wrong, and you cannot identify the last state that definitely worked. That is the moment the project stops being under control. Not the first unverified change — the point at which you can no longer get back to solid ground.
Why it accelerates instead of levelling off
Each unverified change makes the next one harder to verify.
The AI takes the existing code as its description of reality. Anything wrong in that code becomes an input to the next answer, and gets treated as intentional. Meanwhile the amount you would need to re-read in order to regain confidence grows with every step, so the cost of stopping to check keeps rising at exactly the moment the need for it is increasing.
That is why drifted projects tend to feel fine and then feel hopeless, with very little in between. The underlying problem was building steadily the whole time; only the symptoms arrived suddenly.
Three places to interrupt it
You do not need a heavy process. You need three habits, each of which breaks the chain at a different link.
Verify before you build on it. The single most effective habit is refusing to start the next piece of work until the current one has been checked against what you actually asked for. Not "does it run" — does it do the specific thing you described? This is cheap when the change is small and recent, and expensive later, which is the whole argument for doing it now.
Keep a state you can return to. Once something is verified, preserve it — commit it, or otherwise mark it as a point you trust. The value is not the commit itself; it is that you always have a definite answer to "what was the last version I know was correct?". A project that can answer that question can recover from almost anything. A project that cannot is one bad afternoon from a rewrite.
Bound each request. Drift feeds on changes that reach further than intended, so say what must not change as well as what should. An edit that quietly extends past its brief is drift arriving through the front door, and it is worth knowing how to contain: when AI changes code you didn't ask it to touch.
If you are already drifting
Most advice about drift assumes you have not started yet. If you are already in it, the order matters.
First, stop adding. This is genuinely difficult, because the instinct when a project feels shaky is to fix it forwards — one more change to sort out the mess. That reliably makes it worse. Nothing new goes in until you have solid ground again.
Second, find the last state you actually understand. If you have version control, that may be a real commit. If not, it may be "the version before I added the export feature", reconstructed by hand. It does not have to be recent. It has to be trustworthy.
Third, re-establish what the software should do — not by reading the code, but by writing down the behaviour you want, from the outside. Working out what the software currently does from a drifted codebase is slow and demoralising. Deciding what it ought to do is fast, and it is the thing you will test against.
Fourth, resume in pieces small enough to check. You are rebuilding confidence rather than features, so the first few steps should be almost boringly small.
The uncomfortable part is that this often means discarding work. It usually costs less than carrying an unreliable foundation forward, and it always costs less than discovering the same problem again in three weeks.
The underlying trade
Every time you accept an unverified change, you are borrowing certainty from your future self at a poor rate of interest. Occasionally that is the right call — a throwaway prototype does not need this discipline, and treating it as though it does is its own kind of waste. Where that trade is genuinely worth making, and where it stops being worth it, is the subject of vibe coding and what it costs you later.
But for anything you intend to keep, the question is not whether you can afford to verify each step. It is whether you can afford to reach the point where you no longer know what your own software does.
Keeping increments small enough to check is the practical half of this, and it is worth understanding properly: see why the smallest useful increment beats the smallest increment. The full cycle these habits belong to is set out in the PDAID method.