# The repository-standards spec

Version 1.1.20 - the spec is versioned with the standard (`VERSION`). **The standard is
living and the only target is latest** (ADR-025): a repo complies against the state it
last aligned to, recorded in its own `.standards-version`. That record is a bookmark -
it makes an update a delta and self-verify a meaningful assertion, and it never names a
version to stay at. Tags mark the standard's own development; nothing downstream tracks
them. The key words MUST, MUST NOT,
SHOULD and MAY are to be read as in RFC 2119.

This page is the whole normative core. Everything else in the standard explains,
templates or enforces what is written here; where any other document appears to add
a requirement, this page wins. Rules are numbered R1-R27 and the numbers are stable -
tooling cites them. `standard.manifest.json` is this spec's machine-readable
projection (each manifest entry names the rule it enforces), and
`scripts/self-verify.mjs` reports unmet rules as a drift count. Rules the manifest
cannot check mechanically are verified at review or by the shipped guards the
skills invoke (the clarify gate checks R12 by script, outside the manifest).
Rules marked *(scale)* bind repos on the scale profile - which a repo is on by
reach, not by headcount (ADR-040); everything else is the core profile and
binds every repo, a solo one included.

## Entry and knowledge

- **R1.** A repo MUST carry `AGENTS.md` at its root as the single entry point for
  agents and humans: what the project is, where each kind of knowledge lives, how
  work flows. It MUST state the altitude order - `PRINCIPLES -> ADR/BDR -> specs +
  ARCHITECTURE -> conventions -> code` - which wins on conflict. Whatever file the
  repo's agent loads **first**, before it is asked anything, MUST point here and MUST
  carry the working rule: check whether a shipped skill covers the request before
  acting on it, and again when the work closes. For Claude Code that file is
  `CLAUDE.md`; another agent has its own. A rule that only exists one hop away is a
  rule the agent reaches after it has already started.
- **R2.** A repo MUST record the standard's state it last aligned to in
  `.standards-version`, and MUST carry the matching copy of
  `standard.manifest.json`. This is a bookmark, not a constraint - it is what makes
  an update a delta and self-verify a meaningful assertion, and nothing MAY read it
  as a version the repo is held at or as a compatibility requirement (ADR-025). The
  repo SHOULD carry the spec page (`SPEC.md`) the manifest projects, so the rules it
  is checked against are readable in place.
- **R3.** Project knowledge - documentation, specs, decisions, conventions - MUST
  live in the repo, versioned with the code. A rule that exists only in chat, a
  wiki or someone's personal agent config does not exist.
  **In a repo is not the same as in public.** Work whose *publication* is itself the
  harm - an unfixed vulnerability before its fix ships, a third party's material the
  repo is contractually bound not to publish, an unannounced commercial move with a
  set date - MAY be held in a private mirror of the repo (the platform's private
  advisory fork is the paved road) and MUST rejoin the mainline when the embargo
  lifts. This defers publication and waives nothing: every rule binds inside that
  mirror - the spec, the coupled change (R11), the backlog intent (R15) and the
  changelog entry are written there, while the work happens, not reconstructed
  afterwards. An embargo MUST name its lifting condition and its owner the moment it
  starts; one with no stated end is knowledge kept out of the repo, which is exactly
  what this rule forbids. "Not written up yet", "it is in the chat", and work someone
  would rather not publish are not embargoes. A repo that is already private needs
  none of this: its knowledge is in the repo, which is all this rule ever asked
  (ADR-034).
- **R4.** Documents are living: they MUST be updated in place. The current version
  is the truth; git is the history. When a change reverses something a future
  reader will need, the document SHOULD say so in one line. History MUST NOT
  accumulate inside a living document - a spec or doc carries no change-log
  section; git and the changelog (R18) hold the past (ADR-018).
  A **fact has one home**: a count, a version, a path or a command restated in
  another document MUST either link to its home or be a **declared** restatement -
  listed in `docs/facts.json` with its source, so `scripts/facts-check.mjs` fails
  when the two disagree. A restatement nobody declared is drift waiting for a
  reader to notice, and a surface reworded past its own declaration fails the same
  way: silence there is indistinguishable from agreement.

## Decisions

- **R5.** A contestable, re-litigable choice MUST be recorded as a decision record
  in `docs/decision-records/` - ADR for technical, BDR for business, MADR form. A
  settled way of doing a recurring thing MUST be written as a rule where the next
  person will look; the standard's taxonomy (adopted by reference from the living standard - always latest) is the map of where each kind lands.
- **R6.** An accepted record MUST NOT be edited into a different decision. It is
  superseded by a new record: status flip plus link. An accepted record **binds work
  in its scope** until it is superseded: a spec, plan or change that contradicts one
  MUST stop, and then either come into line or supersede the record. Writing around
  it is not a third option.
- **R7.** Every fork in the decision checklist that applies to the repo MUST be
  consciously decided and recorded; an area that does not apply MUST say so once,
  in one line. Silence is not an answer - an undecided area gets decided anyway, by
  whoever writes the first file that depends on it. Which areas apply is a property
  of what is being built, so this rule names no subset and asserts no count; the
  checklist owns the areas and carries a paved-road default for each, and accepting
  a default is a decision.

- **R8.** Behavior MUST be specified by capability - never by ticket, page or
  feature number.
- **R9.** A capability spec MUST be buildable by default: an agent could rebuild
  and verify the capability from the spec alone. The behavioral tier is an escape
  hatch that MUST be justified in the spec and SHOULD be rare.
- **R10.** Every capability spec MUST name the persona it serves; a spec that
  serves nobody fails the structure guard.
- **R11.** Every capability MUST have an entry in `specs/capability-map.json`
  binding it to code globs. A change to a capability's code MUST land in the same
  PR as its spec update. *(scale)* The coupling guard blocks any PR that breaks
  this. A capability whose implementation lives in a repository this one does not
  own MUST still have an entry: it names that repository, with a recorded reason,
  in place of the globs it cannot have. No coupling can be enforced for that part,
  and the audit names it on every run (ADR-039).
- **R12.** A spec MUST pass the clarify gate before planning or implementation:
  zero open questions, with explicit deferrals recorded as answers, never dropped.
- **R13.** Plan and task scaffolding is ephemeral and MUST be removed when the work
  closes. Specs, records and docs are permanent.

## Ideas and backlog

- **R14.** A speculative idea MUST NOT mint records or specs before it is approved.
  It lives in `docs/ideas/` under a status - idea, exploring, approved, parked,
  dropped, graduated - and on approval hands off to the normal flow (a backlog
  intent, a spec, any decision records the shape now demands), with the idea doc
  itself flipping to `graduated` and pointing at what it became.
- **R15.** The repo backlog holds intents, each with a definition of done; an item
  leaves only when its DoD is met. Execution state and work history live in the
  tracker - GitHub Issues by default, or an adapter for whatever the team already
  runs (Jira and Linear are field-proven; GitLab Issues and others follow the same
  shape). The list is not exhaustive - the tracker is wherever execution state
  actually lives, not a fixed set of product names.

## Verification and updates

- **R16.** Compliance MUST be enforced by tooling, not prose: `self-verify`
  (against the recorded manifest) and `spec-structure` MUST gate CI; *(scale)*
  `spec-guard` too. Aligned means self-verify reports drift 0. These guards, and
  `facts-check`/`schema-pair`, are dependency-free Node scripts (`scripts/*.mjs`),
  and the agent guards R19 relies on are shell scripts that read their input with
  `jq`. A Node runtime, a POSIX shell and `jq` MUST therefore be present to run
  what the standard ships, regardless of the repo's own language, stack or
  operating system - the complete list, and what each absence actually does,
  is `prerequisites.md` (by reference - it is not a file in this
  repo). This is a real cost for a non-Node repo and for a team on a platform
  with no POSIX shell, not a rounding error: adoption states it plainly, and a
  repo that cannot meet it records the guards it consequently does not run as a
  deviation - rather than letting it surface the first time CI runs, or never
  surfacing at all, which is what an absent guard does.
- **R17.** Adoption and updates MUST adapt, never blind-copy: align reconciles a
  repo to the standard - always the latest; the record then names the state
  aligned to, and an update applies the delta between that and latest,
  preserving the repo's recorded deviations (the manifest's `exceptions`).
- **R26.** Adoption's Step 0 (intake, ADR-020) MUST leave a record of what it
  measured and asked: `docs/adoption-intake.md`, a required manifest entry
  filled before any greenfield, brownfield or stack work proceeds and never
  deferred to a later wave - the same standing this standard already gives
  `PRODUCT.md` and `docs/personas.md` (ADR-042). An agent that skipped the
  question round and one that ran it in full produce the same tree without
  this file; the record is what makes intake checkable rather than merely
  claimed.
- **R27.** Adoption's assessment and count gates MUST leave artifacts that carry
  what the gate is for, not merely files: `docs/adoption-assessment.md`, a
  required manifest entry rating all eight assessment passes `absent` /
  `partial` / `solid`, naming the top risks, and grouping every finding by the
  owner role that must act; and a backlog whose alignment scope block states a
  total that its own categories sum to, every item naming its owner role
  (ADR-048). `adoption-gates` reads both for shape. R26 made a gate's artifact
  checkable by requiring it to exist; these two are the case where existing is
  not enough, because the count a human says go or no-go on is the part a file
  can omit while still being present.

## Releases and hygiene

- **R18.** A PR describes its change under the changelog's Unreleased heading and
  bumps the version itself, as part of that PR - PATCH by default, with no
  request required. The requester directs anything else, per PR and explicitly:
  a stated MINOR or MAJOR bump, or an instruction to withhold the bump entirely
  and leave the entry under Unreleased for a later PR to promote (see
  CONTRIBUTING.md) - at every profile, with no second mechanism. A repo that
  maintains more than one release line (R23) carries one changelog per line, each
  with its own Unreleased heading, and a PR bumps the line it targets - the same one
  mechanism applied per line, never a second one. A repo that ships more than
  one independently-versioned, independently-publishable unit from the same
  tree - a monorepo of packages, gems or crates, each on its own release
  cadence - carries one changelog per unit instead of one at the root, each
  with its own Unreleased heading, and a PR bumps every unit it actually
  touches. This is a different axis from the release-line clause above, not a
  variant of it: release lines split a changelog across branches over time,
  units split it across the same tree at once, and a repo can face either,
  both or neither - the one mechanism per line becomes one mechanism per unit,
  never a second kind of mechanism (ADR-044).
- **R19.** Secrets MUST NOT enter the repo - environment and a secret manager only.
  The shipped secret scan SHOULD gate CI, and agent access to remote databases
  SHOULD be write-blocked by the shipped settings baseline. The security baseline
  R7 requires as a recorded decision MUST state, at minimum, where each of the
  axes in `security-baseline.md` (by reference) lands for this repo - including the ones
  answered "not applicable", because an axis nobody considered and an axis
  deliberately dropped are indistinguishable a year later. Technology-specific
  depth belongs to the stack layer, never here.

## Layers and profiles

- **R20.** The standard is two layers, adoptable independently - Layer 1, this
  methodology, for any stack; Layer 2, optional technology best practices living
  in per-technology stack repos, official only when listed in the core registry
  (`stacks.json`) - and one standard with two profiles: core keeps knowledge
  alive in every repo, scale adds what carries it to people who are not in the
  room. Which profile a repo is on is a question about reach - work handed off
  asynchronously, contributors or readers outside the conversation, a release
  audience that is not the authors - and never about how many people it has
  (ADR-040). Solo repos meet core alone and are compliant. A stack declares what adopting it
  means in its own manifest (`stack.manifest.json`, the core schema); a repo
  that adopted one carries it, and `self-verify` counts one drift across both.
  A repo whose stacks coexist permanently carries one manifest per stack
  (`stack.<technology>.manifest.json`); every one is read and the drift stays a
  single number (ADR-037).

## Supply chain

- **R21.** Everything a repo consumes MUST be pinned exact and move only by an
  explicit, reviewed diff: dependency manifests and overrides carry exact versions
  (no ranges), sealed by a committed lockfile; container images, CI runners and
  actions name an exact version or digest - never `latest`, never a floating tag.
  A new version SHOULD clear a release-age cooldown (the paved road is seven days)
  before adoption; a critical security fix MAY bypass the cooldown through a
  recorded, temporary exclusion. Per-stack mechanics live in the stack repos
  (ADR-017).

## Agent executability

- **R22.** The lifecycle procedures - the spec loop, backlog capture, pre-PR
  review, version updates - MUST ship in the repo in a form the repo's coding
  agent can execute. The standard ships them as Claude-format skills
  (`.claude/skills/`) with their engine in `scripts/spec/` - the reference
  implementation. A repo whose agent tooling is not Claude MUST port them to its
  agent's own instruction mechanism (e.g. `.agents/skills`) - strictly and
  completely, before claiming compliance; `self-verify` accepts the ported
  location. A partial port is drift, not a variant (ADR-019).

## Integration and history

- **R23.** The mainline's history MUST read as one finished unit of work per
  **reviewed change**. The pull request is the paved road's unit of review; a
  repo whose review does not happen on the git host has another one - a
  mailing-list patch series, a Gerrit or Phabricator change - and MUST name it
  in the branching decision (R7), because every clause below binds to that unit
  and not to a platform feature. A branch is brought up to date by **rebasing
  onto its base**; the base MUST NOT be merged back into the branch. Every
  reviewed change MUST be based on the branch it will merge into - the mainline,
  or a **maintained release line** - never on another open change's branch. A
  maintained release line is a long-lived, protected branch that the repo has
  declared as supported with its branching decision (R7) and never rewrites;
  every requirement in this rule binds it exactly as it binds the mainline. A
  fix that applies to more than one line MUST land on the mainline first and
  reach each supported line as its own reviewed change against that line, unless
  the mainline no longer carries the affected code (ADR-035). It MUST land by
  **rebase-merge** (the paved road) or squash-merge - decided once and recorded
  with the branching decision (R7); the platform's linear-history protection
  SHOULD enforce it where the platform has one. Rebase-merge publishes every
  commit, so it MUST NOT be chosen unless each commit is a complete, buildable,
  reviewed change; a repo that will not hold that bar squashes instead. A branch
  MAY be rewritten while it is the author's alone; once another person or branch
  builds on it, it MUST NOT be (ADR-026).

- **R25.** A PR that changes what the standard ships describes that change under
  `CHANGELOG.md`'s `## Unreleased` heading and MUST move the version itself, in the
  same PR (R18) - the version MUST be one fact restated nowhere unchecked: every
  surface that carries it is declared and verified against its single home (R4).
  **Patch is the default and covers nearly everything** - the ordinary PR, however
  much prose it moves, bumps patch with no request required. **Minor is a judgment,
  not a trigger**: it is the requester's explicit, stated instruction on that PR,
  never derived mechanically from "a rule was added" or "a path changed"; that
  reasoning promotes routine work and inflates the number until it stops meaning
  anything, and it is spent sparingly. A PR MAY be told explicitly not to bump at
  all, leaving its entry under `Unreleased` for a later PR to promote; absent a
  stated MINOR, MAJOR or no-bump instruction, patch is what ships. The patch
  position is not a two-digit field: 1.0.12 is followed by 1.0.13, then
  eventually 1.0.99, then 1.0.100 - each larger than the last, never resetting to a
  two-digit assumption. Versions mark this standard's own development; an adopting
  repo still tracks latest and never a pin (ADR-025).


## Data and schema

- **R24.** A repo that owns a database MUST carry that schema as executable DDL
  under `database/schema/`, complete enough to rebuild the database from a
  checkout alone - the disaster-recovery copy, and the artifact a schema change
  ships as (R19: an agent prepares the reviewed file, a human applies it).
  Migrations stay how a change reaches a database; they are the delta, never the
  readable current state. The same schema MUST also exist as a **typed,
  documented** definition in the stack's idiom (Zod in TypeScript, Pydantic in
  Python), and every path that reads or writes the database MUST go through it
  rather than restating row shapes inline. The two are **1:1**: every table,
  column, constraint and enum present in one is present in the other, each side
  names its counterpart, and a change to either MUST land in the same PR as the
  change to the other. Each side MUST name its counterpart in the file itself, so
  the pair is a declared edge rather than a convention: the shipped
  `scripts/schema-pair.mjs` resolves it both ways and fails when a name the DDL
  defines is absent from the twin. Either side MAY be generated from the other
  where the stack has a generator that does not silently drop what DDL can
  express; type agreement and generation are per-stack mechanics and live in the
  stack repos (ADR-027).
  **Owning a database and shipping the mechanism that changes one are different
  shapes.** A repo whose product *is* the schema change - a migration library, an
  ORM's DDL layer, a schema toolkit - owns no database: what it emits runs against
  somebody else's. `database/schema/` and the typed twin therefore do not apply,
  and the repo says so once (R7). What it does own is that emitted DDL, for every
  backend it claims to support, and that is an interface contract: it MUST be
  specified verbatim per backend (R9), including where the backends genuinely
  differ, so a supported backend's gap is something the spec states rather than
  something a consumer discovers in production.

## What this standard does not do

It does not mandate a tracker, a CI vendor or a stack - Layer 2 is a paved road,
not a toll gate. It carries no company-specific configuration: tokens, tenant ids
and their like stay variables. It does not accept per-ticket or per-page specs -
that shape is rejected, not merely omitted (R8). It is not an open-source community
kit: codes of conduct, support and governance files are the adopter's own affair.
Edge cases and "what about X" belong in the standard's FAQ, never here as new rules.
