AGENTS.md and CLAUDE.md
fairlead agents sync keeps a block in the files an agent reads before anything else, AGENTS.md and CLAUDE.md, so it knows the change loop, the lessons that apply to every change and which skills exist before it has run a command. The block sits between two markers, and nothing outside them is written. Since 0.8.0.
fairlead agents sync # write or update the block in each file
fairlead agents sync --check # write nothing; exit 1 naming each file whose block is missing or stale
fairlead agents sync --clean # remove the block and its markers
[agents]
write = "block" # or "never": write nothing, print the block for a person to copy in
files = ["AGENTS.md", "CLAUDE.md"] # from the repository root
files appends to the defaults like any list, so files = { replace = ["AGENTS.md"] } keeps the block in one file. A path outside the repository is a config check problem.
The block
<!-- fairlead:begin -->
<!-- Generated by `fairlead agents sync`: edit fairlead.toml or .fairlead/lessons instead, then sync again. -->
**Fairlead: the change loop**
- Before an edit: `fairlead brief <paths>` names what they reach, the tests that will run, and the lessons and skills that apply.
- Before you finish: `fairlead done` runs the gate the change has to pass.
- After it: `fairlead receipt` compares the change with its brief, and `fairlead next` names the step that's due.
- The pull request: open it as a draft, `gh pr create --draft`, and mark it ready, `gh pr ready`, once `fairlead done` passes.
- `fairlead find <words>` searches the lessons, skills, docs headings and symbols.
- `fairlead learn` records a lesson a change taught, with its scope and evidence.
**Lessons for every change**
- Leave settles at sign-off (leave-settles-at-sign-off)
**Skills: load the one for the code you change**
- forms: How forms validate. (.claude/skills/forms/SKILL.md)
<!-- fairlead:end -->
- The loop: the commands of the brief, the done gate, the receipt and next,
findandlearn, and when to open the pull request as a draft and mark it ready, asnextsays. - Lessons for every change: the lessons with
always: true, astitle (id), by id. A lesson scoped to paths stays in the brief, which offers it when a change reaches it. - Skills: every routed skill, as
name: description (path), by name.
The block is at most 40 lines, markers included. Past that, the longer list gives up lines first and ends with … N more and the command that lists the rest: fairlead lessons list or fairlead brief --all. The same lessons, skills and config always give the same block, so --check in CI fails only when one of them changed and the block wasn’t synced.
A lesson or skill file that can’t be read is left out and named in a warning.
What it writes
- A file with the markers: only what’s between them is replaced.
- A file without them: a blank line and the block are added at its end.
- No file: it’s created with the block alone.
The file keeps its line endings (a CRLF file gets a CRLF block) and its final newline, or the lack of one. A file whose markers don’t make one block, such as a begin marker with no end marker, or two begin markers, is an error naming the file, and it’s left untouched; the other files are still synced.
--clean removes the markers, what’s between them and the blank line sync added before them, so a file it appended to comes back byte for byte. A file sync created, which holds only the block, is deleted.
Writing nothing: write = "never"
For a team that wants a person to own every line of those files. agents sync prints the block and writes nothing, and --clean removes nothing. --check still fails while a file is missing the block or holds a stale one, and fairlead doctor names each such file in either mode:
agents: AGENTS.md has no fairlead block; copy in the block `fairlead agents sync` prints
agents: CLAUDE.md's fairlead block is stale; copy in the block `fairlead agents sync` prints
[agents] is left out of the plan digest, so plan ids don’t move.