rock-101
«Create an exact copy of this image, don't change anything» 101 times in a row. Author: u/Foreign_Builder_2238, r/ChatGPT, April 2025

A person asked ChatGPT to create an exact copy of an image and not change anything. He provided a real photo of Dwayne Johnson. With each iteration, the image changed beyond recognition until it became a cartoon mess. On every step, he kept asking not to change anything.

The same goes for code. You told the AI which fonts to use, and it uses the same font. But the sizes vary: each page has its own font size. As a result, the overall site style is lost.

This is architectural drift. I gave an example with the frontend as the simplest for understanding, but the principle applies to all other development areas as well. The main problem is that the source of truth is scattered.

I don't read code at all. I control only the specs. Below, how to fix drift in agent-based development.

Architectural drift is treated with three principles. The truth is not in the code, but in the documentation (specs).

  1. Single source of truth is defined by the specs.

  2. The AI must first read the specs associated with the task before executing it.

  3. Spec-tests deterministically check the code against the documentation.

scheme-v3-crop
Single source of truth is defined by the specs → The AI reads the specs before the task → Spec-tests check the code

1. Single source of truth is defined by the specs

Truth is not in the code

How do we solve the drift problem? Using the principle of single source of truth. The truth is in one place. And this truth is not in the code, but in the documentation.

Why is the truth in the spec, and not in the code? Here is an architectural principle: the spec acts as a blueprint, and the code is the detail that is carved according to a pre-existing blueprint. The detail is checked against the blueprint, not against another detail. If there are two sources of truth in a project, it leads to chaos and bad code.

7 thousand documents, and this is not a mess.

All the documentation is in one folder called docs at the root of the project. Right now there are more than 7 thousand documents in it, and each is in its own place. This is not a mess, but a structured folder with ten levels of nesting, where in each folder there are no more than seven files in 90% of cases. I structure it according to the rule of 7 plus or minus 2: in each folder, there are no more than nine objects related to key entities. Therefore, I know exactly where everything is.

docs folder on November 5, 2026

files.md

7 478

levels of nesting under docs

11

folders with no more than 7 files

95,3%

folders with no more than 9 files

97,4%

The spec itself is just a .md file, in which it is written what is what. The spec is written by agents. Agents also read it. As a user, I read the admin panel: each specification has its own page in the admin panel, where everything is written the same way, but in a more user-friendly format.

PLACEHOLDER-spek-md
Typography specification as a file: role table, on the left a folder tree with 17 brand base files
PLACEHOLDER-admin-tipografika
The same specification in the admin panel: role, family, size (desktop · mobile), weight, color, and live sample of each row. Screen 2 November 2026

One file typography.md

On the example of fonts. All typography rules are in one file typography.md: all fonts, sizes, and colors, as they appear on the site.

Excerpt from the typography.md registry, in the full table there are 22 roles:

@@TAG20 7@@

role

family

size (desktop · mobile)

weight

color

H1 cards

Inter

52/56 · mobile 34/38

700

#111111

H2 articles

Inter

38/45 · mobile 28/32

700

#111111

article lead

Charis

27/35 · mobile 23/30

400

#111111

paragraph of the article

Charis

21/30 · 25px margin

400

#111111

base

Inter

14/21

400

#8A8A8A

meta

Inter

13/19

400

#8A8A8A

caption

Inter

12/18

400

#8A8A8A

Two families for the entire site: Charis for long reading, Inter for everything else. Only weights 400 and 700. (From the same specs: "there are no states outside the registry: new link = new line by verdict.")

When an agent works on a particular part of the problem, he has a specific folder containing the necessary documentation. Because each document is in its place, the agent can easily make sure that nothing in the folder contradicts the intention. The agent keeps track of ensuring that specs are consistent and nothing in them contradicts each other.

2. The AI reads the specs before the task

He needs to be made to read the required document, and this is specified in the base document AGENTS.md. There are rules: he must read the docs that correspond to the task. When I need to make a change on the site, the agent will first always read the folder with the original documentation, and in 9 out of 10 cases won't break the rules.

For example, I see that cloud costs have flown away, and I set a task to conduct an audit, figure out what can be trimmed. The agent should go and read all the cloud documentation. He will see that there is a separate folder directly under this, see all cloud providers and analyze them.

From AGENTS.md, as is:

agents-md-v2
Lines 19–22 and 541–556: reading order and three principles of Spec-Driven

3. Spec-tests check the code

Specs and admin are in an indeterminate plane: there is a probability that the agent follows examples or doesn't follow them. On the tenth case, we have spec-tests. We write a test based on the spec. The spec lists allowed font sizes, and the spec-test checks that other sizes don't pass through the site. If we release something on the site that doesn't pass the spec-test, it doesn't pass.

The test reads two tables from typography.md, collects allowed font pairs from the "size" column, and traverses the entire frontend. A pair or size not in the spec fails the build with the filename and line number:

spek-test-v2
lib/brand-type.test.ts after November 6th, as is: a white list of font pairs and sizes from typography.md

Before November 6th, this test was a blacklist of nine deprecated pairs. When I prepared this article, it turned out that there are about 150 pairs outside the spec in the code. For one run, the agent matched 637 usages to the spec, added 4 missing lines, and rewrote the test into the whitelist.

red-run
The same test, run on the code before the cleanup on November 6: 637 usages of font sizes outside the spec, red build

when

what came from the agent

what the test did

how it ended

October 1, 2026

price cards on the service page with font size pairs 14/20 and 12/16

red build: "displaced font size pair"

font size pairs replaced with 14/21 and 12/18 from the spec, commit 1797f67

When the doc and code diverged

When the doc and code diverge, three things come into play. First, the testing phase, which should catch the problem. Second, self-heal, which will catch the problem already on production. There will be a separate article about it. If the first two didn't work, I step in as a human. My task is not to catch the problem, but to understand why this error passed, and to make sure it doesn't pass again next time.

It often happens that the spec existed, but the agent did it his own way. Usually, this is because the agent didn't read the relevant spec. For this reason, we have strict rules to make him read. Sometimes, however, you have to directly point him to the right spec.

In short

One of the main goals of the entire approach: having a single source of truth. And how we inform this with spec tests is exactly how we solve the problem of architectural drift.

The term is not new: Perry and Wolf introduced architectural drift / architectural erosion in 1992 in the article Foundations for the Study of Software Architecture. With agents, it was reborn: The Spec Growth Engine, October 2026. On Habr: «What to do with architectural drift in the era of AI?», April 2026.

Where is your source of truth: in the code, in the docs, or in your heads? Write in the comments which one drifted first.