ADR Examples
هذا المحتوى غير متوفر بلغتك بعد.
Illustrative only. The ADR page states the rules; these are the judgement calls the rules cannot make for you.
1. A good short ADR
Section titled “1. A good short ADR”A load-bearing decision fits on one screen. Note that the Consequences line reframes the whole thing — that sentence is what stops someone “simplifying” it two years later.
# 0003. Split the writable and read-only database contexts
Status: AcceptedState: CurrentDate: 2026-05-27Scope: Persistence. Applies to every data path in the API.Enforcement: ErpReadDbContext.SaveChanges throws; a startup check aborts the API if the ERP database is not attached READ_ONLY.
## ContextWe read route, customer and salesman data from the client's ERP database andown our own planning data. One DbContext over both makes an accidental writeto the ERP a normal-looking line of code — no reviewer would catch it, and theclient's system of record is the blast radius.
## DecisionWe will run two contexts. `AppDbContext` is writable and owns the RoutePlannerschema. `ErpReadDbContext` is read-only over ERP views.
## Rules- Do not merge the two contexts.- `ErpReadDbContext` exposes no public `DbSet<T>` and runs `NoTracking`.- EF migrations target `AppDbContext` only.
## ConsequencesTwo contexts to register and two connection strings to configure. Queriesspanning both must be composed in memory. The type split is a data safetyfeature, not a style preference.2. An honest Enforcement line
Section titled “2. An honest Enforcement line”The field is only worth having if it is true on the merging branch.
| Enforcement line | Verdict |
|---|---|
ErpReadDbContext.SaveChanges throws; startup aborts if the ERP DB is not READ_ONLY |
Good. Both checks exist in code; the rule cannot be broken silently. |
A folder-scan unit test walks the Endpoints/ tree and fails the build — where no such test was ever written |
Bad. Reads as enforced; is not. The convention drifts and nobody notices. |
Review-only |
Good. Honest. A reviewer knows to look, and nobody assumes a machine is watching. |
If you write an Enforcement line describing work you intend to do, the ADR is not ready to merge — the check merges with it.
3. Amend, don’t rewrite
Section titled “3. Amend, don’t rewrite”Two legal shapes. Both leave the original Decision text intact, so the history stays readable.
Prepended banner — corrects the record after acceptance:
# 0022. Cluster affinity as a compactness force
> **Amended 2026-07-09.** Decision §4 described cluster affinity as the> *primary* compactness force. It is secondary — the backbone term dominates.> The weight of 3.0 stated below was recalibrated to 10.0 in ADR-0024.
Status: Accepted...Appended section — sharpens without reversing:
## Amendment — 2026-07-05: one use case per folder
This sharpens, and does not reverse, the original decision. It retires theclause "a slice may contain related endpoints": one slice is now exactly onefolder containing exactly one `*Endpoint.cs`.
Enforcement: Review-only.Supersede instead when the decision is genuinely reversed — a new ADR, Supersedes: 0020, 0021 at the top of the new one, and a banner on the old ones pointing forward.
4. The repo index
Section titled “4. The repo index”/docs/adr/README.md. Without it, the only way to learn that three ADRs are dead is to open all of them.
# Architecture Decision Records
| # | Title | Status | State | Scope ||---|-------|--------|-------|-------|| 0001 | Aspire for local orchestration | Accepted | Current | Local dev || 0002 | ERP is read-only | Accepted | Current | Persistence || 0003 | Dual DbContext split | Accepted | Current | Persistence || 0012 | Customer grouping engine | Superseded by 0025 | — | Territory || 0020 | Circuity travel model | Superseded by 0025 | — | Territory || 0025 | OSRM replaces circuity | Accepted | Current | Territory |5. What ADR abuse looks like
Section titled “5. What ADR abuse looks like”A real run from one of our repos — twelve ADRs in three weeks on a single solver:
| ADR | What it did | Should have been |
|---|---|---|
| 0014 | Adopted an external solver dependency | ADR — a dependency is a boundary |
| 0015 | Chose the solver formulation | ADR — a seam |
| 0016 | Chose the assignment algorithm | ADR — a seam |
| 0022 | Set a weight to 3.0 |
Design doc — a number |
| 0024 | Retuned the same weight to 10.0 |
Design doc — the same number |
| 0026 | Promoted the weight to a per-scenario slider, “fixes the slow-solve regression” | Design doc, and a bug fix is never an ADR |
| 0025 | Deleted the objective term, making the slider inert | ADR — reversal, correctly superseding 0020 and 0021 |
Three of the twelve were decisions. The rest were calibration, and turned the ADR folder into a changelog — which meant an agent told to “read the ADRs” got tuning history instead of a decision record. The right home already existed in the same repo: a living design doc plus a calibration-findings file.
Back to Architecture Decision Records.