From 2a5f5414850b718cee6518d43ac4b2c4c0880897 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Sat, 31 Oct 2026 16:53:42 +0100 Subject: [PATCH] docs: AGENTS.template.md in the README The dependency notes section now starts from the template: what to commit and what to ignore, the two commands that move a project with a committed AGENTS.md over, what a build writes, where the section goes, and what becomes of an AGENTS.md no build wrote and of one that still holds a section from 3.0.0. Co-Authored-By: Claude Opus 5.5 --- README.md | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 77514ec..c57beb6 100644 --- a/README.md +++ b/README.md @@ -101,9 +101,23 @@ Such a dependency is built for the host, whatever the project targets, and its ` ### Dependency notes for agents -An agent working on a project reads its `AGENTS.md`, which says nothing about the libraries the project builds against unless someone copied that in by hand. A library ships it instead: an `AGENTS.consumer.md` beside its `project.cpp`, written for whoever uses the library rather than whoever works on it. When a consumer has an `AGENTS.md` beside its own `project.cpp`, `crafter-build` and `crafter-build test` keep its dependencies' notes in a section of it: +An agent working on a project reads its `AGENTS.md`, which says nothing about the libraries the project builds against unless someone copied that in by hand. A library ships it instead: an `AGENTS.consumer.md` beside its `project.cpp`, written for whoever uses the library rather than whoever works on it. + +A consumer that wants its dependencies' notes writes its own instructions in an `AGENTS.template.md` beside its `project.cpp`, and commits that instead of an `AGENTS.md`. `crafter-build` and `crafter-build test` then write `AGENTS.md` from the template with the notes added, so `AGENTS.md` is build output and stays out of version control: a dependency that changes its notes changes nothing a diff shows. A project with a committed `AGENTS.md` moves over from the directory of its `project.cpp`: + +```bash +git mv AGENTS.md AGENTS.template.md +echo /AGENTS.md >> .gitignore +``` + +What a build then writes: ```markdown + +# The template's text + +... + @@ -116,11 +130,13 @@ An agent working on a project reads its `AGENTS.md`, which says nothing about th ``` - Each file goes in as written, under a line naming the dependency: its repository's name, or a `LocalProject`'s directory name. That reads the same on every machine, and for a `--local` checkout and its git clone alike. The file lands among the consumer's own headings, so start it with a `##` heading that names the library. -- The section is appended the first time, after a blank line, and rewritten in place after that, wherever it has been moved to. Edits inside it are lost on the next build; the text around it is left as it is. The file is written only when the section changes, in place, so hard links, ownership and a read-only `AGENTS.md` are respected, and an `AGENTS.md` is never created. +- The section goes after the template's text and a blank line. To have it elsewhere, put the begin and end marker lines in the template where it should go: whatever they enclose is replaced. A template moved over from a committed `AGENTS.md` has them where its section was, around notes that can be deleted. +- `AGENTS.md` is written only when its text changes, in place, so a `CLAUDE.md` linked to it, its ownership and a read-only `AGENTS.md` are respected. An edit made in it is gone after the next build, and a fresh clone has none until its first build. The template is never written. +- An `AGENTS.md` that no build wrote, such as a committed one still next to a new template, is never replaced: each build warns instead, until it is deleted. Without a template, `AGENTS.md` is never touched. One that still holds a section from crafter-build 3.0.0, which kept the notes in a committed `AGENTS.md`, gets a warning: move it over as above, or delete the section. - The update runs once `project.cpp` has loaded and before the project compiles, so a build that fails still has the notes. A `project.cpp` that fails to load gets no update. `test --list`, `lint`, `format`, `run` and `clean` leave the file alone. - The section follows what the build loaded: a dependency that only some flags pull in (a `--target=`, a flag of the project's own) comes and goes with them. An unpinned dependency's notes follow its default branch, as its code does, so the section can change on any build. Pin a `commit` to decide when. - A library reached through two specs, pinned at one revision here and another further down, is described once, as the nearer one has it. -- When there are notes to write, unbalanced markers leave the file as it is, with a warning. A notes file that would break the section (a code block it never closes, a marker line of its own) is left out, also with a warning. Markers quoted inside a fenced code block don't count. +- When there are notes to write, unbalanced markers in the template leave `AGENTS.md` as it is, with a warning. A notes file that would break the section (a code block it never closes, a marker line of its own) is left out, also with a warning. Markers quoted inside a fenced code block don't count. `cfg.dependencyNotes` picks the dependencies: @@ -128,7 +144,7 @@ An agent working on a project reads its `AGENTS.md`, which says nothing about th |---|---| | `DependencyNotes::Transitive` (default) | everything the project builds against, all the way down: its `dependencies` and its own `#pragma crafter dependency` tooling | | `DependencyNotes::Direct` | only the projects the project's own configurations and `#pragma crafter dependency` lines name | -| `DependencyNotes::None` | none, and a section from an earlier build is removed | +| `DependencyNotes::None` | none: `AGENTS.md` holds the template's text alone | Three things never count: the project's own `AGENTS.consumer.md`; its tests' dependencies, since a plain build never looks at the tests; and a dependency's `#pragma crafter dependency` tooling, which is about how the dependency is built, not how it is used.