Each coding agent reads its own file: Codex and others read AGENTS.md, Claude Code reads CLAUDE.md, Cursor reads rules in .cursor/rules/, and Gemini CLI reads GEMINI.md. Left alone, the copies drift and each agent follows different rules. Rules sync keeps one source and writes the rest from it.
overlane rules sync
overlane rules check
overlane doctorThe source
Write the rules once, in .overlane/rules.md. It is plain Markdown. Its revision is a short digest of its text, so every change gets a new revision. The text is placed into the other files as it is and is never run or interpreted. It cannot contain the managed-region markers.
Where it goes
| File | Read by | What sync writes |
|---|---|---|
AGENTS.md |
Codex, Cursor, Gemini CLI and other agents | A managed region |
CLAUDE.md |
Claude Code | A managed region |
.cursor/rules/overlane.mdc |
Cursor | Frontmatter (alwaysApply: true) and a managed region |
GEMINI.md |
Gemini CLI | A managed region |
.gemini/settings.json |
Gemini CLI | context.fileName lists GEMINI.md and AGENTS.md |
A managed region is the text between two comment lines. The first holds the source revision and a digest of the region itself:
<!-- overlane-rules:begin rev=3f9a1c07d2e4 digest=9b1c0d7a4e2f6a18 -->
...
<!-- overlane-rules:end -->Everything outside the region is yours and sync never changes it. A hand-written CLAUDE.md with no region gets the region appended at the end, and every existing line stays. In the Gemini settings, sync only adds the missing names; every other setting and every other file name stays.
Drift
overlane rules check changes nothing and compares each target with the source:
| State | Meaning | What sync does |
|---|---|---|
in_sync |
Matches the current revision | Nothing |
missing |
The file does not exist | Creates it |
unmanaged |
The file has no region yet | Appends the region |
stale |
The source changed since the region was written; nobody edited it | Updates the region |
edited |
Someone edited inside the region | Refuses, writes nothing |
damaged |
A marker is missing, doubled or malformed, or the file is a symbolic link | Refuses |
For an edited region the check names the first line that differs and what the source says instead. If a hand edit is worth keeping, move it into .overlane/rules.md and run sync. If it is not, overlane rules sync --overwrite-edits replaces the region and prints the lines it replaces first. If any target refuses, sync writes none of them, so the files never end up half synced. A damaged file is never overwritten, even with --overwrite-edits.
Exit codes: check exits 0 when everything is in sync (or the project has no source) and 6 on drift. sync exits 5 when it refuses.
In overlane doctor
overlane doctor prints a rules line when the project has a source. In sync, it shows the revision. Drifted, it lists the files and the next command, and the result is not ready (exit 5).
In CI
Run the check on every pull request:
- name: Rules are in sync
run: npx overlane rules checkFrom a checkout of the Overlane repository, node scripts/rules-check.mjs runs the same check.
Agent use and the override
An agent edits .overlane/rules.md, runs overlane rules sync, and commits the result. When check reports edited, it reads the named line, moves the change into the source if it is worth keeping, and syncs. A person can edit any of the files directly at any time; the next check shows it as drift instead of losing it.
Command reference: rules sync and rules check.