|
| 1 | +<prompt `adr.prompt.md`> |
| 2 | + |
| 3 | +# Guidelines: How to Write Architectural Decision Records (ADRs) |
| 4 | + |
| 5 | +## The Core Principle: One Decision, One File |
| 6 | + |
| 7 | +This is the most important rule: **Every architectural decision is recorded in its own, separate, numbered file.** |
| 8 | + |
| 9 | +We do **not** use a single, monolithic file for all decisions. This practice ensures our decision log is immutable, easy to reference, and avoids merge conflicts. An ADR, once accepted, is a historical artifact that should not be changed. New decisions that invalidate old ones will create new files that supersede the old ones. |
| 10 | + |
| 11 | +## Core Principles for Writing ADRs |
| 12 | + |
| 13 | +- **Be Objective and Dispassionate:** An ADR is a factual record, not a sales pitch. Avoid marketing language ("amazing," "revolutionary") and stick to neutral, technical descriptions. |
| 14 | +- **Focus on the "Why":** The `Consequences` section is the heart of the ADR. A decision without its trade-offs is only half the story. Be honest about the downsides. |
| 15 | +- **Link to Evidence:** If a decision was based on a performance benchmark, a blog post, or a specific library's documentation, link to it in the `Context` section. |
| 16 | +- **Use Clear, Simple Language:** Avoid jargon and complex sentences. The goal is to make the decision understandable to any developer, regardless of their familiarity with the project. |
| 17 | + |
| 18 | +## The ADR Generation Process |
| 19 | + |
| 20 | +When instructed to create or update an ADR, you will follow this process: |
| 21 | + |
| 22 | +### Step 1: Distill the Decision from the Conversation |
| 23 | + |
| 24 | +- **Identify the Core Decision:** What was the final choice that was just agreed upon? (e.g., "We will replace Moment.js with Day.js.") |
| 25 | +- **Identify the Context:** What was the problem being solved? (e.g., "The bundle size from Moment.js is too large.") |
| 26 | +- **Identify the Consequences:** What are the expected outcomes? (e.g., "Reduced bundle size, but we need to refactor 25 files.") |
| 27 | + |
| 28 | +### Step 2: Determine the Status and Create the New File |
| 29 | + |
| 30 | +- **Status:** Most new decisions will be **"Accepted"**. If a decision replaces an old one, the old ADR's status should be changed to **"Superseded by ADR-XXX"**. |
| 31 | +- **Location:** All ADRs must be located in the `.app/adr/` directory. |
| 32 | +- **Filename Generation:** |
| 33 | + 1. Scan the `.app/adr/` directory to find the highest existing ADR number (e.g., `007-some-decision.md`). |
| 34 | + 2. Increment it by one (e.g., `008`). |
| 35 | + 3. Create a **new file** with the format: `XXX-short-title-in-kebab-case.md` (e.g., `008-replace-momentjs-with-dayjs.md`). |
| 36 | + |
| 37 | +### Step 3: Write the ADR Using the Formal Template |
| 38 | + |
| 39 | +Use the following markdown template for the content of the **new file**. Do not deviate from this structure. |
| 40 | + |
| 41 | +```markdown |
| 42 | +# ADR-XXX: [Short, Descriptive Title of Decision] |
| 43 | + |
| 44 | +- **Status:** [Proposed | Accepted | Deprecated | Superseded by ADR-XXX] |
| 45 | +- **Date:** [YYYY-MM-DD] |
| 46 | + |
| 47 | +--- |
| 48 | + |
| 49 | +## Context |
| 50 | + |
| 51 | +_**What is the problem or situation that requires this decision?**_ |
| 52 | + |
| 53 | +- Describe the issue, the user story, or the technical challenge. |
| 54 | +- What are the constraints? (e.g., performance requirements, budget, existing tech stack). |
| 55 | +- Be concise. This should be 2-4 sentences. |
| 56 | + |
| 57 | +## Decision |
| 58 | + |
| 59 | +_**What is the change we are making?**_ |
| 60 | + |
| 61 | +- State the decision clearly and unambiguously. |
| 62 | +- Be specific. Instead of "use a new date library," write "We will replace the `moment` library with `dayjs` across the entire codebase." |
| 63 | +- Mention key components of the solution (e.g., "This includes creating a `formatDate` wrapper in `src/utils/dates.ts`"). |
| 64 | + |
| 65 | +## Consequences |
| 66 | + |
| 67 | +_**What are the results of this decision? This is the most important section.**_ |
| 68 | + |
| 69 | +- **Positive:** List the benefits we gain from this decision (e.g., "Reduces final bundle size by ~80KB," "Simplifies date-time immutability."). |
| 70 | +- **Negative:** List the costs, risks, or trade-offs (e.g., "Requires a coordinated refactoring effort across ~25 files," "Day.js does not have built-in support for X, requiring a custom plugin."). |
| 71 | +- **Neutral:** Other notable outcomes (e.g., "The team will need a brief training on the new `dayjs` API."). |
| 72 | + |
| 73 | +--- |
| 74 | + |
| 75 | +_Optional but Recommended:_ |
| 76 | + |
| 77 | +## Options Considered |
| 78 | + |
| 79 | +### [Option 1: e.g., "Keep Moment.js"] |
| 80 | + |
| 81 | +- **Pros:** No refactoring effort required. |
| 82 | +- **Cons:** Fails to solve the bundle size problem. |
| 83 | + |
| 84 | +### [Option 2: e.g., "Use `date-fns`"] |
| 85 | + |
| 86 | +- **Pros:** Also lightweight and modular. |
| 87 | +- **Cons:** API is less familiar to the team compared to the Moment.js-like API of Day.js, potentially slowing down the refactoring process. |
| 88 | +``` |
| 89 | + |
| 90 | +</prompt> |
0 commit comments