learning_ai_common_plat/docs/rfc/0001-dtcg-v3-token-migration.md
saravanakumardb1 ed5fb707ad ci(packages): close ROADMAP TODOs #5, #6 + draft RFC for #4
═══════════════════════════════════════════════════════════════════════
TODO #6 — size-limit budgets in CI
═══════════════════════════════════════════════════════════════════════
Adds .size-limit.cjs with budgets for 6 pilot @bytelyst/* packages,
plus a Gitea Actions workflow (.gitea/workflows/size-limit.yml) that
fails the build on any regression.

Current measurements vs budget (all comfortably under):
  @bytelyst/api-client       793 B  / 8 KB
  @bytelyst/auth-client     1.97 KB / 8 KB
  @bytelyst/celebrations     236 B  / 6 KB
  @bytelyst/quick-actions    122 B  / 6 KB
  @bytelyst/react-auth      2.71 KB / 10 KB
  @bytelyst/dashboard-shell 3.96 KB / 30 KB

Scripts:
  pnpm size       — measure + assert against budgets
  pnpm size:why   — explain top contributors

Deps: size-limit@^12.1.0, @size-limit/preset-small-lib@^12.1.0.

Pilot scope (this commit): 6 packages. Full @bytelyst/* rollout is
incremental — each entry added separately.

═══════════════════════════════════════════════════════════════════════
TODO #5 — Storybook canonical pattern
═══════════════════════════════════════════════════════════════════════
Discovery: @bytelyst/ui already has Storybook 8 with the @bytelyst/
addon-a11y addon configured and 5 .stories.tsx files.

This commit:
  - Documents that setup as the canonical template
    (docs/STORYBOOK_TEMPLATE.md) including the .storybook/main.ts,
    preview.ts, package.json scripts, and an example story.
  - Catalogs which of the 8 visual @bytelyst/* packages need Storybook
    added (1/8 done — @bytelyst/ui).
  - Per docs/ROADMAP_2026_DECISIONS.md §9, hosting target is
    self-hosted Gitea Pages (no Chromatic).

Full rollout to the other 7 packages stays open as incremental work.

═══════════════════════════════════════════════════════════════════════
TODO #4 — DTCG v3 token migration RFC
═══════════════════════════════════════════════════════════════════════
This is too large to land in a single commit. Drafted RFC instead:
  docs/rfc/0001-dtcg-v3-token-migration.md

The RFC proposes a 4-PR sequence:
  PR 1 — Add converter + dual-emit (byte-identical assertion)
  PR 2 — Flip source of truth to DTCG JSON
  PR 3 — Introduce the component tier
  PR 4 — Multi-theme via DTCG token sets

Estimate: 2 person-weeks total. Backward compatibility: --ml-* and
--bl-* names preserved through all 4 PRs. Status: Draft, awaiting
reviewers.

Refs: learning_ai_uxui_web/docs/ROADMAP_2026.md §10 TODOs #4, #5, #6
2026-05-27 11:49:21 -07:00

6.2 KiB
Raw Blame History

RFC 0001 — Migrate @bytelyst/design-tokens to DTCG v3

Status Draft
Author Cascade
Created 2026-05-27
Tracks ROADMAP TODO #4
Reviewers to be assigned

Summary

Migrate packages/design-tokens/tokens/bytelyst.tokens.json from the current bespoke schema to the W3C Design Tokens Community Group (DTCG) Format Module v3. Re-emit all generated outputs (CSS / TS / Kotlin / Swift / per-product CSS) from the new schema with no observable change to runtime CSS variable names.

Motivation

  1. Designer tooling. Figma-Tokens (now "Tokens Studio") and Specify both speak DTCG natively. Today designers cannot round-trip tokens with engineering — the JSON schema is bespoke.
  2. Long-term portability. DTCG is becoming the lingua franca of design systems (Adobe Spectrum, Salesforce Lightning, GitHub Primer are all migrating).
  3. Three-tier semantics. DTCG $type + reference syntax ({path}) gives us a clean way to express the reference → semantic → component layering documented in learning_ai_uxui_web/docs/ROADMAP_2026.md §3.

Current schema (excerpt)

{
  "meta": { "name": "ByteLyst Design Tokens", "version": "1.1.0" },
  "color": {
    "palette": { "neutral": { "0": "#FFFFFF", "50": "#F6F8FC", ... } },
    "semantic": {
      "dark":  { "bgCanvas": "#06070A", ... },
      "light": { "bgCanvas": "#F8F9FC", ... }
    }
  },
  "spacing": { "0": 0, "1": 4, "2": 8, ... },
  "radius":  { "xs": 4, "sm": 6, ... },
  "typography": { "fontSize": { "xs": 12, ... } },
  ...
}

Proposed DTCG v3 schema (excerpt)

{
  "$description": "ByteLyst design tokens — DTCG v3",
  "$schema": "https://design-tokens.github.io/community-group/format/",

  "color": {
    "neutral": {
      "0": { "$value": "#FFFFFF", "$type": "color" },
      "50": { "$value": "#F6F8FC", "$type": "color" },
      "950": { "$value": "#06070A", "$type": "color" }
    },
    "brand": {
      "blue": { "$value": "#5A8CFF", "$type": "color" },
      "coral": { "$value": "#FF6E6E", "$type": "color" }
    },
    "semantic": {
      "bgCanvas": {
        "$value": "{color.neutral.950}",
        "$type": "color",
        "$description": "Page background — dark"
      }
    }
  },

  "spacing": {
    "1": { "$value": "4px", "$type": "dimension" },
    "2": { "$value": "8px", "$type": "dimension" }
  },

  "radius": {
    "xs": { "$value": "4px", "$type": "dimension" }
  },

  "component": {
    "button": {
      "padding-x": { "$value": "{spacing.4}", "$type": "dimension" },
      "bg": { "$value": "{color.semantic.accent}", "$type": "color" }
    }
  }
}

Key changes

Aspect Today DTCG v3
Value wrapper bare value { "$value": ..., "$type": ... }
Type metadata inferred from JS path explicit $type
References manual JS lookup {path.to.token} syntax
Light/dark parallel sibling objects DTCG token sets (per-theme files)
Documentation none $description per token
Component tier doesn't exist new top-level component group

Implementation plan

The migration is split into 4 PRs to keep each one reviewable.

PR 1 — Add converter + dual-emit (no behaviour change)

  • Add scripts/convert-legacy-to-dtcg.ts that reads the bespoke JSON and emits bytelyst.tokens.dtcg.json.
  • Modify scripts/generate.ts to accept either schema and produce byte-identical output.
  • Add a vitest case asserting the two emitters produce identical CSS byte-for-byte.

PR 2 — Flip source of truth to DTCG JSON

  • Delete the legacy JSON.
  • Update Figma-Tokens plugin documentation + commit a .tokens.config.json for round-trip.

PR 3 — Introduce the component tier

  • New component.* group in the DTCG JSON.
  • Generator emits new --bl-{component}-{slot} variables.
  • Audit existing hardcoded values in @bytelyst/ui and replace with the new component tokens.

PR 4 — Multi-theme via DTCG token sets

  • Split the single JSON into:
    • tokens/global.tokens.json (reference + semantic core)
    • tokens/themes/dark.tokens.json (light/dark overrides)
    • tokens/themes/light.tokens.json
    • tokens/brands/lysnrai.tokens.json (brand-layer overrides — Wave 7)
  • Generator composes per-output set.

Backward compatibility

  • All existing --ml-* and --bl-* CSS variable names are preserved.
  • All TS/Kotlin/Swift exported identifiers preserved.
  • Consumer apps require zero changes through PRs 13.
  • PR 4 introduces multi-set composition but the default still produces the same tokens.css.

Risks

Risk Severity Mitigation
Generator divergence between schemas during PR 1 High Byte-identical assertion test
Figma-Tokens plugin version churn Med Pin plugin version in docs/THEMING.md
Designer learning curve Med One-pager + paired migration session
Reference cycles in DTCG ({a}{b}{a}) Low Generator validates DAG before emit

Alternatives considered

  • Style Dictionary — Amazon's tool. Heavier, more opinionated. Rejected: we already have a working generator; switching tools is a larger change than switching schemas.
  • Stay on bespoke JSON — Rejected: blocks designer round-trip and locks us out of the ecosystem.

Estimate

~1 person-week for PRs 13, +1 pw for PR 4 = 2 pw total.

Open questions

  • Do we adopt the DTCG 2024 candidate or wait for the 2026 final? Candidate is stable enough; recommend candidate now, re-verify when final.
  • Where do per-product brand layers live — separate packages (@bytelyst/brand-lysnrai) or subpaths (@bytelyst/design-tokens/brands/lysnrai)? Recommend subpaths pre-Wave 7, separate packages from Wave 7.