Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions skills/architecture-decision-records/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Architecture Decision Records — Portable AI Skill

A single, tool-agnostic skill that teaches any AI IDE/agent to record **why**
architectural decisions were made, using **Architecture Decision Records (ADRs)**.
The content lives in [`SKILL.md`](./SKILL.md) and is plain Markdown with YAML
front matter, so it is readable by virtually every assistant.

## What it covers

- The ADR **template** (Context, Decision, Consequences, Alternatives Considered)
- **Naming convention** — `ADR-NNNN-kebab-case-title.md` (e.g. `ADR-0001-use-postgresql.md`)
- **Status lifecycle** — Proposed → Accepted / Rejected / Deprecated / Superseded
- **Review & approval process** (PR-based)
- Best practices, anti-patterns, and how to onboard new teammates with ADR history

## Files

- [`SKILL.md`](./SKILL.md) — the skill content
- [`template.md`](./template.md) — copy this for each new ADR
- [`examples/ADR-0001-use-postgresql.md`](./examples/ADR-0001-use-postgresql.md) — a filled-in example

## Use it in your tool

The same `SKILL.md` works everywhere. Pick whichever wiring your tool expects:

| Tool / Agent | How to enable |
| --- | --- |
| **Claude / Claude Code (Agent Skills)** | Place this folder under your skills dir (e.g. `.claude/skills/architecture-decision-records/`) — `SKILL.md` is auto-discovered via its front-matter `name` + `description`. |
| **Cursor** | Reference it from a rule, or add a `.cursor/rules/adr.mdc` that points to / inlines this file. You can also `@`-mention `SKILL.md` in chat. |
| **GitHub Copilot** | Copy the body into `.github/copilot-instructions.md` (or link to it). |
| **Windsurf / Codeium** | Add the body to `.windsurfrules`. |
| **Cline / Aider / others** | Add `SKILL.md` to the project context or instruction file the agent reads. |
| **Any agent** | Just feed `SKILL.md` as context — it's standard Markdown. |

## Tips

- Store actual ADRs in your repo under `docs/adr/` and keep an index README there.
- If your repository already defines an ADR convention, that wins — this skill is
a sensible default, not a mandate.
- Keep the front-matter `description` intact: skill-aware agents use it to decide
*when* to activate the skill automatically.
229 changes: 229 additions & 0 deletions skills/architecture-decision-records/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
---
name: architecture-decision-records
version: 1.0.0
description: >-
Author and manage Architecture Decision Records (ADRs) that capture every
significant architectural decision — its context, the decision itself, the
consequences (trade-offs), and the alternatives considered. Use this skill
whenever a meaningful technical/architectural choice is made or changed (e.g.
picking a database, framework, protocol, deployment model, or design pattern),
when onboarding teammates who need to understand *why* the system looks the way
it does, or when reviewing/superseding past decisions. Covers the ADR template,
the ADR-NNNN-kebab-title.md naming convention, status lifecycle, and the
review/approval process.
license: MIT
compatibility: >-
Universal Markdown + YAML front matter. Works as an Anthropic/Claude Agent Skill
(SKILL.md), and as a generic instruction/context file for Cursor, GitHub Copilot,
Windsurf, Codeium, Cline, Aider, and any agent that can read Markdown.
tags:
- architecture
- documentation
- decision-records
- adr
- governance
---

# Architecture Decision Records (ADRs)

> A portable engineering "skill" for recording **why** architectural decisions
> were made — so the current architecture is explainable, reviewable, and
> evolvable. Format: one Markdown file per decision, stored in the repo.

An **ADR** is a short document that captures a single, significant architectural
decision along with its context and consequences. ADRs are **immutable history**:
you don't delete or rewrite an old decision — you supersede it with a new one.
This gives new team members a chronological, searchable record of *how* and *why*
the system reached its current state.

---

## 0. Quick checklist (apply when writing an ADR)

- [ ] The decision is **architecturally significant** (affects structure, deps,
interfaces, cost, security, or is hard/expensive to reverse).
- [ ] File is named `ADR-NNNN-kebab-case-title.md` with a zero-padded number.
- [ ] It has a **Status**, **Context**, **Decision**, **Consequences**, and
**Alternatives Considered**.
- [ ] Consequences list both **positive and negative** outcomes (trade-offs).
- [ ] At least 2 real **alternatives** are described with why they were rejected.
- [ ] It links related/superseded ADRs and relevant issues/PRs.
- [ ] It is **dated** and attributes deciders/approvers.
- [ ] It is concise (~1–2 pages); link out to deep design docs instead of inlining.

---

## 1. What deserves an ADR?

Write an ADR when a decision is **significant and not easily reversible**, e.g.:

- Choosing a datastore, message broker, cache, or search engine
(e.g. *use PostgreSQL*, *adopt Kafka*).
- Selecting a language, framework, or major library.
- Defining a service boundary, API style (REST vs. gRPC vs. GraphQL), or
monolith-vs-microservices split.
- Authn/authz approach, multi-tenancy model, data partitioning/sharding.
- Deployment/runtime model (containers, serverless, region strategy).
- Cross-cutting standards (error handling, versioning, observability).
- Reversing or replacing a previous decision.

**Don't** write an ADR for routine, low-impact, or trivially reversible choices
(variable naming, a one-file refactor, a dependency bump with no API impact).
Rule of thumb: *"Would a new engineer ask 'why did we do it this way?' in 6 months?"*

---

## 2. ADR template

Copy [`template.md`](./template.md) for each new ADR. The canonical structure:

```markdown
# ADR-NNNN: <Short, decision-oriented title>

- **Status:** Proposed | Accepted | Rejected | Deprecated | Superseded by ADR-XXXX
- **Date:** YYYY-MM-DD
- **Deciders:** <names/roles>
- **Consulted / Informed:** <optional>
- **Tags:** <e.g. database, security, api>

## Context
What is the problem, force, or requirement driving this decision? Describe the
situation, constraints (technical, business, team, time, cost), and assumptions.
State the question we are answering. Keep it factual and neutral.

## Decision
The decision, stated in active voice: "We will ...". Be specific and concrete.
Include the scope of what this does and does not cover.

## Consequences
The results of applying the decision — what becomes easier and what becomes
harder. List **both** positive and negative outcomes, plus follow-up actions,
risks, and what we now have to live with or revisit later.

### Positive
- ...

### Negative / Trade-offs
- ...

### Follow-ups
- ...

## Alternatives Considered
For each realistic option we did NOT choose:
### <Alternative A>
- Summary, pros, cons, and **why it was rejected**.
### <Alternative B>
- ...

## References
- Links to related ADRs (supersedes / superseded by / relates to), design docs,
issues, PRs, benchmarks, or external articles.
```

The four required sections are **Context, Decision, Consequences, Alternatives
Considered** (the others are lightweight metadata that make ADRs searchable).

---

## 3. Naming convention

- File name: **`ADR-NNNN-kebab-case-title.md`**
- `NNNN` = zero-padded, monotonically increasing sequence number
(`0001`, `0002`, ... — 4 digits scales well).
- Title = short, lowercase, hyphen-separated, decision-focused.
- Examples:
- `ADR-0001-use-postgresql.md`
- `ADR-0002-adopt-event-driven-architecture.md`
- `ADR-0003-rest-over-grpc-for-public-api.md`
- `ADR-0007-superseded-use-cockroachdb.md` (when one decision replaces another)
- Numbers are **never reused** and ADRs are **never renumbered**, even if rejected
— the sequence is permanent history.
- Store all ADRs together, conventionally in **`docs/adr/`** (or `doc/adr/`).
- Keep an `docs/adr/README.md` (or `index.md`) listing every ADR with its number,
title, status, and date for quick scanning.

---

## 4. Status lifecycle

```
Proposed ──approve──▶ Accepted ──replaced──▶ Superseded by ADR-XXXX
│ │
└──reject──▶ Rejected └──no longer relevant──▶ Deprecated
```

- **Proposed** — drafted and under review; not yet binding.
- **Accepted** — approved; this is the current decision teams must follow.
- **Rejected** — considered but not adopted (kept for the record and rationale).
- **Deprecated** — no longer recommended, but not directly replaced.
- **Superseded by ADR-XXXX** — replaced by a newer decision; link both ways.

When superseding: create a **new** ADR, set the old one's status to
`Superseded by ADR-XXXX`, and add a `Supersedes ADR-YYYY` reference in the new one.
**Never edit the body of an Accepted ADR to change the decision** — record changes
as new ADRs so history stays intact (typo/clarity fixes are fine).

---

## 5. Review & approval process

1. **Draft.** Author copies `template.md`, assigns the next free number, fills in
Context/Decision/Consequences/Alternatives, sets **Status: Proposed**.
2. **Open a PR.** Add the new ADR file in `docs/adr/` and open a pull request.
The PR *is* the review thread — comments and discussion live there.
3. **Review.** Required reviewers (e.g. tech lead + ≥1 senior engineer / architect,
plus any affected team) discuss trade-offs and request changes. Aim for
consensus; if blocked, the designated decider (e.g. tech lead/architect) breaks
ties.
4. **Approve.** On approval, change **Status: Proposed → Accepted**, fill in
**Deciders** and the final **Date**, then merge the PR.
5. **Communicate.** Announce accepted ADRs (changelog/Slack/standup) and update the
ADR index. The decision is now binding for new work.
6. **Revisit later.** If circumstances change, propose a new ADR that supersedes
the old one rather than silently diverging from it.

Lightweight teams may compress this (single approver, async review), but keep the
**immutable-record + status + PR-review** core intact.

---

## 6. Best practices & anti-patterns

**Do**

- Keep each ADR to a single decision; split unrelated decisions into separate ADRs.
- Write in plain language; favor "We will ..." statements over passive voice.
- Capture the *forces* and *constraints* honestly, including non-technical ones.
- Always include the alternatives — the rejected options are often the most useful
context for future readers.
- Date and attribute every ADR; link to the PR/issue that drove it.
- Keep ADRs in-repo and versioned with the code they describe.
- Start at ADR-0001 even for an existing project; backfill key past decisions.

**Avoid**

- Editing or deleting accepted decisions to "fix" them — supersede instead.
- Vague titles (`ADR-0001-database.md`) — be specific (`...-use-postgresql.md`).
- Skipping consequences/trade-offs — an ADR without downsides is a red flag.
- Turning ADRs into full design specs — link out for deep detail.
- Writing ADRs after the fact only for failures — record the successful, default
choices too, so the architecture is fully explained.

---

## 7. How to apply this skill

1. **Detect significance.** When a meaningful architectural choice is being made
or changed, propose creating an ADR.
2. **Scaffold.** If `docs/adr/` doesn't exist, create it plus an index README and
`ADR-0001`. Otherwise find the next free number.
3. **Write.** Copy `template.md`, fill Context → Decision → Consequences →
Alternatives Considered, name it `ADR-NNNN-kebab-title.md`, set
**Status: Proposed**.
4. **Review.** Open a PR, gather approvals, flip status to **Accepted**, set
deciders/date, merge, and update the index.
5. **Maintain.** Supersede (never overwrite) when decisions change, keeping links
between related ADRs intact.
6. **Match the project.** If the repo already has an ADR convention (location,
numbering, template), follow it over these defaults.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# ADR-0001: Use PostgreSQL as the primary datastore

- **Status:** Accepted
- **Date:** 2026-06-05
- **Deciders:** Tech Lead, Backend Team
- **Consulted / Informed:** Platform/DevOps, Product
- **Tags:** database, persistence, infrastructure

## Context

We are building a transactional web application that needs durable storage for
user accounts, orders, and billing data. Requirements:

- Strong consistency and ACID transactions for financial data.
- Relational data with clear foreign-key relationships and reporting needs.
- Moderate write volume now, with room to scale reads.
- The team is small and has more SQL than NoSQL operational experience.
- We want a mature, open-source option that all major cloud providers support
as a managed service (to avoid heavy ops burden).

## Decision

We will use **PostgreSQL** (managed, e.g. cloud RDS/Cloud SQL equivalent) as the
primary system-of-record datastore for all transactional data. Application access
goes through a single connection-pooled client; schema changes are managed via
versioned migrations.

This decision covers the primary OLTP store. It does **not** cover caching
(future ADR) or analytics warehousing (future ADR).

## Consequences

### Positive

- ACID transactions and strong consistency out of the box.
- Rich SQL, JSONB for semi-structured data, and a large extension ecosystem.
- Available as a managed service on every major cloud — low ops overhead.
- Team can be productive immediately with existing SQL skills.

### Negative / Trade-offs

- Horizontal write scaling requires extra work (read replicas, partitioning, or
sharding) if volume grows substantially.
- We must own schema migrations and connection-pool tuning.

### Follow-ups

- Add a migration tool and CI check.
- Define backup/restore and PITR policy with DevOps.
- Revisit read-replica strategy when read load grows.

## Alternatives Considered

### MySQL

- **Summary:** Mature relational database with managed offerings.
- **Pros:** Widely supported, well understood.
- **Cons:** Weaker support for advanced types/JSONB and some SQL features vs. Postgres.
- **Why rejected:** Postgres's feature set (JSONB, extensions, constraints) better
fits our needs with comparable operational maturity.

### MongoDB (document store)

- **Summary:** Schema-flexible NoSQL document database.
- **Pros:** Flexible schema, easy horizontal scaling.
- **Cons:** Weaker multi-document transactional guarantees historically; relational
reporting is harder; team has less operational experience.
- **Why rejected:** Our data is strongly relational and requires robust
transactions for billing — a poor fit for a document model.

## References

- Relates to: future ADR on caching layer, future ADR on analytics warehouse.
- Design doc: <link>
- Issue/PR: <link>
Loading