When code drifts out of date, something tells you: a compiler error, a failing test, a 500 in the logs. When the instructions your AI agents read drift out of date, nothing flags it. The agent reads the stale sentence, quietly works around it — or worse, obeys it — and the session looks fine.

Agents handle much of our day-to-day platform work, steered by a project instruction file, a generated per-client context file, prompt templates for every workflow stage, and nineteen skill playbooks. This week we audited all of it against the actual code. In a codebase we'd call well-maintained — conventional commits, generated changelogs, docs that get edited — we found roughly forty verified divergences. A handful were the dangerous kind.

The rot has a shape

Reading forty findings side by side, they sorted into four patterns.

Renames outlive themselves. Modules had been renamed, a test file had moved into a package, an app had been deleted — and the instruction files still pointed at the old names. Our favourite: one section of the project doc mandated the new test layout while another section cited a file by its old, pre-layout name. Both sentences had been true — just never at the same time.

The architecture moved on; the playbook didn't. Months ago, edits went directly into the generated site files. Then we shipped an assembler: sources in one folder, generated output in another, output overwritten on every build. Three skills never got the memo — one still instructed the agent to edit the generated output directly. Every image the agent placed that way survived exactly until the next build, then silently vanished. Nobody saw an error, because losing work by overwriting it isn't an error.

Docs claim guards that don't exist. A module docstring assured readers that a named test kept two files reconciled "byte-for-byte". The test had never been written. The two files had, of course, drifted — that's what happens where the claimed guard is imaginary.

Copy outlives the feature. Our WhatsApp bot promised customers a "free 1-page demo site" in four places, weeks after the build had become multi-page. And inside one system prompt, one paragraph said ask one question at a time while an earlier paragraph said a couple of related things in one sentence is fine — the model got pulled both ways, turn after turn.

Why nothing ever fails

Prose has no compiler. A wrong path in code throws; a wrong path in an instruction file just makes the agent search, shrug, and improvise. That improvisation is the trap: agents are good at working around wrongness, so stale instructions don't produce loud failures — they produce slightly worse behaviour everywhere: an edit applied to the wrong file, a customer promised the wrong thing, minutes burned re-discovering what a sentence could have said.

The habits that keep code honest — review on the diff, tests on the behaviour — don't naturally cover the instruction layer, because the person renaming a module gets no failing signal pointing at the six prose files that mention it.

What we did about it

Audit with a drift checklist, not a vibe. We ran three review agents in parallel — one per set of files — each armed with a list of things that recently changed: renamed modules, deleted columns, retired policies, moved files. That checklist is the whole trick. "Review these docs" finds typos; "these ten things no longer exist — find every reference" finds rot.

Pin claims with tests where code can check them. Our per-client context file is generated from the database, so we added a test that renders it for each stage of a project and asserts the rules that matter are actually present — the imaginary guard from earlier, made real. Now if the generator and the product definition disagree, something finally fails.

Move rarely-needed detail out of the files agents read every time. Every line in a file the agent loads on every run adds tokens to every run. Our eight-step "add a billing currency" checklist lived there for months and mattered maybe twice a year — it moved to the payments doc, with a two-line pointer left behind. Smaller file, less to rot, less to pay for.

Prefer generated over hand-written. The file that came through the audit cleanest was the one rendered from live state on every save. Generated files drift far less because they stay tied to what's actually true; hand-written ones are drifting right now.

The takeaway

Instructions are code that runs on a very forgiving interpreter. The forgiveness is the problem — nothing red ever appears. If agents do real work in your codebase, put a date in the calendar and audit the words they read against the code they touch. Ours took an afternoon and closed three ways to silently lose customer work. We'd do it quarterly even if it found half as much.