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

6.4 KiB

id, title, theme, status, created, date_source, order
id title theme status created date_source order
docs-conventions/sweep-agents-md-primary-claude-md-pointer Sweep: AGENTS.md becomes the real instructions everywhere, CLAUDE.md a pointer beside it docs-conventions open 2026-08-25 stated 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.