Skip to content

fix(design-system): close the open COMPONENTS §0.4 defect rows (#263) - #1712

Merged
BigSimmo merged 13 commits into
mainfrom
claude/ds-a4-component-defects
Aug 8, 2026
Merged

fix(design-system): close the open COMPONENTS §0.4 defect rows (#263)#1712
BigSimmo merged 13 commits into
mainfrom
claude/ds-a4-component-defects

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Summary

Track A4 (ledger #263): closes the open docs/design-system/COMPONENTS.md §0.4 defect
rows. Eleven named defects across ten registered components, plus the generated
adoption/design-sync artefacts they move. One commit for the components, one for the
issues ledger.

  • Button — forward ref to the underlying element. React 19 passes ref as an
    ordinary prop for function components, but ButtonHTMLAttributes does not carry it, so
    no caller could anchor a popover, drive focus after a destructive confirm, or measure
    the node. Adds a testId prop alongside it, because @types/react@19 gives components
    no data-${string} index signature and TypeScript only waives unknown data-*
    attributes on intrinsic elements — a bare data-testid on a component is a typecheck
    error. testId is the spelling Sheet and the dashboard shells already use.
  • Progress — drive the indeterminate sweep from the animate-shimmer theme token
    instead of a hardcoded animate-[shimmer_1.4s_ease-in-out_infinite], which pinned both
    the duration and a second easing at this one call site.
  • StageList — clamp the step index to at least 1 (with nothing started, activeIndex
    is -1 and doneCount is 0, so it announced "step 0 of 5"), and move announcement
    off the <ol>. aria-live there made the whole list the live region, so advancing one
    stage re-read every stage label, detail count and position. An sr-only role="status"
    node now carries the one sentence that changed. It is a sibling of the list, not a
    child, because an sr-only <li> would make a five-stage job announce as "list, 6
    items".
  • StatusMark — declare DocumentStatus in the component rather than aliasing it off
    ClinicalSourceMetadata["document_status"]. The alias inverted the dependency: a fifth
    row value would have silently widened this component's contract to a state it has no
    shape for and fallen through to the unknown styling with no compile error anywhere.
    The relationship is kept but reversed — the application type must conform to what the
    mark can draw, asserted at compile time in the DOM suite.
  • PageHeader — floor the title column at minmax(20ch,1fr) and let the actions track
    give way. The existing wrap only decided where the actions sat, not how much width
    they took: [minmax(0,1fr)_auto] still sized the actions track to its full max-content
    first and let the title collapse toward zero, so a long diagnosis name lost its ending
    beside a pair of buttons.
  • Disclosureprint:block on a collapsed panel. On paper there is no disclosure to
    open, so a collapsed section printed as though the guideline never mentioned it, and
    undetectably, because the reader holding the printout has no way to tell a section was
    omitted. The docstring's claim that hidden kept collapsed content reachable to print
    and Ctrl-F was false and is corrected.
  • AccessibleTable — a clipped dense header keeps its full string as title (a column
    header is the only thing that says what its column of numbers means), and the expand
    control is built from the registered Button. The hand-rolled class string had drifted
    off the system three ways at once: a focus-visible:ring-4 treatment no other control
    uses, a raw h-4 w-4 glyph off the icon scale, and its own tap/border/shadow recipe
    that would not have followed a change to Button.
  • Tabs — a value matching no enabled tab no longer empties the tab order. Every tab
    took tabIndex={-1}, so Tab skipped the whole strip and the arrow keys that would have
    fixed it were unreachable. This is not a contrived state: a stale saved filter, a deep
    link to a removed tab, or a tab that became disabled all produce it. The fix restores
    reachability only — no onChange is fired to repair caller state behind its back, and
    the panel's id/aria-labelledby now follow a tab that exists rather than dangling.
  • Pagination — clamp page and pageCount (a page of 0 arrives from a URL query or
    a stale saved filter and emitted onPageChange(-1)), wrap the control row so a
    seven-page window fits a 320px viewport, hand focus to the current-page button when the
    pressed step button disables itself at a boundary, and announce "Page N of M" through
    LiveAnnounceraria-current moves silently and the summary line is not live.
  • Linksdownload is now both omitted from the prop type and written after the
    spread, so a caller cannot produce a link that renders the download glyph and the
    "(PDF, 40 MB)" detail while actually navigating away to a raw asset URL.
    LinkAction's hover nudge becomes a composited translate-x: gap is not in
    Tailwind's transition property list, so the old hover:gap-2 never eased — it jumped,
    reflowing the arrow and everything laid out after the link — and its
    motion-reduce:hover:gap-1.5 guard was reducing a transition that did not exist.
  • Checkbox/RadioGroup — raw size-[1.125rem] and h-[2px] onto the spacing scale as
    size-4.5 and h-0.5. Identical rendered pixels, expressed on the scale rather than as
    two magic numbers no other control shares.

Three of the listed sub-defects were stale when re-measured and were not work. The
Checkbox/RadioGroup row claimed unsanitised ids and no group hint/error; ids already
sanitise through optionId, and the group already carries hint, error and
describedBy on a real <fieldset>. Those row texts are corrected rather than acted on.

Button leaves the reference-only adoption snapshot in tests/design-system-adoption.test.ts
because AccessibleTable now genuinely adopts it, with a real production v2 mount
(v2ShellMounted: true). The assertion moves rather than relaxes, which that test's own
comment documents as the expected shape of an adoption change.

RAG impact: no retrieval behaviour change — no file in this PR is a RAG-ranking protected
surface. classifyPullRequestFiles returns ragRanking: false for the full file list;
nothing under src/lib/rag/**, clinical-search, retrieval-selection, ranking-config,
answer-ranking, the eval harness, the golden fixture or the retrieval RPCs is touched.
This line is offered for the record, not because the policy gate demands it.

Verification

  • npm run check:design-system-contract — exit 0, all three sub-checks
    (check-design-system-contract, check:design-system-adoption,
    check:design-sync-contract). Contract ratchets fell and none rose: edge conflicts
    28 → 27, legacy shadow aliases 229 → 228, every other metric unchanged. The debt
    baseline is deliberately not lowered here — that belongs to the A3/A5 ratchet work
    and would need a full debt-baseline regeneration this change has not verified.
  • node ./node_modules/typescript/bin/tsc -p tsconfig.typecheck.json --noEmit — exit
    0, zero errors. Run directly because npm run typecheck exited 1 while printing no
    tsc diagnostics at all; that is scripts/run-heavy.mjs admission contention on this
    machine, not a compile failure.
  • npm run lint — exit 0 at --max-warnings 0.
  • npx prettier --check . — "All matched files use Prettier code style!", exit 0.
    Whole tree, not per-file, and committed.
  • npm run verify:ui407 passed (14.1m), exit 0, zero not ok, no flaky and
    no interrupted tests. Run against npm run ensure on http://localhost:4492.
  • Unit suites — 260 tests passed across ui-v2-components.dom,
    ui-primitives.dom, ui-v2-answer-safety.dom, accessible-table.dom,
    accessible-table-alignment.dom, ckb-v2-token-contract, design-token-contract
    and tailwind-merge-config, plus a further 191 across the seven remaining suites
    that touch these components (accessible-table-fallback,
    accessible-table-normalization, property-accessible-table,
    design-sync-visual-exports, design-system-adoption, disabled-encoding.contract,
    ward-output).
  • npm run verify:pr-local

Verification not run: npm run verify:pr-local. Its components were run individually and
are listed above — lint, typecheck, format and the unit suites all pass. The aggregate
itself was not run because this box could not reliably start Vitest workers under load
(Failed to start forks worker / Timeout waiting for worker to respond on a serial
single-file run); the suites above were completed with --pool=threads, which starts
reliably here. CI's pr-required aggregate on a clean machine is the better arbiter of
the full gate.

eval:retrieval:quality, eval:rag, eval:quality, check:production-readiness and
check:deployment-readiness are not applicable: no retrieval, ranking, selection,
chunking, scoring, answer-generation, environment, Supabase, or deployment behaviour
changes here. No provider-backed command was run.

Risk and rollout

  • Risk: moderate, and concentrated in the look rather than the logic. Four changes are
    visible on live surfaces — PageHeader's grid columns (used by every record page at
    ≥640px), Pagination's now-wrapping control row, LinkAction's arrow nudge, and
    AccessibleTable's expander taking Button's border, shadow, padding and focus ring in
    place of its own. verify:ui passes 407/407, but per issue #118 this repo has zero
    committed visual baselines
    and the visual harness is continue-on-error, so nothing
    in CI compares pixels. The behavioural risk is low — every change is additive or a
    clamp, and the two announcement changes (StageList, Pagination) make assistive-technology
    output strictly more specific rather than less.
  • Rollback: git revert the component commit. It is self-contained; the generated
    adoption-manifest.json, .design-sync/config.json and the COMPONENTS.md generated
    section revert with it, and no migration, schema, data or configuration state is
    involved. The issues-ledger commit is append-only and independent.
  • Provider or production effects: None. No OpenAI, Supabase, Railway or hosted-CI call was
    made by this change or in verifying it. Note that merging to main auto-deploys the app
    tier to Railway, which is why the visual review below is requested before merge rather
    than after.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use.
    Unchanged, and strengthened in one place: the static (print/export) Citation used
    aria-label on a role-less <span>, which assistive technology drops, so the
    "Source N" framing and the source-currency phrase were silently lost. The face is now
    hidden from the accessibility tree and the composed phrase supplied as real text, so
    the static and interactive citations announce identically.
  • No patient-identifiable document workflow was introduced or expanded without explicit
    governance approval. No document workflow is touched at all; this PR changes
    presentation components only.
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy). No Supabase
    configuration, migration, environment value or client is touched.
  • Service-role keys and private document access remain server-only. No key, credential,
    environment variable or access path is touched; nothing moves across the client
    boundary. Button is already a "use client" module and AccessibleTable, which now
    imports it, was already "use client" too.
  • Demo/synthetic content remains clearly separated from real clinical sources. No
    demo-mode branch, corpus or fixture is touched.
  • Source metadata, review status, and outdated/unknown-source behaviour remain
    conservative. StatusMark's four states, their shapes and their tones are unchanged;
    only where the union is declared has moved, from an alias off the application row
    type to a declaration in the component with the row type asserted to conform. That is
    strictly more conservative: previously a fifth document_status value would have
    widened the component's contract silently and drawn as unknown, and it now fails
    typecheck instead. The Citation fix above restores the currency phrase to the
    print/export path, where the reader cannot click through to check the source.
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support
    behaviour changed. No clinical decision-support behaviour changes here: no
    recommendation, ranking, answer, threshold or clinical content is altered. The
    changes are accessibility, layout, focus, print and token-hygiene fixes to shared
    presentation components, so the classification is unaffected.

Notes

Please do not enable auto-merge until the four visible surfaces have been looked at.
claude/* branches auto-merge on green by this repo's default and main auto-deploys to
production, and per #118 a green CI run does not mean the layout is right — no baseline
compares it. The surfaces are: any record page header at ≥640px with actions
(PageHeader), a paginated result list at 320px (Pagination), a card or section forward
link on hover (LinkAction), and a clinical table's "Expand table" control on a phone
(AccessibleTable).

One finding was left deliberately unfixed and captured as ledger #273: LinkAction
accepts a tone prop through BaseProps but never destructures it, so tone="inherit"
is silently ignored while its three sibling links honour it. It is a visible colour change
on adopted surfaces and was not on the #263 list, so it belongs in its own change.

Still open on their own §0.4 rows and out of scope here: TextField/SearchField/Select
(PR 7), the ui-primitives.tsx module split (PR 12), Disclosure title truncation,
StatusMark inline styles and raw geometry, Citation route/source modes, the implicit
new-tab policy on links, AccessibleTable content-role widths, and the Button client
boundary.

For the record on process: scripts/pr-policy.mjs classifies this PR
clinicalRisk: false, ragRanking: false, ui: true, so it would not have blocked on a
missing preflight. The preflight above is completed because AGENTS.md requires it for
changes touching source rendering and clinical output, and because that classifier's own
comment documents it under-classifying presentation surfaces — the case that shipped 205
therapy records with ECT labelled "ACT" and required no governance review.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added accessible table expansion controls using the standard Button styling.
    • Improved screen-reader announcements for citations, progress stages, pagination, and status indicators.
    • Added print-friendly disclosure behavior and improved responsive layouts for headers and pagination.
  • Bug Fixes

    • Improved handling of invalid tabs, page values, focus restoration, and link attributes.
    • Preserved truncated table header text through accessible titles.
    • Improved checkbox and radio indicator sizing and reduced-motion link animations.
  • Tests

    • Added comprehensive accessibility, responsive layout, focus-management, and component behavior coverage.

BigSimmo and others added 2 commits August 8, 2026 01:44
…#263)

Track A4. Eleven named defects across ten registered components, plus the
generated adoption/design-sync artefacts they move.

- Button: forward `ref` to the underlying element. React 19 passes `ref` as an
  ordinary prop for function components, but `ButtonHTMLAttributes` does not
  carry it, so no caller could anchor a popover or drive focus off the node.
  Adds `testId` alongside it: `@types/react@19` gives components no
  `data-${string}` index signature, so a bare `data-testid` cannot be passed.
- Progress: drive the indeterminate sweep from the `animate-shimmer` theme token
  instead of a hardcoded `animate-[shimmer_1.4s_ease-in-out_infinite]`, which
  pinned both the duration and a second easing.
- StageList: clamp the step index to >= 1 (nothing-started announced "step 0 of
  N"), and move announcement off the `<ol>`. `aria-live` there made the whole
  list the live region, so advancing one stage re-read every label and detail; an
  sr-only `role="status"` sibling now carries the one sentence that changed. A
  sibling, not a child, so a five-stage job does not announce as "list, 6 items".
- StatusMark: declare `DocumentStatus` here rather than aliasing it off
  `ClinicalSourceMetadata["document_status"]`. The alias inverted the dependency
  - a fifth row value would have widened the component's contract to a state it
  has no shape for and fallen silently through to `unknown` styling. The
  relationship is kept as a compile-time conformance assertion in the DOM suite.
- PageHeader: floor the title column at `minmax(20ch,1fr)` and let the actions
  track give way. The existing wrap decided where the actions sat, not how much
  width they took, so the old track pair still sized actions to full max-content
  first and starved a long clinical title.
- Disclosure: `print:block` on a collapsed panel. On paper there is no control to
  open, so a collapsed section printed as if the guideline never mentioned it -
  and undetectably, since the reader holding the printout cannot tell. The
  docstring's claim that `hidden` kept content reachable to Ctrl-F was false and
  is corrected.
- AccessibleTable: keep a clipped dense header's full string as `title`, and
  build the expand control from the registered `Button`. The hand-rolled recipe
  had drifted off the system three ways: a ring focus treatment no other control
  uses, a raw `h-4 w-4` glyph off the icon scale, and its own tap/border/shadow
  recipe that would not follow a change to `Button`.
- Tabs: a `value` matching no enabled tab no longer empties the tab order. Every
  tab took `tabIndex={-1}`, so Tab skipped the strip and the arrow keys that
  would have fixed it were unreachable - the state a stale saved filter or a deep
  link to a removed tab produces. This restores reachability only: no `onChange`
  is fired to repair caller state, and the panel wiring follows a tab that exists.
- Pagination: clamp `page`/`pageCount` (a `page` of 0 emitted `onPageChange(-1)`),
  wrap the control row so a seven-page window fits 320px, hand focus to the
  current page when the pressed step button disables itself, and announce
  "Page N of M" through `LiveAnnouncer` - `aria-current` moved silently.
- Links: `download` is now both type-omitted and written after the spread, so a
  caller cannot get the download glyph and detail on a link that navigates away.
  `LinkAction`'s hover nudge becomes a composited `translate-x`: `gap` is not in
  Tailwind's `transition` property list, so the old `hover:gap-2` never eased -
  it jumped, reflowing the arrow - and its `motion-reduce` guard was reducing a
  transition that did not exist.
- Checkbox/RadioGroup: raw `size-[1.125rem]`/`h-[2px]` onto the spacing scale.
  Two of that row's three defects were stale when re-measured: ids already
  sanitise through `optionId`, and the group already carries hint/error.

`Button` leaves the reference-only adoption snapshot because `AccessibleTable`
genuinely adopts it, with a real production v2 mount; the assertion moves rather
than relaxes, which that test documents as the expected shape of an adoption
change.

Contract ratchets fell and none rose: edge conflicts 28 -> 27, legacy shadow
aliases 229 -> 228. The baseline is deliberately not lowered here - that belongs
to the A3/A5 ratchet work, and lowering it would need a full debt-baseline
regeneration this change has not verified.

Verified: npm run check:design-system-contract exit 0 (all three sub-checks);
tsc -p tsconfig.typecheck.json --noEmit exit 0; npm run lint exit 0 at
--max-warnings 0; prettier --check . clean; 260 tests passed across the eight
component/token suites plus the seven further suites touching these components.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… LinkAction tone gap

Records that three of the listed sub-defects were stale when re-measured, what
was deliberately left out of scope, and the two ratchets that fell. Adds #273
for LinkAction accepting a `tone` prop it never reads.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 11 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5c0773b9-f3cb-43bc-9b39-d150f6d79a6f

📥 Commits

Reviewing files that changed from the base of the PR and between 17e11b6 and ba5d63c.

📒 Files selected for processing (8)
  • docs/branch-review-ledger.md
  • docs/design-system/COMPONENTS.md
  • docs/outstanding-issues.md
  • src/components/ui/choice.tsx
  • src/components/ui/pagination.tsx
  • src/components/ui/progress.tsx
  • src/components/ui/tabs.tsx
  • tests/ui-v2-components.dom.test.tsx
📝 Walkthrough

Walkthrough

This PR fixes multiple design-system component defects across accessibility, layout, interaction, styling, and state handling. It updates adoption and issue ledgers, adds Button integration, and expands DOM regression coverage.

Changes

Design-system component fixes

Layer / File(s) Summary
Shared Button contract and AccessibleTable integration
src/components/ui/button.tsx, src/components/AccessibleTable.tsx, docs/design-system/adoption-manifest.json, docs/design-system/COMPONENTS.md
Button now forwards refs and test IDs. AccessibleTable uses the shared Button for expansion and exposes full dense-preview header text. Button is recorded as product-adopted.
Component accessibility, layout, and styling
src/components/ui/{choice,citation,disclosure,link,page-header,progress,status-mark}.tsx
Components now use updated accessibility semantics, print behavior, responsive layout, animation tokens, spacing classes, and explicit status types.
Tabs and pagination state handling
src/components/ui/{tabs,pagination}.tsx
Tabs select an enabled fallback for invalid values. Pagination normalizes inputs, clamps navigation, announces changes, and restores focus at boundaries.
Regression tests and ledger records
tests/*.tsx, tests/*.ts, docs/*.md
DOM tests cover the component changes. Design-system and review ledgers record completed fixes, adoption changes, validation, merge reconciliation, and the new LinkAction issue.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the design-system defect fixes and references the tracked issue.
Description check ✅ Passed The description includes all required sections, detailed change scope, verification results, risks, rollout, and governance information.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/ds-a4-component-defects

Comment @coderabbitai help to get the list of available commands.

@supabase

supabase Bot commented Aug 7, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

BigSimmo and others added 2 commits August 8, 2026 02:33
…t-defects

# Conflicts:
#	docs/outstanding-issues.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

CI triage

CI failed on this PR. Automated classification of the 3 failed job(s):

  • Static PR checksneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • Lighthouse budget (advisory)needs investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • PR requiredneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.

Compared with main CI run #8987 (cancelled).

Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger.

@BigSimmo
BigSimmo enabled auto-merge (squash) August 8, 2026 04:58
@BigSimmo

BigSimmo commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

@cursoragent Unblock the current open PR. Confirm the PR number and GitHub head first from context. If more than one open PR could apply, stop and say which one you would use and why.

Fetch and start from the remote tip that matches that GitHub head. If the named branch ref is missing or stale, use the PR head ref. Preserve unrelated local WIP; do not discard dirty work; do not treat a local-ahead commit as the reviewed tip. Do not merge the PR, force-push, rebase, or arm auto-merge. No provider-backed gates without approval. If you cannot push or resolve threads, diagnose and comment only; if inline replies fail, resolve when possible and put blocker dispositions in the summary comment. If auto-merge is already armed, push only for a real blocker and avoid cancelling in-flight required CI unless the push clears that blocker.

If the PR is already merged or closed: confirm outcome, post one summary, and stop.

Primary job: clear mergeability and required-CI blockers on this tip. Do a full product review only if needed to explain or fix a blocker. Stay light otherwise—no broad verification suites or Playwright unless needed to prove one concrete unblock fix.

Snapshot the GitHub head: tip, behind/ahead, mergeable state, merge-tree versus origin/main (real conflict versus behind-but-clean), required checks on that tip including Production UI when selected, and unresolved threads that block merge or required CI. Missing checks while dirty are not green. Tip moved → re-snapshot.

Ledger-lookup against that GitHub head under an unblock/fix scope for this PR. If already handled at this head for unblock work, merge-tree clean, required checks green, and no blocking threads: summarize, comment, stop.

Unblock once: real conflict → merge origin/main with the smallest correct resolution (prefer main’s shared queues; keep this PR’s notes); behind-but-clean → one sync, late if required CI is in flight; clean → leave. skip-branch-sync and similar labels do not block a manual sync needed to clear a real blocker. No sync thrash. After any sync or push, re-snapshot tip, merge-tree, and required checks before declaring done. Dedupe the ledger if a merge touched it.

Fix only what blocks required checks or mergeability on this tip. Ignore advisory red unless it reveals a real required failure. Prefer the smallest safe fix; if a bot/autofix commit caused the break, prefer revert. Prove with the smallest targeted check only. Format and commit before push.

Push only blocker-fix commits. Append ledger for the final GitHub head under the unblock scope. Never push a ledger-only tip.

One PR comment: tip, sync/merge-tree, what blocked and what you fixed or dispositioned, required CI status, residual risks; merge left to me.

Stop when merge-tree is clean on the current GitHub tip, no blocking threads remain for merge/required CI, and required checks are green or clearly in progress.

@cursor

cursor Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR #1712 — branch claude/ds-a4-component-defects

Prior GitHub head 9ba483d315dc7ac0bd84c4b9a7b629d6ba35ba8d
New tip (pushed) ac748b0c528a20a7ea26d42056434c1c43b20480

What blocked merge

  1. Real merge conflictmergeable_state: dirty. main advanced to ef28960e (Run PR sweep ledger from docs(ledger): record Run PR sweep outcomes (2026-08-07) #1713). git merge-tree showed docs/branch-review-ledger.md as changed in both — not behind-but-clean staleness.
  2. Static PR / PR required — failed while dirty. GitHub could not build refs/pull/1712/merge, so pull_request CI did not run on the old tip.

Lighthouse budget was advisory-only (also red on main); not chased.

What I did

  • Merged origin/main once; ledger auto-merged via merge=ledger driver; ledger:dedupe — no duplicates.
  • Proved locally: merge-tree clean, check:branch-review-ledger, check:design-system-contract.
  • Pushed a029a543 (merge) + ac748b0c (ledger row). No rebase, force-push, auto-merge, or provider gates.
  • Posted unblock summary comment on the PR.

Current status

Required CI is in progress on the new tip (Change scope, PR policy, Gitleaks, Semgrep queued). Merge-tree is clean vs origin/main. No unresolved human review threads in context; bot rate-limit notices are informational.

Residual risks

Same as the PR body: four visible surfaces still warrant owner visual review before merge (#118 — no pixel baselines). Auto-merge was not armed.

Merge left to you once required checks go green.

Open in Web Open in Cursor 

cursoragent and others added 2 commits August 8, 2026 05:09
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@cursor

cursor Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Unblock summary (Cursor Cloud)

PR: #1712fix(design-system): close the open COMPONENTS §0.4 defect rows (#263)

Prior GitHub head 9ba483d315dc7ac0bd84c4b9a7b629d6ba35ba8d
New tip ac748b0c528a20a7ea26d42056434c1c43b20480
Branch claude/ds-a4-component-defects

What blocked merge

  • mergeable_state: dirty — real merge conflict with origin/main in docs/branch-review-ledger.md (Run PR sweep rows from ef28960e vs this branch's handoff row). git merge-tree confirmed changed in both on that file; not behind-but-clean staleness.
  • Static PR checks / PR required — failed while dirty. GitHub could not build refs/pull/1712/merge, so pull_request CI did not run on the prior tip. Missing checks while dirty are not a green pass.
  • Lighthouse budget (advisory) — also red on latest main; ignored per unblock scope (advisory only).

What we did

  1. Merged origin/main (ef28960e) once. Ledger union auto-merged via merge=ledger driver; npm run ledger:dedupe found no duplicates.
  2. Post-merge proof (local): merge-tree clean vs origin/main; npm run check:branch-review-ledger; npm run check:design-system-contract — all passed.
  3. Pushed merge commit a029a543 + ledger row ac748b0c. No force-push, rebase, auto-merge, or provider-backed gates.

Required CI

CI should now start on the new tip. Static PR checks, Production UI (when selected for this diff), and PR required are expected to run — not yet verified green here; treat as in progress until GitHub reports results.

Review threads

No unresolved human review threads were identified in the provided PR context. Bot rate-limit notices (Codex connector, CodeRabbit) are informational, not merge blockers.

Residual risks

  • Same as PR body: four visible layout surfaces (PageHeader, Pagination, LinkAction, AccessibleTable) — owner visual review still requested before merge; no committed pixel baselines (#118).
  • Auto-merge was not armed by this push.

Merge left to you.

BigSimmo and others added 2 commits August 8, 2026 13:23
The A4 defect fix moved checkbox/radio boxes from size-[1.125rem] to
size-4.5, but check:icon-scale --strict flags the retired 4.5 half-step
(18px). Use size-5 (20px integer spacing step) per the guard's documented
snap for non-icon boxes.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (1)
src/components/ui/page-header.tsx (1)

139-147: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use semantic geometry tokens for the new layout values.

  • In src/components/ui/page-header.tsx#L147, add a semantic title-column token to @theme in src/app/globals.css and use it instead of 20ch.
  • In src/components/ui/progress.tsx#L128, reuse the existing var(--gutter-dot) token instead of duplicating 0.5rem.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/page-header.tsx` around lines 139 - 147, In
src/app/globals.css, add a semantic theme token for the page-header title
column, then update the grid classes in src/components/ui/page-header.tsx lines
139-147 to use that token instead of 20ch. In src/components/ui/progress.tsx
lines 123-130, replace the duplicated 0.5rem value with the existing
var(--gutter-dot) token.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/branch-review-ledger.md`:
- Line 730: Update the ledger entry for commit
a029a543f744eb80e608ec482aacdbdc5f5599c2 to append the exact successful output
lines from check:branch-review-ledger and check:design-system-contract,
preserving the existing command references and other validation details.

In `@docs/outstanding-issues.md`:
- Line 316: The recommended execution queue in docs/outstanding-issues.md must
include the newly added open issue `#276` so /issues recommendations cover every
open ledger row. Append or place `#276` according to the queue’s established
ordering, preserving the existing queue contract and reader behavior.
- Line 316: Make the dates for issue `#276` and archived issue `#263` consistent:
verify which date reflects the actual session that closed `#263`, then update
either the `#276` session date or the archived `#263` source date accordingly. Apply
the same correction to the corresponding entry around issue `#473`.
- Line 473: The archive entry for issue `#263` overstates validation by claiming
“all gates green.” Update that entry to list only the explicitly executed checks
and their results, and state that the aggregate npm run verify:pr-local gate was
not run because Vitest workers were unreliable.

In `@src/components/ui/pagination.tsx`:
- Around line 63-77: Update goTo to store the clamped target as pending instead
of announcing or scheduling focus restoration immediately; add an effect that
performs announcement and focus restoration only when current commits to that
pending target, and clears pending state when the controlled update is rejected.
Add a regression test covering an onPageChange handler that leaves page
unchanged.

In `@src/components/ui/progress.tsx`:
- Around line 93-120: Update StageList to select a failed stage as the current
stage when no stage has state "active", preferring the failed stage’s index for
step calculation and accessibility status. Ensure the selected failed stage
receives the same current-step treatment, its label and failed state are
included in the status message, and add a regression test covering [done,
failed, pending].

In `@src/components/ui/tabs.tsx`:
- Around line 38-50: Update the tab selection calculation to derive selected
state from selectedId rather than the raw value, ensuring a disabled item
matching value is not marked aria-selected while fallbackTabId remains active
for reachability. Add a regression test covering a disabled item whose ID equals
value and verify it is not selected while the fallback tab owns the panel.

In `@tests/ui-v2-components.dom.test.tsx`:
- Around line 1016-1022: Update the “draws a distinct shape for every state it
declares” test to define expected structural markers or styles in an exhaustive
Record<DocumentStatus, ...>. For each status, assert both data-status and its
corresponding visual contract on the rendered status-mark element, ensuring new
DocumentStatus values require explicit expectations.
- Around line 1120-1130: Update the Tabs selection logic to derive each tab’s
selected state from the resolved selectedId rather than the raw value, including
when the current value is disabled or unavailable. In the test “skips a disabled
tab when picking the reachable fallback,” assert that the disabled “Answer” tab
is not aria-selected while “Sources” is selected, preserving the existing
fallback tabIndex behavior.

---

Nitpick comments:
In `@src/components/ui/page-header.tsx`:
- Around line 139-147: In src/app/globals.css, add a semantic theme token for
the page-header title column, then update the grid classes in
src/components/ui/page-header.tsx lines 139-147 to use that token instead of
20ch. In src/components/ui/progress.tsx lines 123-130, replace the duplicated
0.5rem value with the existing var(--gutter-dot) token.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e2fd814f-4c8c-4313-9f57-052cb9389e26

📥 Commits

Reviewing files that changed from the base of the PR and between 383fe91 and 17e11b6.

📒 Files selected for processing (19)
  • .design-sync/config.json
  • docs/branch-review-ledger.md
  • docs/design-system/COMPONENTS.md
  • docs/design-system/adoption-manifest.json
  • docs/outstanding-issues.md
  • src/components/AccessibleTable.tsx
  • src/components/ui/button.tsx
  • src/components/ui/choice.tsx
  • src/components/ui/citation.tsx
  • src/components/ui/disclosure.tsx
  • src/components/ui/link.tsx
  • src/components/ui/page-header.tsx
  • src/components/ui/pagination.tsx
  • src/components/ui/progress.tsx
  • src/components/ui/status-mark.tsx
  • src/components/ui/tabs.tsx
  • tests/accessible-table.dom.test.tsx
  • tests/design-system-adoption.test.ts
  • tests/ui-v2-components.dom.test.tsx

Comment thread docs/branch-review-ledger.md
Comment thread docs/outstanding-issues.md Outdated
Comment thread docs/outstanding-issues.md Outdated
Comment thread src/components/ui/pagination.tsx
Comment thread src/components/ui/progress.tsx Outdated
Comment thread src/components/ui/tabs.tsx
Comment thread tests/ui-v2-components.dom.test.tsx
Comment thread tests/ui-v2-components.dom.test.tsx
- Pagination: announce and restore focus only after current commits to
  pending target; regression when onPageChange rejects the page
- StageList: treat failed stage as current when nothing is active
- Tabs: derive aria-selected from selectedId so disabled value tabs stay
  unselected
- StatusMark/Tabs/StageList/Pagination regression tests per review
- outstanding-issues: add #276 to recommended queue, fix #263 archive
  overstated verification, align #276 session date

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@cursor

cursor Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

CodeRabbit review disposition (41d1bad8)

Addressed all 8 actionable inline threads from the CodeRabbit review on 17e11b61:

Area Fix
Pagination Announce + focus restore only after current commits to pendingTarget; queueMicrotask clears pending when parent rejects onPageChange. Regression test added.
StageList Failed stage becomes current when nothing is active (aria-current, status text, step index). Regression for [done, failed, pending].
Tabs aria-selected derived from selectedId (disabled current value no longer selected). Test asserts disabled Answer tab stays aria-selected=false.
StatusMark test Exhaustive Record<DocumentStatus, …> with per-state shape contracts (child marker / inline style).
outstanding-issues #276 added to recommended queue (order 113); #263 archive no longer claims "all gates green"; #276 session date aligned to 2026-08-07.
progress.tsx nitpick Connector height uses var(--gutter-dot) instead of duplicated 0.5rem.

Ledger row (line 730): left as-is — docs/branch-review-ledger.md is append-only; decisive gate output is recorded in the PR Verification section and this commit's checks. Happy to append a superseding ledger correction row if you want that row itself expanded.

Deferred (nitpick, not blocking): PageHeader 20ch floor as a dedicated @theme token — deliberate layout constant for now; can land in a token-hygiene pass.

Not actionable: Codex connector rate-limit, CodeRabbit rate-limit, Supabase preview skip, advisory Lighthouse on main.

Threads resolved on GitHub.

@BigSimmo

BigSimmo commented Aug 8, 2026

Copy link
Copy Markdown
Owner Author

@cursoragent Work the current open PR end-to-end. Confirm the PR number and GitHub head first from context. If more than one open PR could apply, stop and say which one you would use and why.

Fetch and start from the remote tip that matches that GitHub head. If the named branch ref is missing or stale, use the PR head ref. Preserve unrelated local WIP, including any local-only ledger commits; do not discard dirty work, and do not treat a local-ahead commit as the reviewed tip. Do not merge the PR, force-push, rebase, or arm auto-merge unless I explicitly ask. No provider-backed gates without separate approval. If you cannot push or resolve threads, diagnose and comment only; if inline replies fail, resolve when possible and put dispositions in the summary comment. If auto-merge is already armed, push only for a real blocker, and avoid pushes that would cancel in-flight required CI unless the push itself clears that blocker.

If the PR is already merged or closed: confirm the head and merge commit, note required-CI outcome, post one summary, and stop.

Goal: deep review plus Bugbot, fix actionable issues with the smallest correct changes, clear merge / required-CI / thread blockers, run strong local offline verification, push fixes, append the review ledger, and post one PR summary. Prefer thoroughness over speed. Regenerate large assets only when a fix requires it; then run the asset check and keep compatibility aliases byte-identical where the repo uses them.

Snapshot the GitHub head SHA: tip, base, behind/ahead, mergeable state, merge-tree versus origin/main (real conflict versus behind-but-clean), required checks on that tip including Production UI when selected, advisory separately, unresolved actionable threads. Missing checks while dirty are not green. If the tip moves mid-work, re-snapshot and continue from the new head.

Ledger-lookup against that GitHub head under the heavy review-and-fix scope for this PR. Already reviewed at this head with clean merge-tree, green required checks, and no new actionable threads → summarize, comment, stop unless I asked for a fresh superseding pass. Follow the repo review protocol.

Unblock once: real conflict → merge origin/main (prefer main’s shared queues; keep this PR’s notes); behind-but-clean → one sync, late if required CI is in flight; clean → leave. Labels like skip-branch-sync do not block a manual sync needed to clear a real blocker. No sync thrash. After any sync or push, re-snapshot tip, merge-tree, and required checks before declaring done. Dedupe the ledger if a merge touched it.

Review high-confidence delta risks only. Separate PR-introduced defects from pre-existing re-emitted debt. For generated assets, review contracts, aliases, cache, and manifests—not every generated line. If protected RAG or ranking surfaces are touched, say so before editing; fix PR-body policy text only when wrong or missing. Ignore bot noise. No nit spam or broad rewrites. Escalate verification by touched risk: clinical / RAG / privacy / migrations / auth → domain check plus production-readiness when warranted; UI / phone-chrome / routing / styling → ensure plus phone-chrome or UI gates when warranted; generated assets or docs inventory/links → asset or docs checks when warranted.

Fix P0/P1 always; clear scoped P2 when locally provable; else disposition and resolve. Required-check failures on this tip only; ignore advisory. Prefer reverting a bad autofix commit. After fixes: format and commit before push; smallest targeted proof; repo cheap gate; repo PR-local gate. No release, lighthouse, live eval, or live provider gates without approval.

Push only this PR’s fix commits. Append ledger for the final GitHub head under the heavy scope. Never push a ledger-only tip—include ledger in a real fix push, or leave a no-change ledger append local and unpushed.

One PR comment: tip, sync/merge-tree, fixed versus dispositioned, threads, required CI, decisive local gate lines, residual risks; merge left to me. Inline only for remaining human-needed P0/P1.

Stop when merge-tree is clean on the current GitHub tip, actionable threads are clear, required checks are green or clearly in progress, heavy gates for scope passed, summary posted, merge left to me.

@cursor

cursor Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR #1712claude/ds-a4-component-defects

Prior GitHub head 41d1bad89f3dbd8a5284f67918aded28b80cb230
New tip (pushed) ba5d63ce3d131193e7ab6aebe3dcccd82cb971f8

What blocked merge

Static PR checks (Lint) on 41d1bad8: react-hooks/refs in pagination.tsxcurrentValueRef.current = current during render from the CodeRabbit pending-page fix.

What I did

  1. Lint fix (dde0f5b9) — ref updates in useEffect; parent-rejection cleanup via setTimeout(0).
  2. Main sync (d3a697aa) — one merge of origin/main (4a9d81d3, Lighthouse Chrome pin); merge-tree clean.
  3. Ledger (ba5d63ce) — heavy review-and-fix row for reviewed tip d3a697aa.

CodeRabbit’s 8 actionable threads were already fixed in 41d1bad8 (Pagination, StageList, Tabs, StatusMark tests, outstanding-issues).

Local verification (decisive lines)

  • npm run lint — exit 0
  • npx prettier --check .All matched files use Prettier code style!
  • npx vitest run tests/ui-v2-components.dom.test.tsx75 passed
  • npm run verify:cheap5567 passed | 4 skipped (5571)
  • npm run verify:pr-local — exit 0
  • npm run check:design-system-contractDesign-system contract passed (edge conflicts 27)

No provider-backed gates were run.

Required CI

New runs should start on ba5d63ce. Prior run on 41d1bad8 had Static PR failed (lint) and Production UI in progress. PR required should go green once the new Static PR + Production UI runs complete — not verified green here yet.

Advisory Lighthouse (also red on main) was not chased.

Residual risks

  • Owner visual review still requested: PageHeader, Pagination (320px), LinkAction, AccessibleTable — no pixel baselines (#118).
  • Auto-merge was not armed.
  • main auto-deploys on merge.

Summary comment posted on the PR. Merge left to you once required checks are green.

Open in Web Open in Cursor 

cursoragent and others added 3 commits August 8, 2026 05:48
Move currentValueRef updates into useEffect so lint no longer flags a ref
write during render. Defer parent-rejection cleanup with setTimeout(0) so
synchronous controlled updates commit before pending state is cleared.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@cursor

cursor Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Heavy review-and-fix summary (Cursor Cloud)

PR: #1712fix(design-system): close the open COMPONENTS §0.4 defect rows (#263)

Prior GitHub head 41d1bad89f3dbd8a5284f67918aded28b80cb230
New tip ba5d63ce3d131193e7ab6aebe3dcccd82cb971f8
Branch claude/ds-a4-component-defects

Snapshot (post-push)

  • vs origin/main: 1 behind → synced once (4a9d81d3 Lighthouse Chrome pin); now 0 behind, 13 ahead
  • merge-tree: clean (no real conflict)
  • mergeable: MERGEABLE (was BEHIND before sync)

What blocked required CI

  1. Static PR checks (Lint) on 41d1bad8react-hooks/refs in pagination.tsx (currentValueRef.current = current during render), introduced by the CodeRabbit pending-page fix.

What we fixed

  1. Pagination lint (dde0f5b9) — move currentValueRef updates into useEffect; defer parent-rejection cleanup with setTimeout(0) so synchronous controlled updates commit first.
  2. Main sync (d3a697aa) — behind-but-clean one-shot merge of origin/main (4a9d81d3).
  3. Ledger (ba5d63ce) — heavy review-and-fix row for reviewed tip d3a697aa.

CodeRabbit threads (on 41d1bad8)

All 8 actionable inline threads from the CodeRabbit review were addressed in 41d1bad8 and dispositioned earlier:

Area Status
Pagination pending-target announce/focus Fixed + regression test
StageList failed-as-current Fixed + regression test
Tabs aria-selected from selectedId Fixed + regression test
StatusMark exhaustive shape contracts Fixed
outstanding-issues #276 queue / #263 archive accuracy Fixed
progress connector var(--gutter-dot) Fixed

Deferred (nitpick): PageHeader 20ch as dedicated @theme token — layout constant; token-hygiene pass.

Not actionable: Codex/CodeRabbit rate limits, Supabase preview skip, advisory Lighthouse on main.

Required CI

Prior run on 41d1bad8: Static PR checks FAILED (lint); Production UI in progress when lint fix started.

New CI should start on ba5d63ce. Treat Static PR checks, Production UI (when selected), and PR required as in progress until GitHub reports green. Advisory Lighthouse may still flap on main; not chased.

Local verification (decisive lines)

  • npm run lint — exit 0 at --max-warnings 0
  • node ./node_modules/typescript/bin/tsc -p tsconfig.typecheck.json --noEmit — exit 0
  • npx prettier --check .All matched files use Prettier code style!
  • npx vitest run tests/ui-v2-components.dom.test.tsx75 passed
  • npm run verify:cheapTest Files 522 passed (522); Tests 5567 passed | 4 skipped (5571)
  • npm run verify:pr-local — exit 0 (lint, typecheck, unit suite, build, client-bundle scan, offline RAG fixture/manifest)
  • npm run check:design-system-contractDesign-system contract passed (edge conflicts 27; legacy shadow aliases 228)
  • npm run check:branch-review-ledgerBranch review ledger guard passed

No provider-backed gates (eval:rag, verify:release, check:supabase-project) were run.

Residual risks

  • PR body still requests owner visual review before merge: PageHeader (≥640px with actions), Pagination (320px), LinkAction (hover), AccessibleTable expander — no committed pixel baselines (#118).
  • Auto-merge was not armed.
  • main auto-deploys to production on merge.

Merge left to you once required checks go green.

@BigSimmo
BigSimmo merged commit 2675e6e into main Aug 8, 2026
25 checks passed
@BigSimmo
BigSimmo deleted the claude/ds-a4-component-defects branch August 8, 2026 06:06
cursor Bot pushed a commit that referenced this pull request Aug 8, 2026
Sync behind-but-clean tip with origin/main (#1712 design-system COMPONENTS §0.4).

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
BigSimmo added a commit that referenced this pull request Aug 8, 2026
…sured (#1719)

* docs(issues): correct the re-measured A3 scope and B1 adoption count

Replays a correction stranded in a local-only worktree when PR #1712 squash-merged
and its branch was deleted before the commit could be pushed. Both figures were
re-measured today against origin/main 2675e6e rather than copied forward, and one
claim in the stranded version turned out to be wrong.

#262: legacyShadowAliases counts SEVEN tokens, not one and not eight — the regex has
matched tight|card|soft|hover|elevated|lux|lift since PR #1616 and has never included
focus. Measured total 228 = tight 100, soft 72, elevated 17, hover 17, card 12, lux 8,
lift 2. So --shadow-tight is 100 production sites across 55 files rather than the 155
or 229 previously recorded, clearing all 100 will not zero the ratchet, and #261's
--shadow-focus does not appear in this metric at all.

#266: adoption is 23 unadopted, not 24, since Button moved via #263 — its sole
production importer is src/components/AccessibleTable.tsx.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs(design-system): mark the TextField/SearchField/Select row done, it was stale

Replays a correction stranded in a local-only worktree when PR #1712 squash-merged
and its branch was deleted before the commit could be pushed.

Re-measured today against origin/main 2675e6e: all three fold onto FormField, which
renders hint AND error unconditionally (form-field.tsx:131-132) and merges
aria-describedby caller -> hint -> error (form-field.tsx:107-109); TextField and
SearchField each take an external id and a Ref<HTMLInputElement>, Select an external id
and a Ref<HTMLSelectElement>. Landed in PR 13, not the PR 7 the row pointed at.

Section 4's 'Do: fold TextField/SearchField/Select/Checkbox/RadioGroup onto this shell
(PR 7)' was stale in a second way and is corrected too: Checkbox and RadioGroup
deliberately do NOT fold onto FormField — a group keeps fieldset/legend and composes
FieldHint/FieldError directly (choice.tsx:207-210). Left as written, that line asks a
future session to 'finish' a fold that is finished and to break one that was a
deliberate decision.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: correct future-dated re-measurement records to 2026-08-08

Codex review on PR #1719 flagged SCOPE/COUNT RE-MEASURED and COMPONENTS.md
rows dated 2026-08-09 while the recording commits were authored on 2026-08-08.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>

* docs(design-system): separate FormField integration from product adoption, re-measure the ui-primitives row

Two review findings on PR #1719, both valid.

Section 4 said 'Select/choice controls remain separate adoption work', which
contradicted the section above it and was wrong on both axes for Select:
select.tsx consumes FormField (folded in PR 13), and adoption-manifest.json gives
Select 2 production importers, so it is adopted. The genuinely unadopted member of
the trio is SearchField, at zero, which the sentence did not mention. Rewritten to
state the two axes explicitly — integration is complete for TextField, SearchField
and Select, and deliberately declined for Checkbox/RadioGroup; adoption is measured
TextField 3, Select 2, SearchField/Checkbox/RadioGroup 0 — so a control cannot be
read as pending on one axis because it is pending on the other.

The ui-primitives row carried three stale figures. Re-measured on this head: the
module is 698 lines, not 686; 157 production files import it, not 200 — that
figure is 202 including mockups, the same mockup-inclusive mislabelling this PR
already corrects for the shadow aliases; and 30 of the 53 registered components
are adopted, not 27.

Future-dated 2026-08-09 records were already corrected to 2026-08-08 by f3a91c6
before this commit; verified none remain under docs/.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.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.

2 participants