Skip to content

adrinaline: Git-native Architecture Decision Records for humans and coding agents

CI PyPI Python OpenSSF Scorecard OpenSSF Best Practices

Why

An Architecture Decision Record (ADR) is a short file that records one significant decision, the options considered and the consequences. Keeping them next to the code means new team members and coding agents can see why things are the way they are.

  • One command bootstraps the practice: adr init.
  • Plain Markdown with YAML frontmatter; hand edits stay first-class.
  • Sequential numbering, with collisions between branches detected early.
  • adr check validates the set in CI or pre-commit, with GitHub annotations or a GitLab Code Quality report; adr check --fix repairs the mechanical findings.
  • Read-only git integration: it never stages, commits or fetches.
  • The ADR set is a graph (text, Mermaid, DOT, JSON), tied to code via scope globs and queryable at any git revision.
  • Decision health: review-by dates and churn over an ADR's scope (adr drift), reported by adr check and adr prime.
  • Commit traceability: ADR: trailers tie commits to decisions (adr trace), and adr check --diff flags governed changes that cite none.
  • Every command has --json; adr prime briefs an agent at session start.

How it compares

adrinaline adrs adr-tools log4brains MADR
What it is Python CLI Rust CLI Shell scripts Node CLI + static site Template only
Create, link, supersede yes yes yes create from template no CLI
Validation for CI adr check, with GitHub and GitLab annotations adrs doctor no no no
Decision graph export text, Mermaid, DOT, JSON DOT DOT web UI no
Tie decisions to code (scope, adr for) yes no no no no
Commit traceability (ADR: trailers) yes no no no no
Decision health (review dates, scope drift) yes no no no no
Agent integration any agent with a shell: skill + adr prime, no server MCP server no no no

Cells for the other tools reflect their READMEs; "no" means the feature is not documented there.

Install

uv tool install adrinaline   # provides `adr` (and `adrinaline`)
# or run without installing:
uvx adrinaline --help
# or:
pipx install adrinaline

Requires git. Python 3.14+ is needed; uv tool install and uvx download it automatically if it is missing.

Quick start

adr init                                   # docs/adr/.template.md + 0001-record-architecture-decisions.md, then next steps
adr new "Use PostgreSQL" --tag storage --scope "src/db/**"  # docs/adr/0002-use-postgresql.md (proposed)
adr accept 2
adr new "Use PostgreSQL 17" --supersedes 2 --accepted
adr list
adr graph --format mermaid                 # paste into any GitHub/GitLab Markdown file
adr check                                  # CI-friendly validation

An ADR is a Markdown file with frontmatter (docs/adr/0003-use-postgresql-17.md):

---
status: accepted
date: YYYY-MM-DD
supersedes: [2]
---
# Use PostgreSQL 17

## Context and Problem Statement

## Considered Options

## Decision Outcome

Chosen option: "…", because …

### Consequences

* Good, because …
* Bad, because …

Status lifecycle

Statuses: proposed, accepted, rejected, deprecated, superseded.

From To Command
(new) proposed adr new
(new) accepted adr new --accepted
proposed accepted adr accept
proposed rejected adr reject
accepted deprecated adr deprecate
accepted superseded adr supersede

Example output

adr list:

0001  accepted    YYYY-MM-DD  Record architecture decisions
0002  superseded  YYYY-MM-DD  Use PostgreSQL
0003  accepted    YYYY-MM-DD  Use PostgreSQL 17

adr prime --budget 150 (shortened):

# ADR briefing

ADRs live in `docs/adr`: 2 accepted, 1 superseded.

## Decisions in force

- 0001 Record architecture decisions
- 0003 Use PostgreSQL 17

## Proposed

None.

adr graph --format mermaid:

flowchart LR
  A1["0001 Record architecture decisions"]:::accepted
  A2["0002 Use PostgreSQL"]:::superseded
  A3["0003 Use PostgreSQL 17"]:::accepted
  A3 -->|supersedes| A2
  classDef proposed fill:#fff4cc
  classDef accepted fill:#d9f2d9
  classDef rejected fill:#f2d9d9
  classDef deprecated fill:#e6e6e6
  classDef superseded fill:#e6e6e6,stroke-dasharray:4 2
  classDef missing fill:#ffffff,stroke-dasharray:2 2

Tie decisions to code

Add scope globs to an ADR's frontmatter:

scope: ["src/db/**", "migrations/**"]

Then:

adr for src/db/pool.py                     # which decisions govern this file?
adr check --diff origin/main --strict      # CI gate: changed files governed by ADRs in force

CI

- uses: actions/checkout@v7
  with:
    fetch-depth: 0   # shallow or fresh clones lack origin/main history, so --diff fails
- uses: astral-sh/setup-uv@v10.3.3
- run: uvx adrinaline check --diff origin/main --strict --format github  # annotates the PR

GitLab, with findings in the merge request's Code Quality widget:

adr-check:
  image: ghcr.io/astral-sh/uv:python3.14-bookworm  # non-slim: --diff needs git
  variables:
    GIT_DEPTH: 0   # --diff needs the target branch history
  script:
    - git fetch origin "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
    - uvx adrinaline check --diff "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" --strict --format gitlab > gl-code-quality.json
  artifacts:
    when: always
    reports:
      codequality: gl-code-quality.json
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

pre-commit

repos:
  - repo: https://github.com/maximiliancw/adrinaline
    rev: vX.Y.Z  # a release tag that contains .pre-commit-hooks.yaml
    hooks:
      - id: adr-check

The hook runs adr check --strict when files under docs/adr/ change; override files if your ADRs live elsewhere. The hook installs adrinaline, which needs Python 3.14 on PATH.

Exit codes and error codes: CLI reference.

History

Every read command accepts --at REF:

adr list --at v1.2 --status accepted       # what was in force at release 1.2?
adr log 7                                  # git history of ADR 0007
adr trace 7                                # commits whose ADR: trailer cites 0007

Git access is read-only, and adr log only sees committed changes, so commit first.

For coding agents

adr init --agents (or adr init on a terminal, which asks) adds the adr prime line below to AGENTS.md (or CLAUDE.md when only that exists) and installs the skill, which teaches agents when and how to write ADRs, where the agents it detects read it: .claude/skills/adr when the repo has CLAUDE.md or .claude/ (or you have ~/.claude/CLAUDE.md), .agents/skills/adr when it has AGENTS.md, .agents/, .cursor/ or .github/ (or nothing). To install by hand:

Agent Install
Claude Code adr skill --install .claude/skills/adr
Codex adr skill --install .agents/skills/adr
Cursor adr skill --install .cursor/skills/adr (also reads AGENTS.md)
GitHub Copilot adr skill --install .github/skills/adr

Codex, Cursor and Copilot all read .agents/skills/, so one install there covers all three. Rerun the install after upgrading adr; adr check reports stale-skill for an installed skill from another version.

Or install the skill without adr writing files, from any agent supported by the skills CLI:

npx skills add maximiliancw/adrinaline

In Claude Code, the plugin adds the skill plus a SessionStart hook that runs adr prime (silent when adr is missing or the repo has no ADRs):

/plugin marketplace add maximiliancw/adrinaline
/plugin install adrinaline@adrinaline

Both still need the adr CLI on PATH. Update those copies with npx skills update or /plugin update; adr check leaves them out of stale-skill.

Or add one line to AGENTS.md (or your agent's equivalent):

Run `adr prime` at the start of every session and follow the ADRs it lists.

adr prime --budget 400 limits the decisions-in-force list to about 400 words, picking the most important and most relevant decisions first (the top-scored ADR is always shown). Agents create ADRs as proposed; humans accept them. Every command accepts --json.

Commands

Command What it does
init create the ADR directory, template and ADR 0001
new create a new ADR
show show one ADR
list list ADRs
index print a Markdown index table
accept / reject / deprecate set an ADR's status
review record that an ADR was reviewed today
supersede mark OLD as superseded by NEW
link / unlink add or remove a relation
graph render the ADR graph
renumber give an ADR a new number and update references
log show the git history of an ADR
trace list the commits that cite an ADR
for list the ADRs in force that govern each path
drift show churn over each ADR's scope since its baseline
check validate all ADRs (text, GitHub annotations or GitLab Code Quality); --fix repairs mechanical findings
prime print the agent briefing
skill print or install the bundled agent skill

Full documentation: https://maximiliancw.github.io/adrinaline/. Changelog: GitHub Releases. This repo's own decisions are in docs/adr/.

Questions, bug reports and feature requests go to GitHub Issues; vulnerabilities go through the security policy. To contribute code, see CONTRIBUTING.md.

License

MIT