All posts

REPO.md: the operational authority map at the repo root

An agent can read every file in a checkout and still misunderstand the system.

It can find two plausible task queues without knowing which one is current. It can edit a generated client because the upstream source is not obvious. It can search for prices that exist only in a payment dashboard. It can merge an innocent-looking change without knowing that the merge deploys production.

These are not failures of code search. They are missing facts about authority, negative knowledge, and consequences.

REPO.md gives those facts one stable home. It is a short operational map at the repository root: where consequential truth lives, what the repository only points at, and what happens when important things change.

Why a third root file earns its place

The first objection is correct: repositories already have Markdown files. Adding another free-form bucket would make orientation worse.

REPO.md earns a separate slot only because it has a narrower job and readers the other files do not share:

File Mode Question
README.md descriptive onboarding What is this, and how do I use it?
AGENTS.md / CLAUDE.md imperative instructions What rules govern my work?
CONTRIBUTING.md procedural guidance How do I submit a change?
REPO.md declarative reference Where is truth, and what happens when it changes?

The boundary is descriptive versus prescriptive. “Merge to main deploys the API” describes a durable side effect and belongs in the map. “Never merge without approval” grants no information about topology; it governs behavior and belongs in the agent file.

That separation matters because agent instructions are fragmented by design. A repository may carry several model- or harness-specific files with different permissions and workflows. The location of the canonical schema should not be copied into each one. A human on their first day, a coding agent, a shell script, and a portfolio renderer can all read the same neutral fact from REPO.md.

If a tiny repository has one agent surface and no other reader, a section in AGENTS.md may be enough. The convention becomes useful when the map needs to survive a change of agent or harness, orient more than one audience, or compose across repositories.

A disclosure card, not an encyclopedia

The useful analogy is a model card for repository authority: structured enough to make important omissions visible, but written for judgment rather than form completion.

The convention uses exactly two required sections:

# REPO.md

## In this repo
- **Work queue** — `TODO/` — canonical; [repotodo](https://repotodo.com) reads it — `todo ls`
- **Blog** — `content/posts/` — the site renders from here; no CMS copy

## Outside this repo
- **Prices & plans** — Stripe dashboard — code holds only the price IDs
- **Secrets** — 1Password — `.env.example` lists names; values never here

*Format: [repo.md](https://repo.md)*

Each record reads entity — local anchor or external authority — disambiguating claim. A parser can split the first two em dashes and preserve the rest as natural claim text. The shape is stable without requiring YAML, frontmatter, generated timestamps, completeness scores, or a central registry.

Three tests prevent the file from becoming another prose bucket.

First, use the local-anchor test: is the subject a meaningful path in this repository, or a fact about an entity anchored at one? If yes, put it under “In this repo” and keep its facts together. If no, put the external record authority under “Outside this repo.” A hosted database can be a fact about a locally anchored API; secret values remain outside even when .env.example lists their names.

Second, write claims, not inventory. A line earns its place only when it settles a question with more than one plausible answer. “Payments — Stripe” is visible in configuration and teaches little. “Prices live in Stripe; code holds only price IDs” tells a reader which copy wins and where a search ends.

Third, omission means unknown. REPO.md is selective. If billing is not mentioned, a reader cannot infer that billing is local, external, or absent. The goal is not a complete architecture catalog. It is a trustworthy map of the ambiguities most likely to cause wrong work.

Let the map grow without losing its shape

Facts stay attached to the entity they qualify. Deployments, live data, generated sources, relationships, and lifecycle status should not be scattered into detached inventories:

- **API** — `apps/api/` — Fly.io; merge to main deploys
  - data: Neon Postgres — schema in `apps/api/db/`; live rows never here
- **Client** — `packages/client/` — generated from `spec/api.yml`; not source

A deployment claim names both target and mechanism. “Runs on Cloudflare” is less useful than “merge to main deploys the Worker.” A manual release should say “deployed by hand: pnpm deploy.” The reader needs to know whether shipping happens to them or whether they must cause it.

Larger repositories may add optional ### groups inside “In this repo”:

  • Apps — what the repository ships.
  • Harness — systems that help humans and agents change it: work queues, knowledge bases, memory, skills, evals, and CI.
  • Ops — repo-owned operational records and engines: content, mail, runbooks, scheduled jobs, and internal operations.

These are presentation, not a type system. Small repositories skip them. The local-anchor test still decides what belongs inside, and a parser may ignore the groups entirely. A new heading per entity is a warning that architecture prose is leaking into the map.

The “Harness” group becomes more valuable as agentic systems move into the repository. A task queue, durable agent memory, an evaluation set, and local skills are no longer invisible properties of a hosted agent product; they are systems the repository can own and disclose. “Ops” does the same for content, mail, runbooks, and internal tools. REPO.md does not require that migration. It makes the current boundary legible as it moves.

Off the agent, off the harness

The highest-value fact in a repository should not exist only in the prompt of the agent currently working there. It also should not be trapped in a harness configuration that another agent cannot read.

That is why tools should primarily read REPO.md. Humans and agents author it from repository evidence and maintainer-confirmed external facts. A tool may propose a reviewable patch, but silent self-enrollment turns an authority map into advertising inventory.

The map also gives repo-native tools a clean way to compose. A work-queue tool can find the declared queue. A portfolio view can read maps across sibling repositories. A content or mail system can keep its record in files while an external service renders or delivers it. None of those tools owns the map, and the map does not depend on any of them.

That is the broader product direction: more systems agents can operate directly inside repositories, with fewer opaque integration layers. REPO.md remains the map above them.

Start with an audit, not a template

The first draft should come from evidence. Inspect workspace manifests, CI and deployment workflows, infrastructure configuration, environment examples, generated paths, data migrations, content and task systems, runbooks, and existing documentation. Trace source versus derived output. Determine which deployments are automatic and which are manual. Identify external truths the checkout can name but not prove.

Then ask a maintainer to confirm the invisible edges. A repository cannot prove what a dashboard owns or whether an old sibling repository is still canonical. Uncertainty should become a question, not a confident-looking line.

The REPO.md convention page now includes a complete copyable prompt that delegates that audit and writes the first draft. Run it with a coding agent at the repository root, review the external claims, and commit one map that every reader can share.