The repository's architecture decisions as objects: what was decided, why, what it cost,
and where the record came from. Under the layer's adrs section.
A decision is a file .ai/repo/adrs/<NNNN>-<slug>.md — YAML front matter satisfying
share/schemas/majordomus/adr/adr.v1.schema.json over a body carrying # Context, # Decision and
# Consequences. Nothing registers it: the source class adr in
.ai/repo/knowledge/sources.yaml discovers it over the tracked tree, which is the same
declaration the Rust executable indexes. See SCHEMAS.md for the contract.
majordomus adr list [--status <status>] [--json] every decision: id, status, date, title
majordomus adr show <id> [--json] the path, then the file as written
majordomus adr next [--json] the next free identity, and every source surveyed
majordomus adr propose "<title>" [--from <ref>]... write a new decision, status proposed
[--tag <tag>]... [--supersedes <id>]
majordomus adr check [--json] validate every decision and every reference
majordomus adr affected [--base <ref>|--staged|--worktree] [--json] the decisions a change set touches
-
listprints one line per discovered decision, invalid ones included;--statusfilters to one ofproposed,accepted,superseded,rejected. -
showprints the repository-relative path on the first line and the file below it. An id that is not a decision exits12and namesadr list. -
nextanswers what the next free identity is, and says what it looked at to decide. Four sources, each reporting how many identities it claimed: this working tree, every sibling worktree as it stands on disk (authored and not yet committed is a real claim), every ref — branches, tags, remote-tracking refs and every linked worktree'sHEAD, in onegit log --all --no-renames --diff-filter=A— and the peer board of the shared server, which is the only source that knows about an identity a session has decided to take and has not written anywhere. A source that could not be reached is reported as unreachable and never dropped silently from the denominator. Allocation is monotonic: one above the highest identity anything has ever claimed, never into a hole. A hole means an identity was taken and withdrawn, or taken and not yet written, and nothing can tell either from a number nobody ever used —0034of this repository is on no branch, in no tag and in no working tree, andADR 0035cites it. Holes are therefore listed as spent, with whatever cites them named as evidence for the reader. The shell tool has no peer identity of its own, so a session that announced an allocation and then asks is stepped over its own claim; the output says when the high-water mark came from a board claim.proposeallocates through the same survey. -
proposewritesstatus: proposedand nothing else. There is no way to writeaccepted:--statusexits15naming the reason, because a tool that can writeacceptedturns its own inference into repository truth and a later reader cannot tell which decisions a person actually made. The identity is allocated under a lock over the section directory, so two worktrees proposing at the same moment get two identities. A--fromreference is<type>:<value>with the type one ofdecision,session,commit,issue,file,test; afile:ortest:path that does not exist exits2. Referenced evidence makes the recordprovenance.origin: extracted, and an extracted record with no evidence is refused as an assertion.--supersedeswrites both halves of the relation, so the chain is walkable from either end. -
relatedis the other half of a record's references, and it is authored rather than written bypropose:rule:<id>,claim:<id>,file:<path>,test:<path>— what the decision put in force, as againstprovenance.derived_from, which is where it came from. Each is validated where its type says the target lives, and the extractor turns it into a graph edge (declares,supports,references,tested_by), so the reverse direction — which decision put this rule in force — isknowledge edges, not a second list somebody keeps in step. -
checkvalidates every record against the allow-list generated from the schema (no unknown key),schema: adr/v1, the closed status set, anidwhose number equals the file-name prefix, the required body sections; and across the set: duplicate identities, asupersededrecord with nosuperseded_by, one-sided supersession, and a reference that resolves to nothing. It exits10on any failure. -
checkalso asks the question no single tree can answer about itself: for every identity this tree adds relative to the base (origin/master,origin/main,master,main, in that order;MJ_ADR_BASEoverrides and is then the only candidate), does another ref carry a different document at that identity? A different file name is a competing claim and is refused, naming both documents, the refs that carry the other one, andmajordomus adr next; the same file name on two refs is an edit and is resolved by merging. The verdict always states its subject — how many identities were added and what they were measured against — and when the base does not resolve it says the other refs were not surveyed rather than exiting clean with nothing said.doctorruns the same examination: the pre-commit hook prints it on the branch, and CI's core-check refuses it there, rather than at the merge wheregenerate --strictwould exclude every claimant and name only the identity.ADR 0053is the reasoning. -
affectedreads a change set — the working tree againstHEADby default,--stagedfor the index,--base <ref>for<ref>..HEADplus the working tree — and names every decision whose own file changed, or whoserelatednames a path the change touches (a reference to a directory covers everything below it). Every item is aWARNreview note and the exit code stays0: whether a decision still holds after the code it governs moved is the judgement a tool may not make. It is the reverse question the graph answers — what decided this file? — asked from the change set instead of from a record.
doctor and watch run the same examination through the doctrine
majordomus.adr-integrity. The threshold for recording a decision at all is the rule
majordomus.decision-threshold, which a reviewer decides: the tool validates records and
reports what a change reaches, and never claims to know that a diff embodied a decision.
$ majordomus adr propose "The registry is the one canonical declaration" --from file:docs/CAPABILITIES.md
proposed: adr-0011 The registry is the one canonical declaration
.ai/repo/adrs/0011-the-registry-is-the-one-canonical-declaration.md
status is "proposed"; accepting it is a person editing that field.
$ majordomus adr check
examined 11 decision(s) in .ai/repo/adrs/
every identity unique, every status known, every reference resolves