Skip to content

fix(design-tokens): backfill generationRule for legacy semantic tokens#1433

Open
ssilvius wants to merge 2 commits intomainfrom
fix/semantic-cascade-backfill
Open

fix(design-tokens): backfill generationRule for legacy semantic tokens#1433
ssilvius wants to merge 2 commits intomainfrom
fix/semantic-cascade-backfill

Conversation

@ssilvius
Copy link
Copy Markdown
Collaborator

Summary

Existing rafters projects' on-disk semantic.rafters.json was authored before semantic.ts started writing generationRule. populateDependencyGraph requires both dependsOn AND generationRule to enter the dependency graph, so legacy semantic tokens are silently skipped at registry init -- the cascade is dormant on every project initialized before the fix shipped.

Verified in this repo: 198/198 semantic tokens in .rafters/tokens/semantic.rafters.json have generationRule = null. Setting accent to a new family via the studio API would update only the seed; every variant (-foreground, -hover, -active, -border, -ring) would stay pointing at the previous family. Designer sees a half-themed UI.

Self-heal at registry init by inferring the rule from the token name suffix and dependsOn[0] shape:

  • -foreground / -text / -contrast -> contrast:auto
  • -hover / -active / -focus / -disabled -> state:*
  • everything else -> scale:N from value position or dependsOn[0] suffix

In-memory only -- no on-disk migration. The next normal write through the persist path picks up the backfilled rule.

Includes a small refactor: extracted parseTokenPosition() to scale-positions.ts to consolidate three inlined copies of the same regex.

Test plan

  • New legacy semantic token backfill describe block in packages/design-tokens/test/semantic-cascade.test.ts
  • cascades semantic tokens loaded without generationRule -- strips generationRule from generated tokens, constructs registry, cascades neutral, asserts primary + primary-hover + primary-foreground all follow
  • preserves explicit generationRule when present -- regression guard so live-generated tokens still carry their explicit rule
  • All 294 design-tokens tests green
  • Manual studio-server verification with accent -> silver-true-honey + highlight -> silver-true-sky (pending; the broken-cascade evidence motivated this fix, in-DOM verification of the fix still owed)

🤖 Generated with Claude Code

ssilvius and others added 2 commits April 27, 2026 20:54
Semantic tokens persisted by rafters versions before the generationRule
fix shipped have dependsOn but no generationRule. populateDependencyGraph
silently skipped them, so semantic cascade was dormant on every existing
project: changing a family's seed only updated the seed, not the variants.

Self-heal at registry init: infer the rule from name suffix
(-foreground -> contrast:auto, -hover -> state:hover, etc.) plus
dependsOn[0] for scale position. No on-disk migration; in-memory
backfill writes back through the normal persist path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The /-(\d+)$/ token-name parser was inlined three times (registry.ts,
plugins.ts twice). Consolidate into scale-positions.ts where the rest
of the position math lives.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant