Skip to content

feat(design-system): close gate 2's h-10 case with a ratcheted static check (#265) - #1984

Merged
BigSimmo merged 8 commits into
mainfrom
claude/ds-gates-265
Aug 15, 2026
Merged

feat(design-system): close gate 2's h-10 case with a ratcheted static check (#265)#1984
BigSimmo merged 8 commits into
mainfrom
claude/ds-gates-265

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Summary

Gate 2 named two gaps: the rendered interactive enumeration, and fixed-height h-10 controls. The first landed on main as 885c613 (PR #1962) — the deterministic phone-viewport min-h-tap audit on /forms. This PR closes the second, and corrects three figures that were costing readers time.

  • New interactiveTapFloorDeclarations metric in check:design-system-contract: an interactive element (a, button, input, select, summary, textarea) that declares its own unprefixed min-h-* below the 48px token. Ratcheted at 41 across 17 files with per-path pins, so a new sub-floor control anywhere in src/** fails today on both the total and its own path.
  • Mutation-verified rather than assumed. Lowering one shortlist button to min-h-9 produced exactly:
- interactiveTapFloorDeclarations increased from 41 to 42
- interactiveTapFloorDeclarations at src/components/services/services-navigator-page.tsx increased from 0 to 1

Worth reporting: an earlier mutation attempt targeted a <Link> and did not trip the check. That is how the component-wrapper blind spot got found and documented rather than shipped unnoticed — the walker sees intrinsic lowercase tags only, and the pre-existing legacyTapClasses check has the same hole.

  • Scoped to min-h-*, deliberately not h-*/size-*. A short h-4 on an interactive element is routinely the visible box of a control whose hit area belongs to a tap-sized wrapper — SelectionCheckbox in differentials-home.tsx is exactly that, and ui-smoke asserts its label still meets the floor. Flagging those would pad the baseline with non-defects, which GATES.md §5 names as how a gate ends up switched off. A first measurement including h-*/size-* returned 48 findings; the principled min-h-* rule returns 41, and I spot-checked the flagged sites (a 24px "show more tags" button, a 40px calculator reset with no responsive release) to confirm they are genuine.
  • Unit coverage for the detector including the negative cases: the repo's correct min-h-12 sm:min-h-10 release must not be flagged, and neither must a short height on a non-interactive element.

Corrections landed alongside:

  • Gate 8's evidence cell said "27 conflicts across 15 files". The baseline records 25 across 12, and GATES.md §3 already said 25 — PR Re-land the --shadow-tight retirement and close three design-token debt rows #1942 paid three files down without updating the prose. Per docs/design-system/README.md's source ranking the baseline outranks the document, so the prose was the defect. Ledger #265 carried the same stale figure and is corrected too.
  • legacyShadowAliases was pinned at 119 while measuring 118 on clean origin/main. Verified by running the checker against an unmodified tree while working #163. Tightened to the measured value, closing one unit of stale ratchet slack.
  • Gate 4's Status cell still read implemented-partial although its own evidence cell and the §3 row both declared it closed on 9 Aug.

What is deliberately NOT in this PR

Gate 8 is not closed, and the reason is worth reading before someone assumes it was skipped for time. I inspected all 25 conflict sites. They are not 25 mechanical one-line edits:

  • The large majority are focus:ring-4 focus indicators co-existing with a border on inputs, selects and textareas (master-search-header 5, formulation-builder 3, plus singles across formulation-compare, dashboard-nav, favourites, specifiers, DocumentTagCloud, ui-primitives). Retiring those means restyling focus from ring to outline across roughly 17 controls — an accessibility-visible change that needs focus-state proof in a browser.
  • Only pwa-lifecycle's shared cardClassName (border + a persistent ring-1 ring-[color:var(--ring-glass)]) is the decorative double edge the rule was written for, and that is one recipe counted five times.
  • Three further constraints: this container cannot run Chromium (ships chromium-1194 against a pinned 1234, #255/#312), so that proof was unavailable; 8 of the 25 sit in files that open PRs Polish the responsive PWA install lifecycle #1976, feat(services): progressive referral rail and compact result rows (#163) #1982 and feat(favourites): search-led workspace, no ModeHome (#164) #1983 are currently editing; and pinning at zero without first widening the onePixelShadowSpreads property filter would be a partly false close — design-system-contract-utils.mjs matches --e[0-4] and --shadow-* but not --glow-primary, --glow-soft or --ring-hairline, all of which carry 0 0 0 1px.

Gate 7 is untouched, as its own scope note in #265 describes. All of this is recorded in the ledger update so the next session starts from the finding rather than re-deriving it.

Verification

  • npm run verify:pr-local
 Test Files  607 passed (607)
      Tests  6585 passed | 4 skipped (6589)

PR-local verification summary:
- completed: check:runtime, check:installed-lock-parity, format:changed, sitemap:check, docs:check-index, docs:check-inventory, docs:check-scripts, docs:check-links, check:branch-review-ledger, check:outstanding-issues, check:ledger-write-discipline, lint, typecheck, test, check:rag:fixtures, check:medication-interactions, check:medication-lexicon-report
- failed: (none)
- not reached: (none)
Design-system contract passed (734 production files; raw colors 2; literal shadows 0; legacy tap classes 0; sub-floor interactive min-heights 41; edge conflicts 25; 1px shadow spreads 2).

Gate-manifest OK: all 35 verify:cheap gates are enforced in CI (static-pr + mapped jobs), and the 32 static gates are documented consistently.

Every other metric was asserted unchanged before the baseline was rewritten, per the GATES.md §5 discipline. The only two deltas were the new metric (41) and the legacyShadowAliases tightening (119 → 118) described above.

UI verification not run, and no browser gate is claimed: check:playwright-browser-revision fails closed here (chromium-1194 vs pinned 1234), and pointing PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH at the stale shell is forbidden by AGENTS.md. This PR adds no rendered UI — the change is a static analyzer, its baseline, its unit tests, and documentation — so the static gates above are the correct and sufficient coverage for it.

Risk and rollout

  • Risk: low, and it is contained to CI strictness rather than product behaviour. The realistic failure mode is a false positive blocking an unrelated PR; the scoping decision above (min-h-* only) exists precisely to avoid that, and the negative-case unit tests pin it. The opposite risk — a false negative — is real and documented: component-wrapper tags are invisible to the walker.
  • Rollback: two commits, revertable together. Reverting restores the previous baseline and removes the metric; nothing depends on it.
  • Provider or production effects: None. No product code, no runtime behaviour, no provider call.

Notes

  • `RAG impact: no retrieval behaviour change — this PR touches a design-system static analyzer, its baseline, its unit tests and documentation. No retrieval, ranking, selection, chunking, scoring, or answer-path file is involved.
  • #293 is resolved and needs no action here: 885c613 is on main, and PR docs(issues): close #293 and #312 — confirmed merged on main #1977 is already open to close that row. I deliberately did not queue a second close for it.

Generated by Claude Code

claude added 2 commits August 15, 2026 07:57
… check (#265)

Gate 2 named two gaps: the rendered interactive enumeration, and fixed-height
`h-10` controls. The first landed on main as 885c613 (PR #1962) — the
deterministic phone-viewport min-h-tap audit on /forms. This closes the second.

- New `interactiveTapFloorDeclarations` metric in check:design-system-contract:
  an interactive element (a, button, input, select, summary, textarea) that
  declares its OWN unprefixed `min-h-*` below the 48px token. Ratcheted at 41
  across 17 files with per-path pins, so a new sub-floor control anywhere in
  src/** fails today on both the total and its own path.
- Mutation-verified rather than assumed. Lowering one shortlist button to
  min-h-9 produced exactly:
    interactiveTapFloorDeclarations increased from 41 to 42
    interactiveTapFloorDeclarations at src/components/services/services-navigator-page.tsx increased from 0 to 1
  An earlier mutation attempt on a <Link> did NOT trip it, which is how the
  component-wrapper blind spot below was found rather than shipped unnoticed.
- Scoped to min-h-* and deliberately not h-*/size-*. A short h-4 on an
  interactive element is routinely the visible box of a control whose hit area
  belongs to a tap-sized wrapper — SelectionCheckbox in differentials-home.tsx
  is exactly that, and ui-smoke asserts its label still meets the floor.
  Flagging those would pad the baseline with non-defects, which GATES.md §5
  names as how a gate ends up switched off. A first measurement including
  h-*/size-* returned 48 findings; the principled min-h-* rule returns 41.
- Unit coverage for the detector, including the negative cases: the repo's
  correct `min-h-12 sm:min-h-10` responsive release must not be flagged, and
  neither must a short height on a non-interactive element.

Corrections landed alongside, all of which cost a reader time:

- Gate 8's evidence cell said "27 conflicts across 15 files". The baseline says
  25 across 12 and GATES.md §3 already said 25; PR #1942 paid three files down
  without updating this prose. Per docs/design-system/README.md the baseline
  outranks the document, so the prose was the defect.
- legacyShadowAliases was pinned at 119 while measuring 118 on clean main —
  one unit of stale slack, found while working #163 and tightened here.
- Gate 4's Status cell still read implemented-partial although its own evidence
  cell and the §3 row both declared it closed on 9 Aug.

Gate 8 is NOT closed here and the reason is recorded in the ledger: its 25
conflicts are mostly focus:ring-4 indicators co-existing with a border, not the
decorative double edges the rule was written for, so retiring them is a focus
restyle across ~17 controls needing browser proof this container cannot produce.
Gate 7 is untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYphQZmsBBeqnidpSnAtjE
- Branch review record for 6de09c4.
- issues:update (not done — #265 is only part-closed): gate 2 closed, gates 7
  and 8 still open, with the stale 27/15 and 10-rows figures corrected and the
  gate-8 stop reason recorded in enough detail to pick up cold.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYphQZmsBBeqnidpSnAtjE
@coderabbitai

coderabbitai Bot commented Aug 15, 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: 15 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: 6bc54f49-b1d4-44c2-b01a-508404f982b5

📥 Commits

Reviewing files that changed from the base of the PR and between 261ef46 and da38d9f.

📒 Files selected for processing (8)
  • docs/branch-review-records/f11604766bd32807910a04f2bc52664b0d8615e08db6094e54733085c7427d0c.record.md
  • docs/branch-review-records/f1fda63bd3854860481ab01a098aff859e2c8d4ea54160fe52e351afd389f9de.record.md
  • docs/design-system/GATES.md
  • docs/outstanding-issues-inbox/8c133c4e-23e7-427f-b1b8-6d6a64dfd381.json
  • scripts/check-design-system-contract.mjs
  • scripts/design-system-contract-baseline.json
  • scripts/design-system-contract-utils.mjs
  • tests/design-system-contract-utils.test.ts

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

@supabase

supabase Bot commented Aug 15, 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 ↗︎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ddde893032

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/design-system-contract-utils.mjs Outdated
Comment thread scripts/design-system-contract-utils.mjs Outdated
@BigSimmo
BigSimmo enabled auto-merge (squash) August 15, 2026 12:55
@BigSimmo
BigSimmo merged commit e8c035b into main Aug 15, 2026
24 checks passed
@BigSimmo
BigSimmo deleted the claude/ds-gates-265 branch August 15, 2026 13:34

Copy link
Copy Markdown
Owner Author

Codex review-and-fix summary

  • Final state: merged externally by the PR's pre-existing auto-merge workflow.
  • Final reviewed head: da38d9f83b1f2203ed96d966ab7eea49f792a4ab
  • Base at merge: 261ef4665af53b58e1ce040b9f93b9f5e56ca0ae
  • Merge commit: e8c035bb5d014dabfc84123883bba35d08997033
  • Branch update / merge tree: the latest base was merged into the PR branch; the final head contains the reviewed fixes, is current with that base, and has a clean merge tree.
  • Issues fixed: two P2 static-gate bypasses were corrected: comparable arbitrary minimum heights such as min-h-[42px] are now measured, and reachable conditional/composed class alternatives are evaluated independently so a safe branch cannot hide a sub-floor runtime path.
  • Adversarial review: the independent GitHub Codex review produced both confirmed findings. Each was reproduced, fixed narrowly, covered by regression tests, replied to with the fixed head, and resolved. No actionable thread remains.
  • Decisive offline checks: focused detector Vitest 36/36; design-system contract; design-system adoption/sync checks; source typecheck; changed-file ESLint; Prettier; gate manifest; branch-review-ledger and outstanding-issues guards.
  • Exact-head CI: required CI completed successfully; advisory SAST and Secret Scan also completed successfully. No pending or failed exact-head checks remain.
  • Residual finding: the exact final head measures 40 sub-floor declarations while its baseline/documentation remains at 43. The stronger parser removed three old false-positive counts from calculators/search-page.tsx, so the merged baseline permits three units of stale slack. A focused local correction was verified (check:design-system-contract and 36/36 tests) but could not be published after the PR merged; it requires a follow-up change.
  • Blockers: none to the already-completed merge; the residual ratchet slack above remains actionable follow-up risk.

Codex did not merge or modify auto-merge. The existing merge workflow completed the PR.

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