Livemark

Guides

How to stop coding agents drifting from your architecture

Coding agents copy what they see in the code. Write down the decisions they can't see, with reasons, where they read them, and test the ones that matter.

By ·

A coding agent drifts from your architecture because it copies what it can see in the code, and the decisions behind an architecture usually aren't there. To stop the drift, write those decisions down where the agent reads them, give each one its reason, test the ones that must never break, and agree on the plan before the agent builds.

  1. List the decisions the code doesn't show.
  2. Write each one with its reason.
  3. Put them where the agent reads them.
  4. Back the rules that must hold with a test.
  5. Agree on the plan before the agent builds.
  6. Turn every drift you catch into a rule.

Why agents drift

An agent works from the files it opens, its instructions and the code nearby. Where the code shows a convention, the agent follows it. Where a decision was made for a reason the code doesn't show, in a meeting or after an incident nobody wrote up, the agent does whatever looks reasonable, and that's often what you decided against.

Long sessions make it worse. Anthropic's Claude Code documentation warns that as the context window fills, Claude "may start 'forgetting' earlier instructions or making more mistakes."

Step 1: list the decisions the code doesn't show

Start with what a capable new hire would get wrong in their first week, even after reading the code. These are usually decisions made for a reason outside the code. Here are two from the repository I build Livemark in, with coding agents.

The document text in Livemark's database is only a copy. The live document sits with a hosted real-time sync service, and the database copy is refreshed about once a minute. Anything that acts on a document's content reads the live version. An agent that reads the database column, which is right there on the model, works from text that may be a minute old.

Livemark also has no bulk pruner for documents. A pruner built on Laravel's mass-prunable feature deletes through the query builder and fires no model events, so it would skip the hook that deletes a document's collaboration room. The room, with the document's text and comment threads, would stay in the sync service after the document was gone.

Leave out what the agent can work out for itself, like the directory layout or the framework's conventions. A 2026 study from ETH Zurich found that context files did not generally raise coding agents' success rates, added over 20% to cost, and gained nothing from overviews of the repository. The authors concluded the files are useful for describing non-standard practices. Claude Code's documentation suggests asking of every line, "Would removing this cause Claude to make mistakes?" If not, cut it.

Step 2: write each one with its reason

When Michael Nygard proposed architecture decision records in 2011, he pointed out that someone who inherits a decision without its rationale has two choices: "Blindly accept the decision" or "Blindly change it." An agent is in that position at the start of every session.

Here is one of my rules, word for word from Livemark's CLAUDE.md:

- **Never let Eloquent touch a binary column.** `content_yjs` and
  `snapshot_yjs` go through `HasBinaryColumns` (`writeYjsState()`,
  `yjsState()`, `snapshotBytes()`). Eloquent binds bytes as text: PostgreSQL
  rejects the write, and a bytea read back is a stream whose second read is
  empty — which merges real documents away. The SQLite test suite cannot catch
  this; `tests/Drivers` (run with `DB_DRIVER_TESTS=pgsql`) can.

It names the rule, the helpers to use instead, the reason and the test that enforces it. The rule lists two columns. If a third binary column is added, the reason tells the agent the rule covers that one too, because Eloquent would bind its bytes as text the same way.

Step 3: put rules where the agent reads them

Coding agents read an instruction file at the start of each session, CLAUDE.md for Claude Code and AGENTS.md for Codex and the other tools that adopted it. Claude Code reads AGENTS.md only when a repository has no CLAUDE.md, so if you use both agents, keep the rules in AGENTS.md and put an @AGENTS.md line in CLAUDE.md to import them. Put the rules that apply everywhere in that file and keep it short. Claude Code's documentation warns that "Bloated CLAUDE.md files cause Claude to ignore your actual instructions!"

Most rules apply to only a few files, so scope them. Claude Code loads a rule file under .claude/rules/ only when it works on files that match the rule's paths list. Codex joins the AGENTS.md files from the repository root down to the directory it's working in. Use those where you can. I keep Livemark's rules in a .ai/rules folder that no agent loads on its own, so an index maps each rule file to the paths it covers:

CLAUDE.md                    rules for everything, and how to find the rest
.ai/rules/index.md           which rule file covers which paths
.ai/rules/concerns.md        rules for app/Concerns/HasBinaryColumns.php
.ai/rules/collab-server.md   rules for collab-server/**
                             (64 rule files in all)

CLAUDE.md tells the agent to open the index before it plans or edits anything, and to read every rule file whose paths cover the files it's about to touch. Nothing forces the agent to follow that instruction, so the rules that matter most also have tests.

If you already keep architecture decision records, don't copy them into the instruction file. Put a short rule in the scoped rule file for the code the decision governs, and point it at the record. Say your billing code stores money as integer cents and the reasoning is in a decision record. For Claude Code, the rule goes in .claude/rules/billing.md:

---
paths:
    - 'src/Billing/**'
---

- Store amounts as integer cents, never floats. Why, and what we
  rejected: docs/decisions/0012-money-as-integer-cents.md

The agent sees the rule whenever it opens a billing file and can read the record when a change touches the decision.

Keep hand-written rules out of generated files. Part of Livemark's CLAUDE.md is regenerated by a package on update, and one update wiped out a section of my own rules that had been sitting inside that block.

Step 4: back the rules that must hold with a test

An instruction file can't make the agent do anything. Claude Code's documentation says so directly: "Unlike CLAUDE.md instructions which are advisory, hooks are deterministic and guarantee the action happens." A rule that must never break needs something that fails when it's broken, like a test, a lint rule, a hook or a CI check. Have the agent run those checks before it says it's done. The same documentation puts it as "If you can't verify it, don't ship it."

The binary-column rule exists because the bug reached a browser before any test caught it. Livemark's test suite runs on SQLite, which stores any bytes in a text column without complaint, so no test could see what PostgreSQL would refuse. A separate set of tests now runs against a real PostgreSQL server in CI. If the server can't be reached, those tests fail instead of skipping, because a silent skip would hide the problem again.

Test the rules where a mistake loses data, breaks production or slips past review easily. Leave the rest as written rules.

Step 5: agree on the plan before the agent builds

For anything bigger than a small change, have the agent write a plan first, in Claude Code's plan mode or your agent's equivalent. Whoever owns the decisions approves it before any code is written. For small changes, Claude Code's documentation says, "If you could describe the diff in one sentence, skip the plan."

A plan lets a person make the decisions the rules don't cover, before the agent makes them halfway through a change. By the time a design problem shows up in a diff, the agent has already built on it. Keep each change small enough to review, and when a plan settles something new, add it to the rules.

I write these plans in Livemark. A spec there is marked Approved once each reviewer named on it has said Ready, and the coding agent reads the approved version over MCP. Decisions that aren't written down anywhere else go in as memories, which the agent can search the same way. The rules and tests still live in the repository.

Step 6: turn every drift you catch into a rule

You'll still catch drift in review. When the agent couldn't have known better from what it was given, write the rule and its reason in the same change as the fix, and add a test if the rule must hold. That's how Livemark's rules grew. I started keeping rule files in August 2026, and by the end of September they had changed in 164 commits. All but five of those commits also changed code.