Skip to content

vt-c-adr

Create structured Architecture Decision Records from natural language. Links to active spec, stores in docs/decisions/, supports listing and superseding.

Plugin: core-standards
Category: Other
Command: /vt-c-adr


Architecture Decision Record (ADR)

Create, list, and manage Architecture Decision Records. ADRs capture the context, alternatives, decision, and consequences of significant architecture choices in a structured, searchable format.

When to Use

  • After making a significant architecture or technology choice during /vt-c-3-build
  • When /vt-c-journal captures a decision that deserves permanent, structured documentation
  • When revisiting a past decision that needs to be superseded

Invocation

/vt-c-adr "use PostgreSQL instead of MongoDB"     # Create new ADR
/vt-c-adr --list                                    # List all ADRs
/vt-c-adr --supersede ADR-005                       # Supersede existing ADR

Execution Instructions

Step 1: Parse Arguments

Extract from the invocation: - Description text — natural language description of the decision (default mode) - --list flag — show all ADRs - --supersede ADR-NNN — supersede an existing ADR

If --list: skip to Step 7. If --supersede: skip to Step 8. Otherwise: proceed to Step 2.

Step 2: Ensure Directory Exists

Check if docs/decisions/ exists. If not:

mkdir -p docs/decisions/

Step 3: Compute Next ADR Number

Scan existing ADR files to determine the next number:

ls docs/decisions/ADR-*.md 2>/dev/null | grep -o 'ADR-[0-9]*' | sed 's/ADR-//' | sort -n | tail -1

If no ADRs exist: start at 001. Otherwise: increment the highest number by 1, zero-padded to 3 digits.

Step 4: Derive Spec Linkage

Determine the active spec for traceability:

  1. Primary: Read .design-state.yaml specs_status entries. Find the spec whose specs_dir matches the current working context.
  2. Fallback 1: Parse current git branch name. If it matches feature/spec-NNN-*: extract SPEC-NNN.
  3. Fallback 2: Read .active-spec file if it exists.
  4. No spec found (EC-1): Set spec_id: null. Display:
    Note: No active spec found. ADR created without spec linkage.
    

Step 5: Check for Duplicate Decisions

Scan existing ADR titles in docs/decisions/ADR-*.md YAML frontmatter. Extract the title: field from each.

Compare the new decision description against existing titles. If any existing title shares 3 or more significant words with the new description (ignoring stop words: "use", "for", "the", "instead", "of", "to", "a", "an", "in", "with", "and", "or", "not", "over"):

Use AskUserQuestion: - Create new ADR anyway — proceed with creation - Supersede ADR-{NNN} ("{existing title}") — run supersede flow (Step 8) instead

If no duplicates found: proceed to Step 6.

Step 6: Generate ADR

Create the ADR file based on the natural language description. Generate substantive content for each section — never use placeholder text.

File name: docs/decisions/ADR-{NNN}-{kebab-title}.md

Where {kebab-title} is the description converted to lowercase kebab-case, truncated to 50 characters.

File structure (YAML frontmatter + 5 sections):

YAML frontmatter: id, title, date, status (accepted), spec_id, supersedes, superseded_by
Heading: # ADR-{NNN}: {Title}
Section: ## Context — why this decision is needed, forces at play, constraints
Section: ## Alternatives Considered — at least 2 options, each with Pro/Con bullets
Section: ## Decision — what was chosen and why
Section: ## Consequences — Positive and Negative subsections
Section: ## Implementation Notes — practical guidance, follow-ups

IMPORTANT: Generate real, substantive content for every section based on the user's description and your architecture knowledge. The sections above are structural guidance — you must fill them with actual analysis, not repeat the bracketed hints. If the description is too vague, ask one focused clarifying question (but aim for single-interaction completion per NFR-1).

Example — for input "use PostgreSQL instead of MongoDB":

---
id: ADR-001
title: Use PostgreSQL Instead of MongoDB
date: 2026-03-23
status: accepted
spec_id: SPEC-042
supersedes: null
superseded_by: null
---

# ADR-001: Use PostgreSQL Instead of MongoDB

## Context

The project requires persistent storage for user profiles, orders, and audit logs.
The data model has strong relational characteristics with cross-entity queries...

## Alternatives Considered

### Option A: PostgreSQL
- **Pro**: ACID compliance, mature ecosystem, strong JOIN performance
- **Con**: Schema migrations required for model changes

### Option B: MongoDB
- **Pro**: Flexible schema, horizontal scaling for document workloads
- **Con**: Weak cross-collection queries, eventual consistency concerns

## Decision

PostgreSQL was chosen because the data model is inherently relational...

## Consequences

### Positive
- Reliable transactions for order processing
- Rich query capabilities with CTEs and window functions

### Negative
- Schema migrations add deployment complexity
- Less flexibility for rapid prototyping of new entity types

## Implementation Notes

- Use connection pooling (PgBouncer) from the start
- Set up migration tooling in the bootstrap phase

Display confirmation:

Created: docs/decisions/ADR-{NNN}-{kebab-title}.md

  Title:   {title}
  Status:  accepted
  Spec:    {SPEC-NNN or "none"}
  Date:    {date}

Step 7: List Mode (--list)

Read all docs/decisions/ADR-*.md files. Parse YAML frontmatter from each (id, title, status, spec_id, date).

Display as a table:

Architecture Decision Records
─────────────────────────────────────────────────────────────────
  ID       Title                        Status       Spec        Date
  ADR-001  Use PostgreSQL               accepted     SPEC-042    2026-03-23
  ADR-002  Event-Driven Messaging       proposed     SPEC-045    2026-03-24
  ADR-003  REST Over GraphQL            superseded   SPEC-042    2026-03-20
─────────────────────────────────────────────────────────────────
  Total: {N} records | {accepted} accepted | {superseded} superseded

If no ADRs exist:

No Architecture Decision Records found in docs/decisions/.
Create one with: /vt-c-adr "your decision description"

Step 8: Supersede Mode (--supersede ADR-NNN)

  1. Read target ADR: Parse docs/decisions/ADR-{NNN}-*.md. If not found: error and exit.

  2. Display the existing decision for context:

    Superseding ADR-{NNN}: {title}
    Current decision: {brief summary from Decision section}
    

  3. Ask for new decision: Use AskUserQuestion or accept from arguments: "What is the new decision that replaces this one?"

  4. Update old ADR: Set status: superseded and superseded_by: ADR-{new} in the old file's frontmatter.

  5. Create new ADR: Follow Steps 3-6 with supersedes: ADR-{NNN} in frontmatter and a note in the Context section referencing why the old decision was superseded.

  6. Display confirmation:

    Superseded: ADR-{old} → ADR-{new}
    
    ADR-{old}: {old title} — now superseded
    ADR-{new}: {new title} — accepted
    

ADR Format Compatibility

The ADR format follows the widely-used convention from Michael Nygard's article and is compatible with: - adr-tools (https://github.com/npryce/adr-tools) - adr-log - Most ADR aggregation and search tools

Key compatibility points: - YAML frontmatter with standard fields (id, title, date, status) - Status values: proposed, accepted, superseded, deprecated - Kebab-case file naming with numeric prefix

Relationship to Other Skills

Skill Relationship
/vt-c-journal Captures informal decisions → promote to ADR for structured record
/vt-c-pd-capture-decisions Captures PD-phase decisions in same docs/decisions/ directory
/vt-c-consolidate Synthesizes journal entries into ADRs and other durable artifacts
/vt-c-2-plan Research phase may reference existing ADRs for context