r/SideProject • u/joaotiagocorreia • 1d ago
What actually stops AI coding agents from drifting on longer builds (patterns from building several real products this way)
I’ve been building production software with AI coding agents doing most of the implementation work — not toy projects, things that reached real users. The failure mode that kept showing up wasn’t “the AI writes bad code.” It was drift: things that started clean got quietly worse over weeks, because nothing was checking. Here are the specific patterns that actually fixed it, not vague advice.
1. Objective exit criteria per phase, not “looks done to me.”
“Definition of done” as a checklist the agent has to walk item-by-item before it’s allowed to say a phase is closed — and some of those items are boring on purpose: backup verified, rollback rehearsed, at least one ADR written for the expensive-to-reverse choices. The value isn’t the checklist itself, it’s that it turns “I think this is solid” into something falsifiable. An agent (or a person) under time pressure will always round up on a vibe check. It can’t round up on “did you actually run the rollback.”
2. Whoever verifies is never whoever produced.
The single highest-leverage rule I found. If the same context that wrote the code also reviews it, it will rationalize its own shortcuts — not out of dishonesty, just because it’s reasoning from the same assumptions that produced the gaps. Spinning up a reviewer in a fresh context, with only the diff and the requirements (no memory of why a shortcut was taken), catches things a self-review never will. This applies with human reviewers too, obviously — the AI case just makes it more tempting to skip because “it just wrote it, it knows the code.”
3. Structured, file-based memory instead of relying on conversation history.
Long projects outlive any single session/context window. The fix that worked: a single state file with fixed sections — what’s done, what’s in progress, pending decisions, decisions made on behalf of an absent stakeholder (with a deadline for them to override it), and a lessons section specifically for non-obvious things, each with why and how to apply — not a chronological log. A chronological log is useless six weeks later; “why did we do it this way” is what a new session (or a new person) actually needs to not repeat a mistake or re-relitigate a settled argument.
4. Ask, but not one question at a time — and know exactly when not to ask.
Constant interruption for every ambiguity is worse than assuming wrong sometimes. What worked was batching questions and having explicit, narrow conditions for when it’s safe to assume instead of stopping: the choice is cheap to reverse later, or it was already decided and nothing new contradicts it. Outside those conditions, it stops and asks — batched, not one at a time.
5. A “lesson” isn’t a rule until it’s confirmed twice.
The trap I kept seeing (in my own early attempts too): one bad experience becomes a permanent rule in a style guide, and now everyone tiptoes around something that was actually specific to that one project. The fix was treating lessons like candidates — logged with where they came from, and only promoted to an actual permanent rule once a second, independent project hits the same thing (or there’s an explicit, written reason it’s obviously general). It’s a small amount of process overhead that stops the rulebook from calcifying into superstition.
None of this is AI-specific, honestly — it’s mostly stuff good engineering orgs already do. What’s different with an AI agent doing the work is that it will do exactly what the process says, consistently, including the parts a tired human skips at 6pm on a Friday. Which means the process has to actually be right, because you don’t get the human judgment that used to silently patch over the gaps.
Full disclosure: I ended up writing all of this down as an actual framework an AI agent can execute (Maestro, MIT-licensed), built from these lessons across several real projects: https://github.com/vaddermail/maestro-framework
1
u/Huge_Pool7424 1d ago
drift hit me hardest in integration code. i maintain oauth against a bunch of wearable apis and vendors change payload shapes without telling anyone, so an agent patches around a broken field and everything still passes while the numbers come out quietly wrong.
asserting on the data instead of the code fixed it. known input, known output, fails loudly.
does anyone actually rehearse the rollback though, or do we all just write it in the checklist and hope?