Draw the boundary before naming anything
A taxonomy classifies design decisions. A naming convention expresses that classification in identifiers. A source format serializes the decisions, while a transformation converts them for a target. A project mapping connects an emitted identifier to local code. The rendered consumer is the actual button, card, page, or application state that uses that mapping. These records are related, but none proves the next link in the chain.
| Artifact | It decides | It does not prove | |
|---|---|---|---|
| Taxonomy | Layer, purpose, scope, authority, and permitted relationships | Architecture and governance | That an identifier was generated, adopted, or rendered correctly |
| Naming convention | Identifier grammar, ordering, vocabulary, and separators | Syntax for accepted decisions | That the named decision belongs in the taxonomy |
| Source token format | How token data and references are represented | Portable source structure | That a transformation or consumer supports that structure |
| Generated artifact | What a particular build emitted for a target | Output from a named transformation | That the intended project received or uses the output |
| Project mapping | How an emitted value connects to local code | Adoption within a named project scope | That every intended consumer uses the mapping |
| Rendered consumer | What appeared under recorded conditions | A bounded runtime observation | Why it appeared or whether other consumers match |
The Design Systems Collective source covers hierarchy, aliases, modes, and component tokenization. VA.gov documents one applied vocabulary of primitive, semantic, and component types. Both are useful references, but neither is a universal answer. Your taxonomy still needs to state which authority, products, platforms, brands, modes, and consumers make a boundary valid for your system.
Freeze the current system first
Don't begin a revision with proposed names. First, preserve the existing route from authority to consumer. The EightShapes account moves from planning and audits of token paths and uses through proposal, specification, handoff, and implementation. A current-system intake protects the evidence you'll need during migration.
| Current-system field | What to record | Failure condition | |
|---|---|---|---|
| Governing source | Document, repository, library, or authority that owns current intent | Record its exact location and authority | Two sources claim final authority without a precedence rule |
| Version | Release, revision, commit, or dated snapshot under review | Use a value that another reviewer can retrieve | The source can change without the record showing what was assessed |
| Products and platforms | Named products and in-scope platforms | List web, mobile, design libraries, documentation, or other targets separately | Scope is described only as all products or digital |
| Brands and modes | Every in-scope brand, theme, mode, density, or other axis | State unsupported and excluded axes too | An axis is inferred from filenames rather than declared |
| Token paths | Source, alias chain, transformation, distribution target, and project entry point | Preserve current paths before proposing replacements | A value is visible but its origin cannot be traced |
| Transformations | Tool or process, configuration version, input, and output | Separate the operation from its artifacts | A generated value has no reproducible production record |
| Consumers | Named components, pages, packages, applications, and representative states | Use inspectable consumer names | Consumers are reduced to a vague label such as frontend |
| Owners | Decision, artifact, project, correction, and retest owners where they differ | Name accountable roles rather than a broad audience | A failure can be found but nobody owns its correction |
| Exclusions | Products, platforms, brands, modes, states, or categories outside the review | Give the reason for each material exclusion | Readers could assume excluded surfaces were assessed |
| Known exceptions | Existing deviations, owners, rationale, and review trigger | Distinguish accepted exceptions from unexplained drift | A local override is mistaken for the shared rule |
Copy the taxonomy decision record
Use one record for each decision whose authority, placement, or migration can be reviewed independently. Required means the review can't proceed without the field. Conditional means the field becomes required when that feature exists. Unresolved means an owner still needs to decide it. Not applicable means the team considered the field and excluded it for a recorded reason.
record_id: "[required: stable review identifier]"
record_version: "[required: revision of this record]"
governance:
governing_source: "[required]"
governing_source_version: "[required]"
decision_owner: "[required]"
approval_state: "[required: proposed | accepted | revised | blocked | superseded]"
scope:
products: ["required: named products"]
platforms: ["required: named platforms"]
brands: ["conditional: named brands, or not applicable with reason"]
modes: ["conditional: named modes, or not applicable with reason"]
exclusions: ["required: explicit exclusions, may be empty"]
identity:
current_identifier: "[conditional: required for an existing decision]"
proposed_identifier: "[conditional: required for a new or renamed decision]"
purpose: "[required: stable meaning in plain language]"
value_type: "[required: color | dimension | fontFamily | number | ...]"
layer: "[required: primitive | shared-semantic | component | exception | implementation-rule | unresolved]"
namespace: "[conditional: project or platform namespace]"
reach:
brand_scope: "[conditional: shared, named brands, or unresolved]"
mode_scope: "[conditional: shared role with per-mode values, named modes, or unresolved]"
component_reach: ["required: named components or none"]
named_consumers: ["required: concrete components, pages, packages, or apps"]
independent_change_scope: "[required: what may change and what must remain unaffected]"
relationships:
alias_target: "[conditional: target, unresolved, or not applicable]"
token_paths: ["required: known source and downstream paths"]
generated_artifacts: ["conditional: named outputs and versions"]
transformations: ["conditional: tool or process, configuration, input, output"]
project_mappings: ["conditional: emitted identifier to local implementation"]
migration:
migration_state: "[required: not-started | mapped | compatibility-active | adopted | retired | blocked]"
considered_alternatives: ["required: candidates and rationale"]
rejected_alternatives: ["required: rejected candidate and reason"]
old_to_new_mapping: "[conditional]"
temporary_compatibility: "[conditional: mechanism or not applicable with reason]"
known_exceptions: ["required: exception, owner, reason, review trigger"]
evidence:
evidence_state: "[required: missing | expected | generated | implemented | observed]"
expected_result: "[required: falsifiable expectation for named consumers]"
observed_result: "[required: pending until inspected, then record what was found]"
observation_context: "[conditional: versions, mode, brand, state, viewport, content, method]"
ownership:
implementation_owner: "[conditional]"
correction_owner: "[required when unresolved or a failure is found]"
retest_owner: "[required when observation is pending or correction is needed]"
disposition:
decision: "[required: accept | revise | block | supersede]"
rationale: "[required]"
decided_by: "[required]"
decided_at: "[required when disposition is final]"How to fill the fields without hiding uncertainty
Purpose should describe stable meaning, not appearance. Write "background for primary action surfaces" rather than "bright yellow." Independent change scope should state what may move together and what must remain unaffected. Named consumers should be inspectable, such as "checkout submit button, default and focus states," rather than "buttons." The record will remain useful even if your vocabulary differs from a published system.
- Use unresolved when the answer affects placement and no authority has decided it. Don't fill the gap with the author's preference.
- Use not applicable only after considering the field and recording why it doesn't apply. An empty cell isn't the same decision.
- Record aliases as relationships between meanings. Don't add one merely to make a hierarchy look complete.
- List artifacts separately from transformations. An artifact is an output; a transformation is the reproducible operation that produced it.
- Write expected results before inspection, then record what you found even when it contradicts the proposal.
- Assign correction and retest to named owners. The source owner may not own the project mapping or consumer verification.
Route each decision with six possible outcomes
Primitive, semantic, and component are useful categories, but the familiar three-tier model doesn't settle every case. Real systems also need deliberate exceptions, ordinary implementation rules, and unresolved decisions. Placement follows meaning and change authority, not the number of consumers alone.
| Outcome | Choose it when | Reject or defer it when | |
|---|---|---|---|
| Primitive | The value is reusable raw material without contextual purpose | Another layer controls meaning and consumption | Consumers depend on its appearance as though that appearance were a stable purpose |
| Shared semantic | A stable purpose is shared by named consumers | Those consumers should change together across declared brand and mode scope | They merely share today's value or one needs an independent lifecycle |
| Component | A named component property has independent change authority | Its states, affected consumers, and protected consumers are defined | The proposed layer only repeats a shared role or has no plausible independent change |
| Approved exception | A specific consumer must deviate and the authority accepts it | The record names its owner, rationale, and review trigger | The deviation is accidental or avoids an unresolved taxonomy decision |
| Ordinary implementation rule | The decision governs selector behavior, responsive composition, content structure, or algorithmic layout | Token delivery would not make the rule portable or clearer | The decision is a reusable value or role that must travel through artifacts |
| Unresolved | Meaning, authority, alias target, scope, consumers, or evidence is insufficient | An owner and next decision are recorded | Enough evidence already supports another outcome |
The shortcut "shared by several components means semantic" is unsafe. Several components may use the same value by coincidence. Before creating a shared role, ask whether they share one meaning, one authority, and one intended change. A component token earns its layer only when the component owns an independent decision and the record names both affected and protected consumers.
Apply the matrix to boundary cases
| Boundary case | Routing consequence | Evidence or failure condition | |
|---|---|---|---|
| Mode-specific values | Keep one semantic role when meaning stays stable and its value changes by mode | Record light and dark values separately under the declared mode scope | Fail if a verified light value is silently assigned to dark mode |
| Brand variants | Keep one role when brands express the same purpose differently | Split the role or approve an exception when meaning, contract, or authority changes | Fail if brand parity is inferred from a shared file rather than recorded |
| Status states | Use shared roles when success, warning, or destructive meaning travels across components | Use component scope only for independently governed behavior | A matching color without shared meaning is insufficient |
| Interaction states | Keep hover, focus, disabled, and pressed behavior in the owning component contract | Alias to shared roles where the underlying meaning is genuinely shared | Defer when global and component authority cannot be distinguished |
| Typography roles | Tokenize reusable family, size, weight, line-height, or role decisions | Keep wrapping, truncation, and content-dependent behavior in implementation or guidance | Do not convert every text declaration into a taxonomy level |
| Spacing | Use primitives for reusable dimensions and higher layers only for stable intent or independent authority | Keep one-off arrangements in implementation | A repeated number alone does not establish semantic meaning |
| Layout | Keep composition, ordering, grids, and container behavior as implementation rules | Tokenize only portable values that need distribution | A breakpoint token does not specify responsive behavior |
| Component contracts | Use component tokens for independently changeable visual properties | Keep structure, variants, behavior, and content rules in code and documentation | Fail when a token name is expected to carry a complete behavioral contract |
| CSS-only rules | Keep selectors, pseudo-classes, media queries, inheritance, and calculations in CSS | Extract only reusable values that need a token path | A literal inside CSS does not automatically need a token |
| Documentation-only guidance | Keep prohibitions, rationale, examples, and usage boundaries in governed documentation | Link the guidance to relevant records and consumers | Do not encode prose policy as a token or claim documentation proves adoption |
More layers don't resolve missing authority
If a proposed token has no stable meaning, named consumers, or owner, another alias won't make it safer. Mark the decision unresolved and assign an owner.
Record Ambient Sage v1 as bounded upstream intake
Ambient Sage v1 works as a source fixture because its public page identifies a versioned kit with 28 semantic roles in light and dark modes. It also provides six artifact families: DESIGN.md, DTCG tokens, CSS variables, Tailwind v3, Tailwind v4, and a shadcn registry. Those facts stop at the upstream boundary. They don't establish a receiving project's namespace, aliases, transformations, mappings, consumers, migration status, accessibility evidence, or runtime observations.
Token specimen · real values
Ambient Sage
Live renderAmbient Sage's actual tokens — the same values its exports use.
| Record area | Ambient Sage v1 intake | Evidence state | |
|---|---|---|---|
| Governing source and version | Public Ambient Sage kit page | Version v1 | Verified upstream input |
| Semantic scope | 28 semantic roles | Light and dark values are documented | Verified upstream input |
| Available artifacts | DESIGN.md, DTCG tokens, and CSS variables | Tailwind v3, Tailwind v4, and shadcn registry | Verified upstream input |
| Project namespace and aliases | No receiving-project namespace supplied | No project alias policy supplied | Unresolved |
| Transformations and mappings | No receiving-project pipeline supplied | No emitted-to-local mapping supplied | Unresolved |
| Named consumers | No receiving-project component supplied | No page, state, or application supplied | Unresolved |
| Migration and compatibility | No current project taxonomy supplied | No compatibility requirement assessed | Unresolved |
| Accessibility evidence | No project-specific evaluation supplied | No consumer conditions supplied | Unresolved |
| Runtime observations | No project implementation performed | No rendered consumer inspected | Unresolved |
Inspect the upstream roles before designing the mapping
Open the public Ambient Sage kit and inspect the source system. Adopt only the roles and artifacts that your taxonomy record can trace into named project consumers.
Trace one proposed row without pretending it ran
The fixture below is illustrative and unexecuted. Ambient Sage supplies the verified upstream light value and artifact availability. Every receiving-project identifier, alias, mapping, consumer, owner, expectation, and disposition remains explicitly proposed. The dark value is unresolved; it isn't inferred from the light value.
record_id: "example-surface-canvas-001"
execution_status: "illustrative and unexecuted"
governance:
governing_source: "Ambient Sage public kit"
governing_source_version: "v1"
decision_owner: "proposed: design-system lead"
approval_state: "proposed"
source_input:
verified_light_value: "#f3f4ef"
dark_value: "unresolved: inspect the v1 dark role before mapping"
source_role: "proposed interpretation: main canvas surface"
identity:
current_identifier: "not applicable: fictional new project mapping"
proposed_identifier: "app.color.surface.canvas"
purpose: "proposed: default application canvas background"
value_type: "color"
layer: "proposed: shared-semantic"
namespace: "proposed: app"
relationships:
alias_target: "proposed: exact Ambient Sage source path unresolved"
emitted_artifact: "proposed: CSS variables artifact"
project_mapping: "proposed: --app-surface-canvas maps to the inspected emitted role"
named_consumer: "proposed: Settings page root, default state, light mode"
component_reach: ["proposed: page canvas only"]
protected_consumers: ["proposed: cards, dialogs, and navigation remain unchanged"]
migration:
migration_state: "not-started"
temporary_compatibility: "not applicable unless inventory finds an existing identifier"
evidence:
expected_result: "Changing the mapped light canvas role changes the Settings page root while cards, dialogs, and navigation remain unchanged."
observed_result: "pending: no artifact inspection, mapping, build, or rendered observation performed"
accessibility_evidence: "unresolved: requires project-specific evaluation"
ownership:
implementation_owner: "proposed: frontend platform owner"
correction_owner: "proposed: owner of the first divergent layer"
retest_owner: "proposed: Settings page maintainer"
disposition:
decision: "block"
rationale: "Do not accept until the exact source path, dark value, emitted identifier, mapping, and consumer observation are recorded."This row stays blocked even though its source is real and its expectation is plausible. That is intentional. Upstream approval, artifact availability, a proposed alias, project adoption, and a rendered observation are separate claims. None can stand in for the next.
Migrate the taxonomy as an evidence chain
A rename can affect design libraries, source data, transformations, packages, documentation, component code, and product surfaces. The EightShapes process connects audit, proposal, specification, handoff, and implementation. Use that breadth, but limit each recorded result to the layer you actually inspected.
- 1
Inventory current uses
Record every known source identifier, alias, transformation, artifact, project mapping, component, page, mode, brand, and local override. Name exclusions and gaps instead of assuming the inventory is complete.
- 2
Record considered and rejected alternatives
For every candidate structure, note its meaning, authority, change reach, migration consequence, and reason for retention or rejection. This preserves decisions that later contributors might otherwise reopen.
- 3
Map old identifiers to proposed replacements
Classify each relationship as one-to-one, one-to-many, many-to-one, removed without replacement, or unresolved. A textual rename is insufficient when meaning or scope changes.
- 4
Identify affected artifacts and named consumers
List every output and the concrete packages, components, pages, states, modes, and brands expected to change. Name the protected consumers that must remain unchanged.
- 5
Define temporary compatibility
If old and new identifiers must coexist, record whether an alias, adapter, duplicate output, or another bounded mechanism provides compatibility. Assign an owner and removal condition. Otherwise, mark it not applicable and record why.
- 6
Write expected results before implementation
State what should change, what should stay stable, and under which versions and conditions. Avoid subjective expectations such as looks correct.
- 7
Generate and inspect artifacts
Record what each transformation produced and whether the expected identifiers and mode values are present. Classify this as generated evidence, not project implementation.
- 8
Adopt the mapping in named consumers
Record the project version and exact mapping used by each representative consumer. Adoption establishes implementation only for that recorded scope.
- 9
Observe and route divergence
Inspect the named consumers under recorded modes, brands, states, content, and other relevant conditions. Record what happened, assign correction to the first divergent layer, and name a retest owner.
- 10
Choose the final disposition
Accept when the required evidence supports the stated scope. Revise a correctable proposal. Block when required authority, evidence, or ownership is missing. Supersede when an identified newer decision replaces the record.
Use states that describe evidence, not optimism
| State | What it records | What it does not prove | |
|---|---|---|---|
| Proposed | A candidate meaning, placement, name, scope, or migration plan | The candidate is ready for review | Approval, output, adoption, or runtime behavior |
| Accepted | The named authority approved the decision for the stated scope | The source decision is settled for that scope | That an artifact was produced or a project adopted it |
| Generated | A named transformation produced a recorded artifact | Artifact production under a stated context | That the artifact is correct for every target or used by a project |
| Implemented | A named project or consumer adopted the recorded mapping or contract | Project adoption for the named version and scope | That the rendered result matches the expectation |
| Observed | An inspection recorded what happened under stated conditions | The result may be a match, mismatch, or new finding | Success or coverage outside the recorded conditions |
| Revised | The decision or implementation changed in response to evidence | A new revision now requires downstream checks | That regeneration, adoption, or observation has occurred |
| Blocked | A required decision, artifact, mapping, result, or owner prevents acceptance | The blocking reason and owner are recorded | That the proposal must be abandoned rather than corrected |
| Superseded | A newer identified record replaces this decision | Historical authority remains traceable | That old consumers migrated or compatibility can be removed |
| Disposition | A reviewer chose accept, revise, block, or supersede | The rationale and evidence boundary are explicit | Any broader claim than the stated scope supports |
Keep the record beside the source or change process your reviewers already use. A spreadsheet can work. A repository file, issue, or decision register is often easier to version when identifiers, transformations, and consumers change together. The storage format matters less than preserving the authority-to-consumer chain and refusing to treat blank fields as implied approval.
Complete one reused role before expanding the taxonomy
Choose the semantic role with the widest known reuse or the most disputed boundary. Complete its current-system intake, route it through the six-outcome matrix, name representative and protected consumers, and review the full record. Don't rename the rest of the taxonomy until that row has accepted authority, an explicit migration path, and observations recorded for its stated scope.
Sources
- Reimagining a Token Taxonomy: The documented redesign process moves from planning and current-state audits through taxonomy decisions, specification, handoff, review, and implementation across design, code, and documentation.
- Systematic Taxonomy in Design Tokens: The captured article discusses hierarchical naming, aliases, modes, component-specific tokens, and contextual token structures.
- Design tokens - VA.gov Design System: The VA.gov Design System documents an applied taxonomy with primitive, semantic, and component token types, along with an explicit naming vocabulary.
- Naming design tokens: The resource page collects separate guides, templates, workshops, and examples about token naming across platforms and brands.
- Best Practices For Naming Design Tokens, Components And Variables: The article surveys naming conventions and examples for tokens, variables, components, and complex taxonomies.
- An introduction to design tokens: The guide presents primitive, semantic, and component tokens as a common three-tier baseline while distinguishing design tokens from implementation variables.
- Ambient Sage Design Kit: The public Ambient Sage v1 page documents 28 semantic tokens in light and dark modes and provides DESIGN.md, DTCG tokens, CSS variables, Tailwind v3, Tailwind v4, and shadcn registry artifacts.