adrman is a Git-first, agent-friendly CLI tool for managing Architectural (Any) Decision Records.
adrman helps humans and AI agents work with decision records as plain files in a Git repository.
The CLI binary name is adr.
- Keep decision records easy to create, review, and evolve through Git.
- Support configurable paths, templates, statuses, relationships, and indexes.
- Help agents discover existing decisions before proposing changes.
- Provide structured output for automation, CI, and AI-assisted workflows.
adrman is a Rust Cargo workspace.
cargo check --workspacecargo fmtcargo fmt --checkcargo clippy --workspace --all-targetscargo test --workspacecargo run -p adrman-cli --bin adr -- list- Bootstraps an ADR workspace in the current repository.
- Creates
docs/adr/when it does not exist. - Creates
docs/adr/.adr-template.mdwhen it does not exist. - Does not overwrite an existing
docs/adr/.adr-template.md. - Prints a success message when the template is created.
- Prints an informative message when the template already exists.
- Exits with status code
0for both created and already-existing outcomes.
Example:
adr init- Reads ADR files from
docs/adr/only. - Includes only files matching
^[0-9]+[-_ ].*\.md$. - Extracts:
IDfrom filename numeric prefixStatusfrom## StatusTitlefrom first#headingFileas base filename
- Uses
Unknownwhen title or status is missing. - If
docs/adr/is missing, prints a warning and exits successfully. - Sorts rows by numeric
ID, then byFile.
Output format:
ADRs (docs/adr/)
ID Status Title File
- Requires a title argument.
- Requires an existing ADR workspace:
docs/adr/anddocs/adr/.adr-template.md. - Does not create
docs/adr/or bootstrap a template when either is missing. - Discovers the next ADR ID from files in
docs/adr/matching^[0-9]+[-_ ].*\.md$. - Assigns the highest numeric filename prefix plus one, formatted as four digits (for example
0005). - Builds filenames as
<id>-<slug>.md, where the slug is a lowercase ASCII form of the title. - Populates new files from
docs/adr/.adr-template.md:- Replaces
# Titlewith the provided title. - Sets the initial
## Statuscontent toProposed.
- Replaces
- Refuses to overwrite an existing target file.
- Prints the created file path on success.
Example:
adr new "Use SQLite for local cache"- Validates ADR files in
docs/adr/only. - Reports markdown files in
docs/adr/that do not match^[0-9]+[-_ ].*\.md$, exceptdocs/adr/.adr-template.md. - Detects duplicate numeric ADR IDs across included files.
- Requires Nygard sections with exact
##headings:StatusContextDecisionConsequences
- Reports missing or empty required sections.
- Validates
Statusvalues against:ProposedAcceptedRejectedDeprecatedSuperseded
- Prints human-readable output by default.
- Supports
--format jsonfor agents and CI. - Exits with status code
0when all ADRs are valid. - Exits with a non-zero status code when validation fails or
docs/adr/is missing.
Examples:
adr check
adr validate --format json- Generates or updates
docs/adr/README.md. - Reuses the same ADR discovery and metadata extraction rules as
adr list. - Writes a Markdown table with columns
ID,Status,Title, andADR. - Each
ADRcell links to the ADR filename with a relative Markdown link. - Sorts rows by numeric
ID, then byFile. - Prints the written index path on success.
- Supports
--checkfor CI:- Exits with status code
0whendocs/adr/README.mdexists and matches the generated index. - Exits with a non-zero status code when the index is missing, stale, or
docs/adr/is missing.
- Exits with status code
Examples:
adr index
adr index --check