All reference pages
Rule

Writing rules, CLAUDE.md and memory files (all projects)

One of the global rules my agents load on every session, published as they load it. Links to reference files point at documents I do not publish.

Source
rob/agents/policy/claude/claude-md-and-memory.md
Revision
8ffc462

These files load automatically — a CLAUDE.md in a session’s folder and every folder above it, a MEMORY.md index in every session in its project, every file in <config-dir>/rules/. Those tokens are spent before the user has said anything, and they are re-sent on every turn of the session.

Write instructions, not explanations

A rule is an instruction to an agent. It does not justify itself.

  • Imperative, not narrative. “Use --append-notes; the bare flag silently replaces the section.” Not three paragraphs on how that was discovered.
  • No dates, no changelog, no “an earlier version of this rule said”. State what is true now. Where a wrong belief is genuinely seductive, one clause is enough: “Tailnet Lock is off”, not the story of believing otherwise.
  • No rationale unless the rationale changes what you’d do. “Keep the directory name because a repository automation matches it exactly and a rename silently stops it” earns its clause. “This was chosen after careful consideration” does not.
  • A statement of fact beats a paragraph making the case for it. If a sentence could be deleted without changing any action an agent takes, delete it.

What earns a place in an always-loaded file

Gotchas and traps (“silently no-ops”, “the status command lies”, “a 2xx proves nothing”). Standing prohibitions. Decisions stated as the decision, not the debate. Deliberate omissions, marked as deliberate so they don’t get “fixed”. Non-guessable identifiers: IPs, tenant and app IDs, ports, absolute paths, credential locations, exact odd invocations.

What does not

  • Generic agent-behaviour rules — “read-only first”, “confirm before mutating”, “dry-run first”, “present a plan and wait”. The harness system prompt already says this.
  • “Related Context” tables restating the folder tree. Keep a line only where the relationship is non-obvious and load-bearing.
  • Command blocks a model writes unprompted (df -h, docker logs, systemctl status). Keep only non-guessable invocations: odd flags, exact API shapes, the one command that doesn’t lie.
  • Cached live inventory — device/user/policy tables, counts, “current health as of ”, versions stated as fact. It rots silently and is then trusted. Name the command that fetches it live.
  • Vendor endpoint or API reference — fetch it per context7.
  • Anything a parent CLAUDE.md already says. They load recursively; a child carries deltas only.

The progressive-disclosure seam

Content that is valuable but only matters for some tasks goes in a sibling .md (bulk under reference/), indexed as the last section:

## Deeper references
- `reference/dns-dhcp.md` — read before touching DNS or DHCP on this box

The seam must sit outside the auto-loaded directory. For a repo folder that means a sibling of CLAUDE.md. For the user-level config it means a sibling of rules/, not a subdirectory of it<config-dir>/rules/ is loaded recursively, so rules/reference/foo.md lands in every session’s context exactly like rules/foo.md, while <config-dir>/reference/foo.md is loaded by neither. Index those by their absolute ~/.claude/reference/<name>.md path so they resolve from the work config and the Linux servers.

The trigger must be specific enough to decide from (“read before granting the service account org-level IAM”, not “more on IAM”). An unindexed reference file is dead weight.

A rule that is mostly a lookup table, a config reference or a runbook belongs behind the seam, or as a skill — a skill’s body loads only when it is used, and only its one-line description is always on.

Memory files

MEMORY.md is always-on; the memories themselves are on-demand. Terseness pays in the index, accuracy pays in the files. One line per memory — the shortest hook that supports a decision to open it. name: must equal the filename stem. One fact per file. Never the same fact under two project keys. Don’t store what the repo permanently records; do store the expensive, correction-shaped and pending-action things. A memory recording an unfinished commitment must stay loud.

When you touch any of this

Learned something expensive — a live-verified fact, a negative result, a trap? Write it down as an instruction. Found two statements that disagree? Resolve it and delete the loser; do not keep both with a note explaining which won. Adding a long-lived plan or runbook? It’s a reference file with a trigger, not a new section.