{
  "markdown": "# adrkit\n\n**Decision memory for human- and agent-authored plans** — architecture decision\nrecords that are machine-readable, enforceable in CI, and legible to agents,\nwithout leaving git.\n\n[![npm version](https://img.shields.io/npm/v/@adrkit/cli?logo=npm&label=%40adrkit%2Fcli)](https://www.npmjs.com/package/@adrkit/cli)\n[![CI](https://github.com/mbeacom/adrkit/actions/workflows/ci.yml/badge.svg)](https://github.com/mbeacom/adrkit/actions/workflows/ci.yml)\n[![ADRs](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fadrkit.dev%2Flint.json&query=%24.checked&label=ADRs&color=cb492d)](./docs/adr)\n[![ARB queue](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fadrkit.dev%2Fqueue.json&query=%24.totalItems&label=ARB%20queue&suffix=%20pending&color=cb492d)](./docs/adr)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](./LICENSE)\n\nMost ADR tooling is a markdown template and a static site generator. That\n*records* a decision; it doesn't make the decision *do* anything. adrkit treats a\nrecord as **typed data with a markdown body** and adds one field — `affects` —\nso a tool can answer *\"which decisions govern this pull request?\"* and put the\nanswer where the next decision is being made.\n\n## Decision governance, not generated documentation\n\n**Proposed interoperability direction:** [ADR-0037](docs/adr/0037-treat-generated-knowledge-systems-as-downstream-read-models-not-decision-authorities.md)\nis under review and has not been ratified.\n\nGenerated knowledge systems answer *\"how does the system work now?\"* adrkit\nanswers *\"what did people decide, what alternatives were rejected, and which\ndecisions govern this change?\"*\n\nTools such as [OpenWiki](https://github.com/langchain-ai/openwiki) can consume\nADRs as evidence and turn them into browsable current-state documentation. That\nis complementary to adrkit: the generated wiki is a downstream read model, while\nthe reviewed records in git retain authority over decision lifecycle and typed\nrelationships. Machine verification of generated content is not human\nratification of a decision.\n\nSee the provisional\n[generated-knowledge guide](https://adrkit.dev/generated-knowledge/) for the\nOpenWiki setup being evaluated and the proposed ownership boundary between the\ntwo tools.\n\n## Quickstart\n\nThe CLI is published as [`@adrkit/cli`](https://www.npmjs.com/package/@adrkit/cli)\nand exposes the `adr` binary. Published artifacts target **Node 22+**:\n\n```sh\nnpx @adrkit/cli lint                 # validate the corpus in docs/adr\nnpx @adrkit/cli explain src/payments/api.ts   # which decisions govern this file?\n```\n\nOr add it to a project (Bun-first repos can use `bun add -D @adrkit/cli` / `bunx`):\n\n```sh\nnpm i -D @adrkit/cli\n```\n\nThe pure library surfaces install independently:\n`npm i @adrkit/core @adrkit/evaluator`.\n\nSee the [Quickstart guide](https://adrkit.dev/quickstart/) and the full\n[command reference](https://adrkit.dev/commands/).\n\n## Choose a starting point\n\n| If you want to... | Start here | Notes |\n|---|---|---|\n| Validate or inspect an ADR corpus | [`@adrkit/cli`](packages/cli/README.md) | `npx @adrkit/cli ...` on Node 22+ |\n| Build your own tooling | [`@adrkit/core`](packages/core/README.md) | Pure parser, validator, matcher, and queue APIs |\n| Run the deterministic proposal checks | [`@adrkit/evaluator`](packages/evaluator/README.md) | Pass 0 is the shipped evaluator surface today |\n| Feed prior decisions to coding agents | [`@adrkit/mcp`](packages/mcp/README.md) | Local, read-only stdio MCP server |\n| Run adrkit from an OCI image | [Container usage](#container-usage) | Lockstep multi-architecture image, beginning with the first release containing ADR-0032 |\n| Comment governing decisions on pull requests | [Use in CI](https://adrkit.dev/ci/) | GitHub Action from this repository |\n| Evaluate decision governance with a generated wiki | [Generated knowledge guide](https://adrkit.dev/generated-knowledge/) | Provisional OpenWiki recipe; no runtime coupling |\n| Add decision memory to Spec Kit | [`@adrkit/spec-kit`](packages/adapters/spec-kit/README.md) | Published separately for Spec Kit `>=0.13.0,<0.16.0` |\n| Add decision memory to Copilot, Claude Code, or opencode | [`adrkit` agent plugin](packages/adapters/agent-plugin/README.md) | Install from this repository or marketplace |\n\n## Container usage\n\nBeginning with the first lockstep release containing\n[ADR-0032](docs/adr/0032-publish-one-lockstep-oci-image-after-the-coordinated-release-succeeds.md),\nreleases are published as a multi-architecture OCI image at\n`ghcr.io/mbeacom/adrkit`. Pin an immutable `vX.Y.Z` tag in automation; `vX`\nand `latest` move only after that lockstep release has completed:\n\n```sh\ndocker run --rm --read-only --network none \\\n  -v \"$PWD:/workspace:ro\" \\\n  ghcr.io/mbeacom/adrkit:vX.Y.Z lint\n\ndocker run --rm --read-only --network none -i \\\n  -v \"$PWD:/workspace:ro\" \\\n  ghcr.io/mbeacom/adrkit:vX.Y.Z mcp\n```\n\nThe MCP command keeps stdin open because MCP uses stdio. Its repository mount is\nread-only, matching the server contract; use an absolute host path in MCP client\nconfiguration. For CLI commands that intentionally write (`new`, or\n`migrate` without `--dry-run`), omit `--read-only` and the mount's `:ro`\nsuffix. The image runs as the non-root `node` user; on a host with a different\nUID/GID, add `--user \"$(id -u):$(id -g)\"`. On SELinux hosts, add the\nappropriate bind-mount label (for example, `:Z`).\n\nThe default image treats an unrecognized selector as an `adr` subcommand.\nExplicit selectors are `cli`/`adr`/`adrkit`, `mcp`/`adrkit-mcp`,\n`ci`/`adrkit-ci`, and `queue-action`/`adrkit-queue-action`. The default\n`--help` describes these selectors; `cli --help` opens the CLI command\nreference. The container also reserves `-h`, `container-help`, and\n`--container-help`; CLI help subcommands such as `help lint` otherwise pass\nthrough unchanged.\n\nBuild the same source locally with Docker or Podman. Purpose-specific `cli`,\n`mcp`, `ci`, and `queue-action` targets are isolated for local policy and SBOM\ninspection; the registry publishes only the all-in-one `adrkit` target:\n\n```sh\ndocker build -f Containerfile -t adrkit:local .\ndocker build -f Containerfile --target mcp -t adrkit-mcp:local .\ndocker run --rm --read-only --network none -i \\\n  -v \"$PWD:/workspace:ro\" \\\n  adrkit-mcp:local\n```\n\nThe two CI entry points preserve the existing GitHub Actions runtime contract:\nthey expect `GITHUB_WORKSPACE`, the event payload and repository environment,\n`INPUT_*` values, and a token. For hosted GitHub Actions, the repository-backed\nActions remain the simpler interface:\n`mbeacom/adrkit/packages/ci@v0` and\n`mbeacom/adrkit/packages/ci/queue@v0`. Container publication and recovery are\ndocumented in [`docs/RELEASING.md`](docs/RELEASING.md#oci-container-image).\n\nThe governing-decisions Action also has a repository-root entry point for its\nGitHub Marketplace listing. That root form is available beginning with\n`v0.13.0`; the existing `packages/ci` form remains supported.\nGitHub lists only root Action metadata, so the queue Action stays at its nested\npath.\n\n## What it looks like\n\n`adr queue` emits the review backlog as a deterministic, read-only projection of\nthe corpus — byte-for-byte identical for identical inputs:\n\n```text\n# ARB Queue — 2026-07-25\n\nCorpus fingerprint: `96e7f3185c5bb89bd1c87e10a28dcbef66703f381d3f14ea486ceaf29903cb00`\n7 item(s) | 0 corpus finding(s) | 0 item(s) with findings\n\n## Queue Items\n\n| # | ID | Title | Tier | SLA State | Deadline | Approvals | Objections |\n|---|----|-------|------|-----------|----------|-----------|------------|\n| 1 | `0005` | Gate proposals with a deterministic-first evaluator … | arb | within-sla | 2027-01-18 | 0/- | 0 |\n| 2 | `0015` | Validate descriptors against Backstage field formats … | arb | within-sla | 2027-01-25 | 0/- | 0 |\n```\n\nIn CI, the `@adrkit/ci` Action comments the governing decisions on the PRs that\ntouch them — read-only, comment-only, no database, no approval. See\n[Use in CI](https://adrkit.dev/ci/).\n\n## For agents: the MCP server\n\nThe most differentiated hook: `@adrkit/mcp` is a local, **read-only**\n[Model Context Protocol](https://modelcontextprotocol.io) server that lets an\nagent retrieve prior decisions — **including the rejected and superseded ones** —\nbefore proposing something already tried. No writes, no HTTP/auth, no model,\nembedding, or network access, and no persistent index. It exposes exactly four\ntools:\n\n| Tool | Purpose |\n|------|---------|\n| `search_decisions` | Filtered search across the corpus |\n| `get_decision` | Fetch one record by id |\n| `get_decision_context(files[])` | Decisions governing a set of files |\n| `list_superseded` | The graveyard — what was already rejected |\n\nRun it against a repository's corpus:\n\n```sh\nnpx @adrkit/mcp             # or the adrkit-mcp bin\nadrkit-mcp --cwd /path/to/repo --dir docs/adr\n```\n\n`--cwd` (env `ADRKIT_MCP_CWD`) must be a Git worktree root; `--dir` (env\n`ADRKIT_MCP_DIR`, default `docs/adr`) is resolved within it. stdout carries only\nJSON-RPC frames; diagnostics go to stderr; the graveyard is included by default.\nSee the [MCP setup guide](https://adrkit.dev/mcp/) and\n[`packages/mcp/README.md`](packages/mcp/README.md) for the full tool contracts.\n\n## For spec-driven workflows: the Spec Kit extension\n\n[Spec Kit](https://github.com/github/spec-kit) takes you from `specify` to\n`plan` to `tasks` to `implement`. What it does not do is check the plan it just\nproduced against the decisions you already made, or record the new decisions\nthat plan contains — so every feature starts from an empty context and\nre-litigates settled questions.\n\n[`@adrkit/spec-kit`](packages/adapters/spec-kit/README.md) closes that loop:\n\n| Command | Purpose | Writes |\n|---|---|---|\n| `/speckit.adrkit.context` | Pull the governing decisions — including rejected and superseded ones — into context *before* planning | no |\n| `/speckit.adrkit.check` | Check a produced plan against the decisions that govern it | no |\n| `/speckit.adrkit.draft` | Scaffold a draft ADR from the plan artifact | one new record |\n\nPlus one `after_plan` hook that *offers* to run the check. It is optional by\nconstruction, and hooks can only reach commands that do not write — `draft` is\ndeliberately unreachable from any hook, because a plan-phase hook creating\nrecords unprompted would manufacture decision memory rather than record it.\n\nPinned to Spec Kit `>=0.13.0,<0.16.0` and tested against 0.13.0, 0.14.4, and\n0.15.1. It is available from the Spec Kit community catalog; see the package\nREADME for setup.\n\n## For any coding agent: the plugin\n\n[Spec Kit](https://github.com/github/spec-kit) is one workflow. The place plans\nare actually written now is inside a coding agent that has no idea your decision\ncorpus exists.\n\n[`packages/adapters/agent-plugin`](packages/adapters/agent-plugin/README.md)\npackages the same loop as portable agent components — installable into GitHub\nCopilot CLI, Claude Code, opencode, and anything\n[APM](https://github.com/microsoft/apm) targets:\n\n```sh\ncopilot plugin marketplace add mbeacom/adrkit && copilot plugin install adrkit@adrkit\n/plugin marketplace add mbeacom/adrkit        # Claude Code, then /plugin install adrkit@adrkit\napm install mbeacom/adrkit/packages/adapters/agent-plugin --target opencode\n```\n\nEvery component shells out to the `adr` CLI, so install that too if you have not\nalready — `npm i -g @adrkit/cli`, or add `@adrkit/cli` to the project. The\ncomponents resolve it from `$ADRKIT_CLI`, then `./node_modules/.bin/adr`, then\n`PATH`.\n\n| Component | Purpose | Writes |\n|---|---|---|\n| `decision-memory` skill | Teaches the context → check → draft loop, the exit-code contract, and the rules that keep the record honest | no |\n| `decision-backfill` skill | Audits code, documentation, plans, and history for evidence-backed ADR candidates without treating implementation as ratification | no |\n| `decision-checker` agent | Reconciles a plan or diff against the corpus, one verdict per decision | no |\n| `/adr-context [paths...]` | Load the decisions governing the paths you are about to change | no |\n| `/adr-check [paths...]` | Check the change, or a plan, against them | no |\n| `/adr-draft <title-or-candidate-key>` | Draft one ADR from a current decision or selected backfill handoff | one new record |\n| `/adr-queue` | The review queue — the questions still open | no |\n| `/adr-backfill [paths...]` | Produce a coverage ledger and deduplicated candidate ADR report from an inherited codebase or documentation corpus | no |\n\nIt deliberately ships **no MCP configuration**: Copilot CLI spawns a plugin's\nMCP servers outside the workspace, and outside any Git repository, so the adrkit\nserver exits during `initialize`. MCP is wired per project instead — see the\n[plugin README](packages/adapters/agent-plugin/README.md#mcp-is-configured-per-project-not-shipped-here)\nfor the host-specific setup and\n[ADR-0028](docs/adr/0028-ship-decision-memory-as-a-portable-agent-plugin-and-omit-the-mcp-wiring-hosts-cannot-honor.md).\nThe backfill expansion is authorized by\n[ADR-0034](docs/adr/0034-extend-the-portable-agent-plugin-with-decision-backfill.md).\n\nStatus: installable today from this repository and versioned independently from\nthe npm packages. It makes the context -> check -> backfill -> draft loop\navailable inside current coding-agent hosts.\n\nThe backfill workflow is read-only until a human selects a candidate. See the\n[guide](https://adrkit.dev/backfill/) for source routing, evidence thresholds,\nstatus treatment, and the `/adr-backfill` → `/adr-draft` handoff.\n\nIndependently versioned per ADR-0007. The original context/check/draft/queue\nworkflow is at **rung 1** of ADR-0014 — unit and contract coverage plus\nmaintainer verification against the installed hosts. The v0.2.0 backfill\naddition is contract- and static-host-validated and has a fresh functional\nCopilot synthetic-consumer run proving candidate reconciliation and no writes.\nNo persistent reference-repository run or external validation exists for the\nplugin.\n\n## The problem\n\nYour organization decides something. Six months later nobody remembers, the\ndecision gets re-litigated, and the code drifts from what was agreed. Now agents\nwrite plans too — faster than anyone can review them, with no memory of what was\nalready decided and rejected.\n\n## The idea\n\nTreat a decision record as **typed data with a markdown body**, and give it one\nfield that changes everything — `affects`, declaring what the decision governs:\n\n```yaml\n---\nid: \"0042\"\ntitle: Use server-side rendering for authenticated routes\nstatus: accepted\nreversibility: one-way-door\nblastRadius: cross-team\naffects:\n  - type: path\n    pattern: \"apps/web/app/\\\\(authed\\\\)/**\"   # ( and ) are glob syntax — escape them\n  - type: package\n    pattern: \"next@>=16\"\n---\n```\n\nNow a tool can answer *\"which decisions govern this pull request?\"* — and put the\nanswer where the next decision is actually being made.\n\n## What it does\n\n- **`adr lint`** — validate records, catch supersession cycles, find decisions\n  that silently contradict each other. Warns when markdown under the corpus\n  directory is not discoverable, so \"checked 0 records\" is never silent.\n- **`adr migrate --from madr`** — adopt an existing MADR corpus in place,\n  additively, without breaking your current tooling. Reads status, date, and\n  deciders from MADR 3.x frontmatter, MADR 2.x `* Status:` bullets, and Nygard\n  `## Status` sections. `--rename` also renames each file to `<id>-<slug>.md`.\n- **`adr explain <path>`** — print every decision governing a file, and why.\n  Decisions reach a file in two directions and the output keeps them apart: the\n  record's own `affects` pattern matched (`via path: src/**`), or the file\n  declared the decision itself with an `@adr 0012` marker in a comment\n  (`declared by src/sync.ts:3`). Markers let `affects` stay narrow — the\n  defining files — while the surrounding code opts in one line at a time, in any\n  language, with no schema change. Only `accepted` records are reported as\n  governing; matched proposals and superseded/rejected/deprecated records are\n  listed separately.\n- **`adr check <files...>`** — validate the changed records and list the decisions\n  governing a changed-file set, including inbound `@adr` declarations. Marker reads\n  are bounded to 3,000 files / 16 concurrent reads, 64 declarations per file, and\n  10,000 declarations per batch, all reported in `--json`; marker claims and scan\n  warnings never influence the exit code.\n- **`adr evaluate <proposal> --snapshot <bundle.json> --date YYYY-MM-DD`** — run the\n  **deterministic, model-free Pass 0** over a proposal ADR plus an immutable offline\n  snapshot bundle. It applies the eleven rubric rules, escalates on **proven**\n  triggers to one named active human (or an explicit `unresolved`), and **returns**\n  a rich `Pass0Report` plus a schema-compatible `evaluationPatch`. It reads **no**\n  model, network, clock, or (in the library) filesystem, and **routes — it never\n  approves, persists, or writes**.\n- **`adr queue`** — emit the ARB operations queue: a read-only, deterministic\n  projection of the corpus's `review` metadata (tiers, SLA state, approvals,\n  objections) as Markdown or `QueueReport` v1 JSON; also a managed-issue Action.\n- **CI comment** — the `@adrkit/ci` GitHub Action surfaces the governing decisions\n  on the PRs that touch or explicitly declare them; pattern matches render as `via`\n  and PR-authored marker claims as `declared by`. The comment also distinguishes\n  marker files it could not inspect, marker declarations omitted at a safety cap,\n  claims it read but could not bind, and stale claims naming historical records.\n  All are advisory: they never fail the job.\n  It runs with only the default\n  `GITHUB_TOKEN` and degrades (never fails the job) on a read-only fork token.\n- **MCP server** — let agents retrieve prior decisions, including the rejected\n  ones, before proposing something already tried.\n\nIt never approves anything. It routes, and humans decide.\n\nThe first Marketplace release is planned as `v0.13.0`. Its immutable root\nreference gives a new adopter the complete governing-decisions workflow (see\n[Use in CI](https://adrkit.dev/ci/)):\n\n```yaml\nname: ADR governing decisions\n\non:\n  pull_request:\n\npermissions:\n  contents: read\n  pull-requests: write\n\njobs:\n  governing-decisions:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: mbeacom/adrkit@v0.13.0\n```\n\nUntil that release exists, and for existing consumers after it does, use\n`mbeacom/adrkit/packages/ci@v0`. The queue Action remains available at\n`mbeacom/adrkit/packages/ci/queue@v0`.\n\n## Why not plain MADR — or \"Structured MADR\"?\n\nadrkit's frontmatter is a strict [MADR](https://adr.github.io/madr/) superset, so\nthis is not \"instead of MADR\" — you can `adr migrate --from madr` an existing\ncorpus in place. The distinction is what happens *after* the record exists.\n\nA **template** — including a more structured MADR variant — standardizes how you\n*write* a decision. It does not:\n\n- **enforce it in CI** — adrkit resolves `affects` and comments the governing\n  decisions on the PRs that change the files they govern;\n- **answer \"which decisions govern this PR?\"** — that requires a pure,\n  reproducible matcher over typed `affects` fields\n  ([ADR-0009](docs/adr/0009-affects-resolution-and-catalog-binding.md)), not prose;\n- **let an agent retrieve the graveyard** — the read-only MCP server surfaces\n  `rejected`/`superseded`/`deprecated` records so an agent stops re-proposing them.\n\nA schema you can hand to a linter, a resolver, an agent, and a CI job is a\ndifferent artifact from a heading convention. That is the whole thesis.\n\n## Project status\n\nadrkit is still pre-1.0, but several surfaces are ready to use today. This\ntable is the short version:\n\n| State | Surface | What that means |\n|---|---|---|\n| Available now | `@adrkit/core`, `@adrkit/cli`, `@adrkit/evaluator`, `@adrkit/mcp` | Published on npm for Node 22+ |\n| Available now | `@adrkit/spec-kit` | Published separately for current Spec Kit releases |\n| Available now | `adr queue` and the governing-decisions GitHub Action | Queue reporting and PR comments are part of the shipped workflow |\n| Available now | `adrkit` agent plugin | Install from this repository or marketplace; shells out to `adr` |\n| In development | Later evaluator passes | Passes 1–3 and calibration remain design targets; Pass 0 is the implemented evaluator surface |\n| In development | Catalog packages | `@adrkit/catalog-envelope` and `@adrkit/catalog-backstage` exist in the workspace at `0.0.0` and are not released |\n| Planned | Additional downstream integrations | Future integrations will build on the current typed corpus and read-only retrieval model |\n\n## Design commitments\n\nThese are enforced, not aspirational. Each links to the record that decided it.\n\n| Commitment | Record |\n|---|---|\n| Git is the source of truth; every machine write opens a PR | [0001](docs/adr/), [0004](docs/adr/) |\n| The schema is a strict MADR superset — migrations are additive | [0002](docs/adr/) |\n| A clean clone with no credentials builds, tests, and lints green | [0007](docs/adr/) |\n| Every integration is an optional adapter; the core depends on none | [0007](docs/adr/) |\n| Match resolution is a pure function — reproducible in CI | [0009](docs/adr/) |\n| Deterministic checks run before any model call | [0027](docs/adr/) |\n| Bun is a development dependency only; published artifacts run on Node | [0010](docs/adr/) |\n| Parsers are deterministic; models suggest, they never parse | [0008](docs/adr/) |\n\n## Dogfooding\n\nEvery decision in this project is governed by this project. The repository's\nfirst commit is its own decision corpus — see [`docs/adr/`](docs/adr/). The\nevaluator rubric is itself versioned here too. The published evaluator currently\nimplements the deterministic Pass 0 only; later passes remain documented design\ntargets rather than released behavior.\n\n## License\n\nApache-2.0 — see [LICENSE](./LICENSE).\n\n**Exception:** the contents of [`schema/`](./schema/) are additionally released\nunder [CC0](./schema/LICENSE). The schema is intended to become a shared\ncontract; competing implementations should be able to adopt it with no license\nconsideration at all.\n\n## Toolchain\n\nBuilt with [Bun](https://bun.com) — see\n[ADR-0010](docs/adr/0010-bun-toolchain.md). **Bun is a development dependency\nonly.** Nothing published by this project requires it: the CLI, the GitHub\nAction, and the MCP server are Node-targeted and smoke-tested under Node 22 and\n24 in CI.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md), including the **\"Your first PR\"**\non-ramp. Contributions require a DCO sign-off, and must build from a clean clone\nwith no credentials configured.\n",
  "bytes": 22812,
  "sha": "8625a44311b9bd1f4b157383f798c4c652e6b7eae603b68bc7a3bc10c2c8c7e6",
  "repo_slug": "mbeacom/adrkit",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_dev_adrkit_mcp_99b66b08/readme"
}