feat(agents-init): retire CLAUDE.md, discover and normalize AGENTS.md in every subdirectory #177

Merged
rootiest merged 12 commits from docs/retire-claude-md-for-agents-md into main 2026-09-24 04:56:06 +00:00
Owner

What

claude-code now reads AGENTS.md natively when no CLAUDE.md is present, so agents-init no longer needs to create or maintain CLAUDE.md anywhere. This retires it entirely and generalizes the root-only AGENTS.md/CLAUDE.md handling into a per-directory sync that discovers any directory with scoped agent instructions (not just the root) and settles each one on AGENTS.md-only.

Spec: AGENTS/specs/2026-09-23-retire-claude-md-design.md
Plan: docs/superpowers/plans/2026-09-23-retire-claude-md.md

Changes

  • New: functions/_agents_init_sync_instructions.fish — per-directory sync helper. Handles four states in order: an inverted mirror (CLAUDE.md real, AGENTS.md symlinked to it — this repo's docs//functions/ shape before this PR), adopting a lone real file (a lone CLAUDE.md is renamed, never preserved under its own name), byte-identical duplicates (keep AGENTS.md, drop CLAUDE.md), and differing duplicates (touch neither, warn to stderr, skip — never silently discard real content).
  • Rewritten: functions/agents-init.fish's --agents mode replaces the old root-only inline logic with a discovery loop calling the helper above, once per directory found. Discovery is repo-wide but contained: a non-git root syncs only itself (no recursion at all), and a git root's walk prunes nested repos/submodules, any dot-directory (.git, .claude, .gemini, .github, …), any directory named AGENTS, node_modules, and generated-output directories (build, dist, out, target).
  • New: functions/_agents_init_path_is_protected.fish — a real AGENTS.md/CLAUDE.md is left alone (not adopted, not symlinked over) when it's deliberately tracked: staged or committed in git's index, in a project whose .gitignore is actually populated. An untracked file is always safe to adopt regardless of ignore state, and a tracked file in a project with no established ignore conventions at all is treated as an adoptable first-run/bootstrap case rather than a deliberate choice. This closes the "team/shared repo" gap flagged in review (see below) — a subdirectory's intentionally-committed CLAUDE.md in someone else's repo is no longer touched.
  • .gitignore management switched from anchored /AGENTS.md + /CLAUDE.md patterns to a single unanchored AGENTS.md pattern (covers every discovered depth), with a migration step that also cleans up the old anchored lines on a project agents-init previously scaffolded.
  • functions/claude.fish, functions/agy.fish, and the C1 command-shadows manual page had their "auto-links AGENTS.md as CLAUDE.md" wording dropped — that job no longer exists.
  • AGENTS/AGENT-TEMPLATE.md (gitignored sub-repo, separate commit there) had its CLAUDE.md warning dropped, keeping the unrelated GEMINI.md mention.
  • New hermetic test suite tests/test-agents-init.fish.
  • New: docs/manual/16-agent-tooling.md — a full concept/behavior/purpose write-up of this whole system as its own manual section (separate from the auto-generated function reference in Section 5): the AGENTS.md convention, the AGENTS/ sub-repository's layout/versioning/hooks, per-directory discovery and its four-state normalization, both safety mechanisms, a scenario reference (two tables covering every combination of what a directory can hold crossed with its git-tracked state, and what happens in each case), the plans/specs/devlogs wiring, and the launch lifecycle. Inserted before Attribution/License (now Sections 17/18) — the only placement that doesn't disturb any of the manual's existing prose cross-references to other section numbers. docs/fish-config.index updated to match.
  • New: a manual-section(<slug>) CLASSIFICATION tag, so a function with a dedicated manual section (like this one) is grep-able and machine-checked instead of relying on someone reading its NOTES. docs/build-manual.py resolves the tag's target page fresh at build time (title, not a hardcoded section number, so a later renumbering — this section has already been renumbered twice on this branch — never requires touching the tag) and renders a "See also" line on the function's generated Section 5 entry, a real link on the site. docs/verify-manual.py fails the suite if a tag's slug doesn't resolve to a real page — the actual enforcement half, since the build itself stays silent about a bad one. CONTRIBUTING.md and docs/function-classification-schema.md document the tag and the now-widened, general-purpose framing of CLASSIFICATION itself (not just hazard/shadow tags anymore).
  • New (CONTRIBUTING.md): a "Dedicated manual sections for complex subsystems" subsection documenting this pattern generally — when a subsystem outgrows its doc-header and deserves its own manual section, and the obligation to update that section in the same change.
  • This repo's own root (redundant CLAUDE.md symlinks) and docs//functions/ (previously-inverted mirrors) were migrated live by running the finished tool against the actual checkout.

Safety notes

Three rounds of review on this branch (each dispatched independently, several with live fixture reproduction rather than just reading the diff) found and closed:

  1. Discovery had no containment. From a non-git root (e.g. ~) it would have walked the entire subtree; inside a git repo it didn't stop at nested repos/submodules/.claude. Fixed as described above.
  2. Silent data loss. Once a directory's mirror was already settled, a new real file written at the project level (e.g. a fresh CLAUDE.md/AGENTS.md) was silently deleted with no comparison — a regression from the old code, which at least errored. Fixed by applying the same identical/differ-and-warn logic used elsewhere in the helper.
  3. Tracked-file protection — closes the "git-tracked instruction files in other team/shared repos" gap the second review round flagged as a deliberate open question rather than fixing outright, since it was a scope/design call rather than a clear bug. Implemented, independently reviewed with 6 live fixtures (committed/staged/bootstrap/gitignored/pruned-dir/settled-mirror cases), one Minor finding (glob characters in a filename could false-match via git's pathspec globbing — fixed with --literal-pathspecs).

Testing

tests/run-tests.fish: 882/882 assertions passed, exit 0 (syntax/indent lint, shadow-classification lint, test-agents-init.fish, test-agents-vault.fish — no regressions — and every other suite). docs/verify-manual.py: 88/89 passed — the one failure (test_concat_roundtrips_original) is the expected, pre-existing PR-branch state (regeneration of the generated docs/fish-config.md is a main-branch-only CI step). The scenario-reference tables and the manual-section See-also rendering were both independently verified against build-manual.py's real parser/build logic and the generated Starlight site output, not just visually.

## What `claude-code` now reads `AGENTS.md` natively when no `CLAUDE.md` is present, so `agents-init` no longer needs to create or maintain `CLAUDE.md` anywhere. This retires it entirely and generalizes the root-only `AGENTS.md`/`CLAUDE.md` handling into a per-directory sync that discovers *any* directory with scoped agent instructions (not just the root) and settles each one on `AGENTS.md`-only. Spec: `AGENTS/specs/2026-09-23-retire-claude-md-design.md` Plan: `docs/superpowers/plans/2026-09-23-retire-claude-md.md` ## Changes - **New:** `functions/_agents_init_sync_instructions.fish` — per-directory sync helper. Handles four states in order: an inverted mirror (`CLAUDE.md` real, `AGENTS.md` symlinked to it — this repo's `docs/`/`functions/` shape before this PR), adopting a lone real file (a lone `CLAUDE.md` is **renamed**, never preserved under its own name), byte-identical duplicates (keep `AGENTS.md`, drop `CLAUDE.md`), and differing duplicates (touch neither, warn to stderr, skip — never silently discard real content). - **Rewritten:** `functions/agents-init.fish`'s `--agents` mode replaces the old root-only inline logic with a discovery loop calling the helper above, once per directory found. Discovery is repo-wide but contained: a non-git root syncs only itself (no recursion at all), and a git root's walk prunes nested repos/submodules, any dot-directory (`.git`, `.claude`, `.gemini`, `.github`, …), any directory named `AGENTS`, `node_modules`, and generated-output directories (`build`, `dist`, `out`, `target`). - **New:** `functions/_agents_init_path_is_protected.fish` — a real `AGENTS.md`/`CLAUDE.md` is left alone (not adopted, not symlinked over) when it's *deliberately tracked*: staged or committed in git's index, in a project whose `.gitignore` is actually populated. An untracked file is always safe to adopt regardless of ignore state, and a tracked file in a project with no established ignore conventions at all is treated as an adoptable first-run/bootstrap case rather than a deliberate choice. This closes the "team/shared repo" gap flagged in review (see below) — a subdirectory's intentionally-committed `CLAUDE.md` in someone else's repo is no longer touched. - `.gitignore` management switched from anchored `/AGENTS.md` + `/CLAUDE.md` patterns to a single unanchored `AGENTS.md` pattern (covers every discovered depth), with a migration step that also cleans up the old anchored lines on a project agents-init previously scaffolded. - `functions/claude.fish`, `functions/agy.fish`, and the C1 command-shadows manual page had their "auto-links AGENTS.md as CLAUDE.md" wording dropped — that job no longer exists. - `AGENTS/AGENT-TEMPLATE.md` (gitignored sub-repo, separate commit there) had its `CLAUDE.md` warning dropped, keeping the unrelated `GEMINI.md` mention. - New hermetic test suite `tests/test-agents-init.fish`. - **New:** `docs/manual/16-agent-tooling.md` — a full concept/behavior/purpose write-up of this whole system as its own manual section (separate from the auto-generated function reference in Section 5): the AGENTS.md convention, the AGENTS/ sub-repository's layout/versioning/hooks, per-directory discovery and its four-state normalization, both safety mechanisms, a **scenario reference** (two tables covering every combination of what a directory can hold crossed with its git-tracked state, and what happens in each case), the plans/specs/devlogs wiring, and the launch lifecycle. Inserted before Attribution/License (now Sections 17/18) — the only placement that doesn't disturb any of the manual's existing prose cross-references to other section numbers. `docs/fish-config.index` updated to match. - **New:** a `manual-section(<slug>)` `CLASSIFICATION` tag, so a function with a dedicated manual section (like this one) is grep-able and machine-checked instead of relying on someone reading its `NOTES`. `docs/build-manual.py` resolves the tag's target page fresh at build time (title, not a hardcoded section number, so a later renumbering — this section has already been renumbered twice on this branch — never requires touching the tag) and renders a "See also" line on the function's generated Section 5 entry, a real link on the site. `docs/verify-manual.py` fails the suite if a tag's slug doesn't resolve to a real page — the actual enforcement half, since the build itself stays silent about a bad one. `CONTRIBUTING.md` and `docs/function-classification-schema.md` document the tag and the now-widened, general-purpose framing of `CLASSIFICATION` itself (not just hazard/shadow tags anymore). - **New (CONTRIBUTING.md):** a "Dedicated manual sections for complex subsystems" subsection documenting this pattern generally — when a subsystem outgrows its doc-header and deserves its own manual section, and the obligation to update that section in the same change. - This repo's own root (redundant `CLAUDE.md` symlinks) and `docs/`/`functions/` (previously-inverted mirrors) were migrated live by running the finished tool against the actual checkout. ## Safety notes Three rounds of review on this branch (each dispatched independently, several with live fixture reproduction rather than just reading the diff) found and closed: 1. **Discovery had no containment.** From a non-git root (e.g. `~`) it would have walked the entire subtree; inside a git repo it didn't stop at nested repos/submodules/`.claude`. Fixed as described above. 2. **Silent data loss.** Once a directory's mirror was already settled, a new real file written at the project level (e.g. a fresh `CLAUDE.md`/`AGENTS.md`) was silently deleted with no comparison — a regression from the old code, which at least errored. Fixed by applying the same identical/differ-and-warn logic used elsewhere in the helper. 3. **Tracked-file protection** — closes the "git-tracked instruction files in other team/shared repos" gap the second review round flagged as a deliberate open question rather than fixing outright, since it was a scope/design call rather than a clear bug. Implemented, independently reviewed with 6 live fixtures (committed/staged/bootstrap/gitignored/pruned-dir/settled-mirror cases), one Minor finding (glob characters in a filename could false-match via git's pathspec globbing — fixed with `--literal-pathspecs`). ## Testing `tests/run-tests.fish`: 882/882 assertions passed, exit 0 (syntax/indent lint, shadow-classification lint, `test-agents-init.fish`, `test-agents-vault.fish` — no regressions — and every other suite). `docs/verify-manual.py`: 88/89 passed — the one failure (`test_concat_roundtrips_original`) is the expected, pre-existing PR-branch state (regeneration of the generated `docs/fish-config.md` is a main-branch-only CI step). The scenario-reference tables and the manual-section See-also rendering were both independently verified against `build-manual.py`'s real parser/build logic and the generated Starlight site output, not just visually.
rootiest added the Kind/FeatureArea/FunctionsArea/DocsArea/Tests labels 2026-09-24 00:18:23 +00:00
rootiest added 7 commits 2026-09-24 00:18:26 +00:00
rootiest added 2 commits 2026-09-24 01:09:14 +00:00
A real AGENTS.md/CLAUDE.md that is in git's index, in a project with a
non-empty .gitignore, is now left in place (with a stderr warning) by
steps 2 and 4 of _agents_init_sync_instructions instead of being moved
into AGENTS/ and symlinked. Discovery also prunes build/, dist/, out/
and target/ outright.
fix(agents-init): use --literal-pathspecs so glob characters in a path can't false-match tracked files
CI / github-mirror (pull_request) Skipped
CI / test (pull_request) Successful in 2m28s
CI / docs (pull_request) Successful in 1m21s
de92277226
rootiest added 1 commit 2026-09-24 01:47:43 +00:00
docs: add AI Agent Tooling manual section
CI / github-mirror (pull_request) Skipped
CI / test (pull_request) Successful in 2m26s
CI / docs (pull_request) Successful in 1m14s
e01e83bd36
Documents agents-init/agents-vault's concept, purpose, and complete
behavior as its own manual section (16), separate from the auto-generated
function reference: the AGENTS.md convention and CLAUDE.md retirement,
the AGENTS/ sub-repository (layout, versioning, hooks), per-directory
discovery and its four-state normalization, the two safety mechanisms
(discovery containment, deliberately-tracked-file protection), the
plans/specs/devlogs wiring, and the launch lifecycle.

Inserted before Attribution/License (now 17/18) rather than mid-document,
since that's the only placement that doesn't touch any of the manual's
prose cross-references to other section numbers. docs/fish-config.index
updated to match (new keywords, renumbered attribution/license entries;
agents-init and agy were already indexed to their own function-reference
entries and are left pointing there, not redirected to this new page).
rootiest added 1 commit 2026-09-24 02:10:51 +00:00
docs(agent-tooling): add scenario reference table, cross-reference from code
CI / github-mirror (pull_request) Skipped
CI / test (pull_request) Successful in 2m24s
CI / docs (pull_request) Successful in 1m37s
1d714a84d0
Adds a 'Scenario reference' subsection to docs/manual/16-agent-tooling.md:
two ruled tables covering every combination of what a directory can hold
(only AGENTS.md, only CLAUDE.md, both identical, both different, an
inverted mirror, an already-settled symlink) crossed with whether the
file is deliberately git-tracked, plus the settled-mirror/later-arrival
case separately. Verified against build-manual.py's actual table parser
and the generated Starlight site output, not just visual inspection.

Also closes the gap this section itself pointed out: nothing previously
linked a reader of agents-init.fish or agents-vault.fish's own doc-header
to this page, and nothing told a future contributor the page has to be
kept in sync. Adds:
- CONTRIBUTING.md: a new 'Dedicated manual sections for complex
  subsystems' subsection documenting the pattern in general (when to use
  one, and the update-it-in-the-same-change obligation verify-manual.py
  cannot check for you).
- functions/agents-init.fish, functions/agents-vault.fish: a NOTES
  pointer to the section from each function's own header, so a reader
  who only sees the header still finds the fuller page.
rootiest added 1 commit 2026-09-24 04:51:01 +00:00
feat(docs): add manual-section CLASSIFICATION tag, wire it into the build
CI / github-mirror (pull_request) Skipped
CI / test (pull_request) Successful in 2m26s
CI / docs (pull_request) Successful in 1m17s
911c6e95ed
A function with a dedicated manual section (docs/manual/16-agent-tooling.md,
so far) now carries manual-section(<slug>) in its own CLASSIFICATION line
instead of relying on a NOTES pointer nobody can grep for. Applied to
agents-init and agents-vault, both pointing at 16-agent-tooling.

docs/build-manual.py: _resolve_manual_section reads the target page's own
manTitle/title fresh at build time rather than duplicating a section
number into the tag, so a renumbered section (like this one, twice
already) never requires touching the tag -- only the slug (the filename)
does, and only if the page itself is renamed. render_entry and
render_entry_site both gained an optional root parameter and now emit a
'See also' line (plain text + relative path for the man page, a real
markdown link on the site) whenever the tag resolves; omitted silently
when it doesn't (a build isn't the place to fail on a bad slug).

docs/verify-manual.py: unit tests for the new resolver and both renderers,
plus a real-data scan (test_real_manual_section_tags_resolve) that fails
the suite if any function's manual-section(<slug>) tag points nowhere --
the actual enforcement half of the convention, since the build stays
silent about it.

docs/function-classification-schema.md, CONTRIBUTING.md: documents the
tag, and widens CLASSIFICATION's own framing from strictly hazard/shadow
tags to general-purpose (the user's call, not mine to make unilaterally --
scope-broadening an existing convention). The 'Dedicated manual sections'
subsection (added earlier this branch) now names the tag as the
machine-checked half of that convention, with NOTES demoted to a
nice-to-have for a header-only reader.
rootiest merged commit ec700cece1 into main 2026-09-24 04:56:06 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rootiest/fish-config#177