On this page

← RCF

Concept

Architectural decisions and ADRs

An architecture decision record (ADR) captures one architectural choice, its reasons, alternatives and consequences.

Last updated

An Architectural Decision Record, or ADR, records one architectural choice, why it was needed, the alternatives considered and the consequences accepted. Michael Nygard described the pattern in 2011. RCF adopts it with few changes.

ADRs sit on the architecture arm alongside the TAD and its components. The document chain page describes how that arm meets the intent arm at the FBS. ADRs capture the significant architecture choices.

What an ADR is

An ADR records one decision. RCF uses these conventional sections:

  • Context. The situation that forced the decision. What problem is being solved, what constraints are in play, what was already decided that this decision sits on top of.
  • Decision. The choice that was made. Stated clearly, in the active voice, with enough specificity that an engineer six months later can tell whether the system still matches the decision or has drifted from it.
  • Alternatives considered. The other options considered and the reasons they were rejected.
  • Consequences. What follows from the decision. The things the team is now committed to, the trade-offs accepted, the things now harder to change.
  • Status. Proposed, accepted, deprecated, superseded. ADRs aren’t edited after they’re accepted; they’re superseded by a new ADR that records the change.

Keep ADRs short enough to write routinely. Half a page can record a significant choice without requiring a full design document.

Why ADRs earn their keep

ADRs provide three benefits.

The decision survives the conversation. Record the reasoning alongside the implemented choice. For example, an ADR explains why the identity service owns session tokens instead of the API gateway, even after the engineers involved have left.

The alternatives aren’t re-litigated. Recording rejected options lets new engineers check whether the trade-offs have changed before reopening a decision.

The chain stays traceable. An FBS that depends on a decision (the session-token-ownership choice, say) can reference the ADR by ID, the same way an FBS references the TAD components it relies on. If the ADR gets superseded later, the chain surfaces the FBSs that depended on the old decision, and the team can ask explicitly whether each one needs revisiting. Without the ADR, that query has no answer.

What makes a decision “architectural” enough to ADR

Write an ADR when another engineer would otherwise need to reconstruct a significant decision. The following criteria help identify those cases.

Write an ADR when the decision constrains things outside the immediate slice. Picking a JSON serialiser inside one service is a code review note, not an ADR. Picking the auth model the whole product uses is an ADR.

Write an ADR when the decision is hard to reverse. Choosing a database flavour is an ADR because changing it later costs months. Choosing a naming convention is an ADR because once it’s in the codebase, changing it touches every file.

Write an ADR when the decision needs cross-role sign-off. If security, devops, or product had a stake in the choice, the choice needs a record that captures whose stake was honoured and whose was traded against. That record is an ADR.

Don’t write an ADR for choices that are local to a single FBS, that are obvious from the surrounding code, or that the next engineer can reverse without extensive investigation. Those choices belong in the code, in the commit message, or in a comment. An ADR for every choice is the template-filling failure mode the theatre risk page warns about.

Where ADRs live in the chain

ADRs belong to the architecture arm of the Y-shape. They reference the TAD they sit under and the TAD components they constrain. FBSs reference them as build context the worker needs.

Concretely: a TAD has a decisions section. The decisions section is a list of ADRs. Each ADR carries an opaque ID (ADR-001, ADR-002, and so on), a status, a date, the four-or-five sections above, and any links to other decisions it supersedes or builds on. The ADR isn’t stored inside the TAD document; it’s a separate artefact that the TAD references by ID. That keeps the TAD readable and lets the ADR carry as much detail as it needs without bloating the parent document.

In smaller projects, the TAD’s decisions section can carry the ADRs inline as short blocks. The decision to break them out into their own artefacts is a project-size question, not a methodology question. The methodology says ADRs exist and are referenceable; how they’re filed is a tooling choice.

Where architectural decisions live in the RCF chain: the Y with the architecture arm in focus A feed-legible infographic showing the RCF document chain drawn as a horizontal Y reading left to right. The architecture arm on the upper left is highlighted in signal red: a large TAD box (the architecture record) with a cluster of four signal-filled ADR chips attached (each ADR is one decision, half a page). The requirements arm on the lower left is quiet outline: REQ (requirement), then US (user story), then AC (acceptance criterion), rising rightward to meet the junction. Both arms converge on a signal-stroked BUILD SPEC pill in the centre-right (the brief for one small slice of work). From the junction, a quiet verification tail continues right to TS (test suite) and TC (test case). Closing line, in signal red: the decision is the deliverable. RCF walkthrough 10 · architectural decisions the Y, architecture arm in focus Where the decisions live the RCF chain in outline, one arm detailed TAD: the technical architecture document. What the system is; the anchor of the architecture arm. TAD the architecture record Four ADR chips. Each ADR is a single architectural decision, roughly half a page, holding the situation, the choice, the options that lost, the consequences, and a status. ADR ADR ADR ADR each ADR: one decision, half a page REQ: a requirement. Head of the requirements arm. REQ requirement US: a user story. Sits between REQ and AC on the requirements arm. US user story AC: an acceptance criterion. End of the requirements arm before it meets the junction. AC acceptance criterion BUILD SPEC: the brief for one small slice of work. The Y junction where the requirements arm and the architecture arm meet, and where the ADR ID gets named alongside the acceptance criteria the slice has to satisfy. BUILD SPEC the brief for one small slice of work TS: a test suite. The first step of the verification tail leaving the junction. TS test suite TC: a test case. The end of the verification tail. TC test case the decision is the deliverable Where architectural decisions live in the RCF chain (narrow layout) Same content stacked for portrait. Requirements arm on the left, quiet: REQ, US, AC descending into the junction. Architecture arm on the right, highlighted in signal red: a large TAD box with four ADR chips (each ADR is one decision, half a page). Both meet at a signal-stroked BUILD SPEC pill (the brief for one small slice of work). Verification tail drops straight down: TS, TC. Closing line: the decision is the deliverable. RCF walkthrough 10 architectural decisions Where the decisions live the RCF chain, architecture arm in focus REQ: a requirement. REQ requirement US: a user story. US user story AC: an acceptance criterion. AC acceptance criterion TAD: the technical architecture document. What the system is. TAD the architecture record ADR chips. Each ADR is one decision, half a page. ADR ADR ADR ADR one decision, half a page BUILD SPEC: the brief for one small slice of work. BUILD SPEC the brief for one small slice of work TS: a test suite. TS test suite TC: a test case. TC test case the decision is the deliverable
the Y in outline · architecture arm in focus · where the decisions live

ID scheme and references

ADR IDs are ADR-NNN, sequential within a TAD. They’re opaque strings, never renumbered, never reused. ADR-007 stays ADR-007 forever, even after it’s superseded by ADR-019. The supersession gets recorded as a link from ADR-019 back to ADR-007, and the old record stays in place as a frozen snapshot of what the team thought at the time.

ADRs get referenced from the buildContext.adrs field on an FBS, alongside the TAD sections and PRD sections the worker will need. An FBS that depends on a specific decision lists the ADR ID so the worker (human or agent) reads the decision as part of the brief.

The relationship to the TAD

The TAD describes the system. ADRs describe the decisions that shaped the system. The two are linked but not the same.

The TAD describes the current architecture. ADRs explain how and why the team chose it.

The TAD gives the decisions their system context. ADRs give the current architecture its reasoning.

The approval gate

ADRs go through the same approval pattern as every other artefact in the chain (described on the theatre risk page): a standard for what an ADR must contain, AI-assisted extraction of the decision and its alternatives from the conversation that produced it, a visible gap if any required section is missing, and a human signature at the approval commit. The signing role depends on the decision: the tech architect signs for cross-cutting choices; specialised roles (security, devops, data) co-sign where the decision touches their domain.

The approval discipline is what stops ADRs becoming after-the-fact justifications. An ADR that gets written and approved before the work commits is a decision. An ADR that gets written and approved after the work is a description.

Worked example

ADR-014: Session tokens are owned by the identity service.

Status. Accepted, 2026-03-12.

Context. The product needs session tokens for authenticated requests across four services. We’ve already decided on an API gateway as the entry point (ADR-009) and on OAuth as the external auth model (ADR-011). The remaining decision is which service owns the token lifecycle: minting, rotation, revocation.

Decision. The identity service owns session tokens. The API gateway validates them but doesn’t mint or revoke. Other services trust the gateway’s validation result.

Alternatives considered. (a) Gateway owns tokens. Rejected because it couples the auth model to the gateway in a way that’s hard to reverse if we change gateway. (b) Each service owns its own tokens. Rejected because it produces inconsistent revocation semantics across services. (c) External token service. Rejected as overkill for current scale.

Consequences. Token rotation policy is now an identity-service concern, not a gateway concern. Compromise of the identity service is a single point of failure for all sessions (accepted; mitigated by the identity service’s isolation requirements in TAD-001 Section 4). Other services no longer need to understand token internals; they get a validated user identity from the gateway.

References. Supersedes nothing. Constrains FBS-051, FBS-052, FBS-063 (export, profile, billing slices that all depend on session ownership). Sits under TAD-001 Section 3 (Identity).