DEV Community

untactit
untactit

Posted on • Originally published at untactit.com

AGENTS.md was supposed to end the sprawl. I counted the files on one laptop.

AGENTS.md solved the format argument. Codex CLI, GitHub Copilot, Cursor, Windsurf, Amp and Devin
all read the same file now. Claude Code still reads CLAUDE.md, Gemini CLI still reads GEMINI.md,
and that exception list keeps getting shorter.

The format was never the expensive part.

I scanned one working laptop this morning. Nothing exotic — one developer, a few years of projects,
the normal agent tooling:

file copies on disk distinct contents
AGENTS.md 111 19
CLAUDE.md 38 19
GEMINI.md 2 2
SKILL.md (agent skills) 3,073 887

Method: find ~ -maxdepth 7 -type f -name <X>, pruning node_modules, .venv*, site-packages
and Library/Caches. "Distinct contents" is the count of unique md5 hashes. Vendor-installed skill
bundles are included in the SKILL.md row, which is exactly the point — they are on the machine and
an agent can read them.

111 files. 19 different things being said.

Nested files are a feature. A monorepo should scope instructions per package, and the spec says so.
But 19 distinct contents across 111 copies is not scoping. That is copy, edit one copy, forget.

Where the copies come from

1. The hand copy. You write a rule you like. You paste it into the next repo. Six months later you
fix a typo in one of them. Every other copy is now wrong and nothing tells you.

2. The machine boundary. Global config lives outside every repo: ~/.claude/CLAUDE.md,
~/.gemini/GEMINI.md, ~/.config/opencode/AGENTS.md. Two laptops, two versions, and the difference
surfaces as "it behaves differently on my machine" three weeks later.

3. The generator. The common fix is to keep one source file and generate the rest —
AGENTS.mdCLAUDE.md.cursor/rules/*.mdc.github/copilot-instructions.md. It works on
the day you run it. It does not survive the next person who edits a generated file directly, because
nothing on disk marks a file as generated, and nothing checks.

I wrote about that failure mode separately:
Generating your agent rules from one file does not stop them drifting.

Where each agent actually looks

Worth having in one table, because the paths are the thing people get wrong:

tool file it reads
Claude Code CLAUDE.md (project root, subdirectories, ~/.claude/), .claude/skills/*/SKILL.md, .claude/agents/*.md
Codex CLI AGENTS.md (root + nested, nearest wins)
GitHub Copilot .github/copilot-instructions.md, scoped .github/instructions/*.instructions.md
Cursor .cursor/rules/*.mdc (legacy .cursorrules)
Windsurf .windsurf/rules/*.md (legacy .windsurfrules)
Gemini CLI GEMINI.md (~/.gemini/, workspace root, subdirectories)
opencode AGENTS.md, falls back to CLAUDE.md, global at ~/.config/opencode/AGENTS.md

A script that shows you the spread

agent-drift is a single-file Python script, MIT, no dependencies. It walks a tree, finds every
instruction file the agents above read, groups them by content hash and prints the ones that disagree.

curl -O https://raw.githubusercontent.com/untactit/agent-drift/main/agent_drift.py
python3 agent_drift.py ~
Enter fullscreen mode Exit fullscreen mode

Repo: https://github.com/untactit/agent-drift

It does not fix anything. It tells you how bad it is, which is the part most teams are missing —
you cannot argue for a process change without a number.

What we are building

I work on untactit. One place to hold the skills, rules and memory your agents
run on, review a change once, and have it land in every target without anyone opening a file.

The distinction that matters: a person decides what gets approved. Nothing after that is touched by
hand.
Drift is not something we repair afterwards — it stops being produced, because nobody is
editing copies any more.

It is pre-launch. The scanner above is useful without it, and that is deliberate.
If you want the longer version of the argument, it is on the
product page.


If you run the scan on your own machine, I would like to see the numbers. My guess is that the
AGENTS.md row is worse than mine on any team of more than three people.

Top comments (0)