docs(agents): make AGENTS.md the only instruction file and require platform-agnostic work
Adds AGENTS.md with the binding rule that skills, scripts, hooks and installs work on every agent runtime (Claude Code, Codex, Gemini CLI, Hermes, OpenClaw) and every OS: logic in scripts, runtime hooks as thin adapters, cross-runtime install locations, no single package manager. Claude Code reads AGENTS.md natively since v2.1.277, so no CLAUDE.md or GEMINI.md exists; kvb-agent-optimize now flags CLAUDE.md, .claude/CLAUDE.md, CLAUDE.local.md and GEMINI.md as drift to fold into AGENTS.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ca98ab4a30
commit
bd73b197b2
4 files changed
+54
-14
No files matched your search
@@ -0,0 +1,32 @@
|
||||
# Agent Instructions
|
||||
|
||||
## Platform-agnostic development
|
||||
|
||||
Everything in this repository MUST work on every agent runtime, not only on
|
||||
the one developing it: Claude Code, Codex, Gemini CLI, Hermes, OpenClaw and
|
||||
any other that reads skills. The same holds for operating systems and
|
||||
distributions.
|
||||
|
||||
- **Logic in scripts**: behaviour lives in `python3` or `bash` scripts that
|
||||
any runtime can call. Hooks, plugins and settings of one runtime are thin
|
||||
adapters over those scripts, never the only path to a feature.
|
||||
- **Skills stay portable**: a `SKILL.md` that uses a runtime-specific tool
|
||||
(`AskUserQuestion`, `SendMessage`, a slash command) says what the step
|
||||
needs, so another runtime can use its own equivalent.
|
||||
- **Installs reach every runtime**: install into the cross-runtime locations
|
||||
(`~/.agents/skills`) or through an installer that configures every
|
||||
detected agent; runtime-specific locations are mirrors. Of a tool that
|
||||
ships both, take the agent-agnostic integration over one runtime's plugin,
|
||||
and never both: the same server would run twice.
|
||||
- **No single package manager**: an install never depends on one OS or
|
||||
distribution's package manager; prefer upstream or statically linked
|
||||
release builds.
|
||||
- **One instruction file**: rules live here and nowhere else; no
|
||||
`CLAUDE.md`, `CLAUDE.local.md` or `GEMINI.md`. Claude Code reads this file
|
||||
natively from v2.1.277; Gemini CLI once its `context.fileName` setting
|
||||
lists `AGENTS.md`.
|
||||
|
||||
## Code questions
|
||||
|
||||
Ask the codebase-memory-mcp graph first (`search_graph`, `trace_path`,
|
||||
`get_architecture`); grep only after it.
|
||||
@@ -15,8 +15,8 @@ scope: the current one, or those `kvb-optimize` hands over.
|
||||
## Step 1: inventory
|
||||
|
||||
`${CLAUDE_SKILL_DIR}/scripts/agents.py --repo <dir>` prints one line per
|
||||
check: AGENTS.md, whether CLAUDE.md and GEMINI.md point to it, dead relative
|
||||
links in it, whether it names the index, whether the index binary is
|
||||
check: AGENTS.md, any runtime-specific instruction file beside it, dead
|
||||
relative links in it, whether it names the index, whether the index binary is
|
||||
installed, and the state of the shared snapshot
|
||||
`.codebase-memory/graph.db.zst`.
|
||||
|
||||
@@ -48,8 +48,11 @@ installed, and the state of the shared snapshot
|
||||
|
||||
## Step 3: instructions
|
||||
|
||||
- AGENTS.md is the single source; CLAUDE.md and GEMINI.md only point to it
|
||||
(`@AGENTS.md`).
|
||||
- AGENTS.md is the only instruction file: fold any `CLAUDE.md`,
|
||||
`.claude/CLAUDE.md`, `CLAUDE.local.md` or `GEMINI.md` into it and remove
|
||||
them. Claude Code reads AGENTS.md natively (v2.1.277+) but skips it while a
|
||||
`CLAUDE.md` is on the path; Gemini CLI reads it once `context.fileName`
|
||||
lists it.
|
||||
- AGENTS.md sends code questions to the graph first (`search_graph`,
|
||||
`trace_path`, `get_architecture`) and to grep only after it.
|
||||
- `/claude-api prompt-audit` over AGENTS.md and the files it references finds
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Report how ready a repository is for agents: instructions, pointers, code index.
|
||||
"""Report how ready a repository is for agents: instructions, runtime-specific files, code index.
|
||||
|
||||
Args:
|
||||
--repo: path of the repository.
|
||||
@@ -21,7 +21,7 @@ import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
POINTERS = ("CLAUDE.md", "GEMINI.md")
|
||||
RUNTIME_FILES = ("CLAUDE.md", ".claude/CLAUDE.md", "CLAUDE.local.md", "GEMINI.md")
|
||||
INDEX = "codebase-memory-mcp"
|
||||
SNAPSHOT = ".codebase-memory/graph.db.zst"
|
||||
LINK = re.compile(r"\]\(([^)\s#]+)")
|
||||
@@ -50,11 +50,11 @@ def checks(repo: Path) -> list[tuple[str, str, str]]:
|
||||
agents = repo / "AGENTS.md"
|
||||
text = agents.read_text(encoding="utf-8") if agents.is_file() else ""
|
||||
rows = [("AGENTS.md", "ok" if text else "missing", "single source of the agent instructions")]
|
||||
for name in POINTERS:
|
||||
pointer = repo / name
|
||||
if pointer.is_file():
|
||||
points = "AGENTS.md" in pointer.read_text(encoding="utf-8")
|
||||
rows.append((name, "ok" if points else "drift", f"{'points' if points else 'does not point'} to AGENTS.md"))
|
||||
rows.extend(
|
||||
(name, "drift", "runtime-specific; fold into AGENTS.md and remove")
|
||||
for name in RUNTIME_FILES
|
||||
if (repo / name).is_file()
|
||||
)
|
||||
dead = sorted(
|
||||
{
|
||||
target
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Exercise agents.py: instruction pointers, dead links, index pointer, binary and snapshot state."""
|
||||
"""Exercise agents.py: runtime-specific files, dead links, index pointer, binary and snapshot state."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -48,6 +48,9 @@ class TestAgents(unittest.TestCase):
|
||||
)
|
||||
(repo / "CLAUDE.md").write_text("@AGENTS.md\n", encoding="utf-8")
|
||||
(repo / "GEMINI.md").write_text("own rules\n", encoding="utf-8")
|
||||
(repo / ".claude").mkdir()
|
||||
(repo / ".claude" / "CLAUDE.md").write_text("x\n", encoding="utf-8")
|
||||
(repo / "CLAUDE.local.md").write_text("x\n", encoding="utf-8")
|
||||
(repo / ".codebase-memory").mkdir()
|
||||
(repo / ".codebase-memory" / "graph.db.zst").write_bytes(b"x")
|
||||
(repo / ".gitignore").write_text(".codebase-memory/\n", encoding="utf-8")
|
||||
@@ -59,8 +62,10 @@ class TestAgents(unittest.TestCase):
|
||||
self._report(repo),
|
||||
{
|
||||
"AGENTS.md": ("ok", "single source of the agent instructions"),
|
||||
"CLAUDE.md": ("ok", "points to AGENTS.md"),
|
||||
"GEMINI.md": ("drift", "does not point to AGENTS.md"),
|
||||
"CLAUDE.md": ("drift", "runtime-specific; fold into AGENTS.md and remove"),
|
||||
".claude/CLAUDE.md": ("drift", "runtime-specific; fold into AGENTS.md and remove"),
|
||||
"CLAUDE.local.md": ("drift", "runtime-specific; fold into AGENTS.md and remove"),
|
||||
"GEMINI.md": ("drift", "runtime-specific; fold into AGENTS.md and remove"),
|
||||
"links": ("drift", "docs/b.md"),
|
||||
"index-pointer": ("ok", "AGENTS.md names codebase-memory-mcp"),
|
||||
"index-binary": ("ok", "codebase-memory-mcp on PATH"),
|
||||
|
||||
Reference in new issue
Block a user