Claude Code is drifting your repo. Here's how to stop it.
Claude Code is one of the best coding agents you can put on a repo, and it gets noticeably worse the bigger that repo is. On a small project it feels like it can read your mind. On a large, established codebase it starts to drift: the code it writes is correct and reasonable on its own, but it doesn't match how your team already works. A new error pattern here, a slightly different folder layout there, a helper that already exists rewritten from scratch.
This isn't Claude Code being careless. It's a built-in problem with how any stateless agent works on a large codebase, and once you see the shape of it the fixes get obvious. This post covers the Claude Code best practices that really do reduce drift, why they stop short, and the part that closes the gap.
What "drift" actually means here
Drift is when behavior changes from one stateless session to the next. Every Claude Code session starts cold. It knows the model's training, your prompt, whatever it reads during the task, and nothing else. It has no memory of the decision it (or another agent, or you) made in last week's session.
So when a convention isn't obvious from the handful of files it happens to open, Claude does the sensible thing: it picks a reasonable approach. The trouble is that "a reasonable approach" and "the approach this repo already uses" are often not the same. Each single choice is fine. Add them up and you get a codebase that quietly splits into three ways of handling errors, two ways of fetching data, and a pile of near-duplicate utilities.
Why a large codebase makes it worse
The root cause is the context window. Your conventions live across hundreds or thousands of files, and only a small slice of them fits in context at once. On a tiny repo, that slice is most of the repo, so Claude reads your style accurately. On a large codebase, the slice is a rounding error, and the convention Claude needs is usually in a file it never opened.
Three things make it worse:
- +Statelessness. A convention set in one session is invisible to the next. There's no shared memory of "we settled this already."
- +Partial visibility. Claude reasons from the files it read, and on a big repo it can't read enough to see the main pattern.
- +Plausible defaults. When in doubt, the model falls back on what's common in its training, which can be perfectly idiomatic and still wrong for your project.
Claude Code best practices that reduce drift
These are worth doing no matter what. They won't fully solve drift, but they shrink it, and they make everything downstream work better.
Keep a tight, current CLAUDE.md. A focused CLAUDE.md at the repo root is the single best thing you can do. State the conventions that matter: how you handle errors, where new modules go, what you forbid. Keep it short and specific; a bloated file gets skimmed. We go deep on this in CLAUDE.md best practices.
Scope your prompts. A prompt like "add caching" leaves every decision to the agent. "Add caching to getUser using the same Redis wrapper as getOrg" removes the guesswork that drift feeds on. The narrower the decision, the less room there is to wander.
Point to example files. Send Claude to a file that already does it right: "follow the pattern in services/billing.ts." A concrete example in context beats a paragraph of prose describing the same thing.
Review the diff for consistency, not just correctness. When you read Claude's output, ask "does this match how we already do this?" alongside "is this correct?" Drift passes a correctness review by definition, so you have to look for it on purpose.
Why best practices alone aren't enough
Here's the uncomfortable part. Everything above is a suggestion, and suggestions wear off.
- +A
CLAUDE.mdonly holds the conventions someone remembered to write down. Real codebases have dozens of unwritten patterns that live only in the code itself. - +It can't enforce itself. Nothing stops Claude from quietly deviating; the file is context, not a gate.
- +In a long session, instructions near the top of context lose pull as the window fills. The longer the task, the more the guidance fades.
- +Scoped prompts and example files depend on you already knowing the right convention and remembering to mention it, every single time.
So you get a real drop in drift and a stubborn residue of it. The practices raise the floor; they don't put in a ceiling. To actually cap drift you need the agent to check the repo's conventions on its own, from the code, while it works, without leaning on anyone's memory.
The real fix: let Claude Code check the repo before it writes
The fix is to give Claude Code a tool it can call mid-task to ask your repo what its conventions actually are. That's what the VibeDrift MCP server does. It's an MCP server built on the Model Context Protocol: a small local program that hands tools to any MCP client. Add it to Claude Code in one line:
claude mcp add vibedrift -- npx -y @vibedrift/cli mcp
It runs locally, needs no login, is free and open source, and your code never leaves your machine. It works the same in Claude Code, Cursor, Windsurf, or any other MCP client. It exposes five tools:
- +
get_dominant_pattern— what convention does this repo actually use for a given concern (error handling, data access, auth)? - +
find_similar_function— does something like this already exist, so Claude reuses it instead of writing a near-duplicate? - +
check_file_drift— does this file already stray from its peers before Claude touches it? - +
validate_change— would this specific change introduce drift? - +
get_intent_hints— what conventions has the team actually written down inCLAUDE.mdor.cursorrules?
The key difference from a CLAUDE.md is timing and grounding. The signal arrives while Claude is deciding, and it's read from the code itself, not from a doc someone has to keep current. So Claude conforms in the first place instead of guessing and hoping the diff review catches the miss. We measured that this signal changes what the agent writes when the convention is hard to infer from context, covered in does a drift checker change agent output.
CLAUDE.md rather than replacing it. get_intent_hints surfaces what you wrote down; the other tools cover the conventions you didn't. If you're weighing this against an editor's rules file, see Cursor rules vs MCP.How to stop Claude Code drift
The four moves below build on each other. The first two raise the floor, the third holds the line as Claude writes, and the last catches whatever slips through.
Catch what still slips: scan and score
Stopping drift at write-time handles the common case. To catch what gets through, run the scanner over the repo. It's a single command, runs locally in a couple of seconds, never sends your code anywhere, and is free, open source, and unlimited:
npx @vibedrift/cli .
It returns a Vibe Drift Score from 0 to 100 with a grade and a list of findings, across five detectors: architectural consistency, security posture, redundancy, convention adherence, and scaffolding hygiene. That gives you a number to watch over time and a list of the exact spots where your codebase has fragmented. For a deeper, Claude-checked pass on the findings that matter most, run vibedrift . --deep.
Used together, the loop closes: Claude Code asks the repo how it does things before it writes, and the scanner checks the result after. Best practices raise the floor, the MCP server holds the line at write-time, and the scan catches the rest.
Where to start
Tighten your CLAUDE.md today; it's free and it helps. Then add the MCP server so the conventions you didn't write down get checked on their own:
claude mcp add vibedrift -- npx -y @vibedrift/cli mcp
The full per-client setup lives in the MCP guide, and if you want to see how the free and paid tiers line up, the pricing is on the homepage. The local scan and the MCP tools are free forever; Pro adds in-editor deep checks, watch mode, and a git pre-push gate when you want drift caught before it lands.
Frequently asked questions
Each Claude Code session is stateless and your repo's conventions are too large to fit in the context window. So when a convention isn't obvious from the files Claude happens to read, it makes a reasonable but different choice. Repeat that across many sessions and the codebase slowly fragments into several competing styles.
It helps a lot, but not completely. A CLAUDE.md captures the conventions you remembered to write down. It can't cover every pattern in a real codebase, it can't enforce itself, and a long enough session will push it toward the edge of the context window where its influence fades. It reduces drift; it doesn't eliminate it.
It gives Claude Code local tools to ask your repo what its actual conventions are before it writes: the dominant pattern for a given concern, whether a similar function already exists, and whether a proposed change would introduce drift. Because the signal arrives mid-task, Claude conforms in the first place instead of guessing.
Yes. The MCP server runs locally, needs no login, is free and open source, and your code never leaves your machine. The same is true of the local scanner. Only the optional deep semantic check draws from your deep-scan budget.
Local scans and the MCP tools are free and open source, forever. The free tier includes 1 deep scan a month; Pro is $15/mo for 12, and you can top up 5 more for $10 on any plan. Credits never expire.