SfSkills Domains Docs GitHub

Home / architect / architecture-decision-records

architecture-decision-records

Author and maintain Architecture Decision Records (ADRs) for Salesforce implementations: capture chosen approach, rejected alternatives, constraints, and consequences. Trigger keywords: adr, architecture decision record, design decision log, technical decision. NOT for making the design decision itself, e.g. Flow vs Apex — use architect/solution-design-patterns. NOT for a formal architecture review that produces findings — use architect/well-architected-review.

Open the skill folder on GitHub


Architecture Decision Records

An ADR's real product is not the decision. It is the recorded premise — the volumes, limits, and requirements the decision depended on. That is what lets a future team test whether the choice still holds rather than re-litigating it, and it is the part most ADRs omit.

On Salesforce specifically, two things make ADR discipline harder than elsewhere: three major releases a year expire premises fast, and the platform's lifecycle churn (product end-of-sale, feature retirement, GA dates) invites confident unsourced claims into a document that is deliberately never updated.


Questions to Ask Before Configuring

Ask these before drafting. Each one traces to a failure mode in references/gotchas.md.

QuestionWhy it mattersWhat a good answer addsWhat proper configuration adds over just doing it
"Which two options could a competent person have chosen here?"No real alternative means a standard, not a decision (Gotcha 4)An Alternatives Considered section a future team will believeThe index holds decisions only, so readers keep reading it
"Does a standards/decision-trees/ tree route this, and are we following it or deviating?"A re-derived tree forks and drifts (Gotcha 1)The branch, the question numbers, and the inputs that selected themOne owner for the reasoning; the ADR records only what was true here
"Which volumes, limits, licences, or product-lifecycle facts does this rest on, and where is each one sourced?"Premises expire on a three-release cadence and lifecycle claims get frozen unsourced (Gotchas 2, 6, 7)A Context section a future reader can re-test line by lineA supersession that says whether a premise expired or a mistake was found
"Does this rest on a current platform limitation or a pending vendor decision, and who watches it?"Backwards compatibility means nothing breaks to force a re-read (Gotcha 14)A Review Trigger with a named owner, listed in INDEX.mdExpired premises surface at release readiness instead of in an incident
"Who decided, in which role and forum, and can every stakeholder open the place this is stored?"Unnamed deciders and unreachable records make revisiting slow (Gotchas 12, 15)Named deciders plus a location business readers can reachThe five-minute conversation with the original decider stays possible
"What will the team writing the superseding ADR complain about?"An all-positive Consequences section means no tradeoff was weighed (Gotcha 5)At least one specific, checkable negativeReviewers can test the decision against its own stated cost

What a proper decision record adds over "just writing it down": the premise is testable, the reversal path is explicit, and the record survives the people who made it.


ADR Candidacy

Promote a decision to ADR when any of these holds:

Out of scope:

The test: if it fits in a PR description, it is not an ADR. The corollary, which is more useful: if you cannot name two alternatives a competent person could actually have chosen, the decision was not open — you are documenting a standard, not deciding.


ADRs And Decision Trees Are Different Layers

This repository has standards/decision-trees/. An ADR that re-derives one of those trees is a fork waiting to diverge — and the first tree update makes them contradict each other.

Decision treeADR
Scopeorganisation-wide routing ruleone situation
Answers"which technology for this shape of problem?""which branch applied here, and what was true?"
Lifecycleupdated as the platform changesfrozen on acceptance

When a tree routes the decision, the ADR records the branch and the inputs, not the reasoning:

## Decision Trees Consulted
- `automation-selection.md` — Q1 (scheduled clock) → Q10 (>50k records) → Batch Apex
- `async-selection.md` — Q9 (needs ad hoc re-run) → Schedulable wrapper

Inputs at the time of this decision:
- 1.9M Account rows today; ~3.4M projected after the Q3 acquisition
- Business requirement: accurate by 07:00 daily

Two cases still need an ADR even when a tree answered:

  1. You are deviating from the tree. Record the branch, why this situation is

    the exception, and what would end the exception. A deviation with no ADR is indistinguishable from an error.

  2. The tree does not cover the scenario. Write the ADR, and raise the gap so

    the tree can be extended — do not force-fit.

And the inverse: when the same decision recurs identically across teams, it belongs in the tree, not in a fourth ADR.


Required Sections

Standard Nygard structure, one file per decision in docs/adr/:

  1. Title — ADR-XXXX: <one-line decision>
  2. Status — Proposed / Accepted / Rejected / Superseded by ADR-YYYY (with date)
  3. Context — the forces, the constraints, and the inputs the decision depended on
  4. Decision — the choice, in the active voice
  5. Consequences — positive and at least one specific, checkable negative
  6. Alternatives Considered — at least two that a competent person could have chosen
  7. Date — the decision date, ISO-8601, never updated
  8. Deciders — named people with the role they held at the time, plus the forum

Plus, on Salesforce:

  1. Decision Trees Consulted — branch and question numbers, or an explicit "no tree covers this"
  2. Review Trigger — where the decision rests on a current platform limitation rather than a principle, with a named owner

Sourcing Platform Claims

An ADR is the worst possible place for an unsourced lifecycle date, because ADRs are deliberately not updated. A wrong date in a design doc is corrected next sprint; a wrong date in an ADR stays load-bearing forever.

Every lifecycle, retirement, GA, or limit claim needs one of:

Consultancy blogs are not sources for an architecture record. Where a claim cannot be verified, mark it inline rather than laundering it:

UNVERIFIED (2026-07-21): a specific end-of-sale date of 27 March 2025
circulates widely in consultancy writing. Not confirmed from a Salesforce
source. Confirm with the account team and record who said it and when.

Write the marker as visible text, not as an HTML comment. GitHub and most wiki renderers hide <!-- --> comments, so a hidden caveat disappears from exactly the reader who needs it.

The same applies to managed-package constraints: record the package name, the version tested, and how the constraint was established, so a future reader can re-test it instead of assuming it still holds.


  1. Apply the candidacy test. If it fits in a PR description, or you cannot name

    two viable alternatives, stop — this is not an ADR.

  2. Check standards/decision-trees/ before writing. If a tree routes this,

    record the branch and the inputs rather than re-deriving the reasoning. If you are deviating from the tree, say so explicitly and name what would end the exception.

  3. Draft from templates/adr-template.md (Status = Proposed only if a real

    review forum exists; otherwise write it Accepted and retrospective), and source every platform claim as you go — Salesforce URL, or a named person and date. Mark anything unverifiable inline. Record package name, version tested, and method for package-attributed constraints.

  4. Force the negatives. Ask what the team writing the superseding ADR will

    complain about, and write that down. If nothing comes to mind, this was not a tradeoff.

  5. Add a Review Trigger with a named owner wherever the decision rests on a

    current platform limitation or on a pending vendor decision. A calendar date is not a trigger — a condition is.

  6. Mark Accepted with the date and named deciders, update docs/adr/INDEX.md

    including the open review triggers table, and cite the ADR number in subsequent PR descriptions.

  7. On supersession: write a new ADR, flip the old one's Status line and nothing

    else, link both ways, and state whether a premise expired or a mistake was found: they teach different lessons. Enforce the "Status line only" rule with the CI check in references/examples.md.


Review Checklist


Worked Examples (see references/examples.md)

Common Gotchas (see references/gotchas.md)

Top LLM Anti-Patterns (full list in references/llm-anti-patterns.md)


Official Sources Used

See references/well-architected.md for the full source list, including an explicit caveat on the CPQ lifecycle claims used in the worked examples.

Dependencies

Package files