Your AI Agents Have a Rules File. They Don't Have a Model of Your System.

Open the CLAUDE.md, AGENTS.md or .cursor/rules file at the root of your repository and read it the way it reaches an agent: as one block of text, with nothing in it marking which lines are still true.

Most of what you'll find is conventions. Use tabs. Don't use any. Return early. Wrap errors with %w. Those lines are durable, because they describe how to write a line of code, and the agent applies them to the code in front of it.

Then there's the other kind of line. The kind that describes your system: what services exist, which package owns what, how the layers are allowed to talk to each other. Those lines are why the file is worth having, and they are the ones that rot.

I know, because ours did.

What went stale in ours

Archyl's repository has a CLAUDE.md at the root. It's a good one by the standards of the genre: 422 lines, an architecture tree, the config variables, the dependency injection wiring, a description of the discovery pipeline. Every agent that touches this codebase reads it before it does anything else.

Here is what it said on the morning I wrote this, 5 August 2026. Line 392:

No test suite: The codebase currently has no Go test files or frontend tests.

There are 146 _test.go files under backend/ and 31 test files under frontend/src/.

Line 140 says:

AI Provider Abstraction: Supports both OpenAI and Ollama via ai.Provider interface.

backend/internal/adapter/ai/resolver.go routes to OpenAI, Anthropic, Gemini, Bedrock and any OpenAI-compatible endpoint, on top of the platform-managed OpenAI and Ollama path. Five provider types in one switch statement. The file names two.

And the architecture tree, at lines 74 to 87, lists eleven packages under internal/domain/: c4, project, user, team, adr, projectdoc, flow, insight, subscription, dependency, history. There are forty-one directories in internal/domain/ today. Among the thirty it doesn't mention: conformance, drift, apicontract, marketplace, reality, managedagent, mcpsession. Which is to say, most of what the product has become since the file was written.

Every one of those lines was true the day it was typed. None of them was corrected afterwards, because correcting them requires a person to notice, and nothing was watching.

This is a company that sells architecture documentation. If discipline were the fix, it would have worked here.

The two halves of that file have nothing in common

The conventions half is enforceable. "No fmt.Println in Go" is a grep. "Go files must be snake_case" is a script. If an agent violates one, a linter says so in CI. If the convention itself changes, the linter starts failing and somebody updates the file. There's a feedback loop, and it's short enough to work.

The system half has no equivalent. There's no go vet for "the payment service is off-limits for direct database access". Nothing parses that sentence, nothing compares it to the repository, nothing fails when it stops matching. It's prose in a markdown file, and prose has no failure mode.

So a rules file is two documents sharing one filename. One is verified continuously, the other is verified never, and nothing in the file distinguishes them. "Wrap errors with %w" and "the codebase has no tests" sit in the same list, in the same voice. One is a rule about the code in front of the agent. The other is a claim about 146 files it isn't looking at.

Absence is the harder half

Staleness is the failure everyone can picture. The quieter one matters more: a rules file contains only what somebody thought to write down, and nothing in it distinguishes "this doesn't exist" from "nobody mentioned it".

Ours never mentions internal/adapter/marketplace/. That package holds a provider interface and eight adapters: GitHub, GitLab, Argo CD, Datadog, Prometheus, Sentry, SonarQube, PagerDuty. The adapter list in CLAUDE.md stops at git, ai, stripe, email, osv and registry. Nothing the file says about the marketplace is wrong. The file doesn't have one.

I haven't run the experiment of asking an agent to add a ninth integration, and I'm not going to tell you what it would produce, because I'd be inventing the result. What I can tell you is that the map has no marketplace on it, and that this is the ordinary condition of every rules file I've read, including the ones I wrote.

A model doesn't have that property. You can ask a model what exists and get an answer that means something, because the answer is a query over a set rather than a search through prose. "What talks to the payment service" is a question a graph can answer and a paragraph cannot.

The two obvious answers, and why neither holds

Write a better rules file. Longer, more careful, a checkbox in the PR template. Teams do this, and it works for a few weeks. It doesn't hold, for a reason unrelated to discipline: every line describing the system is a cached copy of something that lives elsewhere, and caches need invalidation. Here, invalidation is a human noticing. That's the entire mechanism, and it's the same one that was supposed to keep architecture diagrams accurate for the last twenty years. We know how that went; the drift detection guide is the longer version of that argument.

Let the agent read the repository. It can, and for a question about one file it should. But reading the code doesn't tell you which boundaries were deliberate. The interface in front of a service looks identical whether it's there because of a decision made two years ago after an incident, or because somebody likes interfaces. Intent isn't recoverable from the artifact that resulted from it. That's why the rules file exists in the first place, and it's why deleting it isn't the answer either.

Somebody outside this company noticed the same thing

Thoughtworks put "Architecture drift reduction with LLMs" in the Assess ring of Technology Radar Vol. 34, published April 2026. Their opening:

Increased use of AI coding agents can accelerate drift from the intended codebase and architecture designs. Left unchecked, this drift compounds as agents and humans replicate existing patterns, including degraded ones, creating a feedback loop where poor code begets poorer code.

Assess, in the radar's own definition, means "worth exploring with the goal of understanding how it will affect your enterprise". It is not a recommendation of anything, and certainly not of us. It's a note that some of their teams are trying this and that it's early.

The useful part is the shape they describe: deterministic analysis tools (they name Spectral, ArchUnit and Spring Modulith) combined with LLM evaluation, because structure is checkable by a program and intent is not. Their reported lesson is worth stealing too: the first scan surfaces more violations than anyone wants to triage.

Notice what isn't in that recipe. Nobody's answer to agent-accelerated drift is a longer markdown file.

What the artifact would have to do

Two properties. Neither is exotic.

It has to enumerate. You should be able to ask what exists and receive the set, not somebody's recollection of it. That means an artifact you query rather than read, and the difference shows up hardest on the questions nobody wrote down.

It has to be falsifiable. Something must compare it against the code and report which parts stopped being true, on a schedule that isn't "when a human notices". ArchUnit does this for Java layer rules. dependency-cruiser does it for JavaScript imports. Both are deliberately narrow, and both make the point: the artifact worth having is one a program can disagree with.

A rules file fails both. It doesn't enumerate, and nothing can disagree with it.

Where we sit, and what I can't tell you

Archyl maintains a C4 model of your system: systems, containers, components, relationships, generated from the repository by AI discovery and approved by a person rather than drawn by one. That model is the enumerable half, and agents reach it over MCP, 181 tools' worth, so an agent asks what exists instead of hoping somebody wrote it down. The conventions half is a conformance catalog: 169 rules across 23 named technologies plus a language-agnostic set, deterministic checks rather than prose. And the model is re-checked against the code and scored, which is the falsifiability property.

Having an MCP server is not the interesting part, and anyone selling you one as a differentiator is selling you a socket. Structurizr ships one and IcePanel's is in open beta. The question worth arguing about is whether the thing behind the socket is maintained, because an endpoint serving a model that went stale in March is a faster way to be wrong.

I think that's the difference that matters. I can't prove it. Nobody has measured whether an agent working from a maintained model writes better-shaped code than an agent working from a careful rules file, and until somebody does, that sentence is a claim about a mechanism, not a result. Hold it that way, and push back on anyone who states it flatter than I just did.

There's an honest wrinkle here too. Archyl generates a rules file. The get_agent_context MCP tool returns the architecture as a markdown briefing you can commit to your repository, which is a rules file by another name. The file was never the problem. The problem was that nothing stood behind it, so nothing could regenerate it. A rules file that's a cache of a maintained model is fine. A rules file that's the only copy is a snapshot of what one person believed on one afternoon.

The five-minute version, which costs you nothing

Ignore everything above and do this instead.

Open your rules file. Go line by line and mark each one as either a convention, meaning it tells the agent how to write code, or a claim, meaning it tells the agent something about your system. Then, for every claim, write down what would tell you it had stopped being true.

My guess is you'll reach the end of the file with an empty second column. That's the gap. What you do about it is a separate decision, and you don't have to buy anything to see it.

Ours took a few minutes and turned up three wrong lines. Fixing them is one commit, and it changes nothing structural: the next line will go stale the same way, and nothing is watching that one either.