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.mdat 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 isCLAUDE.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 ofstandard.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.jsonwith its source, soscripts/facts-check.mjsfails 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.jsonbinding 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 tograduatedand 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) andspec-structureMUST gate CI; (scale)spec-guardtoo. Aligned means self-verify reports drift 0. These guards, andfacts-check/schema-pair, are dependency-free Node scripts (scripts/*.mjs), and the agent guards R19 relies on are shell scripts that read their input withjq. A Node runtime, a POSIX shell andjqMUST 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, isprerequisites.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 givesPRODUCT.mdanddocs/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 passesabsent/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-gatesreads 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, andself-verifycounts 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 inscripts/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-verifyaccepts 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## Unreleasedheading 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 underUnreleasedfor 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 shippedscripts/schema-pair.mjsresolves 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.
