AGENTS.md and concepts
The canonical agent instructions doc, the @AGENTS.md import from CLAUDE.md, and the read-on-demand convention for concepts/*.md.
Why AGENTS.md, not CLAUDE.md
Every provider has its own name for the instructions file it injects into an agent's system prompt — Claude Code reads CLAUDE.md, Cursor reads .cursorrules, Codex reads AGENTS.md, and so on. Maintaining the same content in multiple files is a drift hazard: the canonical version goes stale the moment one copy changes without the others.
This repo uses AGENTS.md as the single source of truth for agent instructions, and CLAUDE.md simply imports it:
@AGENTS.md
That one-line @AGENTS.md directive is an import instruction: when Claude Code loads CLAUDE.md, it sees the directive and pulls the entire contents of AGENTS.md into the agent's system prompt. From the model's perspective it's identical to reading AGENTS.md directly — but from the maintainer's perspective there is exactly one file to keep current.
Read on demand
AGENTS.md is deliberately short. It describes the platform in a few sentences, lists the concepts/*.md files, and points at the opsx:* skills — nothing more. Everything deeper is kept out of default context to save tokens.
The convention is:
- Always loaded:
AGENTS.md(via theCLAUDE.mdimport). - Loaded on demand: the
concepts/*.mdfiles. Agents read them explicitly, only when the task at hand requires that context.
The load-on-demand list below lives in AGENTS.md under the "Read on demand" heading. Agents follow it as a rule of thumb: if your task is in the "load when" column, read the corresponding file before touching code.
| File | Load when... |
|---|---|
concepts/overview.md | before adding a new backend source or making cross-cutting changes |
concepts/gateway.md | before touching Gateway code, designing new API endpoints, or writing Gateway-related openspec proposals |
concepts/wp-plugin.md | before touching the WordPress headless plugin |
Why not just load everything?
Two reasons:
- Tokens are finite. Loading every architecture doc into every agent's system prompt burns context budget on information 90% of tasks never need. Lazy loading keeps the default prompt tight and leaves headroom for actual work.
- Relevance signals clarity. When an agent has to pick which concept file to read, it has to first articulate what it's about to do. That moment of reflection catches a surprising number of misunderstood tasks before they turn into bad patches.
If you find yourself reading the same concept file in nearly every task, that's a signal the file should be promoted into AGENTS.md itself — or, more likely, that AGENTS.md should gain a one-line pointer summarising the key invariant.
concepts/ vs adr/
Two sibling directories, two very different contracts.
| Directory | Contract | Status |
|---|---|---|
concepts/ | Current-state architecture. Updated in place as the system evolves. Always reflects reality as of HEAD. | Active |
adr/ | Append-only Architecture Decision Records. Each ADR captures one decision ("why Hono", "why Postgres over X") and is never rewritten. | Not yet created — deferred |
The distinction matters:
concepts/*.mdis mutable. If the Gateway's cache strategy changes,concepts/gateway.mdis updated in the same PR. Git history is the audit trail, but the file at HEAD is always the truth.adr/*.mdwill be append-only. ADRs are added when a single decision needs a durable "why". An ADR is never edited in place — superseding decisions get a new ADR that references the old one.
ADRs are deferred. There is no adr/ directory yet. Add one when an individual decision genuinely warrants its own record — for example, a stack choice that will be asked about repeatedly, or a trade-off whose rationale isn't obvious from the code. Until then, concepts docs plus git history cover the need.
Editing the convention
If you need to change how agent instructions are structured:
Edit AGENTS.md
Make the change in AGENTS.md at the repo root. CLAUDE.md picks it up automatically via the @AGENTS.md import — no second edit needed.
Check the import is still in place
Open CLAUDE.md and confirm it still contains the single line @AGENTS.md. If someone has replaced it with inline content, restore the import.
Add or update a concept file if needed
If the change introduces a new architectural concept, add a concepts/<topic>.md file and list it under "Read on demand" in AGENTS.md with a one-line "load when" description.
Propose the change through openspec
Edits to AGENTS.md and concepts/ touch the concepts-docs and ai-tooling surfaces. Use the opsx:propose skill and declare both in the ## Surfaces affected section of the proposal.