# Manage Adrs

> Use whenever the user wants to create, review, approve, reject, version, revise, supersede, undo, migrate, configure, audit, or fix the header/format of Architecture Decision Records (ADRs) via the `adrplus` CLI tool — including bringing pre-existing, hand-written ADR files into compliance with the adrplus schema, and managing adrplus's own plugin system (`adrplus plugins`/`sync`). Trigger on requests like "create an ADR for X", "approve this ADR", "supersede ADR 0001", "set up adrplus in this repo", "fix these ADR headers to match adrplus", "adjust our ADRs to the adrplus standard", "list/activate/install an adrplus plugin", or any mention of ADRs/architecture decision records in a repo that could use adrplus.

- Skill: `fracerqueira/manage-adrs-2` (Agent Skill)
- Install (CLI): `npx skillmds@latest add fracerqueira/manage-adrs-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/fracerqueira/manage-adrs-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: FRACerqueira (https://skillmd.com/u/fracerqueira)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/fracerqueira/manage-adrs-2

---


> Ported from this repo's Claude Code skill (`skills/manage-adrs/SKILL.md`). Content is functionally identical — only `allowed-tools` syntax and a couple of tool-name references below were adapted for the GitHub Copilot / Agent Skills open standard (agentskills.io/specification), plus a foreground-fallback clause in "Before committing or opening a PR" below (deliberate: not every Copilot surface supports launching a subagent non-blocking, unlike Claude Code). **A caveat on `allowed-tools` above, checked against primary sources**: the spec (agentskills.io/specification) marks this field "Experimental — support may vary between agent implementations," and its own official example uses Claude-style names (`Bash(git:*) Read`) — which is why this line keeps Claude's tool vocabulary rather than translating to `runCommands`/`codebase`/`editFiles`/`search` (the *separate* vocabulary this repo's `copilot/agents/*.agent.md` custom agents use — a different GitHub Copilot mechanism, VS Code custom chat agents, not Agent Skills). Concretely, per surface: GitHub Copilot CLI's own docs instead expect a single `shell`/`bash` value here, specifically to skip its terminal-confirmation prompt; VS Code Copilot Chat's SKILL.md validator currently doesn't recognize `allowed-tools` at all (a confirmed VS Code bug, tracked as `microsoft/vscode-copilot-release#14131`), so this line has no effect there either way. Don't assume this field is verified/authoritative for whichever Copilot surface you're actually using — it may do nothing, or may need to become `allowed-tools: bash` instead. There is no generator yet: if the canonical Claude version changes, re-sync this file by hand. **Last synced: 2026-08-27.**

# Managing ADRs with adrplus

`adrplus` is a cross-platform .NET CLI tool for managing Architecture Decision Records. This skill teaches you how to drive it directly, without ever going through its interactive `--wizard` mode.

## Critical rule: never use `--wizard`/`-w`, and never run bare `adrplus wizard`

`adrplus`'s wizard mode is an interactive terminal UI (arrow-key menus, live text prompts) built for a human sitting at a real terminal. You cannot drive it through a non-interactive shell/terminal tool (`Bash` in Claude Code, `runCommands` in GitHub Copilot) — it will hang waiting for keystrokes it will never receive. This applies both to the `-w/--wizard` flag on any subcommand below and to the standalone top-level `adrplus wizard` command (a guided-operations entry point with no non-interactive form at all — it takes no arguments besides `--help`). **Always use the direct, non-interactive flags documented below instead.** If a user explicitly asks to run the wizard themselves, tell them to run the command in their own terminal — don't attempt it yourself.

## Prerequisite

`adrplus` must already be installed as a .NET global tool:
```bash
adrplus --version
```
If this fails, tell the user to run `dotnet tool install -g adrplus` (requires .NET 8+ runtime) before continuing. To upgrade an already-1.0.0-or-later install to a newer release, the command is `dotnet tool update -g adrplus`, then re-check with `adrplus --version`. Don't wait for a crash to mention this.

**Requires v1.0.0 (final) or later — pre-releases (any `-beta*`/`-rc*` suffix) are no longer supported.** `1.0.0` shipped 2026-08-27 as a breaking release: `adrplus version`/`adrplus supersede` gained `-d/--domain`/`-s/--scope` (not present on rc1-rc4) and `adrplus revise` lost `-e/--empty` (present on rc1-rc4) — one command table cannot describe both a pre-1.0.0 install and 1.0.0 correctly, which is why this skill no longer tries to. Earlier pre-releases also aren't supported for the reasons previously documented here: versions before beta1 could fall into an interactive first-run wizard unconditionally, and beta1/beta2 still crashed non-interactively on a genuinely fresh repository or a fresh `adrplus` install — both crashed or hung when an agent runs them non-interactively via a shell/terminal tool, even with all the right non-interactive flags. If a command you run this way fails with `"The handle is invalid"` or similar console errors instead of a normal error message, tell the user their `adrplus` is too old and needs upgrading.

**If the installed version predates 1.0.0, don't upgrade in place.** Per AdrPlus's own 1.0.0 changelog, this is a breaking release with no compatibility shim: run `dotnet tool uninstall -g adrplus` then `dotnet tool install -g adrplus` instead of `dotnet tool update -g adrplus`. Afterward, any `adr-config.adrplus` still carrying `scopes`/`lenscope`/`skipdomain`/`folderbyscope` (see below) must be fixed by hand — the upgrade doesn't do it for you.

**Scope and Domain are always plain free-text header fields with no validation, whitelist, or naming influence.** If you're working in a repository whose `adr-config.adrplus` still carries `scopes`, `lenscope`, `skipdomain`, or `folderbyscope` — leftovers from a pre-1.0.0 config — that config is now invalid: v1.0.0 rejects it outright instead of tolerating and ignoring those keys. Don't treat their presence as harmless; see the next section for how to actually remove them.

## Two config files — and neither `config --repository`/`--template`/`--migrate` edits either one directly

- `adrplus.json` — application settings: `language`, `comandopenadr` (command to open a file, e.g. `code {0}`), `withoutargs`.
- `adr-config.adrplus` — repository settings: naming (`prefix`, `lenseq`, `lenversion`, `lenrevision`, `separator`, `casetransform`), status labels (`statusnew`, `statusacc`, `statusrej`, `statussup`), header labels, and plugin settings — `activeplugins` (names of host-installed plugins expected active for this repo, written by `init` and managed via `adrplus plugins --activate/--deactivate`, see below) and `disableplugins` (repo-wide kill switch; `true` skips all plugin dispatch regardless of `activeplugins`, without affecting the ADR operation itself).

**Verified against the installed CLI: `config --application`/`--repository`/`--template`/`--migrate` — with or without `--file` — write to `adrplus`'s own shared, install-level default template (next to the `adrplus` executable itself), never to the current repository's `adrplus.json`/`adr-config.adrplus`.** Running `config --repository --file <json>` prints the install-directory path it actually wrote; the current repo's own `adr-config.adrplus` is left byte-for-byte unchanged. These commands only affect what a *future* `adrplus init` (without its own `--file`) will seed a *new* repository with — they are not a way to edit settings in a repo you've already initialized. The one command that reads that shared default back and *does* write it into an existing repo's own file is `migrate`: if the repo's own `migrationpattern` is empty, `migrate` pulls the install-level pattern (as set by `config --migrate --file <json>`) and persists it into that repo's `adr-config.adrplus` — so the migration flow under "Typical flows" below still works exactly as written.

**To change a setting in a repository you've already run `init` in:** read `adr-config.adrplus`, edit only the fields that need to change, and write it back. This is the safe default. `adrplus init --path <dir> --file <path-to-full-json>` is a working alternative — it does target the repo's own file, bypassing the "already exists" confirmation — but it **overwrites the entire file and resets `activeplugins` to every plugin currently discovered on the host**, silently undoing any prior `adrplus plugins --deactivate`. Prefer the hand-edit unless you specifically want that reset.

`init` and `migrate` are designed to work non-interactively out of the box with just `--path` — no `--file` needed for a first run.

## Command reference (verified against the actual `Arguments` definitions — do not invent flags not listed here)

Run `adrplus help <command>` yourself if anything here seems inconsistent with what you observe — the CLI's own help output is the source of truth.

| Command | Flags | Notes |
|---|---|---|
| `adrplus --version` | — | Prints the installed version. Not `adrplus version` (that's a different command, see below). |
| `adrplus help [command]` | | |
| `adrplus init` | `-p/--path <dir>` `-f/--file <config.json>` | Creates `adr-config.adrplus` + the ADR folder. **Can be run multiple times as long as `--file` is given** — each run overwrites the repo's config outright (see the reset-`activeplugins` caveat above). Without `--file`, a second run on an **existing** config fails cleanly with `Configuration file already exists at: <path>` instead; verified against 1.0.0. |
| `adrplus config --application` | `-f/--file <json>` | Edits the **shared install-level** `adrplus.json` — see "Two config files" above. **Requires `--file` to be non-interactive.** |
| `adrplus config --repository` | `-f/--file <json>` | Edits the **shared install-level default template**, not the current repo's `adr-config.adrplus` — see "Two config files" above. **Requires `--file` to be non-interactive.** |
| `adrplus config --template` | `-f/--file <template.md>` | Sets the **shared install-level default** ADR template used by future `init` calls — not the current repo's already-set template. **Requires `--file`.** |
| `adrplus config --migrate` | `-f/--file <json>` | Sets the shared install-level default migration pattern; `migrate` (see below) pulls it into a specific repo when that repo's own pattern is empty. **Requires `--file` to be non-interactive** — do NOT confuse with the `migrate` command itself. |
| `adrplus migrate` | `-p/--path <dir>` | Adds AdrPlus headers to existing hand-written ADR files. Only works when **no** ADR has ever been created with `adrplus new` in that repo. Run `config --migrate` first if the default detection pattern doesn't fit — that's the one `config` mode that actually reaches this repo's file, via `migrate`'s own fallback (see "Two config files" above). A file whose sequence/version/revision segment isn't genuinely numeric is rejected as invalid rather than silently treated as `0`. **Verified:** the header row it writes embeds a literal `<!-- Migrated -->` marker inside the "Values" cell (e.g. `|Adr-Plus Fields|Values Migrated <!-- Migrated -->|`) — absent on ADRs created via `new`. `explore`'s `Format` column reports `Migrated` instead of `AdrPlus Format` for these files; this is intentional provenance tracking, not a defect, and `explore` still reads Status/dates correctly either way. Also verified: `migrate` leaves `Version`/`Revision`/`Created`/`Changed` **blank** in the new header — it does not carry values over from the old hand-written block. If you are hand-fixing a header to match this format (e.g. `migrate` itself is unusable because the repo already has `adrplus new`-created ADRs, or you're reconciling many files at once), include the `<!-- Migrated -->` marker for honesty about provenance, and manually carry the real Version/Revision/Status+date values over from the old block before deleting it — do not leave them blank. |
| `adrplus new` | `-p/--path <dir>` `-t/--title "<text>"` `-d/--domain "<text>"` `-s/--scope "<text>"` `-r/--refdate "YYYY-MM-DD"` `-o/--open` | Creates a new ADR with an incremental number. `--scope`/`--domain` are optional free-text fields with no validation. |
| `adrplus approve` | `-f/--file <adr.md>` `-r/--refdate "YYYY-MM-DD"` | Sets status to Accepted. ADR must not already be approved/rejected. |
| `adrplus reject` | `-f/--file <adr.md>` `-r/--refdate "YYYY-MM-DD"` | Sets status to Rejected. Same eligibility as approve. |
| `adrplus undo` | `-f/--file <adr.md>` | Reverts the last status change. ADR must already be approved/rejected and not superseded. |
| `adrplus version` | `-f/--file <adr.md>` `-d/--domain "<text>"` `-s/--scope "<text>"` `-r/--refdate "YYYY-MM-DD"` `-o/--open` `-e/--empty` | Creates a new **major version** of an approved/rejected, non-superseded ADR. `--domain`/`--scope` update those fields on the new version; omit either to keep the source ADR's current value. `--empty` starts from a blank template instead of copying content forward. |
| `adrplus revise` | `-f/--file <adr.md>` `-r/--refdate "YYYY-MM-DD"` `-o/--open` | Creates a new **revision** (minor change) of an ADR. Only works if revisions are enabled (`lenrevision > 0` in `adr-config.adrplus`). No `--empty` (removed in 1.0.0) — `revise` always copies the source ADR's content forward; use `adrplus version --empty` instead when the decision itself changed enough to warrant a blank start. |
| `adrplus supersede` | `-f/--file <adr.md>` `-d/--domain "<text>"` `-s/--scope "<text>"` `-r/--refdate "YYYY-MM-DD"` `-o/--open` | Creates a successor ADR with a new sequence number; marks the original Superseded. Original must already be approved. `--domain`/`--scope` update those fields on the successor; omit either to keep the predecessor's current value. |
| `adrplus explore` | `-p/--path <dir>` `-f/--file <report.md>` `-o/--open` | With both `--path` and `--file` given, generates a full Markdown table report of every ADR in the repo — fully non-interactive, includes all fields. This is the data source the `adr-indexer` agent uses. |
| `adrplus plugins` | `-p/--path <dir>` `-l/--list` `-v/--validate` `-a/--activate <name>` `-d/--deactivate <name>` `-i/--install <zip>` `-u/--uninstall <name>` `-f/--force` | Manages AdrPlus's own plugin system — plugins implementing `IAdrPlugin` that react to ADR lifecycle events (e.g. the bundled `AdrIndexer` reference plugin, which auto-writes `<folderadr>/indexadrs.md` on every create/approve/reject/revise/supersede/undo). **Not this Copilot skill or the Claude Code plugin it's ported from** — a separate, unrelated extensibility mechanism inside the `adrplus` CLI itself. `--path` is required for `--list`/`--validate`/`--activate`/`--deactivate` (repo-scoped); `--install`/`--uninstall` take **no** `--path` — they install/remove a plugin machine-wide. `--force` (with `--install`) overwrites an already-installed plugin entirely. |
| `adrplus sync` | `-p/--path <dir>` `-b/--backfill` | Re-drives plugin dispatches that failed to complete for a repo. `--backfill` re-emits every ADR's current settled event to all active plugins — per the CLI's own help text, this is **manual/occasional use only, never automate via cron/CI**. |

`version` vs `revise` vs `supersede`, in one line each: **version** = a substantial update to the same decision (not just wording — that's `revise`); **revise** = fix/clarify wording, same decision; **supersede** = a *different* decision replaces this one entirely.

Omitting a command's own required argument (e.g. `--file` for `approve`/`reject`/`undo`/`revise`/`version`/`supersede`, `--title` for `new`) without `--wizard` now fails cleanly with `Required argument '--x' (-x) is missing`. If you see a raw `The given key '...' was not present in the dictionary` error instead, the installed `adrplus` predates this fix and is worth flagging as outdated regardless of the version-floor check above.

## Typical flows

**First time in a repo with no existing ADRs:**
```bash
adrplus init --path .
adrplus new --path . --title "Use PostgreSQL as primary database" --domain "Backend"
```

**Repo with existing hand-written ADRs to bring under adrplus:**
```bash
adrplus init --path .
# only if the default filename pattern won't be auto-detected correctly:
adrplus config --migrate --file migration-config.json
adrplus migrate --path .
```

**Everyday lifecycle:**
```bash
adrplus approve --file "./doc/adr/ADR0001V01-UsePostgresql.md"
adrplus revise  --file "./doc/adr/ADR0001V01-UsePostgresql.md"
adrplus supersede --file "./doc/adr/ADR0001V01-UsePostgresql.md" --open
```

## When in doubt

If a user's request doesn't map cleanly onto one of the rows above, run `adrplus help <command>` and read its actual output before guessing at a flag. Never fall back to `--wizard` to sidestep uncertainty.

## Before committing or opening a PR

When you're about to run `git commit` or open a pull request on the user's behalf, launch the `adr-decision-check` agent first. The Claude Code version launches this in the background (non-blocking) and reports the verdict as a follow-up once ready, so it never delays the commit/PR; do the same on Copilot if your surface supports non-blocking subagent invocation. If it doesn't, run it in the foreground instead, but keep it advisory either way: never hold up or refuse a commit because of its recommendation.

