Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 58 additions & 12 deletions docs/design-system/HANDOVER-2026-08-07.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ full session to establish.

## 1 · Measured state

All figures measured on `origin/main` at handover, not recalled.
All figures measured on `origin/main` at handover, not recalled. **Re-measure before acting**
— they drift. The staleness figure below was 111 commits when first written and 129 two days
later; quote your own measurement, never this one.

| Metric | Value |
| ------------------------------------------ | ------------------------------------------------ |
Expand Down Expand Up @@ -47,12 +49,12 @@ npm run design-system:adoption:update && npm run check:design-system-contract

## 2 · What landed on 7 August 2026

| PR | Commit | What |
| ------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| [#1655](https://github.com/BigSimmo/Database/pull/1655) | `cc349d130` | Gate 3's false `--focus` evidence, GATES §1's false "type-step unenforced" note, three stale §0.4 rows, ToggleSwitch knob onto `transform` |
| [#1658](https://github.com/BigSimmo/Database/pull/1658) | `d9221389c` | `AnswerCard` adopted on the live answer surface; `#207`-vs-`#227` resolved. Adoption 27 → 29 |
| [#1663](https://github.com/BigSimmo/Database/pull/1663) | `82b6f5a4c` | Five named tracking tokens + `arbitraryTracking` contract ratchet |
| [#1669](https://github.com/BigSimmo/Database/pull/1669) | open at handover | 68 tracking sites across 40 files migrated; ratchet baseline 68 → **0** |
| PR | Commit | What |
| ------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| [#1655](https://github.com/BigSimmo/Database/pull/1655) | `cc349d130` | Gate 3's false `--focus` evidence, GATES §1's false "type-step unenforced" note, three stale §0.4 rows, ToggleSwitch knob onto `transform` |
| [#1658](https://github.com/BigSimmo/Database/pull/1658) | `d9221389c` | `AnswerCard` adopted on the live answer surface; `#207`-vs-`#227` resolved. Adoption 27 → 29 |
| [#1663](https://github.com/BigSimmo/Database/pull/1663) | `82b6f5a4c` | Five named tracking tokens + `arbitraryTracking` contract ratchet |
| [#1669](https://github.com/BigSimmo/Database/pull/1669) | `b557a26b8` | 68 tracking sites across 40 files migrated; ratchet baseline 68 → **0** |

### The clinical decision recorded in #1658

Expand Down Expand Up @@ -110,11 +112,42 @@ measurement and cost real time.
### Track A — finish the kit

**A1 · `cn()` + tailwind-merge (`#218`).** The keystone. Blocks Chip/metadataPill
convergence and any reliable size override; `cn()` is plain concat today and two source
sites already carry workaround comments. **Its own PR** — it adds a dependency
(`operationalRisk: true`) and changes class resolution across ~200 importing files, so it
must not be bundled or landed alongside a visual change whose Chromium job you still need to
read.
convergence and any reliable size override. **Its own PR** — it adds a dependency
(`operationalRisk: true`), so it must not be bundled or landed alongside a visual change
whose Chromium job you still need to read.

Blast radius, measured: `cn(` is called **1 888 times across 188 source files**; **210 files**
reference `ui-primitives`. Five comments across four files already document working around the
concat behaviour — `page-header.tsx:150` (names `#218`), `document-search-results.tsx:368` and
`:636`, `master-search-header.tsx:2085`, `mode-home-template.tsx:106`. Note the last one does
not merely comment: it **strips stray `justify-*` tokens** from incoming `className`, so
twMerge would make that workaround redundant or double-handle it. Grep for "plain join" and
"concatenates" as well as "tailwind-merge" — a literal grep for the hyphenated term finds only
three of the five.

**The deliverable is the `extendTailwindMerge` config, not the `cn()` body.** This is the part
that will bite. Stock tailwind-merge classifies an unknown `text-<x>` as a **text colour**, and
this repo's `@theme` defines scales it has never seen: `text-2xs`, `text-3xs`, the five
`tracking-*` roles, `min-h-tap` / `h-tap` / `w-tap`, `size-icon-*`, thirteen `shadow-*`, custom
`radius-*` and `leading-*`. So `cn(eyebrowText)` — `text-2xs … text-[color:var(--text-muted)]`
— would have one of those two silently deleted, shipping a size or colour regression across the
kit with **no type or lint signal**. Declare every custom group in the config, comment it
against its `globals.css` source of truth, and pin it with tests that prove custom groups do
not collide while real conflicts still resolve last-wins.

Requires **tailwind-merge v3.x** — v2 targets Tailwind 3, and this repo is on `tailwindcss ^4.3.1`.
Neither `tailwind-merge` nor `clsx` is currently a dependency.

Two hazard classes to audit before switching, in this order:

1. **Order-reliance** — anywhere a later class currently loses to an earlier one, twMerge flips
it. `page-header.tsx` documents exactly this shape (`hidden` + `sm:grid` + `grid`) and dodged
it with `max-sm:hidden`; other sites may not have dodged. Do **not** revert those dodges in
this PR — that is a visual change and belongs elsewhere.
2. **Custom-token misclassification** — the landmine above.

Baseline the three known-failing Windows suites on the untouched base **before** touching
`cn()`. Without a before-shot, "unchanged, not mine" is an assertion rather than proof.

**A2 · `--shadow-focus`.** Replace the composer's companion ring with the sanctioned
`outline` / `--focus` treatment used everywhere else, then delete the token (both theme
Expand Down Expand Up @@ -267,9 +300,22 @@ check so a rewrite could not silently move an unrelated number.
> and the component DOM suites in §8. Expect three pre-existing Windows test failures listed in
> §7 — confirm they are unchanged rather than treating them as yours.
>
> **Pre-authorised, do not stop to ask:** `git fetch` (read-only, and the local `main` ref is
> reliably stale so you need it), cutting a worktree off latest `origin/main`, and
> `npm install tailwind-merge` as a single package. These are routine and inside the dependency
Comment on lines +303 to +305

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the standing authorization for git fetch

When a fresh session follows this embedded prompt, it is told to contact GitHub without asking the current user, even though repository policy explicitly classifies git fetch as provider access requiring user confirmation. A handover document cannot supply that session-specific confirmation, so a compliant agent must ignore this paragraph and stall again, while an agent that follows it performs unauthorized provider access; require the next session to ask before fetching instead.

AGENTS.md reference: AGENTS.md:L302-L306

Useful? React with 👍 / 👎.

> change already approved. Still ask before: OpenAI or Supabase calls, hosted-CI mutations,
> `npm ci`, deploys, or anything touching production data.
>
> Do not commit visual baselines, do not merge any `codex/v2-*` branch, do not build the
> outlined P1/P2 components, and do not write a lint duplicating `check:type-scale`.

**Why that pre-authorisation paragraph exists.** The first session handed this file stalled
before step 0, asking whether `git fetch` fell inside the provider-confirmation boundary. It
was right to read the earlier wording that way — "do not touch … any provider-backed workflow
without asking" plainly covers a fetch. The boundary exists for spend, mutation and production
risk, none of which a read-only fetch carries. Name the routine operations explicitly, or the
next session stalls on the same gate.

Register the Track A and Track B items in the durable ledger with `/issues capture` rather
than hand-writing rows into [`docs/outstanding-issues.md`](../outstanding-issues.md) — ids are
allocated read-modify-write and hand-edits have collided before (`#156`).
Loading