diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..ce2bbc6
--- /dev/null
+++ b/AGENTS.md
@@ -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.
diff --git a/skills/kvb-agent-optimize/SKILL.md b/skills/kvb-agent-optimize/SKILL.md
index ddc0ca8..8dc04a5 100644
--- a/skills/kvb-agent-optimize/SKILL.md
+++ b/skills/kvb-agent-optimize/SKILL.md
@@ -15,8 +15,8 @@ scope: the current one, or those `kvb-optimize` hands over.
## Step 1: inventory
`${CLAUDE_SKILL_DIR}/scripts/agents.py --repo
` 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
diff --git a/skills/kvb-agent-optimize/scripts/agents.py b/skills/kvb-agent-optimize/scripts/agents.py
index 511aa57..57f44f9 100755
--- a/skills/kvb-agent-optimize/scripts/agents.py
+++ b/skills/kvb-agent-optimize/scripts/agents.py
@@ -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
diff --git a/tests/test_agent_optimize.py b/tests/test_agent_optimize.py
index 668babe..7d270e7 100644
--- a/tests/test_agent_optimize.py
+++ b/tests/test_agent_optimize.py
@@ -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"),