# Upgrade to v3.12.0 — UI Excellence & Registry Coherence

> **Audience**: Claude (or a human operator) working inside a **consumer
> repo** (any project that installed BALDART via `npx baldart add` and just
> ran `npx baldart update` to v3.12.0). This document is the alignment
> walkthrough — it does not replace the CHANGELOG (which describes *what*
> changed in the framework); it tells you *what to do* in this specific
> project to align an existing graphic organization with the new discipline.
>
> Run this once per project after updating to v3.12.0. It is idempotent —
> re-running on an already-aligned project produces an empty backlog.

## What changed in one paragraph

The `ui-expert` agent received a major upgrade (UI states taxonomy,
Performance Gates, modern CSS, AI-era patterns, 60+ categorized red flags),
and the registry-first discipline gained a **post-intervention coherence
gate**: every UI task that introduces, modifies, or surfaces a primitive or
token must reconcile the registry (`INDEX.md` + `components/<Name>.md` +
`tokens-reference.md`) **in the same change**. Drift can no longer wait for
Monday's `ds-drift` routine — it must be resolved at introduction. Three
layers now enforce coherence: per-task (in `ui-expert` / `ui-design` /
`frontend-design`) → per-merge (`code-reviewer`) → weekly safety net
(`ds-drift`). The full text-of-record lives in
`.framework/framework/agents/design-system-protocol.md` § "Post-Intervention
Coherence Check".

## Step 0 — Should you even run this walkthrough?

Run only if all three are true. Otherwise, exit cleanly.

```
[ ] baldart.config.yml has features.has_design_system: true
[ ] paths.design_system points to an existing directory
[ ] That directory contains at least an INDEX.md
```

If `has_design_system: false` → there is nothing to align. The new gates
short-circuit. Optionally consider bootstrapping a registry via
`/design-system-init` (skill ships with v3.11.0+).

If `has_design_system: true` but `paths.design_system` does not exist or is
empty → run `/design-system-init` first; come back to this walkthrough
after.

## Step 1 — Surface the current state (no edits yet)

Before touching anything, build a snapshot. Do the four scans below and
emit one finding per item. **Do not fix anything yet** — fixing without a
baseline produces churn and hides the size of the gap.

### 1.1 — Silent primitives (`DS_INDEX_DRIFT` baseline)

Goal: find components that exist in the source tree but are NOT documented
in `INDEX.md`.

```bash
# List candidate primitives in the project (adjust glob to match the project)
find $(yq '.paths.components_primitives' baldart.config.yml) \
  -maxdepth 2 -type f \( -name "*.tsx" -o -name "*.vue" -o -name "*.svelte" \)
```

For each filename `<Name>.tsx`, grep `INDEX.md` for `<Name>` (case-sensitive).
Anything not found is a silent primitive. Record name + path + estimated
broadness (broadly-useful vs. surface-specific). Output:

```
SILENT_PRIMITIVES:
  - Badge        | components/ui/Badge.tsx       | broadly-useful
  - PriceTag     | components/marketing/Price.tsx | surface-specific
  ...
```

### 1.2 — Stale specs (`DS_COMPONENT_STALE` baseline)

For each `${paths.design_system}/components/<Name>.md`:

1. Locate the source file for `<Name>`.
2. Compare the spec's documented props/variants against the source's actual
   exported types/props. Use `codebase-architect` if the project has LSP
   enabled — it does this cheaply via go-to-definition.
3. Spec older than the source's last edit in git AND with mismatch on
   props/variants → `DS_COMPONENT_STALE`.

```
STALE_SPECS:
  - Button.md   | source mtime 2026-04-12, spec mtime 2026-01-05
                | spec missing variants: "danger-outline", "icon-only"
                | spec missing prop: leftIcon
  ...
```

### 1.3 — Hardcoded tokens (`DS_TOKENS_DRIFT` baseline)

Scan the codebase for values that bypass `tokens-reference.md`:

```bash
# Hardcoded hex/rgb in styled code (adjust path to actual sources)
grep -RInE '#[0-9a-fA-F]{3,8}\b|rgba?\([^)]*\)' \
  $(yq '.paths.components_root' baldart.config.yml) \
  --include='*.tsx' --include='*.css' --include='*.scss'

# Hardcoded box-shadow tuples
grep -RInE 'box-shadow:\s*[^v;]+;' \
  $(yq '.paths.components_root' baldart.config.yml)

# Spacing values outside the scale (heuristic: any odd or > 64 px literal)
grep -RInE '(padding|margin|gap|inset)[^:]*:\s*[0-9]+px' \
  $(yq '.paths.components_root' baldart.config.yml)
```

For each hit, classify:
- **Tokenizable** — exact value matches an existing token → trivial replace
- **Missing token** — value would belong to the system but no token exists →
  propose adding to `tokens-reference.md`
- **Justified one-off** — surface-specific value with a documented reason →
  leave + add a code comment citing the exception

```
HARDCODED_TOKENS:
  - tokenizable:      37 hits across 12 files
  - missing-token:    8 hits (suggest 3 new tokens)
  - justified-one-off: 2 hits
```

### 1.4 — Overlay drift (only if `.baldart/overlays/ui-expert.md` exists)

The v3.12.0 base `ui-expert.md` now defines authoritatively things the
overlay may have previously codified. Likely conflict points:

| Overlay section likely to conflict | Why |
|---|---|
| Custom "Red Flags" list | Base now has 60+ categorized red flags — overlay items may be duplicates or contradictions |
| Custom workflow steps | Base now has step 10 (Review) and step 12 (Design) as BLOCKING completion gates — overlay must not skip them |
| Custom token rules | Base now references the Reference Tables in `design-system-protocol.md` — overlay numeric scales should defer to the protocol |
| Custom motion guidance | Base now delegates to `motion-design` skill — overlay should point there, not redefine durations/easings |

Read `.baldart/overlays/ui-expert.md` and report each section that:
- Uses `## [OVERRIDE]` marker on a section the base now owns
  authoritatively (red flags, workflow steps, expertise enumeration).
- Uses `## [APPEND]` to add red flags that are now in the base set
  (duplicates).
- Hardcodes scales / thresholds / durations the new protocol tables now
  declare canonically.

Output:

```
OVERLAY_DRIFT:
  - [OVERRIDE] Your Expertise — conflicts with expanded base (consider [APPEND] instead)
  - [APPEND]   Red Flags — 4 of 6 items now in base list (deduplicate)
  - hardcoded  motion duration 250ms — defer to motion-design timing tables
```

### 1.5 — Emit the baseline report

Save the four sections above as:

```
${paths.references_dir:-docs/references}/ds-coherence-baseline-YYYYMMDD.md
```

Present a short summary to the user (totals per finding type + estimated
size of the reconciliation work). **Stop here for user confirmation** before
proceeding to Step 2.

## Step 2 — Prioritize reconciliation

Not all findings are equal. Rank them so the user gets quick wins first.

| Priority | Criteria | Action |
|---|---|---|
| **P0** | Silent primitive used in ≥ 3 places AND broadly-useful | Add INDEX entry + scaffold full `components/<Name>.md` spec |
| **P0** | Hardcoded token (tokenizable) in the design-system entry-point file or in a primitive | Replace with the existing token reference inline |
| **P1** | Silent primitive used in 1–2 places, broadly-useful | Add INDEX entry + stub spec (`status: needs-review`) |
| **P1** | Stale spec on a primitive used by ≥ 3 features | Update spec to match source |
| **P1** | Missing-token (hardcoded value that should be a token) used > 5 times | Propose new token + update `tokens-reference.md` + replace inline |
| **P2** | Surface-specific silent primitive | Add INDEX entry with `scope: local` + 2-line note |
| **P2** | Stale spec on a rarely-used primitive | Update spec OR open follow-up card |
| **P3** | Justified one-off hardcoded value | Add inline code comment citing the exception |
| **P3** | Overlay-base conflict that does not break the new gates | Refactor overlay to use `[APPEND]` instead of `[OVERRIDE]` |

Convert the prioritized findings into the project's backlog format. If
`features.has_backlog: true`:

- One card per P0 item.
- One card per **group** of P1 items (e.g. "Reconcile 8 stale specs in
  `components/forms/`").
- One catch-all card for P2/P3 batched cleanup.

If no backlog feature → emit a markdown checklist under
`${paths.references_dir}/ds-coherence-followups-YYYYMMDD.md` and present it
to the user.

## Step 3 — Quick wins (apply now, with user approval)

Apply only the items that are **truly trivial and reversible**:

- Inline replacement of `tokenizable` hardcoded values (the token already
  exists; the change is a pure substitution).
- Adding INDEX entries for surface-specific silent primitives (no spec
  needed beyond the scope: local note).
- Removing overlay `[APPEND]` items that exactly duplicate the new base
  red flags.

Group them in **one commit per category** (`chore(ds): replace hardcoded
tokens with existing references`, `docs(ds): index surface-specific
primitives`, etc.) so the diff is reviewable.

Anything more substantial (new specs, new tokens, overlay refactors, stale
spec updates) → backlog cards, not inline edits. Resist the urge to "just
clean it up while you're there" — that turns the alignment into a
multi-day refactor.

## Step 4 — Verify the new gates fire correctly

After the quick wins land, pick **one** small UI task that touches a
primitive (e.g. add a variant to an existing Button) and run it end-to-end:

1. Invoke `ui-expert` or the relevant skill.
2. Make the code change.
3. Observe that the agent's final output explicitly reports the
   Post-Intervention Coherence Check result — either "no findings" or one
   of the `DS_*_DRIFT` codes.

If the agent silently skips this step → the upgrade didn't propagate to
this project. Check:

- `npx baldart status` confirms v3.12.0 installed.
- `.framework/framework/agents/design-system-protocol.md` contains the
  "Post-Intervention Coherence Check" section.
- `.framework/framework/.claude/agents/ui-expert.md` has step 10 (Review)
  and step 12 (Design).

If any of those is stale → `npx baldart update` again, then re-test.

## Step 5 — Establish the rhythm

Going forward, the operator (you, or future Claude instances on this
project):

- Treats the coherence check at end-of-task as **non-negotiable**, same
  category as "tests pass". A UI task without the coherence-check report
  is incomplete.
- Treats `DS_*_DRIFT` findings surfaced by `code-reviewer` as merge
  blockers — they indicate the upstream check was skipped.
- Reads the weekly `ds-drift` routine report when it lands and treats any
  finding there as a **process bug** (somewhere the upstream gates were
  bypassed), not just a content fix.

## Reference points (resolved by `npx baldart update`)

After update, these files exist locally and are authoritative:

| Concern | File |
|---|---|
| What "coherence check" means + decision matrix | `.framework/framework/agents/design-system-protocol.md` § "Post-Intervention Coherence Check" |
| Numeric reference tables (type / contrast / spacing / density) | `.framework/framework/agents/design-system-protocol.md` § "Reference Tables (embed)" |
| Token cascade primitive → semantic → component | `.framework/framework/agents/design-system-protocol.md` § "Token Cascade" |
| Upgraded `ui-expert` (states taxonomy, red flags, gates) | `.framework/framework/.claude/agents/ui-expert.md` |
| Code-reviewer rule 8 (merge gate) | `.framework/framework/.claude/agents/code-reviewer.md` § "Design System Compliance" rule 8 |
| `ui-design` Step H (design-time gate) | `.framework/framework/.claude/skills/ui-design/SKILL.md` |
| Performance Gates (CWV 2026, LCP/INP/CLS) | `.framework/framework/.claude/skills/frontend-design/SKILL.md` § "Performance Gates" |
| Motion + reduced-motion + View Transitions | `.framework/framework/.claude/skills/motion-design/reference/accessibility-and-modern-apis.md` |
| Weekly safety net | `.framework/framework/routines/ds-drift.routine.yml` |

The framework files are symlinked, so reading them via the paths above
gets the live, current version.
