Skip to main content
The mechanism on this page is verified against Titan source; the approval path is not. Who signs off a token change, and when, is not recorded anywhere — see TITAN-GAP-20. Constraints are Proposed.

What it governs

Adding a token, changing one, and defining what it is for. Not which token to use when building — that is Foundations.

Before you propose

Three different problems that look alike. Resolve which one you have first, because the fix differs:
A missing token is never resolved with a literal. A hardcoded value is invisible to the audit, carries no recorded intent, and turns every future system-wide change into a search-and-replace. If nothing expresses what you need, that is the proposal.

Which tier

Titan authors tokens in three tiers. Adding to the wrong one is the most common mistake. Add at the semantic tier unless you have a reason not to. A primitive is a value nobody can choose by intent; a component token is reachable only by that component. Existing component tokens alias primitives rather than semantics — a deliberate, already-recorded divergence from the stated model (see Open issues). When adding a new component token, prefer a semantic alias and state a reason if you skip it. Do not “fix” the existing ones.

The mechanism

1

Author it in the DTCG source

Edit the tier file under components/core/src/theme/tokens/. A token is a $type, a $value, and — see below — a $description.
Alias, never inline. {color.blue.50} records where the value came from; #2666f9 records nothing.
2

Define it in the same commit

$description says what the token is for, not what it is made of. “Background for informative outcomes” is a definition. “Blue 50 tint” is a restatement of the value.This is the single highest-leverage line in the change. 112 of 244 shipped tokens have no definition, which is why so much guidance on this site is a proposal rather than a fact.
3

Build

Regenerates the CSS, TypeScript, the token manifest, and the legacy outputs. Never edit a generated file — the build overwrites it and the edit disagrees with the package until someone notices.
4

Let the guardrails run

Thirteen test files gate the token layer. The ones that most often catch a new token:
Compares against a committed baseline, so a drop in coverage fails rather than passing quietly.
5

Re-emit the documentation

Every token table on this site is generated. --check exits non-zero if the committed output no longer matches source — that is the drift gate, and it is what stops the docs and the package disagreeing.

What a new token does not get

Three surfaces a new token will not appear on. None of these is a bug.

Constraints

Retired

Known issues

Token workflow: open issues

Divergences, open decisions, and undocumented gaps for Token workflow.

Why it works this way

The build is the gate, not review. Thirteen guardrail tests and two coverage checks run on every change, which means a broken tier rule or a moved baseline value fails before anyone looks at it. Review is for the decision — whether the token should exist and what it means — not for catching mechanical mistakes a human reads past. The $description requirement is new and deliberate. Two thirds of the existing tokens predate it, which is why this site carries so many proposals in place of facts. Requiring it per token is the only thing that stops the same gap reappearing for every token added from here.
Last modified on September 2, 2026