diff --git a/skills/architecture-decision-records/README.md b/skills/architecture-decision-records/README.md new file mode 100644 index 0000000000..c671fb1aec --- /dev/null +++ b/skills/architecture-decision-records/README.md @@ -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. diff --git a/skills/architecture-decision-records/SKILL.md b/skills/architecture-decision-records/SKILL.md new file mode 100644 index 0000000000..ca02e1b2e2 --- /dev/null +++ b/skills/architecture-decision-records/SKILL.md @@ -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: + +- **Status:** Proposed | Accepted | Rejected | Deprecated | Superseded by ADR-XXXX +- **Date:** YYYY-MM-DD +- **Deciders:** +- **Consulted / Informed:** +- **Tags:** + +## 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: +### +- Summary, pros, cons, and **why it was rejected**. +### +- ... + +## 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. diff --git a/skills/architecture-decision-records/examples/ADR-0001-use-postgresql.md b/skills/architecture-decision-records/examples/ADR-0001-use-postgresql.md new file mode 100644 index 0000000000..4e71f818b3 --- /dev/null +++ b/skills/architecture-decision-records/examples/ADR-0001-use-postgresql.md @@ -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: +- Issue/PR: diff --git a/skills/architecture-decision-records/template.md b/skills/architecture-decision-records/template.md new file mode 100644 index 0000000000..a7c5a8ce62 --- /dev/null +++ b/skills/architecture-decision-records/template.md @@ -0,0 +1,64 @@ +# ADR-NNNN: + +- **Status:** Proposed +- **Date:** YYYY-MM-DD +- **Deciders:** +- **Consulted / Informed:** +- **Tags:** + +## Context + + + +## Decision + + + +We will ... + +## Consequences + + + +### Positive + +- + +### Negative / Trade-offs + +- + +### Follow-ups + +- + +## Alternatives Considered + + + +### + +- **Summary:** +- **Pros:** +- **Cons:** +- **Why rejected:** + +### + +- **Summary:** +- **Pros:** +- **Cons:** +- **Why rejected:** + +## References + +- Related ADRs: +- Design docs / issues / PRs: +- External links / benchmarks: