Problem
AGENTS.md and CLAUDE.md at the repository root carry the same doctrine: 55 lines each, 53 of them byte-identical. The framework's portability depends on them staying in agreement, since Claude Code reads one and every other tool reads the other.
Measured on main, 2026-08-11, via the commits API filtered by path:
CLAUDE.md touched by: d3fe2ac 2026-06-26 - 80daf0d 2026-06-20 - c6b474f 2026-06-06 - 3a91267 2026-05-11
AGENTS.md touched by: cfaf61b 2026-07-18 - 6c0914a 2026-07-07
No commit touches both files. Four commits edited CLAUDE.md without AGENTS.md, then two edited AGENTS.md without CLAUDE.md. If the two files are 53/55 identical today, it is because someone re-copied the content by hand between commits, and the only thing keeping them aligned is the memory of whoever edits next.
The drift is already visible in the two lines that differ, the greeting:
CLAUDE.md : "AI-Driven Development ON - Date: {current_date}, TZ: {current_timezone}."
AGENTS.md : "AI-Driven Development On ⚡"
The {current_date} placeholders look deliberate, since only Claude Code substitutes them. The casing difference and the decorative emoji do not, and the emoji sits in a file whose own Communication section says "no decorative tables or emoji unless they carry information". Whether each difference is a choice or a leftover is exactly what nothing currently records.
I checked whether an existing control covers this: lefthook.yml validates JSON, YAML and skill frontmatter but does not compare the twins; among scripts/, cli/ and .github/, the files mentioning AGENTS.md are CLI tests and a fixture; dev-sync.sh installs, it does not compare; CONTRIBUTING.md has zero occurrences of AGENTS, CLAUDE or sync. If I missed a control somewhere else, this issue collapses and I would be glad to close it.
Scope
A parity check with declared exceptions, not byte parity. Byte parity would flag the greeting line forever and the check would be disabled within a week; a red check nobody can fix is worse than none.
scripts/check-doctrine-parity.mjs: both files must be identical except for lines listed in a small versioned exceptions block (the two title lines, the greeting line). Any undeclared divergence fails with the differing lines printed.
- One entry in
lefthook.yml under pre-commit, next to the existing JSON/YAML checks, scoped to the two files.
- The exceptions block lives in the script or a small config, so a deliberate divergence is one reviewed line in a diff, and drift is a red check.
- I can submit the PR with the script and a test that proves the check goes red on an undeclared mutation and stays green on the declared exceptions.
Acceptance criteria
Prior art in this repo
Same shape as the existing lefthook.yml checks (json-validity, yaml-validity, skill-frontmatter): mechanical, scoped, runs where the mistake happens. #618 makes a neighbouring argument about unverified table cells; this is the same failure one level up, applied to the two files that instruct every agent.
Out of scope
Deciding which greeting is correct, or unifying the two files into one generated artifact. Both are maintainer calls; the check only makes the difference visible and deliberate.
Problem
AGENTS.mdandCLAUDE.mdat the repository root carry the same doctrine: 55 lines each, 53 of them byte-identical. The framework's portability depends on them staying in agreement, since Claude Code reads one and every other tool reads the other.Measured on
main, 2026-08-11, via the commits API filtered by path:CLAUDE.md touched by: d3fe2ac 2026-06-26 - 80daf0d 2026-06-20 - c6b474f 2026-06-06 - 3a91267 2026-05-11
AGENTS.md touched by: cfaf61b 2026-07-18 - 6c0914a 2026-07-07
No commit touches both files. Four commits edited
CLAUDE.mdwithoutAGENTS.md, then two editedAGENTS.mdwithoutCLAUDE.md. If the two files are 53/55 identical today, it is because someone re-copied the content by hand between commits, and the only thing keeping them aligned is the memory of whoever edits next.The drift is already visible in the two lines that differ, the greeting:
CLAUDE.md : "AI-Driven Development ON - Date: {current_date}, TZ: {current_timezone}."
AGENTS.md : "AI-Driven Development On ⚡"
The
{current_date}placeholders look deliberate, since only Claude Code substitutes them. The casing difference and the decorative emoji do not, and the emoji sits in a file whose own Communication section says "no decorative tables or emoji unless they carry information". Whether each difference is a choice or a leftover is exactly what nothing currently records.I checked whether an existing control covers this:
lefthook.ymlvalidates JSON, YAML and skill frontmatter but does not compare the twins; amongscripts/,cli/and.github/, the files mentioningAGENTS.mdare CLI tests and a fixture;dev-sync.shinstalls, it does not compare;CONTRIBUTING.mdhas zero occurrences ofAGENTS,CLAUDEorsync. If I missed a control somewhere else, this issue collapses and I would be glad to close it.Scope
A parity check with declared exceptions, not byte parity. Byte parity would flag the greeting line forever and the check would be disabled within a week; a red check nobody can fix is worse than none.
scripts/check-doctrine-parity.mjs: both files must be identical except for lines listed in a small versioned exceptions block (the two title lines, the greeting line). Any undeclared divergence fails with the differing lines printed.lefthook.ymlunderpre-commit, next to the existing JSON/YAML checks, scoped to the two files.Acceptance criteria
pre-commitwith the differing lines named.Prior art in this repo
Same shape as the existing
lefthook.ymlchecks (json-validity, yaml-validity, skill-frontmatter): mechanical, scoped, runs where the mistake happens. #618 makes a neighbouring argument about unverified table cells; this is the same failure one level up, applied to the two files that instruct every agent.Out of scope
Deciding which greeting is correct, or unifying the two files into one generated artifact. Both are maintainer calls; the check only makes the difference visible and deliberate.