Get started

Design token handoff checklist: prove the path from source to consumer

A design token handoff is complete only when the receiving team can trace each required decision from its governing source to the delivered artifact, project mapping, named consumers, and observed result. Optional or out-of-scope evidence may be marked not applicable, with a reason. Missing evidence required by the stated scope cannot support acceptance.

Updated September 23, 2026

Keep the acceptance boundary narrow

This checklist answers one question: Can the receiving team trace an approved token decision into the named consumers covered by the handoff? Its scope is narrower than a general design handoff. Screens, product behavior, responsive rules, content, assets, and interaction states still need their own decisions and owners.

It is also narrower than token-format validation, accessibility evaluation, and release approval. A handoff record may link to those results, but it can't replace them. Use the DTCG validation procedure for format claims and the alias guide for reference behavior. Use the accessibility checklist for system and product checks. Use the release checklist when the decision includes distribution approval, rollback, or production readiness.

File presence is delivery evidence at most

Finding a file in a repository doesn't establish that it came from the governing source, survived a transformation, reached the intended project version, maps to the right identifier, or controls the rendered consumer.

Copy the complete token handoff register

Use one record for each coherent token group or change. Split it when sources, transformations, project mappings, consumers, owners, or dispositions differ. Define the handoff scope and classify its fields before filling in the record.

MeaningHow to record itAcceptance effect
RequiredThe stated handoff scope cannot be accepted without this field.Record a value and its supporting reference. If it's unknown, record unresolved and name an owner.Unresolved required evidence prevents accept.
ConditionalThe field becomes required when its documented condition applies.Record the value when applicable. Otherwise, use not_applicable and state why the condition doesn't apply.An applicable but unresolved conditional field prevents accept.
Not applicableThe field falls outside the stated scope or its condition does not apply.Record not_applicable plus a specific reason. Don't leave it blank.It does not block acceptance unless the scope changes.
Field-status rules for the register

The template labels each field as required or conditional. Required means the field is necessary for a complete source-to-consumer handoff. Conditional fields include their trigger. If a conditional field doesn't apply, record an explicit reason. Never use a blank to mean both unknown and not applicable.

handoff_id: "" # required
recorded_at: "" # required
scope:
  token_group_or_change: "" # required
  included_roles: [] # required
  excluded_roles: [] # required; may be [] with reason
  required_modes: [] # required
  target_evidence_state: observed # required
  acceptance_claim: "" # required

authority:
  governing_source: "" # required
  source_version_or_revision: "" # required
  approved_by: "" # required
  approval_reference: "" # required
  correction_owner: "" # required

token_contract:
  semantic_purpose: "" # required
  alias_status: "" # required; use none with reason when direct
  aliases: [] # conditional when alias_status is authored
  permitted_transformations: [] # required; use none with reason if prohibited
  candidate_decision: adopt | map | defer | reject # required

delivery:
  generated_artifact: "" # required for delivered, mapped, or observed
  artifact_version_or_hash: "" # required for delivered, mapped, or observed
  transformation_tool_and_version: "" # conditional when transformation occurs
  transformation_configuration: "" # conditional when transformation occurs
  distribution_location: "" # required for delivered, mapped, or observed
  delivery_observation: "" # required for delivered, mapped, or observed

project_mapping:
  project_and_version: "" # required for mapped or observed
  source_role: "" # required for mapped or observed
  destination_identifier: "" # required for mapped or observed
  mode_mapping: "" # required for mapped or observed
  component_contract: "" # required for mapped or observed
  named_consumers: [] # required for mapped or observed
  protected_surfaces: [] # required; may be [] with reason

verification:
  expected_observations: [] # required for observed
  observed_evidence: [] # required for observed; never store non-execution here
  environment: "" # required for observed
  sample_limit: "" # required for observed
  unresolved_fields: [] # required; may be []

exceptions:
  status: none | present # required
  records: [] # conditional when status is present
  # each record needs scope, reason, authority, owner, and review_or_expiry_trigger

retest_triggers: [] # required
evidence_state: unassigned | defined | delivered | mapped | observed # required
disposition: accept | revise | block # required
disposition_reason: "" # required
next_action: "" # required
Copyable design token handoff register with field requirements

Unresolved and not applicable mean different things. Unresolved says the field applies, but its evidence is missing. Not applicable says the field doesn't apply under the recorded scope and explains why. Only the second can be compatible with acceptance.

Do not confuse the layers

  • Governing source: the approved location and version allowed to define the decision.
  • Generated artifact: the exact output handed to the project, such as a DTCG file, CSS variables, a Tailwind mapping, or a registry item.
  • Transformation configuration: the rules between source and output, including renaming, unit conversion, mode handling, filtering, and serialization.
  • Distribution location: the route through which the receiving project obtains the artifact. It isn't necessarily the source that governs the decision.
  • Project mapping: the explicit relationship between a delivered role and the identifier used by a named project version.
  • Component contract: the component property, variant, state, or semantic slot expected to consume the mapped role.
  • Local exception: an authorized, bounded departure from the shared path, with scope, owner, and a review or expiry trigger.
  • Protected surface: a consumer or behavior that must remain unchanged during the handoff or controlled verification.
  • Retest trigger: a change that makes existing evidence stale, such as a source revision, transformer update, mapping change, component release, mode change, or local override.

Use four evidence states, not one done flag

Entry evidenceWhat it provesWhat it cannot prove
DefinedGoverning source and version, semantic purpose, required modes, alias status, approval reference, approver, and correction owner are recorded.The intended token decision is explicit, current for the recorded revision, and governed.That an artifact exists, reached a project, maps correctly, or renders as intended.
DeliveredDefined evidence plus an exact generated artifact, artifact identity, applicable transformation context, distribution location, and delivery observation.The receiving team can identify what was supplied and how it arrived.That a project loaded the artifact, mapped its roles, or used it in a component.
MappedDelivered evidence plus project version, source role, destination identifier, mode mapping, component contract, and named consumers.The recorded project has an inspectable implementation path for the role.That runtime values, cascade behavior, local overrides, loaded assets, or rendered results are correct.
ObservedMapped evidence plus expectations written before inspection, actual evidence, environment, versions, discrepancies, and sample limits.The named consumers behaved as recorded under the inspected conditions.That untested consumers, modes, states, environments, or future versions behave the same way.
A record receives a state only after every applicable entry criterion for that state and all earlier states is present.

Don't assign the highest partly completed state. If even one required defined-state field is missing, the record is unassigned, although other source details may be known. Evidence can also go stale. A source revision can invalidate every later state, while a component rewrite may invalidate mapping and observation without changing the source decision.

Inventory candidates before accepting tokens

A visible value isn't automatically a shared token. Inventory the candidate, name the recurring decision it might represent, identify its current consumers, and choose an outcome. This keeps one-off composition choices out of the shared contract while preserving genuine gaps for later review.

Use whenRecord next
AdoptThe source defines a reusable semantic decision that current consumers need.Its authority, role, modes, delivery route, consumers, and required acceptance evidence.
MapAn approved source role exists, but the project uses a different supported identifier or representation.The source-to-destination relationship and the layer authorized to maintain it.
DeferThe decision may recur, but current consumers, ownership, or change behavior do not justify a shared contract yet.The reason, owner, and a concrete trigger for reconsideration.
RejectThe value is a one-off composition choice, duplicates another contract, or would give a local exception misleading global authority.The reason and the correct local owner or existing token.
Candidate-token decisions

Use change behavior as the test

A shared token should represent a decision that needs coordinated change. Equal values can have different owners and futures. Different light and dark values can still belong to one stable semantic role.

Trace the chain from decision to consumer

Follow the handoff from left to right: approved semantic decision, generated export, optional transformation, distribution route, project mapping, component contract, local exceptions, and rendered consumer. At each hop, record the incoming identity, outgoing identity, permitted change, and correction owner.

  1. 1

    Pin the governing decision

    Record the source location, revision, semantic role, required modes, alias status, approval, and correction owner. If any required defined-state field is missing, keep the evidence state unassigned.

  2. 2

    Identify the delivered artifact

    Record the exact output, its version or hash, how it was generated, any applicable transformation configuration, where the project obtained it, and the evidence that delivery occurred.

  3. 3

    Write the project mapping

    Connect each in-scope source role to the destination identifier and mode behavior in a named project version. Record transformations that occur after delivery.

  4. 4

    Name contracts and consumers

    Identify the shared component property or semantic slot and the product surfaces that consume it. Record overrides as exceptions instead of hiding them in implementation details.

  5. 5

    State expectations before inspection

    Write what should change, what should remain stable, and the relevant modes, states, viewports, or environments.

  6. 6

    Record observations and limits

    Capture what happened, the inspected versions and environment, and what the sample cannot establish. Empty observed evidence means no observation occurred.

Consistency check · No dark-mode parity

The same plan card, built two ways in Ambient Sage.

Drifting system

Pricing

Starter$19/mo

Everything a small team needs to ship a branded UI.

Consistent system

Pricing

Starter$19/mo

Everything a small team needs to ship a branded UI.

What to notice: A paired light and dark source can still drift when downstream mode mappings, component contracts, or local overrides diverge.

Ambient Sage v1 as bounded upstream intake

Ambient Sage v1 works as an example because its public page exposes a real upstream system without proving anything about a reader's project. The published kit assigns Plus Jakarta Sans to heading and body roles at weights 400, 500, 600, and 700. JetBrains Mono serves the mono role at weights 400, 500, and 700. Its typography scale direction is compact-product. The kit also publishes 28 semantic light and dark tokens, DESIGN.md, and export categories for DTCG, Tailwind, CSS, and shadcn use.

Token specimen · real values

Ambient Sage

Live render

Ambient Sage's actual tokens — the same values its exports use.

Color tokensSemantic roles with HEX / HSL / CMYK

Color tokens

Ambient Sage
light · HEX · HSL · CMYK

Core

#F3F4EF

background

H 72 · C0, 0, 2, 4

#1A1C17

foreground

H 84 · C7, 0, 18, 89

#E5E6E0

card

H 70 · C0, 0, 3, 10

#ECEEE8

muted

H 80 · C1, 0, 3, 7

#D8D9D2

border

H 68.57 · C0, 0, 3, 15

Brand

#FEE951

primary

H 52.72 · C0, 8, 68, 0

#1A1C17

primary-fg

H 84 · C7, 0, 18, 89

#E5E6E0

secondary

H 70 · C0, 0, 3, 10

#F7E464

accent

H 52.24 · C0, 8, 60, 3

#FEE951

ring

H 52.72 · C0, 8, 68, 0

Semantic

#C0392B

destructive

H 5.64 · C0, 70, 78, 25

#FFFFFF

destructive-fg

H 0 · C0, 0, 0, 0

#2D7238

success

H 129.57 · C61, 0, 51, 55

#C97D12

warning

H 35.08 · C0, 38, 91, 21

#545651

muted-fg

H 84 · C2, 0, 6, 66

Charts

#FEE951

chart-1

H 52.72 · C0, 8, 68, 0

#4A8FD4

chart-2

H 210 · C65, 33, 0, 17

#6BBF8A

chart-3

H 142.14 · C44, 0, 28, 25

#E07498

chart-4

H 340 · C0, 48, 32, 12

#E8A24B

chart-5

H 33.25 · C0, 30, 68, 9

Type scaleHeading, body, and mono in the kit's fonts

Typography

Ambient Sage

Scale: compact-product

Density: balanced

Heading · Plus Jakarta Sans · 1.875rem

Ship beautiful product faster

Subheading · Plus Jakarta Sans · 1.375rem

A warm-sage neutral-surface mobile kit with a single vivid yellow accent, flat tonal cards, and oversized display numerals.

Body · Plus Jakarta Sans · 1rem

Ambient Sage uses a near-white warm-sage canvas (#f3f4ef) with card panels distinguished only by a tonal shift to #e5e6e0, never by shadows or borders. A single vivid yellow (#fee951) is the only saturated color and appears sparingly at component scale as orbs, button fills, and focus rings. Primary data values render as oversized bold hero numerals with a small superscript unit. Typography is a friendly rounded geometric (Plus Jakarta Sans) with no uppercase and no tight tracking, while JetBrains Mono is reserved for hex codes and technical strings. Generous rounding and luminance-only contrast give the whole system a calm, minimal feel.

Mono · JetBrains Mono · 0.8125rem

npx shadcn add ambientsage.json

Aa

Plus Jakarta Sans · Heading

400500600700

Aa

Plus Jakarta Sans · Body

400500600700

ABCDEFGHIJKLM NOPQRSTUVWXYZ

abcdefghijklmnopqrstuvwxyz

0123456789 & @ # % →

Radius & spacingCorner radius, elevation, and spacing steps

Tokens

Ambient Sage primitives
density: balanced

Radius scale

sm · 0.375rem
md · 0.75rem
lg · 1.25rem
xl · 1.75rem

Component radius

button
card
input

Elevation

level 1
level 2
level 3
level 4

Spacing · base 4px

1x
2x
3x
4x
6x
8x
Ambient Sage v1 shows upstream token, type, and spacing decisions. The specimen doesn't certify a downstream mapping or runtime result.

That public information is enough to start an intake record, but not enough to assign the defined state. The available evidence doesn't identify the consuming team's approval, correction owner, project-specific semantic purpose, or alias decision. Those are required defined-state fields.

handoff_id: "ambient-sage-v1-intake"
recorded_at: "unresolved"
scope:
  token_group_or_change: "published kit intake"
  included_roles:
    - "28 semantic light and dark color tokens"
    - "heading and body typography roles"
    - "mono typography role"
  excluded_roles: "unresolved"
  required_modes: ["light", "dark"]
  target_evidence_state: "observed"
  acceptance_claim: "unresolved"
authority:
  governing_source: "Ambient Sage public kit"
  source_version_or_revision: "v1"
  approved_by: "unresolved"
  approval_reference: "unresolved"
  correction_owner: "unresolved"
token_contract:
  semantic_purpose: "unresolved per consuming project"
  alias_status: "unresolved"
  aliases: "unresolved"
  permitted_transformations: "unresolved"
  candidate_decision: "unresolved per consuming project"
delivery:
  generated_artifact: "unresolved; choose one published export category"
  artifact_version_or_hash: "unresolved"
  transformation_tool_and_version: "unresolved"
  transformation_configuration: "unresolved"
  distribution_location: "unresolved"
  delivery_observation: "unresolved"
project_mapping:
  project_and_version: "unresolved"
  source_role: "unresolved"
  destination_identifier: "unresolved"
  mode_mapping: "unresolved"
  component_contract: "unresolved"
  named_consumers: []
  protected_surfaces: "unresolved"
verification:
  expected_observations: []
  observed_evidence: []
  environment: "unresolved"
  sample_limit: "Upstream public intake only; no downstream inspection performed."
  unresolved_fields:
    - "approval and correction ownership"
    - "semantic purpose and alias status"
    - "artifact identity and delivery"
    - "project and mode mappings"
    - "component and consumer adoption"
    - "accessibility evidence"
    - "rendered observations"
exceptions:
  status: "unresolved"
  records: []
retest_triggers:
  - "public kit version changes"
  - "selected export changes"
  - "consumer scope changes"
evidence_state: "unassigned"
disposition: "revise"
disposition_reason: "Required defined-state and downstream evidence is unresolved."
next_action: "Assign approval and correction ownership, then complete the defined-state fields."
Bounded Ambient Sage v1 intake record

What this example does not claim

The intake doesn't claim automatic compatibility with a framework or design tool. It doesn't prove that fonts load, aliases resolve, modes map correctly, components adopt the roles, accessibility requirements pass, or rendered output matches the kit.

Start with a public kit you can inspect

Choose the exact published artifact your project will receive. Then complete the required authority and mapping fields before implementation spreads to more consumers.

A fictional mapped row, with observation still open

The next record is fictional. It demonstrates a mapped state, not a tested Identity Forge export, real project, product version, transformer, or compatibility result. Every fictional identity is labeled as such.

handoff_id: "fictional-focus-ring-001"
recorded_at: "2026-09-23"
scope:
  token_group_or_change: "fictional focus-ring semantic color"
  included_roles: ["color.focus-ring"]
  excluded_roles:
    status: "not_applicable"
    reason: "The fictional row covers one role only."
  required_modes: ["light", "dark"]
  target_evidence_state: "observed"
  acceptance_claim: "The fictional account input maps color.focus-ring in both modes without changing its error border."
authority:
  governing_source: "Fictional Example Design System"
  source_version_or_revision: "fictional revision A"
  approved_by: "fictional design-system approver"
  approval_reference: "fictional approval record A-17"
  correction_owner: "fictional design-system owner"
token_contract:
  semantic_purpose: "visible focus indication"
  alias_status: "none"
  aliases:
    status: "not_applicable"
    reason: "The fictional role maps directly and defines no alias."
  permitted_transformations: ["rename to the recorded destination identifier"]
  candidate_decision: "map"
delivery:
  generated_artifact: "fictional web token artifact"
  artifact_version_or_hash: "fictional-artifact-hash-001"
  transformation_tool_and_version: "Fictional Transformer 1.0"
  transformation_configuration: "fictional-web-config-v1"
  distribution_location: "fictional package registry"
  delivery_observation: "Fictional project lock record identifies fictional-artifact-hash-001."
project_mapping:
  project_and_version: "Fictional Account App revision B"
  source_role: "color.focus-ring"
  destination_identifier: "--focus-ring"
  mode_mapping: "light and dark values map separately to --focus-ring"
  component_contract: "shared input focus state"
  named_consumers: ["fictional account form input"]
  protected_surfaces: ["error border on the same input"]
verification:
  expected_observations:
    - "Keyboard focus uses the mapped focus-ring role in light mode."
    - "Keyboard focus uses the mapped focus-ring role in dark mode."
    - "The error border remains unchanged in both modes."
  observed_evidence: []
  environment: "not recorded because inspection has not run"
  sample_limit: "No runtime inspection has been performed."
  unresolved_fields:
    - "rendered light-mode result"
    - "rendered dark-mode result"
    - "protected error-border result"
    - "accessibility evaluation"
exceptions:
  status: "none"
  records: []
retest_triggers:
  - "source revision changes"
  - "artifact or transformer changes"
  - "project mapping changes"
  - "shared input implementation changes"
evidence_state: "mapped"
disposition: "revise"
disposition_reason: "Mapped-state evidence is complete, but the target observed state has not been reached."
next_action: "Inspect the named consumer in both modes and record actual results separately from expectations."
Fictional mapped record. No runtime observation is claimed.

The empty observed_evidence array is deliberate. A note such as "unexecuted example" belongs in the sample limit, not in evidence. The record qualifies as mapped because it identifies a fictional delivered artifact, project revision, mode mapping, component contract, and consumer. Its disposition remains revise because the stated target is observed and the required evidence is missing.

Run the verification procedure

  1. 1

    Pin identities and versions

    Freeze the governing source, generated artifact, applicable transformation tool and configuration, distribution identity, project revision, component version, and observation environment. Use unresolved when an applicable identity is missing.

  2. 2

    Inspect the delivered artifact

    Confirm that the received output is the artifact named in the record. Check that the in-scope roles and required modes are present. Route DTCG conformance and alias behavior to their specialist procedures.

  3. 3

    Confirm project mappings

    Trace source roles to destination identifiers and component contracts. Check for stale copies, renamed roles, collapsed modes, literals, and local overrides.

  4. 4

    Select representative consumers

    Choose consumers by reach and risk. Include widely reused components, high-impact flows, applicable modes and states, and surfaces likely to contain exceptions. Record why each consumer belongs in the sample.

  5. 5

    Write expected observations

    For each consumer, record the role, mode, state, expected visible or computed result, and any protected surface that must remain unchanged.

  6. 6

    Inspect actual results

    Record the actual value or behavior, environment, evidence reference, and discrepancy. Leave observed evidence empty until an inspection has occurred.

  7. 7

    State the sample limit

    List untested consumers, modes, states, platforms, viewports, and accessibility conditions. One successful consumer proves only that consumer under the recorded conditions.

  8. 8

    Set the disposition

    Accept only when all evidence required by the stated scope is present. Mark optional or out-of-scope fields not applicable, with reasons. Otherwise revise or block, name the owner, and record the retest trigger.

Sampling follows reach and risk

There is no universal screen count. A role used by one low-risk component needs different coverage from a semantic color shared across navigation, forms, destructive actions, charts, and both modes.

Route failures to the first divergent layer

Start at the governing decision, then move downstream until the recorded contract and actual evidence first disagree. A patch in a later layer may hide the symptom while leaving the cause intact.

Next inspectionPossible correction ownerRetest trigger
Source decisionCheck whether the role, modes, alias status, intended behavior, approval, and current version are explicit.Design-system authority or token owner.The governing decision or approval changes.
Export generationCompare the approved source revision with the generated artifact identity and generation record.Export pipeline or design-system tooling owner.Source input, generator, template, or export logic changes.
TransformationInspect the pinned tool version and configuration for renaming, conversion, filtering, mode handling, or serialization.Transformation configuration owner.Tool version, plugin, preset, or configuration changes.
DistributionVerify that the project retrieved the reviewed artifact from the recorded location rather than a stale or different release.Package, registry, or distribution owner.Published artifact, dependency lock, cache identity, or distribution route changes.
Project mappingTrace the delivered role to the destination identifier in every required mode.Application theme or integration owner.Destination names, theme setup, imports, or mode mapping changes.
Component contractCheck whether the shared component consumes the mapped role for the inspected variant and state.Component library owner.Component implementation, API, variant, or state styling changes.
Local exceptionInspect overrides, literals, detached components, page styles, and exception records that supersede the shared path.Local product owner with recorded exception authority.The exception changes, expires, expands, or reaches a protected surface.
Runtime consumerInspect built output, cascade, loaded assets, current mode, environment, and rendered state.Application implementation owner, unless an earlier divergence is found.Build configuration, dependency, content, environment, or consumer code changes.
Failure routing for a token handoff

The correction owner remains provisional until you locate the first divergence. If the source is correct but a transformer renames a role incorrectly, changing the source alters the wrong layer. If the artifact and mapping are correct but a page overrides the component, regenerating the export won't remove that exception.

Choose accept, revise, or block

  • Accept when every field required by the stated scope has evidence, applicable conditional fields are complete, non-applicable fields include reasons, artifact identity matches the reviewed delivery, mappings and named consumers have the required evidence, exceptions have authority and owners, and sample limits are explicit.
  • Revise when a bounded correction can complete missing artifact, transformation, mapping, documentation, observation, or exception evidence without changing the approved contract. Name the correction owner and required retest.
  • Block when authority is disputed, a material artifact cannot be identified, evidence required by the stated scope is missing, a protected surface regresses, an unapproved exception changes the contract, or no owner can resolve a material gap.

An unresolved optional field or a field explicitly outside the scope doesn't block acceptance. An unresolved field required for the acceptance claim does. A discrepancy doesn't automatically block the whole handoff either. Judge its reach, its effect on protected surfaces, and whether a bounded correction can preserve the approved contract.

Use specialist checks at the right boundary

  • Use the developer brand-kit guide when authority, assets, behavior, responsive decisions, or broader website intake remain undefined.
  • Use the DTCG validation guide when the claim concerns parsing, published format rules, validator scope, or reproducible validator evidence.
  • Use the DTCG alias guide when the claim concerns authored references, resolution, cycles, type compatibility, or emitted alias behavior.
  • Use the accessibility checklist for contrast, focus, typography resilience, assistive technology, and product-context accessibility evidence.
  • Use the release checklist when the decision includes release gates, rollback, distribution approval, or production readiness.

Sources