Blog · September 1, 2026
Get the Architecture Out of Your .md Files
AI agents need an architecture model, not more markdown.
There's a new genre of file at the root of every repository: CLAUDE.md, AGENTS.md, .cursorrules. And buried inside the build commands and style conventions, you'll find the load-bearing part: prose describing the architecture. Which services own which data. What talks to what, and through what. Which patterns are mandatory and which are forbidden.
That architectural content is doing governance work. And prose is the wrong instrument for governance.
To be clear about scope: your readme isn't going anywhere. Build commands, dev setup, naming conventions, PR etiquette — markdown is fine for all of it, because none of it needs to be enforced. The problem is the paragraphs that were pretending to be controls.
Three reasons architectural prose fails
Agents deprioritize it. A markdown file competes for attention with everything else in the agent's context window: the task, the code it just read, the error it's chasing. Under context pressure, your architecture rules lose. Not maliciously; probabilistically. Guidance that holds 95% of the time isn't governance. It's a coin you flip on every change, and agents make hundreds of changes a day.
It drifts. The markdown says the payment service talks to the ledger through a queue. The codebase, eighteen months and four teams later, says otherwise. Nothing flags the gap, because nothing connects the prose to the code. Every architect who has maintained a wiki knows how this ends — except the stale document is no longer misleading a new hire once a quarter. It's misleading an agent on every task.
It's unverifiable. Here's the question that breaks the whole model: given a proposed change and a paragraph of prose, is the change compliant? No procedure answers that. You can ask another LLM for an opinion — and now your governance layer has the same failure modes as the thing it governs. Non-deterministic checking of non-deterministic output isn't a control.
It's vibes reviewing vibes.
We spent two decades learning this lesson in infrastructure. Nobody governs cloud environments with a runbook that says "please keep the databases encrypted." We declare the desired state in code and let machines enforce it. Then AI agents arrived, generating changes faster than any human team ever could, and our answer was a README with rules in it.
Where the architecture should live: FINOS CALM
The right home already exists as an open standard. CALM — the Common Architecture Language Model, from FINOS — describes architecture as structured, machine-readable data: nodes, relationships, flows, and controls. Not a diagram exported to PNG. Not a paragraph of intent. A versioned artifact that lives in the repo, gets reviewed like code, and can be validated against.
That last property is the whole point. A CALM model isn't documentation about the architecture — it is the architecture, in a form a machine can check a change against.
And the checking is done by operators, not opinions. The model enforces on two levels. Topology says what may talk to what: payment reaches the ledger through a queue, and that's a declared relationship, not the sentence that drifted for eighteen months, two sections ago. Controls sit on top and assert attributes: this resource type, this field, this value, authored by your architects against your own control catalog. Both are evaluated the same way on every proposed change. The change that introduces a direct call doesn't get reviewed by opinion. It gets violation.
A RELATIONSHIP, NOT A SENTENCE
"relationships": [
{
"unique-id": "payment-to-settlement-queue",
"description": "Payment service publishes settlement events",
"protocol": "AMQP",
"relationship-type": {
"connects": {
"source": { "node": "payment-service" },
"destination": { "node": "settlement-queue" }
}
}
},
{
"unique-id": "settlement-queue-to-ledger",
"description": "Ledger consumes settlement events",
"protocol": "AMQP",
"relationship-type": {
"connects": {
"source": { "node": "settlement-queue" },
"destination": { "node": "ledger-service" }
}
}
}
]
Guidance and enforcement must derive from one model
A model alone is still just better documentation. The loop closes when two things derive from it:
Guidance. Before an agent writes a line of code, it queries the model: what does this service connect to? Which controls apply to the node that owns this file? What breaks upstream and downstream if I change it? The agent isn't skimming prose and hoping, it's reading structured context from the source of truth. Prose doesn't disappear here; it gets generated from the model instead of hand-maintained beside it. The difference is provenance, and provenance is what keeps it from rotting.
Enforcement. The change is then evaluated against the same approved model. A proposed call from payment to ledger that was never declared isn't a judgment call. It's a violation, with the control named. Not a repo-wide scan, not a quarterly review: every change to governed code, judged when it's proposed, whether an agent wrote it or a human did.
This is what ArchRails does, and the ordering matters: the context an agent receives and the gate that judges its output derive from one model, so guidance cannot drift from enforcement. When they come from different places — as they always eventually do when one is prose and the other is a linter someone bolted on — agents learn to satisfy the gate and ignore the guidance. When they share a source, complying with the guidance is passing the gate.
And when a change is blocked, the response isn't a bare failure code. The agent learns which control fired, why it matters, and what to change; so the next attempt converges instead of thrashing.
Blocking isn't the same as stopping work
The objection every engineering leader raises next:
Won't this just stall my team?
No — because blocked isn't the end of the path.
A developer can authorize the change anyway, in their own words. The code gets written. The finding still stands, and nothing is reported as approved that wasn't.
That's the difference between a guardrail and a gag. Deliberate exceptions stay possible; silent ones stop being possible. Which is precisely the trade auditors have been asking for.
The stakes are different now
Pre-AI, architectural drift happened at human speed, and architecture review boards could almost keep up. Agents drift at agent speed. If your architecture lives in advisory text, you've chosen to find out about violations after they've merged, multiplied across every repository an agent touches. For any organization where architecture is a concern — not just a preference — that's not a tooling gap. It's a control gap.
Keep the markdown for what markdown is good at. Move the architecture into a model.
Declare it in CALM. Enforce it with ArchRails.