Skip to content

How we decide

Every stack decision is recorded as an ADR (Architecture Decision Record) — a short, dated page that captures what we decided and, more importantly, why.

Each decision page has these sections:

  • Status — Proposed → Accepted → (Deprecated | Superseded by ADR-XXXX)
  • Context — the forces at play: requirements, constraints, what prompted this decision now
  • Options considered — the realistic candidates, with pros/cons
  • Decision — the one-line call, plus the reasoning in a few sentences
  • Consequences — what becomes easier, what becomes harder, what we’re explicitly giving up
  1. One decision per page. If a topic fans out (e.g. database choice affects ORM choice), record them as separate ADRs that link to each other.
  2. Numbered sequentially, zero-padded: 0001, 0002, … Numbers are never reused.
  3. Dated. The date on the ADR is the day the decision was made.
  4. Accepted decisions change in place only for corrections and narrow amendments. A change that keeps the decision’s layer and direction — a stale fact, a package or setting swapped — is edited on the page, with a dated note saying what it replaced: “(Amended 2026-11-12: …)”. A different decision gets a new ADR that supersedes the old one. Old pages stay for history.
  5. Company-wide scope. These ADRs are defaults for all new projects. A product can deviate, but it must write its own ADR explaining why.
  6. Alternatives are documented honestly. Future-us should be able to see what was rejected and why, so we don’t re-litigate settled questions without new information.
Proposed ──discuss──> Accepted ──time passes──> Superseded by ADR-XXXX
│
└──> Deprecated (no longer recommended, nothing replaces it yet)
  1. Create src/content/docs/decisions/NNNN-short-slug.md (next number up), plus its Portuguese twin at src/content/docs/pt/decisions/NNNN-short-slug.md.

  2. Start from an existing ADR as the template, and fill in Context / Options / Decision / Consequences.

  3. Fill in the frontmatter. The page header, the sidebar, and the home page are built from it, so there is no table to update by hand, and the build fails if a field is missing:

    title: "ADR-0018: Short layer name"
    description: One sentence with the decision.
    decision: "PostgreSQL" # the short answer
    band: data # app, data, or ship
    status: proposed # proposed, accepted, deprecated, or superseded
    date: 2026-10-21 # the day the decision was made
    scope: "Company-wide default for all new apps"
    supersededBy: ADR-0021 # only when status is superseded
  4. Link the ADRs this one builds on (/decisions/NNNN-…/; /pt/decisions/NNNN-…/ on the Portuguese page). The “Builds on” and “Cited by” connections at the top of each page are built from those links.