← RCF

Concept

Architectural decisions and ADRsCopy link

An ADR is a small record of one architectural choice, with the reasons, alternatives, and consequences captured in a form that survives the conversation that produced it.

An Architectural Decision Record, or ADR, is a short document that captures one architectural choice. The reason it exists, the alternatives that were considered, the choice that was made, and the consequences the team is now committed to. ADRs aren’t new. The pattern’s been around since Michael Nygard wrote it up in 2011 and the wider industry has been running on some variation of it ever since. RCF inherits the pattern with very few changes.

In RCF, ADRs sit on the architecture arm of the document chain, alongside the TAD and the components the TAD defines. The document chain page treats the architecture arm and the intent arm as the two upstream sides of a Y-shape that meets at the FBS. ADRs are the layer on the architecture arm where the consequential decisions get pinned down.

What an ADR isCopy link

An ADR is a record of one decision. Not a survey of the architecture, not a design document, not an essay. One choice, captured tightly. The conventional shape, which RCF uses with no quarrel, is something like:

  • 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 that were on the table, and why they were rejected. This is the part teams consistently skip and consistently regret.
  • 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.

The shape is light because the cost of writing an ADR has to be low enough that teams actually write them. A team that’s asked for a design essay on every choice will produce zero ADRs. A team that’s asked for half a page on the choices that mattered will produce dozens.

Why ADRs earn their keepCopy link

Three reasons, in order of how often they pay back.

The decision survives the conversation. Most architectural choices get made in a meeting, in a thread, or in a half-hour conversation between two engineers. The choice gets implemented; the reasoning evaporates. Three months later, somebody asks why the identity service owns the session token instead of the API gateway, and the answer is “it just does.” That answer is what an ADR exists to prevent. The reasoning is on the page, alongside the choice.

The alternatives aren’t re-litigated. Without ADRs, every new engineer will independently rediscover the alternatives that were already considered and rejected, and propose them as fresh ideas. Sometimes that’s healthy (the trade-offs have shifted; the rejected option is now the right one). More often it’s wasted cycles. An ADR that records the alternatives lets the conversation skip to “has anything changed that would make option B now the right call” instead of starting from zero.

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 ADRCopy link

The honest answer is “you can tell when you have to write one, because the next person to touch the code would have to make the same call from scratch otherwise.” That’s not very crisp, so here are heuristics that hold up.

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 an archaeology dig. 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 chainCopy link

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.

ID scheme and referencesCopy link

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 TADCopy link

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

A useful mental model: the TAD is the architecture as it currently stands. The ADRs are the path the architecture took to get there. Read the TAD if you need to know what the system is. Read the ADRs if you need to know why it is that way.

Both are necessary. The TAD without the ADRs is a snapshot that can’t be reasoned about. The ADRs without the TAD are a pile of decisions with no architecture to anchor them.

The approval gateCopy link

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 exampleCopy link

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).