Skip to content

feat(design-system): v2 token layer + 26 components — reconciled, cascade-ported, forced-colours owned - #1538

Merged
BigSimmo merged 8 commits into
mainfrom
claude/clinical-kb-design-system-333a69
Jul 31, 2026
Merged

feat(design-system): v2 token layer + 26 components — reconciled, cascade-ported, forced-colours owned#1538
BigSimmo merged 8 commits into
mainfrom
claude/clinical-kb-design-system-333a69

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Summary

  • The v2 design-system layer, complete and reconciled (branch claude/clinical-kb-design-system-333a69): opt-in .ckb-v2 token layer (src/app/ckb-v2-tokens.css, the canonical single token file per docs/design-system/TOKENS.md), 26 components under src/components/ui/, previews, and contract tests. Nothing is adopted by any product surface — zero visual change ships.
  • C1 reconciliation (59e4c3dfc): --shadow-well role, evidence-spine + status-mark families, dark --clinical-chat-document fix, answer-card named leading-prose step.
  • Playbook PR 1+2 and first slices of PR 3+4 (latest commit): theme-cascade port (light on .ckb-v2, dark via .dark .ckb-v2, .ckb-v2.dark, never :not(.dark)), the v2 forced-colors block over all three selectors (elevation flattened, system-colour mapping), Button.danger paired with --danger-solid-contrast, AsyncButton defaults type="button". Contract test's block parser updated in the same commit.
  • Merged origin/main (one conflict, tests/source-metadata.test.ts, resolved keeping both sides' tests: main's optional-normalization test + the branch's browser-safe diagnostics-seam trace test).

RAG impact: no retrieval behaviour change — design-system layer and components only; no file under src/lib/rag/**, clinical-search, retrieval-selection, ranking, eval harness, golden fixtures, or retrieval RPCs is touched.

Verification

  • vitest token + component contracts after the cascade/HCM/danger changes — 67 passed (67); after the main merge, source-metadata + both token contracts — 74 passed (74).
  • Recorded at export for the branch baseline: tsc pass · lint pass · unit 4 689/1 (environmental #149)/3 · verify:ui 344 passed · design-system contract pass (625 files).
  • Verification not run locally: full verify:pr-local — deferred to this PR's CI (multi-worktree box, contention false-reds); typecheck of the merged union runs in CI.

Risk and rollout

  • Risk: low-medium. Entirely additive, class-scoped, unadopted layer — no production surface imports any of it; the cascade/HCM changes only affect subtrees that opt in with class="ckb-v2" (none exist).
  • Rollback: revert the squash commit; no data, schema, or provider surface involved.
  • Provider or production effects: None.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed

Notes

🤖 Generated with Claude Code

BigSimmo and others added 4 commits July 31, 2026 17:40
Design-system scope only. Nothing is adopted by a product surface: the new
components are built and tested but unimported, and the v2 token layer is
class-scoped to `.ckb-v2` so importing it cannot repaint any surface that does
not opt in.

Correctness:
- Fix a P1 browser crash. `source-metadata.ts` imported the server logger, whose
  `activeLevel()` reads `process.env.LOG_LEVEL` — a ReferenceError in a browser,
  so any off-vocabulary metadata value unmounted the whole React tree instead of
  falling back. Drops the import, adds a browser-safe diagnostic seam, and guards
  the env read in `logger.ts` as defence in depth.
- Type the three source badges' `metadata` prop. It was `unknown` while the
  published `.d.ts` promised a shape, so the wrong key compiled cleanly.
- Encode the disabled state in `controlBase` instead of `opacity-50`, which dimmed
  fill and label together and dropped secondary labels below 4.5:1.
- Move `fieldLabel` off `--text-soft` (3.07:1) and the uppercase eyebrow treatment.
- Delete `ui/card.tsx` and `ui/badge.tsx` — 7 exports, 0 importers, colliding by
  name with Chip and AnswerCard.

Components (built, not adopted): Button, TextField, SearchField, Chip, Toast,
Tabs, Tooltip, Pagination, ConfirmDialog, PageHeader, Breadcrumb, AnswerCard,
DoseLine, AnswerFooter, Quantity, StatusMark, Citation, the four Link variants,
Select, Checkbox, RadioGroup, Disclosure, Progress, StageList.

AccessibleTable: per-column numeric alignment, `aria-controls` on the expander,
sticky header when expanded, and an explicit unverified-extraction treatment.

Verification: tsc pass, lint pass, prettier clean, verify:ui 344 passed,
design-system contract pass. Unit 4689 passed / 1 failed / 3 skipped — the
failure is `installed-lock-parity`, environmental (brace-expansion 1.1.16 vs
lockfile 1.1.18), tracked as issue #149.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…all-through, leading step

C1 reconciliation per docs/design-system/TOKENS.md - the design-side token file
proved unrecoverable (design project 08d6f126 was last updated 2026-07-13; the
31 July copy was never written to it), so the repo file becomes the canonical
reconciled copy:

- Rename the two v2 --shadow-inset overrides to --shadow-well (recessed-well
  role). The DS bevel --shadow-inset is inherited from globals.css again,
  restoring the bevel highlight to its ~40 consumers.
- Update the token contract test in the same commit: pin --shadow-well as a
  true inset and assert --shadow-inset is not redeclared in the v2 layer.
- Author the evidence-spine and status-mark role families repo-side, derived
  from existing roles (spine from rule/accent/warning, status-mark from the
  gutter dot and StatusMark's previously-inline stroke). Confidence-meter is
  deliberately absent: no call site exists yet.
- Add --clinical-chat-document to the v2 dark block so it resolves against the
  v2 dark inset; custom properties inherit computed values, so the live .dark
  declaration cannot re-resolve inside the subtree.
- answer-card.tsx: use the named leading-prose step instead of the arbitrary
  leading-[var(--leading-prose,1.65)], which tripped the design-token contract
  ('has no arbitrary leading-[...] left in production') and restated a token
  value in markup.

Verified: vitest tests/ckb-v2-token-contract.test.ts tests/design-token-contract.test.ts
-> 47 passed (47). No adopted surface exists, so there is no visual change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…st, AsyncButton type

Playbook PR 1+2 and the smallest slices of PR 3+4 (docs/design-system/SPEC.md §13):

- Cascade: light is the default on .ckb-v2 itself; dark overrides via
  .dark .ckb-v2, .ckb-v2.dark. Never :not(.dark) (DS-01) - it matched a subtree
  inside html.dark and overrode inherited dark values. Contract test's block
  parser updated in the same commit (collects both .ckb-v2 blocks and the
  grouped dark selector).
- Forced colours: v2 layer ships its own forced-colors block over all three
  selectors, last in file (C4/DS-02); roles map to system colours, elevation
  flattens to none.
- Button.danger pairs --danger-solid-contrast (DS-03; dark was 2.87:1, the
  paired token is 6.57:1 and HCM-mapped).
- AsyncButton defaults type=button so it can no longer submit a surrounding
  form (DS-04 adjacent; retirement to Button remains PR 4).

Verified: vitest ckb-v2-token-contract + design-token-contract +
ui-v2-components.dom + ui-primitives.dom -> 67 passed (67). No adopted surface
exists; no visual change ships.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sign-system-333a69

# Conflicts:
#	tests/source-metadata.test.ts
@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.

@supabase

supabase Bot commented Jul 31, 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 ↗︎.

@ecc-tools

ecc-tools Bot commented Jul 31, 2026

Copy link
Copy Markdown

🔒 Upgrade Required

Private repository analysis requires Pro or Enterprise.

Upgrade: https://ecc.tools/pricing?plan=pro


ECC Tools keeps the core app open, and puts private repos, team features, and enterprise controls behind paid tiers.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

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: 17 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: 8294979d-b499-4afe-937d-29e5c9d65330

📥 Commits

Reviewing files that changed from the base of the PR and between 7def8d9 and 02850b3.

📒 Files selected for processing (57)
  • .design-sync/NOTES.md
  • .design-sync/config.json
  • .design-sync/conventions.md
  • .design-sync/entry.tsx
  • .design-sync/previews/AnswerCard.tsx
  • .design-sync/previews/AnswerFooter.tsx
  • .design-sync/previews/AsyncButton.tsx
  • .design-sync/previews/Breadcrumb.tsx
  • .design-sync/previews/Button.tsx
  • .design-sync/previews/Chip.tsx
  • .design-sync/previews/ConfirmDialog.tsx
  • .design-sync/previews/DoseLine.tsx
  • .design-sync/previews/IconButton.tsx
  • .design-sync/previews/PageHeader.tsx
  • .design-sync/previews/Pagination.tsx
  • .design-sync/previews/SearchField.tsx
  • .design-sync/previews/Skeleton.tsx
  • .design-sync/previews/SourceDesignationBadge.tsx
  • .design-sync/previews/Tabs.tsx
  • .design-sync/previews/TextField.tsx
  • .design-sync/previews/ToastRegion.tsx
  • .design-sync/previews/Tooltip.tsx
  • docs/clinical-badge-system-guide.md
  • scripts/design-system-contract-utils.mjs
  • src/app/ckb-v2-tokens.css
  • src/app/globals.css
  • src/components/AccessibleTable.tsx
  • src/components/ui-primitives.tsx
  • src/components/ui/answer-card.tsx
  • src/components/ui/badge.tsx
  • src/components/ui/button.tsx
  • src/components/ui/card.tsx
  • src/components/ui/chip.tsx
  • src/components/ui/choice.tsx
  • src/components/ui/citation.tsx
  • src/components/ui/confirm-dialog.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/quantity.tsx
  • src/components/ui/select.tsx
  • src/components/ui/sheet.tsx
  • src/components/ui/status-mark.tsx
  • src/components/ui/tabs.tsx
  • src/components/ui/text-field.tsx
  • src/components/ui/toast.tsx
  • src/components/ui/tooltip.tsx
  • src/lib/logger.ts
  • src/lib/source-metadata.ts
  • tests/accessible-table-alignment.dom.test.tsx
  • tests/ckb-v2-token-contract.test.ts
  • tests/source-badges-off-vocab.dom.test.tsx
  • tests/source-metadata-browser-safety.test.ts
  • tests/source-metadata.test.ts
  • tests/ui-v2-components.dom.test.tsx

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

@BigSimmo
BigSimmo enabled auto-merge (squash) July 31, 2026 13:07
Comment thread src/components/ui/tooltip.tsx
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

feat(design-system): v2 opt-in token layer + 26 components, forced-colours support

✨ Enhancement 🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Adds an opt-in .ckb-v2 token layer (src/app/ckb-v2-tokens.css) with light/dark cascade and
 forced-colors.
• Ships 26 v2 UI components under src/components/ui/, plus previews and design-sync exports;
 nothing adopts them yet.
• Fixes a P1 browser crash by removing server logger coupling from source-metadata and hardening
 env reads.
• Improves AccessibleTable alignment + a11y wiring, and adds contract/DOM regression tests and
 docs.
Diagram

graph TD
  globals["globals.css"] --> tokens["ckb-v2-tokens.css"] --> components["ui/* components"]
  components --> designSync["design-sync bundle"]
  badges["Source badges"] --> sourceMeta["source-metadata.ts"] --> diagSeam["diagnostics seam"]
  logger["logger.ts"] -.->|no longer imported| sourceMeta
  components --> table["AccessibleTable"]
  subgraph Legend
    direction LR
    _file["File/Module"] ~~~ _ext([External Bundle])
  end
Loading
High-Level Assessment

The .ckb-v2 class-scoped token layer is the right approach for a design-system-only PR: it guarantees no repaint of existing surfaces while still allowing full verification via contract tests. Promoting structural tokens to :root (app-wide) is correctly deferred as a separate, higher-risk change that needs dedicated visual-regression coverage.

Files changed (57) +4165 / -129

Enhancement (22) +2616 / -16
ckb-v2-tokens.cssAdd canonical opt-in v2 token layer (light/dark + forced-colors) +332/-0

Add canonical opt-in v2 token layer (light/dark + forced-colors)

• Introduces the v2 token stylesheet, fully scoped to '.ckb-v2' to prevent unintended repaints. Includes light and dark ramps with corrected cascade selectors and a forced-colors theme mapping roles to system colours and flattening elevation.

src/app/ckb-v2-tokens.css

globals.cssShip the v2 token layer by importing it from globals +3/-0

Ship the v2 token layer by importing it from globals

• Imports './ckb-v2-tokens.css' with explicit commentary that all rules remain '.ckb-v2' scoped, ensuring zero change to existing surfaces without opt-in.

src/app/globals.css

AccessibleTable.tsxAuto/right-align numeric columns and improve a11y/low-confidence messaging +110/-16

Auto/right-align numeric columns and improve a11y/low-confidence messaging

• Adds numeric column detection + optional overrides ('columnAlign'/'numericColumns') to right-align doses and other numeric columns. Wires 'aria-controls' from the expander to the fullscreen dialog id, adds a sticky header in expanded view, and replaces low-confidence copy with a warning-styled notice.

src/components/AccessibleTable.tsx

answer-card.tsxAdd AnswerCard surface + DoseLine ledger + AnswerFooter +188/-0

Add AnswerCard surface + DoseLine ledger + AnswerFooter

• Adds the main answer surface component with reading measure and v2-token fallbacks, plus a dose ledger component emphasizing right-aligned tabular numerals and non-uppercased units. Includes footer component for provenance/version/review date display.

src/components/ui/answer-card.tsx

button.tsxAdd Button component with busy contract and danger variant +87/-0

Add Button component with busy contract and danger variant

• Adds a new Button component with size/variant mapping, folded-in busy state (spinner, aria-busy, disabled) and defaults 'type="button"'. Includes a destructive 'danger' variant tied to '--danger-solid-contrast'.

src/components/ui/button.tsx

chip.tsxAdd Chip component for filter/identity/status chips +76/-0

Add Chip component for filter/identity/status chips

• Implements a non-tap-target chip (28px) with tone variants, optional dot/icon, and an accessible per-chip remove button label when removable.

src/components/ui/chip.tsx

choice.tsxAdd Checkbox and RadioGroup components (native inputs) +192/-0

Add Checkbox and RadioGroup components (native inputs)

• Adds checkbox + radio primitives backed by native inputs for correct keyboard semantics and form participation. Includes indeterminate checkbox support and fieldset/legend for radio groups.

src/components/ui/choice.tsx

citation.tsxAdd Citation and CitationList for auditable grounded answers +134/-0

Add Citation and CitationList for auditable grounded answers

• Formalizes the citation chip (44px hit target wrapping a compact face), integrates StatusMark for source currency, and provides an accessible citation list with a governance-signaling empty state.

src/components/ui/citation.tsx

confirm-dialog.tsxAdd ConfirmDialog built on Sheet + Button with optional confirm phrase +112/-0

Add ConfirmDialog built on Sheet + Button with optional confirm phrase

• Implements a confirm dialog for destructive actions using Sheet, supporting typed confirm-phrase gating and busy state behavior without enabling stale confirmations.

src/components/ui/confirm-dialog.tsx

disclosure.tsxAdd Disclosure and DisclosureGroup with correct aria-controls wiring +140/-0

Add Disclosure and DisclosureGroup with correct aria-controls wiring

• Adds a reusable expand/collapse component that keeps panels in DOM (hidden) for find/print, with roving semantics and explicit 'aria-controls'. Provides group wrapper supporting accordion-style exclusivity.

src/components/ui/disclosure.tsx

link.tsxAdd standardized link components for internal/external/download actions +128/-0

Add standardized link components for internal/external/download actions

• Adds 'TextLink', 'ExternalTextLink', 'DownloadLink', and 'LinkAction' to enforce routing/security/a11y conventions (noopener, visible external indicator, SR-only new-tab text).

src/components/ui/link.tsx

page-header.tsxAdd PageHeader and Breadcrumb for page-level structure +110/-0

Add PageHeader and Breadcrumb for page-level structure

• Adds page-level header component owning the '<h1>' and a breadcrumb nav with current-page semantics, consistent with Next.js routing conventions.

src/components/ui/page-header.tsx

pagination.tsxAdd Pagination with truncated window and aria-current +96/-0

Add Pagination with truncated window and aria-current

• Implements pagination controls with previous/next step buttons and a compact page window, using 'aria-current="page"' for the selected page and optional summary line.

src/components/ui/pagination.tsx

progress.tsxAdd Progress bar and StageList for staged jobs +149/-0

Add Progress bar and StageList for staged jobs

• Adds determinate/indeterminate progress bar with proper 'role="progressbar"' semantics and a stage list component for multi-step workflows (with live announcements and per-stage state).

src/components/ui/progress.tsx

quantity.tsxAdd Quantity component for value+unit rendering (unit case safety) +76/-0

Add Quantity component for value+unit rendering (unit case safety)

• Standardizes number+unit rendering with tabular numerals and explicitly blocks inherited uppercase transforms on units. Supports demoted values for low-confidence extractions.

src/components/ui/quantity.tsx

select.tsxAdd native Select control with shared field shell +100/-0

Add native Select control with shared field shell

• Adds a '<select>' wrapped in the shared label/hint/error shell with a custom chevron and consistent token-based styling. Supports placeholder-as-disabled-first-option.

src/components/ui/select.tsx

sheet.tsxAllow stable dialog id for aria-controls wiring +6/-0

Allow stable dialog id for aria-controls wiring

• Adds an optional 'id' prop to Sheet so openers can point 'aria-controls' at the actual dialog element, improving assistive-tech mapping for expanders.

src/components/ui/sheet.tsx

status-mark.tsxAdd shape-encoded StatusMark for document currency +67/-0

Add shape-encoded StatusMark for document currency

• Adds a small status mark encoded by shape (not just colour) to survive forced-colors/greyscale. Intended to accompany adjacent text and stay aria-hidden to avoid double announcements.

src/components/ui/status-mark.tsx

tabs.tsxAdd Tabs with roving tabindex + keyboard navigation +135/-0

Add Tabs with roving tabindex + keyboard navigation

• Implements ARIA-compliant tabs with roving tabindex and Left/Right/Home/End navigation, plus optional tabpanel rendering and segmented/tabs visual variants.

src/components/ui/tabs.tsx

text-field.tsxAdd TextField and SearchField with hint/error aria-describedby wiring +163/-0

Add TextField and SearchField with hint/error aria-describedby wiring

• Adds field components that correctly wire hint and error nodes via ids and 'aria-describedby', support optional leading icons, and provide a SearchField with an accessible clear control.

src/components/ui/text-field.tsx

toast.tsxAdd toast system (ToastProvider/useToast/ToastRegion) with live region +152/-0

Add toast system (ToastProvider/useToast/ToastRegion) with live region

• Implements toast push/dismiss via context, tone-specific rendering, auto-dismiss timers, and a polite live region for announcing async outcomes without interrupting reading.

src/components/ui/toast.tsx

tooltip.tsxAdd accessible Tooltip (hover + focus + Escape) +60/-0

Add accessible Tooltip (hover + focus + Escape)

• Implements a tooltip that opens on hover and keyboard focus, closes on blur/Escape, and attaches via 'aria-describedby' to supplement (not replace) a control’s name.

src/components/ui/tooltip.tsx

Bug fix (3) +76 / -14
ui-primitives.tsxType badge metadata input and fix disabled/label semantics +49/-9

Type badge metadata input and fix disabled/label semantics

• Introduces 'SourceMetadataInput' to close a compile-time hole in badge metadata props. Replaces opacity-based disabled styling with encoded disabled state, updates field labels away from low-contrast '--text-soft', defaults AsyncButton to 'type="button"', and adds a deprecated 'description' alias to EmptyState’s 'body'.

src/components/ui-primitives.tsx

logger.tsMake logger safe when bundled into browser code paths +11/-3

Make logger safe when bundled into browser code paths

• Adds a defensive env accessor so 'process.env' reads do not throw when 'process' is absent or lacks an env bag. Keeps logger output suppressed during tests.

src/lib/logger.ts

source-metadata.tsIntroduce browser-safe diagnostics seam and drop server logger import +16/-2

Introduce browser-safe diagnostics seam and drop server logger import

• Removes the import of the server logger (browser 'process.env' ReferenceError) and replaces warnings with 'sourceMetadataDiagnostics.warn', which uses structured console.warn and is spyable for tests.

src/lib/source-metadata.ts

Refactor (2) +0 / -75
badge.tsxRemove unused badge component to avoid naming collisions +0/-25

Remove unused badge component to avoid naming collisions

• Deletes 'ui/badge.tsx' (no importers) to prevent collisions with new Chip/AnswerCard naming in the v2 set.

src/components/ui/badge.tsx

card.tsxRemove unused card component to avoid collisions +0/-50

Remove unused card component to avoid collisions

• Deletes 'ui/card.tsx' (no importers) to avoid confusion/collisions with the new v2 AnswerCard surface.

src/components/ui/card.tsx

Tests (6) +724 / -19
accessible-table-alignment.dom.test.tsxTest numeric column auto-alignment and expander aria-controls wiring +98/-0

Test numeric column auto-alignment and expander aria-controls wiring

• Adds DOM tests confirming numeric columns right-align (and prose columns don’t), that overrides work, and that the expander sets 'aria-controls' only when the dialog exists.

tests/accessible-table-alignment.dom.test.tsx

ckb-v2-token-contract.test.tsContract tests for v2 token relationships and opt-in scoping +218/-0

Contract tests for v2 token relationships and opt-in scoping

• Adds tests validating luminance/contrast relationships between border/surface tokens, monotonic dark ramp behavior, and that the stylesheet declares nothing outside '.ckb-v2' scopes (preventing accidental global repaint).

tests/ckb-v2-token-contract.test.ts

source-badges-off-vocab.dom.test.tsxRegression test: source badges render neutral fallbacks for off-vocab enums +72/-0

Regression test: source badges render neutral fallbacks for off-vocab enums

• Ensures SourceProvenance/SourceStatusBadge/SourceDesignationBadge render neutral fallback states rather than crashing when runtime metadata values are off-vocabulary. Verifies tracing occurs once per field.

tests/source-badges-off-vocab.dom.test.tsx

source-metadata-browser-safety.test.tsRegression test: source-metadata normalization is browser-safe +69/-0

Regression test: source-metadata normalization is browser-safe

• Adds tests asserting 'source-metadata.ts' no longer imports the server logger and that both diagnostics and logger behavior do not throw when 'process' is undefined or lacks 'env'.

tests/source-metadata-browser-safety.test.ts

source-metadata.test.tsUpdate metadata tracing assertions to use diagnostics seam +13/-19

Update metadata tracing assertions to use diagnostics seam

• Switches tests from 'logger.warn' spying to 'sourceMetadataDiagnostics.warn' and updates expected call signatures while preserving fallback behavior assertions.

tests/source-metadata.test.ts

ui-v2-components.dom.test.tsxDOM tests for new v2 components (Button/TextField/Chip/Tabs) +254/-0

DOM tests for new v2 components (Button/TextField/Chip/Tabs)

• Adds tests validating the Button busy contract and default type, TextField/SearchField described-by behavior, Chip remove button labeling, and Tabs roving tabindex + arrow-key selection changes.

tests/ui-v2-components.dom.test.tsx

Documentation (3) +132 / -1
NOTES.mdDocument the 2026-07-31 v2 design-system pass and known follow-ups +56/-0

Document the 2026-07-31 v2 design-system pass and known follow-ups

• Adds a detailed notes section describing the v2 token layer, new components, the P1 browser-crash fix, and 'AccessibleTable' improvements. Captures remaining issues that must be fixed in the design-app/sync pipeline rather than this repo.

.design-sync/NOTES.md

conventions.mdAdd v2 token-layer guidance and clarify colour boundary rules +38/-1

Add v2 token-layer guidance and clarify colour boundary rules

• Documents the three colour layers (clinical state vs information vs identity), limits on '--command' and '--danger-solid', and the opt-in '.ckb-v2' token layer usage. Adds guidance to prefer new components over ad-hoc class recipes.

.design-sync/conventions.md

clinical-badge-system-guide.mdClarify status affordances and define enum vocabularies/fallback rules +38/-0

Clarify status affordances and define enum vocabularies/fallback rules

• Adds a matrix for when to use badge/dot/pill/identity chip, and documents the three closed enum fields normalized by 'source-metadata.ts'. Specifies neutral fallback behavior and the browser-safe diagnostics seam.

docs/clinical-badge-system-guide.md

Other (21) +617 / -4
config.jsonRegister 26 component prop types, previews, and source mappings for design-sync +44/-3

Register 26 component prop types, previews, and source mappings for design-sync

• Expands 'dtsPropsFor', 'componentSrcMap', and component overrides to include the new v2 components (and formerly-orphaned primitives). Updates the exported bundle contract so consumers get accurate typings.

.design-sync/config.json

entry.tsxExport new v2 UI components through the design-sync entrypoint +15/-0

Export new v2 UI components through the design-sync entrypoint

• Adds exports for Button/TextField/SearchField/Chip/Toast/Tabs/Tooltip/Pagination/ConfirmDialog/PageHeader/Breadcrumb and AnswerCard/DoseLine/AnswerFooter. Keeps icons/export structure consistent for bundle consumers.

.design-sync/entry.tsx

AnswerCard.tsxAdd AnswerCard preview stories (design-sync) +43/-0

Add AnswerCard preview stories (design-sync)

• Provides preview coverage for AnswerCard and its typical slots so the design-sync gallery can render and validate it.

.design-sync/previews/AnswerCard.tsx

AnswerFooter.tsxAdd AnswerFooter preview stories (design-sync) +20/-0

Add AnswerFooter preview stories (design-sync)

• Adds design-sync previews for AnswerFooter variations used under AnswerCard.

.design-sync/previews/AnswerFooter.tsx

AsyncButton.tsxAdd AsyncButton preview stories (design-sync) +28/-0

Add AsyncButton preview stories (design-sync)

• Adds previews for AsyncButton’s busy contract and states so it is no longer an undocumented export.

.design-sync/previews/AsyncButton.tsx

Breadcrumb.tsxAdd Breadcrumb preview stories (design-sync) +15/-0

Add Breadcrumb preview stories (design-sync)

• Adds preview coverage for breadcrumb rendering and truncation behavior.

.design-sync/previews/Breadcrumb.tsx

Button.tsxAdd Button preview stories (design-sync) +57/-0

Add Button preview stories (design-sync)

• Adds previews for the new Button variants/sizes and busy behavior.

.design-sync/previews/Button.tsx

Chip.tsxAdd Chip preview stories (design-sync) +37/-0

Add Chip preview stories (design-sync)

• Adds previews for Chip tones, dot/icon variants, and removable chips.

.design-sync/previews/Chip.tsx

ConfirmDialog.tsxAdd ConfirmDialog preview stories (design-sync) +55/-0

Add ConfirmDialog preview stories (design-sync)

• Adds previews for primary vs destructive confirmations and typed confirm-phrase gating.

.design-sync/previews/ConfirmDialog.tsx

DoseLine.tsxAdd DoseLine preview stories (design-sync) +40/-0

Add DoseLine preview stories (design-sync)

• Adds previews for the dose ledger rows, including overdue highlighting behavior.

.design-sync/previews/DoseLine.tsx

IconButton.tsxAdd IconButton preview stories (design-sync) +16/-0

Add IconButton preview stories (design-sync)

• Adds preview coverage for IconButton so it’s documented alongside other primitives.

.design-sync/previews/IconButton.tsx

PageHeader.tsxAdd PageHeader preview stories (design-sync) +31/-0

Add PageHeader preview stories (design-sync)

• Adds previews for page-level heading composition, breadcrumb, actions, and meta slots.

.design-sync/previews/PageHeader.tsx

Pagination.tsxAdd Pagination preview stories (design-sync) +19/-0

Add Pagination preview stories (design-sync)

• Adds previews demonstrating truncated window paging behavior.

.design-sync/previews/Pagination.tsx

SearchField.tsxAdd SearchField preview stories (design-sync) +19/-0

Add SearchField preview stories (design-sync)

• Adds previews for SearchField with clear control and hint/error wiring.

.design-sync/previews/SearchField.tsx

Skeleton.tsxAdd Skeleton preview stories (design-sync) +22/-0

Add Skeleton preview stories (design-sync)

• Adds preview coverage for Skeleton so it’s no longer an undocumented export.

.design-sync/previews/Skeleton.tsx

SourceDesignationBadge.tsxAdd SourceDesignationBadge preview stories (design-sync) +21/-0

Add SourceDesignationBadge preview stories (design-sync)

• Adds preview coverage for source designation badges using the typed metadata input.

.design-sync/previews/SourceDesignationBadge.tsx

Tabs.tsxAdd Tabs preview stories (design-sync) +29/-0

Add Tabs preview stories (design-sync)

• Adds previews for tabs and segmented variants plus disabled/count states.

.design-sync/previews/Tabs.tsx

TextField.tsxAdd TextField preview stories (design-sync) +30/-0

Add TextField preview stories (design-sync)

• Adds previews for TextField with icon/hint/error wiring and label visibility options.

.design-sync/previews/TextField.tsx

ToastRegion.tsxAdd ToastRegion preview stories (design-sync) +45/-0

Add ToastRegion preview stories (design-sync)

• Adds previews for the toast live-region, tones, and interactions.

.design-sync/previews/ToastRegion.tsx

Tooltip.tsxAdd Tooltip preview stories (design-sync) +26/-0

Add Tooltip preview stories (design-sync)

• Adds previews for tooltip placement and trigger behavior.

.design-sync/previews/Tooltip.tsx

design-system-contract-utils.mjsAllow raw colour definitions in the new v2 token file +5/-1

Allow raw colour definitions in the new v2 token file

• Extends the raw-colour exemption to include 'src/app/ckb-v2-tokens.css', treating it like globals.css as the token-definition layer.

scripts/design-system-contract-utils.mjs

@BigSimmo

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 Jul 31, 2026

Copy link
Copy Markdown
Contributor

Taking a look!

Open in Web Open in Cursor 

cursoragent and others added 2 commits July 31, 2026 13:12
…sign-system-333a69

Bring in docs/design-system perfection pass (#1537). Merge-tree was clean.

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Static PR checks failed on the type-scale guard: DoseLine used
text-[0.8125rem], which is exactly --text-sm-minus. Replace with the
named step so the zero-arbitrary gate stays green.

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

ecc-tools Bot commented Jul 31, 2026

Copy link
Copy Markdown

🔒 Upgrade Required

Private repository analysis requires Pro or Enterprise.

Upgrade: https://ecc.tools/pricing?plan=pro


ECC Tools keeps the core app open, and puts private repos, team features, and enterprise controls behind paid tiers.

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📜 Skill insights (0)

Grey Divider


Action required

1. design-sync previews have inert buttons 📘 Rule violation ≡ Correctness
Description
Several .design-sync/previews/* stories render enabled buttons without onClick, submit wiring,
navigation, or the explicit disabled-placeholder accessibility pattern. This creates shipped UI
controls that advertise actions but do nothing, violating the button-wiring requirement.
Code

.design-sync/previews/Button.tsx[R4-16]

+export const Variants = () => (
+  <div className="flex flex-wrap items-center gap-2">
+    <Button variant="primary" icon={Plus}>
+      Add source
+    </Button>
+    <Button variant="secondary">Review later</Button>
+    <Button variant="toolbar" icon={Download}>
+      Export
+    </Button>
+    <Button variant="ghost">Cancel</Button>
+    <Button variant="danger" icon={Trash2}>
+      Delete source
+    </Button>
Evidence
PR Compliance ID 1 requires every interactive button to be wired or explicitly disabled with the
placeholder accessibility pattern. The previews render <Button>/<AsyncButton> instances with no
onClick/submit/navigation and not disabled, making them inert controls.

AGENTS.md: Buttons Must Be Wired or Use the Explicit Disabled-Placeholder Pattern
.design-sync/previews/Button.tsx[4-16]
.design-sync/previews/AsyncButton.tsx[6-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`.design-sync` preview stories render enabled buttons without any click handler/submit wiring/navigation and without the explicit disabled-placeholder pattern.

## Issue Context
Compliance requires every interactive `<button>` to be wired (onClick/submit/navigation) or to use the explicit disabled-placeholder accessibility pattern. The current previews show active-looking controls that do nothing.

## Fix Focus Areas
- .design-sync/previews/Button.tsx[4-57]
- .design-sync/previews/AsyncButton.tsx[4-28]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. --tap-min set to 44px 📘 Rule violation ≡ Correctness
Description
The new v2 token layer sets --tap-min to 2.75rem (44px), which is below the required 48px
minimum tap target. If adopted, this would violate the repo’s production tap-target floor contract.
Code

src/app/ckb-v2-tokens.css[R101-105]

+  /* Density - tap target is not row height */
+  --tap-min: 2.75rem; /* 44 - interactive only */
+  --chip-height: 1.75rem; /* 28 - static chips */
+  --row-comfortable: 2.75rem;
+  --row-compact: 2.25rem;
Evidence
PR Compliance ID 5 requires preserving a 48px minimum tap target in production UI. The newly added
v2 token layer explicitly defines the tap minimum as 44px (--tap-min: 2.75rem).

AGENTS.md: UI Styling Must Use Design Tokens (No Hardcoded Hex) and Preserve Production Tap Target Minimum (min-h-12)
src/app/ckb-v2-tokens.css[101-105]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The v2 token layer defines `--tap-min: 2.75rem` (44px), which conflicts with the compliance requirement that production tap targets remain at least 48px.

## Issue Context
Even though `.ckb-v2` is opt-in, this token layer is imported into `globals.css` and is intended for future adoption; it should satisfy the production tap-target minimum contract.

## Fix Focus Areas
- src/app/ckb-v2-tokens.css[101-105]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Selector contract misses groups 🐞 Bug ⚙ Maintainability
Description
tests/ckb-v2-token-contract.test.ts extracts selectors with a line-based regex that only captures
the line containing {, so it skips earlier lines in multi-line selector groups. This can allow a
future regression like :root,\n.ckb-v2 { … } to pass the test even though it would apply tokens
outside .ckb-v2.
Code

tests/ckb-v2-token-contract.test.ts[R78-82]

+    const withoutComments = stylesheet.replace(/\/\*[\s\S]*?\*\//g, "");
+    const selectors = [...withoutComments.matchAll(/^(\S[^{}\n]*)\{/gm)].map(([, selector]) => selector.trim());
+    expect(selectors.length, "no top-level selectors parsed — the matcher is broken").toBeGreaterThan(0);
+    const unscoped = selectors.filter((selector) => !selector.startsWith(".ckb-v2") && !selector.startsWith("@media"));
+    expect(unscoped).toEqual([]);
Evidence
The contract test only captures selector text from the same line as {, but the stylesheet contains
selector groups split across lines (one line ending with a comma, next line containing {). This
proves the test can skip selectors and therefore can miss an unscoped selector if it appears on a
preceding line in a grouped selector list.

tests/ckb-v2-token-contract.test.ts[74-83]
src/app/ckb-v2-tokens.css[238-242]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The `.ckb-v2` opt-in contract test is intended to fail if any top-level selector is not scoped to `.ckb-v2`, but the current selector extraction only matches lines that contain `{`. In multi-line selector groups, this means earlier selectors (lines ending with `,`) are ignored, so an unscoped selector could slip through undetected.

### Issue Context
`src/app/ckb-v2-tokens.css` already contains a multi-line selector group (`.dark .ckb-v2,` followed by `.ckb-v2.dark {`), which demonstrates that the current matcher does not “see” all selectors in a group.

### Fix Focus Areas
- tests/ckb-v2-token-contract.test.ts[74-83]

### Suggested fix
Replace the line-based regex approach with parsing that evaluates **every selector in every rule**, including comma-separated selector lists that span multiple lines.

Two practical options:
1) Use `postcss` (already in repo deps) to parse the stylesheet into an AST, recursively walk rules (including inside `@media`), and validate each rule’s `selector` list.
  - For each `rule.selector`, split into top-level selectors safely (track parentheses/brackets so commas inside functional selectors don’t split), then assert every selector contains `.ckb-v2`.
2) If you want to keep regex-only, first reconstruct the full selector prelude up to `{` across preceding lines (including those ending with `,`) and then split/validate all members—still preferably with a safe top-level comma splitter.

Also update the assertion logic so it checks for `.ckb-v2` **anywhere** in each selector (to allow `.dark .ckb-v2`), not just `startsWith('.ckb-v2')`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread .design-sync/previews/Button.tsx
Comment thread src/app/ckb-v2-tokens.css
Comment thread tests/ckb-v2-token-contract.test.ts
@BigSimmo

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.

Assess comments and only fix if you agree

@cursor

cursor Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

PR #1538 at 02850b3a — already unblocked; no further push.

  • Merge-tree clean, not behind, auto-merge still armed, 0 unresolved threads
  • Required CI: Static PR / Build / Unit / Production UI critical pass; Production UI (1–3) in progress
  • Ledger: already recorded for this head under unblock/fix PR #1538

Comment calls (no code changes):

  1. Design-sync inert buttons — disagree as blocker (design tooling, lint already green)
  2. --tap-min 44px — disagree as must-fix-now (unadopted; matches existing --spacing-tap)
  3. Selector-contract gap — agree it’s real, not a required failure → follow-up
  4. Tooltip handler overwrite — agree, unadopted → already dispositioned

Merge left to you when Production UI shards finish.

Open in Web Open in Cursor 

@BigSimmo

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 Jul 31, 2026

Copy link
Copy Markdown
Contributor

PR #1538 at 02850b3a — nothing to unblock.

  • Merge-tree clean, not behind, auto-merge armed, 0 unresolved threads
  • Ledger already recorded for this head
  • Required CI green except Production UI (1–3) still in progress
  • Stale lint failure on aae15bcf is already fixed on this tip (Static PR pass)

No push. Merge left to you.

Open in Web Open in Cursor 

- Checkbox Check icon: aria-hidden="true" (decorative; label is the name)
- StageList gutter: z-[1] → z-5 (z-index ladder)

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

ecc-tools Bot commented Jul 31, 2026

Copy link
Copy Markdown

🔒 Upgrade Required

Private repository analysis requires Pro or Enterprise.

Upgrade: https://ecc.tools/pricing?plan=pro


ECC Tools keeps the core app open, and puts private repos, team features, and enterprise controls behind paid tiers.

@ecc-tools

ecc-tools Bot commented Jul 31, 2026

Copy link
Copy Markdown

🔒 Upgrade Required

Private repository analysis requires Pro or Enterprise.

Upgrade: https://ecc.tools/pricing?plan=pro


ECC Tools keeps the core app open, and puts private repos, team features, and enterprise controls behind paid tiers.

@cursor

cursor Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Unblock summary — PR #1538

Tip: 02850b3a76732f4c922bdd1bb4599a85ec8fb47c (claude/clinical-kb-design-system-333a69)
Sync / merge-tree: up to date with origin/main (includes #1537 + #1536); git merge-tree --write-tree origin/main <tip> clean. Auto-merge remains armed (left as-is).

What blocked

  1. Static PR checks → Type scale guardDoseLine used text-[0.8125rem] (exact --text-sm-minus).
  2. After that cleared, Static PR → Lint (previously skipped) — Checkbox Check missing aria-hidden; StageList used forbidden z-[1].
  3. Branch was behind-but-clean vs main (then main advanced again with Documents: one reachable filter panel, and a library control named after what it opens #1536; tip now includes it).

What I fixed

Threads dispositioned (no code change)

  • Sentry Tooltip handler overwrite — valid, but component is unadopted; not a required-CI/mergeability blocker. Resolved no-change (inline reply forbidden for this identity).
  • Qodo ×3 (design-sync preview inert buttons; --tap-min 44px; selector-contract grouping) — advisory / design-scratch or intentional v2 token choices; Static PR + design-system contract already green on tip. Resolved. Follow-ups can land in later playbook tranches.

Required CI on this tip

  • Static PR checks: pass
  • Build / Safety / Change scope / PR policy / mergeability / SAST / secrets: pass
  • Unit coverage / Production UI critical: in progress
  • Advisory Lighthouse / visual baselines: in progress (ignored unless they reveal a required failure)

Residual risks

  • Ledger row for this unblock tip is recorded locally under scope unblock/fix PR #1538 and not pushed (no ledger-only tip).
  • Tooltip handler composition still owed when Tooltip is adopted.
  • Qodo --tap-min: 44px note: do not regress production taps to min-h-11 (known ui-smoke flake); v2 token layer remains unadopted.

Merge left to you.

@cursor

cursor Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Unblock re-check — PR #1538 (stop)

Tip: 02850b3a76732f4c922bdd1bb4599a85ec8fb47c
Sync / merge-tree: up to date with origin/main · merge-tree clean · ahead 8 / behind 0
Auto-merge: still armed (untouched)
Ledger: ALREADY REVIEWED at this HEAD under unblock/fix PR #1538 — no repeat unblock pass.

Required CI on tip

Check Status
Static PR checks pass
Build pass
Unit coverage pass
Production UI critical pass
Production UI (1)(2)(3) in progress
Advisory Lighthouse in progress (ignored)

No required-CI or mergeability blocker on this tip. No push (would only cancel in-flight Production UI).

Comment assessment (fix only if I agree + would block)

  1. Qodo — design-sync inert preview buttonsDisagree as a merge/CI blocker. .design-sync/previews/* are design-tooling stories, not production UI. Button-wiring lint already passed Static PR; mockup/design-scratch surfaces are the documented exemption class (eslint.config.mjs mockup ignores; AGENTS mockup exemption). Previews advertising inert controls is expected for a catalog. No code change.

  2. Qodo — --tap-min: 2.75rem (44px)Disagree as must-fix-now. Production floor remains min-h-12 (48px). The v2 layer is unadopted (zero product importers). 2.75rem also matches existing --spacing-tap in globals.css. Changing the token mid-flight would cancel green/in-progress required CI for a non-adopted surface. Follow-up when adopting .ckb-v2 into production controls: align --tap-min to the 48px floor or keep production controls on min-h-12 explicitly (do not regress production to min-h-11).

  3. Qodo — selector contract misses multi-line groupsAgree the gap is real (maintainability), not a required failure. Contract + Static PR are green on tip; hardening the parser is a follow-up, not an unblock push.

  4. Sentry — Tooltip cloneElement overwrites child handlersAgree it’s real; component is unadopted. Already resolved no-change on prior pass. Compose handlers when Tooltip is adopted.

Residual

  • Unresolved thread count: 0
  • Prior tip fixes still on branch: type-scale text-sm-minus; lint aria-hidden + z-5
  • Local ledger WIP only (not pushed)

Merge left to you once Production UI shards finish.

@cursor

cursor Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Unblock status — PR #1538 (no action)

Tip: 02850b3a76732f4c922bdd1bb4599a85ec8fb47c
Sync / merge-tree: up to date with origin/main · merge-tree clean · ahead 8 / behind 0
Auto-merge: armed (untouched)
Ledger: ALREADY REVIEWED at this HEAD for unblock/fix PR #1538

Required CI on this tip

  • Static PR / Build / Unit / Production UI critical / Safety / Change scope / PR policy / mergeability: pass
  • Production UI (1)(2)(3): in progress
  • Advisory Lighthouse: in progress (ignored)

Threads

0 unresolved (Sentry Tooltip + 3 Qodo advisories previously dispositioned no-change).

Note on stale failure context

The lint failure reported against aae15bcf (z-[1] / missing aria-hidden on Checkbox Check) is not on the current tip — fixed in d4d8429b; Static PR is green on 02850b3a.

No push (would cancel in-flight Production UI with no remaining required blocker). Merge left to you.

@BigSimmo
BigSimmo merged commit 0dcb137 into main Jul 31, 2026
26 checks passed
@BigSimmo
BigSimmo deleted the claude/clinical-kb-design-system-333a69 branch July 31, 2026 13:46
BigSimmo added a commit that referenced this pull request Jul 31, 2026
…hygiene PR) (#1541)

* fix(design-system): critique fixes — fallback literals, test precision, HCM backdrop, allowlist

- Strip literal var() fallback values from the v2 components (20 sites, 5
  files) - the last value-restatement channel. The one surviving fallback is
  role-to-role (var(--e2, var(--shadow-soft))), which restates no value.
- Contract test parses the structural and light .ckb-v2 blocks separately, so
  a token declared in the wrong block now fails instead of passing merged.
- Forced-colours --overlay-backdrop is transparent, not opaque Canvas - HCM
  users rely on borders for layer separation.
- Remove the six docs-link allowlist entries whose files landed with #1538,
  per their own remove-after-merge note.

Verified: vitest 5 files -> 70 passed (70); docs:check-links 1517 resolve.

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

* docs(design-system): post-merge truth sweep - rolling status, dark-declaration rule

SHAs now pinned only in DECISIONS' resolution log; SPEC/TOKENS/GATES/README
state rolling status (merged via #1538). Playbook rows PR 1/2 done, PR 3/4
partial. TOKENS fall-through section replaced with the standing rule: a colour
role added to the light block is added to the dark block in the same commit
(ink contract-enforced). Resolution log gains the dark-ink bug record and this
hygiene pass.

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

* fix(design-system): close DoseLine calc() and playbook status drift

Sentry Bugbot correctly flagged DoseLine's left-padding arbitrary value:
pl-[calc(...)] was missing the calc() closer, so browsers dropped the
declaration and dose text could sit under the inset rule.

Also finish the truth-sweep playbook rows this PR claimed: PR 1 done
(#1538), PR 2 partial (HCM block landed; computed assertions still open).

Co-Authored-By: Cursor <cursoragent@cursor.com>

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@cursor cursor Bot mentioned this pull request Jul 31, 2026
10 tasks
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