When a design-system choice deserves a decision record
Record a choice when its consequences will outlast the meeting where it was made. Typical candidates change a shared semantic role, introduce or remove a component contract, set mode behavior, establish an exception, select an authoritative artifact, or alter how several products consume the system.
You usually don't need a record for a reversible local adjustment with one owner, one consumer, and no effect on a shared contract. Diff size isn't the test. Ask whether a future contributor could reasonably reopen the question, misunderstand its authority, or change one layer without knowing what else should move.
- The decision crosses team, repository, product, or platform boundaries.
- Several credible options exist, and rejected alternatives may return later.
- The change affects reusable tokens, modes, components, exports, or agent guidance.
- An exception could otherwise look like accidental drift.
- Acceptance depends on evidence that will arrive after approval.
- Reversing the choice would require migration, coordinated retesting, or a new release.
One record, one decision
Don't use a single record as a project diary. If a proposal contains choices with different authorities, scopes, or reversal conditions, split them into separate records and link them.
Copyable design system decision record template
Keep the record beside the system or in a versioned decision-log directory. Markdown makes the rationale easy to read during reviews, while explicit fields keep authority, scope, and status from disappearing into prose.
# DSDR-[NNN]: [Decision title]
- Decision status: proposed | accepted | rejected | superseded
- Date: YYYY-MM-DD
- Governing authority: [team, role, policy, or source]
- Authority version: [version, commit, release, or dated document]
- Decision owner: [name or role]
- Reviewers: [names or roles]
- Supersedes: [record ID or none]
- Superseded by: [record ID or none]
## Problem
[The one consequential question this record decides.]
## Constraints
- [Requirement, compatibility boundary, or invariant]
- [Known uncertainty]
## Options considered
### Option A: [name]
- Benefits:
- Costs and risks:
- Reversal cost:
### Option B: [name]
- Benefits:
- Costs and risks:
- Reversal cost:
## Selection criteria
- [Criterion and how it affected the choice]
## Decision
[State the selected option and the rule it establishes.]
## Rationale and trade-offs
[Explain why this option won and what the team knowingly gives up.]
## Scope
- Tokens and modes:
- Emitted artifacts:
- Project mappings:
- Component contracts:
- Products and platforms:
- Named consumers:
## Explicit exclusions
- [Similar-looking area this decision does not govern]
## Approved exceptions
- [Exception, owner, reason, and review date]
## Ownership
- Implementation owner:
- Correction owner by layer:
- Acceptance owner:
- Review owner:
## Evidence requirements
- Delivered: [artifact, version, and inspection]
- Mapped: [project mapping and version]
- Adopted: [named component or consumer]
- Observed: [condition, expected result, and evidence location]
## Current evidence
- Evidence status: not-started | delivered | mapped | adopted | observed
- Evidence collected:
- Evidence missing:
- Last checked:
## Consequences
- Intended effects:
- Protected areas that must remain unchanged:
- Migration or release implications:
## Retest and review triggers
- [Source, artifact, mapping, component, exception, or consumer change]
## Disposition
accept | revise | reject | block-implementation | supersede
## Links
- Implementation work:
- Evidence:
- Related records:Fill the record without hiding uncertainty
Give the record a stable identifier. Then name the authority that can make the decision and pin its version. A team name alone doesn't tell readers whether the record applies to the current system. The authority might be a design-system group, an approved specification, a product owner for local behavior, or another explicitly governed source.
Keep authorship separate from authority. The person writing the record may gather evidence and document the options without having the power to accept the decision.
Problem, constraints, options, and criteria
Frame the problem as one question. Constraints describe the conditions the answer must respect, including compatibility, accessibility, platform limits, or protected consumers. For each credible option, record its benefits, costs, risks, and reversal cost. Selection criteria should explain why the chosen option fits this problem instead of restating a preference.
Decision, scope, and exclusions
Make the decision specific enough to falsify. "Use semantic tokens consistently" is too vague. "Buttons with the primary action contract consume the shared action role in light and dark modes" identifies both intent and reach.
Scope names what may change. Exclusions protect nearby areas that resemble the target but remain under different authority. If a shared action role governs primary buttons but not status badges or destructive actions, say so. Without exclusions, downstream teams may read a narrow choice as permission for a wider redesign.
Do not turn uncertainty into a default
If mode behavior, a consumer mapping, or an exception hasn't been decided, mark it unresolved and assign an owner. A blank field can make an open decision look like permission to improvise.
Map the decision from authority to named consumers
Trace the consequences through every layer that can diverge. Start with the governing source, then list each downstream representation and at least one named consumer. This map describes the decision's potential reach. It doesn't claim that every layer already agrees.
- 1
Identify the governing source
Name the authority, version, and exact rule being changed. If two sources appear authoritative, resolve that conflict before implementation.
- 2
List emitted artifacts
Record token files, CSS variables, DTCG exports, DESIGN.md guidance, packages, registry items, or documentation that should carry the decision.
- 3
Record project mappings
Show how each consuming project imports or translates the source role. Include mode-specific mappings where they differ.
- 4
Name component contracts
Identify the components, variants, and states permitted to consume the decision. Prefer a named contract such as Button.primary over a broad category such as buttons.
- 5
Name representative consumers
Name real product surfaces or flows where the result can be observed. Include protected consumers that must remain unchanged.
- 6
Assign correction and retest
For every layer, name who corrects a mismatch and which change or failure requires the team to collect evidence again.
| Layer | Record | Question | Typical correction owner | |
|---|---|---|---|---|
| Governing source | Governing source | Authority and version | Is the intended rule explicit, current, and accepted? | Decision owner |
| Emitted artifact | Emitted artifact | Artifact and build version | Does the expected output contain the decision? | Artifact or build owner |
| Project mapping | Project mapping | Import, alias, or translation | Does the project resolve the intended role and mode? | Project integration owner |
| Component contract | Component contract | Component, variant, and state | Does the component consume the mapped role as specified? | Component owner |
| Approved exception | Approved exception | Reason, boundary, owner, review date | Is the divergence deliberate and still valid? | Exception owner |
| Named consumer | Named consumer | Product surface and condition | Does the intended implementation reach this consumer? | Product owner |
| Rendered observation | Rendered observation | Environment, condition, result, evidence | Did the expected behavior occur under the recorded conditions? | Acceptance owner |
Inspect an upstream system before mapping its reach
A decision record is easier to scope when upstream roles and artifacts are explicit. A published kit shows how tokens, typography, spacing, and usage guidance can arrive as one bounded input. Your team still owns local mappings, exceptions, adoption, and verification.
Keep decision states separate from evidence states
A decision and its implementation answer separate questions. The decision axis records whether the proposal has authority. The evidence axis records how far the accepted rule has travelled. Keeping both prevents a common reporting error: treating approval, documentation, or artifact generation as proof that a product behaves as intended.
| Decision state | What it proves | What it does not prove | |
|---|---|---|---|
| Proposed | Proposed | A bounded option is ready for review. | That the option is authorized or should be implemented. |
| Accepted | Accepted | The named authority approved the decision for the recorded scope. | That artifacts were generated, consumers adopted it, or behavior was observed. |
| Rejected | Rejected | The authority declined the proposal in its recorded form and context. | That the underlying problem disappeared or another option was implemented. |
| Superseded | Superseded | A later linked record now governs the decision. | That every consumer migrated or the old implementation can be removed. |
| Evidence state | What it proves | What it does not prove | |
|---|---|---|---|
| Delivered | Delivered | The identified artifact or output exists at the recorded version. | That a consuming project maps or uses it. |
| Mapped | Mapped | A named project resolves the decision through the recorded mapping. | That supported components or product surfaces use that mapping. |
| Adopted | Adopted | A named component or consumer uses the intended contract. | That the expected result occurred in every state or environment. |
| Observed | Observed | The expected result occurred for the named consumer under recorded conditions. | That every consumer works or the result remains valid after a relevant change. |
Report only the evidence you've collected. If the artifact exists but no one has inspected the application mapping, report delivered, not mapped. If a component references the mapping but no representative state has been run, report adopted and leave observed open.
Acceptance says what should happen. Evidence shows how far the decision actually travelled.
Assign ownership by decision and correction layer
One owner field is rarely enough. The person authorized to accept the rule may not own the export pipeline, component, application mapping, or final observation. Record each responsibility separately so the team knows who owns a failed check.
- Decision owner: maintains the question, options, rationale, scope, and authority status.
- Implementation owner: coordinates the approved change across the intended layers.
- Correction owner: fixes a mismatch in a specific source, artifact, mapping, component, exception, or consumer.
- Acceptance owner: decides whether the collected evidence satisfies the stated requirements.
- Review owner: revisits the record when a trigger fires or the review date arrives.
On a small team, one person may hold several roles. The separation still matters because it shows which judgment that person is making at each point.
Fictional example: change one semantic action role
Fictional and unexecuted
The example below teaches the recording method. The product, values, mapping, and result are invented. No artifact was generated, no interface was inspected, and no implementation claim should be inferred from it.
Imagine a fictional product called Northstar Ledger. Its team proposes changing the shared primary-action role while protecting destructive actions and status colors. The proposal names one button consumer and an expected result, but leaves every downstream observation open.
# DSDR-017: Update the primary action role
- Decision status: proposed
- Date: 2026-10-07
- Governing authority: Northstar Ledger design-system council
- Authority version: council charter v2.1
- Decision owner: Design systems lead
- Reviewers: Product design lead, frontend platform lead
- Supersedes: none
- Superseded by: none
## Problem
Should the shared primary action role use the proposed teal values in both modes?
## Constraints
- The role must remain semantic rather than component-specific.
- Destructive actions and status colors are outside scope.
- No downstream behavior has been observed.
## Options considered
### Option A: Keep the current role
- Benefit: no migration.
- Cost: does not address the recorded brand-direction mismatch.
### Option B: Change the shared role
- Benefit: one governed role can reach intended action consumers.
- Risk: an overly broad mapping could change protected consumers.
## Decision
Proposed, not accepted: change action.primary to new mode-specific values.
## Scope
- Source token: color.action.primary
- Modes: light and dark
- Proposed export: tokens/color.json
- Proposed project mapping: --action-primary
- Named component consumer: Button.primary
- Named product consumer: Invoice editor / Send invoice action
## Explicit exclusions
- Button.destructive
- Validation messages
- Status badges
- Data visualizations
## Ownership
- Implementation owner: Frontend platform lead
- Source and export correction owner: Token pipeline owner
- Mapping correction owner: Invoice application owner
- Component correction owner: Button maintainer
- Acceptance owner: Product design lead
- Review owner: Design systems lead
## Evidence requirements
- Delivered: inspect the versioned export for both mode values.
- Mapped: inspect the application alias for --action-primary.
- Adopted: confirm Button.primary consumes the mapped role.
- Observed: inspect the Send invoice action in default, hover, focus, and disabled states in both modes.
- Protected observation: confirm destructive and status consumers remain unchanged.
## Current evidence
- Evidence status: not-started
- Evidence collected: none
- Evidence missing: delivery, mapping, adoption, and observation
- Expected result: the named primary action follows the proposed role in both modes.
- Observed result: unobserved
## Retest and review triggers
- Source value or alias change
- Export configuration change
- Application mapping change
- Button.primary contract change
- New consumer added to action.primary
- Approved exception created or expired
## Disposition
block-implementation pending acceptanceThe example doesn't use accepted as shorthand for ready. Nor does it present the expected result as something a reviewer saw. If the council accepts the proposal, decision status can change to accepted while evidence remains not-started. Each later evidence update should link to an inspectable artifact, diff, test, or observation.
Review from the governing source to the rendered consumer
When an implementation appears wrong, inspect the chain from authority to consumer. The most visible symptom isn't necessarily the source of the error. A button with the wrong color might reflect an incorrect source decision, stale export, bad project alias, component override, expired exception, or local consumer style.
- 1
Check the governing decision
Confirm that the record is accepted, current, within scope, and tied to the intended authority version.
- 2
Inspect the emitted artifact
Verify the exact artifact and version. Record whether it contains the intended role and mode values.
- 3
Inspect the project mapping
Follow the import or alias used by the target project. Don't assume that it consumes the newest artifact.
- 4
Inspect the component contract
Check the named variant and state for local values, selectors, aliases, or fallback behavior that changes the mapping.
- 5
Check approved exceptions
Confirm the reason, owner, boundary, and review date before classifying a divergence as a defect.
- 6
Inspect the named consumer
Verify that the product uses the intended component and version rather than a fork, wrapper, detached copy, or substitute.
- 7
Record the observation and next action
Write down the environment, state, expected result, actual result, first divergent layer, correction owner, and retest trigger.
Stop at the first layer where the evidence fails the recorded expectation. Fix that layer before compensating farther downstream. A local override may hide the symptom while leaving every other consumer exposed to the same upstream defect.
Supersede rather than silently rewrite
A decision record is useful because it preserves the reasoning available at the time. If a new constraint, product requirement, or technical boundary changes the answer, create a new record. Mark the old one superseded and link the records in both directions.
Supersession changes authority, not consumer state. The old record can be superseded while products still implement it. The new record should name migration ownership, coexistence rules if both versions remain active, affected consumers, and the evidence required before the old implementation can be retired.
- State what new evidence or constraint invalidated the old choice.
- Preserve the previous assumptions that still hold.
- Name the consumers that must migrate and any allowed to remain temporarily.
- Define when migration starts and what counts as complete.
- List the changes that require representative consumers to be retested.
- State when the old artifact, alias, component path, or exception may stop being supported.
Edit facts, preserve history
Correcting a typo or adding a missing link doesn't require a new decision. If the rationale, authority, scope, selected option, or consequences change materially, use supersession so reviewers can see that the governing choice changed.
Keep adjacent governance work in its own record
The decision record governs one choice. Link it to adjacent operational records, but don't ask it to replace them.
| Record | Primary question | Do not use it as | |
|---|---|---|---|
| Decision record | Decision record | What was decided, by whom, for what scope, and why? | A release checklist or complete implementation plan |
| Contribution brief | Contribution brief | What change is being proposed, and who must review it? | Proof that the proposal shipped |
| Token handoff record | Token handoff record | Did a specific token decision reach artifacts, mappings, and consumers? | Authority for changing the underlying decision |
| Component inventory | Component inventory | What design, code, documentation, usage, and evidence exist for each component? | A rationale for every system-wide choice |
| Release record | Release record | Is a versioned release safe to distribute and retain? | The permanent rationale for each included change |
| Taxonomy record | Taxonomy record | Where do token decisions belong, and how may they change? | Observed evidence for every product consumer |
Identity Forge supplies upstream design-kit guidance and token artifacts, including DESIGN.md and token exports. It doesn't decide a consuming team's local mappings, exceptions, component adoption, acceptance evidence, or governance. Record those downstream choices under the authority that owns them.
Record the next disputed decision before implementation begins
Choose one pending design-system question with more than one credible answer. Copy the template and identify the governing authority and version. Then fill in the scope, exclusions, named consumers, correction owners, and evidence requirements before anyone edits an artifact. If you can't complete those fields, the decision isn't ready to implement.
Sources
- Architectural Decision Records: An architectural decision record captures one justified decision and its rationale, trade-offs, and consequences; maintained records form a decision log.
- Capturing your design system decisions: Decision-record practices can be adapted to design-system choices by recording context, the decision, consequences, compliance, and notes.
- Design decision template | Confluence - Atlassian: A collaborative design-decision workflow can explain the problem, present options, gather feedback, and log the resulting decision.
- Design token handoff checklist: prove the path from source to consumer: A token handoff should trace required decisions through delivered artifacts, project mappings, named consumers, and observed results without treating missing evidence as acceptance.
- Design system component inventory template: map design, code, usage, and decisions: A component inventory can connect design and code identities, documentation, named consumers, observations, ownership, exceptions, and pending decisions.
- Design system release checklist: verify artifacts, consumers, and rollback: Release acceptance requires evidence across the approved source change, emitted artifacts, distribution, documentation, and representative consumers; a successful build proves only that the build completed.