adr-create · git:20260819.6ebae09 · 2026-08-19 · sha256 f2ae30d3945a9b68
adr-create git:20260819.6ebae09A
Immutable. This exact content is served forever at /api/v1/blob/f2ae30d3945a9b68.
---
model_tier: high
name: adr-create
description: "Use when capturing an architectural decision — file naming, next ADR number, Status / Context / Decision / Consequences, index regen; fires even without saying 'ADR'."
domain: process
execution:
type: assisted
handler: shell
timeout_seconds: 30
allowed_tools: []
command:
- ./scripts-run
- src/scripts/adr/regenerate_index
- --dir
- docs/decisions
runtime_requires:
bins:
- bash
- node
network: []
workspaces:
- agent-config-maintainer
packs:
- meta
---
# adr-create
## When to use
Use this skill when:
- A non-trivial architectural choice needs a written record (kernel
membership, cap raises, contract changes, library swap, deprecation).
- A decision overrides a previous one and needs `supersedes:` linkage.
- A roadmap phase closes and the chosen variant must be cited.
- The user says "write an ADR for X", "decision log this", "we need
a record of why we picked Y".
Do NOT use when:
- The change is reversible without governance impact (typo, lint
fix, refactor that stays inside one module).
- The decision is already covered by an existing ADR — extend or
supersede it instead of duplicating.
- A skill, rule, or guideline is the better home (use those skills).
## Goal
- Sequential `ADR-NNN-<slug>.md` numbering with no gaps.
- Standard template: Status, Context, Decision, Consequences,
Alternatives, References.
- Regenerated index so readers find the ADR by topic, not by ls.
- Zero MCP-tool dependency — pure filesystem + TypeScript tooling (run via ./scripts-run).
## Preconditions
- An ADR directory exists. Two layouts coexist (see
[`docs/contracts/adr-layout.md`](../../../docs/contracts/adr-layout.md)):
- **Flat** — `docs/decisions/` (or `docs/adr/` alias): cross-cutting
governance ADRs, 3-digit numbering (`ADR-NNN-<slug>.md`).
- **Per-area** — `docs/adrs/<area>/`: sub-area ADRs, 4-digit
numbering (`NNNN-<slug>.md`); `<area>` must match the canonical
inventory in `src/scripts/audit_adr_coverage.ts` (`AREAS`). Deliberately not
a link: this skill is projected into `dist/agent-src/skills/`, whose sibling
`scripts/` directory carries six curated files and not this one, so any
relative href that resolves in `src/` is broken in the projection.
- The decision is **already made** — ADRs record outcomes, they do
not run the decision process. For unresolved trade-offs, run the
council or consult `adversarial-review` first.
## Procedure
### 1. Inspect and pick the surface
Ask one question only if both are plausible:
1. **Flat surface** — chosen when the decision constrains the
package's contract with consumers (kernel composition, rule
taxonomy, package-wide architecture). Directory: `docs/decisions/`
(fallback `docs/adr/`). Filename: `ADR-NNN-<slug>.md`.
2. **Per-area surface** — chosen when the decision constrains code
inside one area folder (one runtime module, one contract group,
one CLI surface). Directory: `docs/adrs/<area>/`. Filename:
`NNNN-<slug>.md` (4-digit, no `ADR-` prefix).
3. **Unknown area** — `<area>` not in the inventory: refuse with a
hint to add the area to `AREAS` in
`src/scripts/audit_adr_coverage.ts` in the same PR. Do not invent.
4. **In doubt** → per-area (cheaper to surface, easier to relocate).
### 2. Pick the next ADR number
- **Flat surface** — scan `docs/decisions/` (or `docs/adr/`) for
`ADR-*.md`, parse the leading 3-digit number, take `max + 1`
(zero-padded to 3). For an empty directory, start at `001`.
- **Per-area surface** — scan `docs/adrs/<area>/` for
`[0-9][0-9][0-9][0-9]-*.md`, parse the leading 4-digit number,
take `max + 1` (zero-padded to 4). For an empty area, start at
`0001`. `README.md` is **not** an ADR — skip it.
Reject re-use of an existing number — index regeneration treats
duplicates as a hard failure on both surfaces.
### 3. Pick a slug
Short, hyphen-lowercase, scope-revealing. Match peer ADRs in the
directory. Examples: `kernel-swap-deferred`, `flat-cluster-subs`,
`http-bridge-deferred-with-trigger`,
`per-tier-smoke-scripts`. Reject slugs longer than 60 chars.
### 4. Author the ADR
Use the surface-specific template. All sections are required; "—"
is acceptable for genuinely empty Alternatives or References blocks
but never for Status, Context, Decision, or Consequences.
**`review_trigger` is required and it names a CONDITION, not a date.** A
decision is a call made under conditions that held at the time; the trigger
records which change would make it worth re-deciding. "Review annually" is
ignored by everyone and rots into ceremony —
`check_adr_frontmatter.ts` rejects bare cadences for exactly that reason. Write
the event: *"when a second consumer reports the same preservation surprise"*,
*"when a host ships a native primitive for this"*, *"if the measured lift drops
below the pre-registered threshold"*. Enforced from 2026-07-25 forward; earlier
ADRs are grandfathered by date.
When you later reopen one, say which **premise moved** and what evidences the
move — not "we were wrong". If the original was right under its own conditions,
record that too. A premise that turns out false while the decision stays correct
gets a logged correction block, never a silent edit.
**Flat-surface template** (`docs/decisions/ADR-NNN-<slug>.md`):
```markdown
---
adr: NNN
status: proposed | accepted | superseded | deprecated
date: YYYY-MM-DD
decision: <slug>
supersedes: — | ADR-MMM
superseded_by: — | ADR-MMM
amends: — | ADR-MMM # optional — this ADR amends that one (reciprocal required)
amended_by: — | ADR-MMM # optional — reciprocal of `amends`
phase: <roadmap> · <phase-id>
review_trigger: <the CONDITION that would reopen this decision>
protected_dimensions: [...] # optional — purpose | security_floor | privacy_floor | external_commitment | governance | none
reopen_policy: directional | owner | unclassified # optional; absent → unclassified
---
# ADR-NNN — <Decision Title>
## Status
**<Proposed | Accepted | …>** · YYYY-MM-DD.
## Context / Decision / Consequences / Alternatives / References
```
**Per-area template** (`docs/adrs/<area>/NNNN-<slug>.md`):
```markdown
# ADR NNNN — <Decision Title>
> Area: `<area>` · Status: accepted · Date: YYYY-MM-DD · Type: retrospective | new
> Roadmap: `agents/roadmaps/<file>.md` <phase-id>
> Supersedes: —
## Context / Decision / Considered alternatives / Consequences / References
```
Per-area ADRs use a quote-style header (no YAML frontmatter) so
`audit_adr_coverage.ts`'s permissive parser can index them. Cite
the area's contract from the README in
[`docs/adrs/<area>/README.md`](../../../docs/adrs/).
### 5. Regenerate the index
- **Flat surface** — `./scripts-run src/scripts/adr/regenerate_index
--dir docs/decisions/` writes `INDEX.md` from `ADR-*.md`.
- **Per-area surface** — `./scripts-run src/scripts/audit_adr_coverage
--regen-area-readme <area>` rewrites `docs/adrs/<area>/README.md`.
Coverage gate: run `./scripts-run src/scripts/audit_adr_coverage` (no
args) — exit 0 only when every canonical area has ≥ 1 ADR.
### 6. Validate
- Flat: `./scripts-run src/scripts/adr/regenerate_index --dir docs/decisions/ --check` exits 0.
- Per-area: `./scripts-run src/scripts/audit_adr_coverage --check` exits 0.
- The project's CI / quality pipeline passes — locally only when
`quality.local_auto_run: true`; under the default (`false` / missing)
remote CI is the gate and no local pipeline run happens.
## Rubric pass (optional, surfacing-only)
After drafting an ADR, run
[`judge-artifact-completeness`](../judge-artifact-completeness/SKILL.md)
with rubric `architecture-score` to confirm alternatives, consequences,
reversibility, and risk are present. Invoke when the user asks for a
completeness check — not on every ADR by default.
## Output format
1. Path of the new ADR file.
2. Path of the regenerated index / README.
3. One-line summary of the decision.
4. Linked roadmap or phase, if any.
## Gotchas
- **Flat default path** is `docs/decisions/` in this package; some
projects use `docs/adr/`. Pass `--dir` when running outside the
default.
- **Per-area numbering is 4-digit** (`NNNN-<slug>.md`); the flat
surface stays 3-digit (`ADR-NNN-<slug>.md`). Do not mix.
- **Area inventory is closed** — `<area>` must already exist in
`AREAS` in `src/scripts/audit_adr_coverage.ts`. Adding a new area is
a separate PR with explicit reviewer sign-off.
- Frontmatter `adr:` (flat) is the canonical number; the filename
prefix must match. The flat regenerator fails on mismatch.
- ADRs are append-only history. To revise a decision, write a new
ADR with `supersedes: ADR-MMM` (flat) or a `Supersedes:` line in
the header quote-block (per-area) and flip the old one's status
to `superseded`.
- Never delete an ADR file — supersede it. Deletion breaks
historical links and round-trips through git history checks.
- **Amending is the common case; wire it in both directions.** Most reopens
correct one decision inside an otherwise sound ADR rather than replacing the
whole record. Use `## Amendment N (YYYY-MM-DD) — <topic>` plus the reciprocal
`amends:` / `amended_by:` pair — the validator rejects a one-sided link,
because a one-sided link is invisible from the stale side, and the stale side
is the one a reader lands on first. Where the amendment reverses text that is
still asserted above it, add a one-line banner there too; the frontmatter
alone does not stop someone quoting the reversed sentence.
- **Who may reopen it is recorded, not assumed** — `reopen_policy` /
`protected_dimensions`, both optional, absent meaning `unclassified`
([`adr-layout § Reopen authority`](../../../docs/contracts/adr-layout.md)).
Reach for `owner` only when EVERY future transition is genuinely reserved;
`directional` is the normal answer, and no answer is a fine answer.
## Frugality Standards
Apply the [Frugality Charter](../../contexts/contracts/frugality-charter.md)
to every ADR you author.
**Examples in this artifact:**
- Per the charter's default-terse rule, `## Context` states the
forcing function in 2–3 sentences; no historical narrative.
- Per the cite-don't-restate principle, `## Decision` links the
rules / contracts it overrides; no rule body is quoted in full.
- Per the cheap-question check, `## Alternatives considered` lists
genuine design alternatives, not strawmen.
**Pre-save self-check:**
1. Does `## Context` carry more than 5 sentences of setup?
2. Does `## Decision` restate rule text instead of citing the rule?
3. Are alternatives evaluated with a real consequence each, or with
stylistic preference?
4. Does the ADR forecast consequences with hedge phrases ("might",
"could potentially") instead of decidable claims?
## Do NOT
- Skip Context — a decision without context is folklore.
- Reuse an existing ADR number — the index regenerator hard-fails.
- Author ADRs for reversible refactors or minor cleanups.
- Cite a council session id without ensuring the file is committed
or otherwise reachable from the repo (per `no-roadmap-references`,
council clause).