{"slug": "generating-your-agent-rules-from-one-file-does-not-stop-them-drifting", "title": "Generating your agent rules from one file does not stop them drifting", "summary": "A developer built a tool to generate agent instruction files from a single AGENTS.md source, but found it does not prevent drift across repositories, global configs, and machines. They then created a detection script that scans entire working directories and groups files by content similarity, revealing multiple divergent versions of the same instruction file on one laptop. The developer warns that generation alone gives a false sense of coverage and recommends combining generation with detection.", "body_md": "The obvious fix for \"our agent instruction files keep diverging\" is to stop maintaining copies. Write `AGENTS.md`\n\n, generate `CLAUDE.md`\n\nand `.cursor/rules/*.mdc`\n\nand `.github/copilot-instructions.md`\n\nfrom it, done.\n\nI built that. It works. It also does not solve the problem, and the gap between those two statements is worth spelling out, because I only saw it after running the thing on a real machine.\n\n```\npython3 agent_fanout.py\n\ncreate    CLAUDE.md\ncreate    .cursor/rules/from-agents-md.mdc\ncreate    .github/copilot-instructions.md\n```\n\nOne source, several derived files, a header on each so nobody edits the derived copy by accident:\n\n``` php\n<!-- Generated from AGENTS.md by agent-fanout. Do not edit this file. -->\n```\n\nAdd it to CI and the pull request that edits `CLAUDE.md`\n\ndirectly turns the build red:\n\n```\n- run: python3 agent_fanout.py . --check\n```\n\nThat covers **this repository, on the machines that run CI**. Which sounds like everything until you list what it isn't.\n\n**Other repositories.** Your team has more than one. Each has its own `AGENTS.md`\n\n, and they were copy-pasted from each other at some point. Generation keeps each repo internally consistent while the repos drift apart from one another.\n\n**Global config.** Claude Code reads `~/.claude/CLAUDE.md`\n\nin addition to the project file. Cursor has user-level rules. Those live outside any repository, are never in CI, and are exactly where people put the rule they didn't want to argue about in review.\n\n**The window between edits.** Generation runs when someone runs it. Between that moment and the next CI run, a derived file can be edited and used. The agent reads it immediately; CI notices on push, if there is a push.\n\n**Repos without CI.** Prototypes, scratch clones, the repo someone made last Tuesday. Those are where instructions get freely modified, and they are the ones with no gate at all.\n\n**Machines, not repositories.** The unit that runs an agent is a laptop. A laptop has many checkouts, several of the same repo, and a home directory. Nothing that operates per-repository can see across that.\n\nPrevention is a policy. Detection is a measurement. Policies get bypassed in ways that are invisible until you measure.\n\n```\npython3 agent_drift.py ~/work ~/side-projects\n\nScanned 47 instruction files.\n\nDRIFT: 2 documents, 5 distinct versions between them.\n\n  claude-code:CLAUDE.md\n    6 copies, 3 versions\n      9b01aeaa204d  3 files, 406 lines\n      2dc3c616c279  2 files, 411 lines\n```\n\nThis one scans paths rather than repositories, and groups files by content similarity rather than by filename — two unrelated projects having different `CLAUDE.md`\n\nfiles is not drift, and reporting it as drift makes the output worthless. (Getting that grouping right took three rewrites; [I wrote that part up separately](https://dev.to/untactit/i-found-18-versions-of-the-same-claudemd-on-one-laptop-bbc).)\n\nRun it across your whole working directory, not one project. The interesting results are the ones that cross repository boundaries.\n\n| Scope | Answers | |\n|---|---|---|\n`agent-fanout` |\none repository | \"are the derived files current?\" |\n`agent-drift` |\nwhole machine, many paths | \"where did copies diverge anyway?\" |\n\nGeneration removes the *reason* copies exist. Detection catches the copies that exist for reasons you did not anticipate. Neither is redundant, and doing only the first one gives you a false sense of coverage — which is the actual failure mode I want to warn about, because it is the one I walked into.\n\nBoth are single-file Python, no dependencies, read-only where it matters, MIT:\n\n`AGENTS.md`\n\nonce, generate the restThe honest end state is that neither script is necessary, because the assets are not files sitting on laptops at all — they live in one reviewed place and reach every machine without anyone copying anything. That is what I am building at [untactit](https://untactit.com), currently pre-launch.\n\nThe scripts stand on their own and don't depend on it. Use them, ignore the rest.", "url": "https://wpnews.pro/news/generating-your-agent-rules-from-one-file-does-not-stop-them-drifting", "canonical_source": "https://dev.to/untactit/generating-your-agent-rules-from-one-file-does-not-stop-them-drifting-3gpb", "published_at": "2026-08-11 22:51:21+00:00", "updated_at": "2026-08-11 23:16:34.256939+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents"], "entities": ["Cursor", "GitHub Copilot", "untactit"], "alternates": {"html": "https://wpnews.pro/news/generating-your-agent-rules-from-one-file-does-not-stop-them-drifting", "markdown": "https://wpnews.pro/news/generating-your-agent-rules-from-one-file-does-not-stop-them-drifting.md", "text": "https://wpnews.pro/news/generating-your-agent-rules-from-one-file-does-not-stop-them-drifting.txt", "jsonld": "https://wpnews.pro/news/generating-your-agent-rules-from-one-file-does-not-stop-them-drifting.jsonld"}}