Files
platform/todo/docs-conventions/sweep-agents-md-primary-claude-md-pointer.md

94 lines
6.4 KiB
Markdown

---
id: docs-conventions/sweep-agents-md-primary-claude-md-pointer
title: 'Sweep: AGENTS.md becomes the real instructions everywhere, CLAUDE.md a pointer beside it'
theme: docs-conventions
status: open
created: 2026-08-25
date_source: stated
order: 1
---
**AGENTS.md becomes the main instruction file everywhere, with a CLAUDE.md beside it that just
references it — not the other way round, which is how it is today.** Wanted 2026-08-25. A full sweep
across the platform and every plugin repo.
**The root pairing exists already, backwards.** `platform/AGENTS.md` is five lines: _"The instructions
live in `CLAUDE.md`. Read it first — this file only points there."_ `CLAUDE.md` is the real, long
document. That is the exact inverse of what is wanted, and it is the clearest single example of the
sweep: swap which file holds the content and which file points, keep both present so either harness's
auto-discovery convention finds the same guidance — which is the reasoning the current file already
states, just applied backwards.
**Four subdirectory `CLAUDE.md` files carry real, substantial documentation and have no `AGENTS.md` at
all** — found 2026-08-25, none of these have a pair to flip, they need one created:
`platform/src/apps/CLAUDE.md` (271 lines), `platform/src/databases/CLAUDE.md` (231 lines),
`platform/themes/CLAUDE.md` (118 lines), `platform/plugins/CLAUDE.md` (92 lines).
**Every plugin repo has NEITHER file — 19 of 19, checked 2026-08-25.** `atelier`, `bitcoin-wallet`,
`browser`, `desktop`, `email`, `example`, `gitea`, `invoices`, `iris`, `jellyfin`, `kiosk`,
`minesweeper`, `music`, `offscale`, `photos`, `proxy-manager`, `soulseek`, `transcribe`, `transmission`,
`vault` — none has a `CLAUDE.md` or an `AGENTS.md`. This is not a swap for plugins, it is adding the
convention where it does not exist yet. **`PLUGIN.md`, present in most of them, is a different document
and stays untouched** — it is the plugin's own manifest/reference doc (conventions, API surface), not
agent guidance; do not conflate the two when sweeping.
**Two lookalikes are NOT documentation and are out of scope for this sweep** — converting them would be
wrong, not just unnecessary:
- **Per-commander `CLAUDE.md` files** (`data/pastilhas@officer.dev/commanders/<id>/CLAUDE.md`) are a
single commander's own standing brief — operational state for one running agent, not source-tree
documentation nobody discovers it by directory convention the way a coding CLI does at a repo root.
- **`plugins/proxy-manager/chat/CLAUDE.md`** carries its own warning: _"rewritten from the plugin on
every chat that starts here, so an edit would be lost."_ Generated per session, not read by directory
convention either — injected directly into that chat's context by the plugin's own code.
**Note `atelier-work/` is a separate checkout carrying its own copies of the root, `themes/`,
`plugins/`, `src/apps/` and `src/databases/` `CLAUDE.md`/`AGENTS.md` files** — apparently a working
clone related to the Atelier extraction. Worth checking whether it is still live before sweeping it
twice; if it is a stale branch, the sweep only needs to happen once, in the platform repo.
---
**2026-08-25 — the owner points at prior art: `docs/claude-md-touchpoints.md`, an audit written the
same day, before any change, exactly so this sweep would not be guessed at.** It replaces the "two
lookalikes" section above with something precise: **three writers, one reader**, all named by file and
line —
1. `command-hq/directory.ts:653`, `createCommanderDirectory()` — generates a commander's `CLAUDE.md`
ONCE, at creation, from `commanderClaudeMd()`. Never rewritten afterward; the commander extends it
itself over its own life, which is why this file is correctly excluded from any flip — there is no
"primary content" to move, because the content is written by the commander, not shipped as
documentation.
2. `api/chat/websocket.ts:237`, `installPluginChatBrief()` — copies a plugin's own `chat/CLAUDE.md`
into a plugin-chat's directory, content-diffed so it only rewrites on an actual change. Of 19
plugins, exactly one (`proxy-manager`) ships one.
3. `scripts/backfill-commander-credentials.ts` — a manual, idempotent append pass over EXISTING
commander files, marker-guarded so it never duplicates a section.
4. `scripts/docs-check.ts` — read-only, checks `platform/CLAUDE.md` and `officer-dev/CLAUDE.md` (not a
plugin's, not a commander's) for numeric drift. This is the one file this sweep must not touch
carelessly: whatever ends up as the "pointer" file still has to carry the two numbers `docs:check`
parses out of it, or the check needs to move to reading `AGENTS.md` instead.
**Confirms the exclusion already written above, with better grounding — do not re-derive it, cite the
audit instead.** Commander files and plugin chat briefs are runtime-authored content injected into an
agent's cwd, not source-tree documentation a coding CLI discovers by walking up from where it starts.
Flipping "which file is primary" has no meaning for a file with no counterpart and no static content to
begin with.
**Two things the audit surfaces that are genuinely new and unresolved, not covered by "flip the pointer
everywhere":**
- **The owner's personal `~/.claude/CLAUDE.md` is explicitly, deliberately, never touched by any of
this** — the audit's own "Explicitly not written" section: the owner's sessions are un-isolated, `HOME`
points at their real home, and a generated file there would land inside the hand-maintained document
the owner edits directly (and that a terminal `claude` also reads). **This file is out of scope for
the sweep entirely** — it is not a repository doc, it is the owner's own, and it is inherently
Claude-specific by its path (`~/.claude/`), not something an `AGENTS.md` convention could apply to.
- **A commander's dynamically-generated file is named `CLAUDE.md` specifically, and commanders can run
under opencode.** The audit does not ask whether opencode discovers a `CLAUDE.md` in its working
directory the way Claude Code does — only Claude/opencode's actual read-side behaviour answers that,
and it was out of scope for an audit about WRITING. If opencode does not read `CLAUDE.md` by
convention, an opencode-run commander is silently briefed with nothing, which would be a real gap
this sweep should catch rather than one it assumes away. Check before deciding whether
`commanderClaudeMd()`'s output needs an `AGENTS.md`-named counterpart too.