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:

markdown
@AGENTS.md
1 line of markdown code

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.

Source of truth

Canonical instructions live in AGENTS.md at the repo root. Architecture concept docs live under concepts/. If this page and those files disagree, the files win.

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 the CLAUDE.md import).
  • Loaded on demand: the concepts/*.md files. 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.

FileLoad when...
concepts/overview.mdbefore adding a new backend source or making cross-cutting changes
concepts/gateway.mdbefore touching Gateway code, designing new API endpoints, or writing Gateway-related openspec proposals
concepts/wp-plugin.mdbefore touching the WordPress headless plugin

Why not just load everything?

Two reasons:

  1. 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.
  2. 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.

DirectoryContractStatus
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/*.md is mutable. If the Gateway's cache strategy changes, concepts/gateway.md is updated in the same PR. Git history is the audit trail, but the file at HEAD is always the truth.
  • adr/*.md will 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:

1

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.

2

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.

3

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.

4

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.