Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
8731a2b
perf(desktop): speed up Windows update installation (#6169)
StiensWout Aug 14, 2026
4905a5a
fix(web): style sidebar action tooltips (#6371)
t3-code[bot] Aug 14, 2026
c0848ae
refactor(web): simplify global styling (#6381)
t3-code[bot] Aug 14, 2026
ab8fefa
fix(server): handle files named HEAD in git status (#6397)
Lucenx9 Aug 14, 2026
68aa831
fix(web): bound OKLCH gamut mapping (#6485)
Lucenx9 Aug 14, 2026
8de01a3
feat(web): open remote environments in your local editor over SSH (#6…
t3dotgg Aug 15, 2026
c1571b1
feat(web): older chat timestamps show the date, not just the time (#6…
t3dotgg Aug 15, 2026
0c42a64
fix(web): align pull request action menu rows (#6534)
Bil0000 Aug 15, 2026
f683c8f
fix(web): restore selected themes in dark mode (#6665)
StiensWout Aug 15, 2026
e4fbc5f
fix(web): improve Codex usage graph contrast (#6669)
StiensWout Aug 15, 2026
97096ff
fix(desktop): app zoom no longer zooms the preview browser (#6649)
rynfar Aug 15, 2026
0ab6714
fix(server): keep provider notification consumers alive past startSes…
btsouth Aug 15, 2026
db13d8e
fix(server): treat removed Bitbucket permissions endpoint as unknown,…
lnieuwenhuis Aug 15, 2026
1de4a1a
fix(ssh): let cold remote servers finish starting (#6168)
gbarros-dev Aug 15, 2026
aef3745
fix(web): preserve Claude insight line breaks (#4344)
nateEc Aug 15, 2026
93cca34
feat(web): accept file drops across the chat workspace (#6636)
dbalders Aug 15, 2026
1c0ecdb
fix(web): widen ordered-list marker gutter for 3+ digit item numbers …
lnieuwenhuis Aug 15, 2026
880d747
fix(server): bound thread activity hydration (#6153)
t3-code[bot] Aug 15, 2026
970a715
fix(web): restore the Archive action in the default sidebar thread me…
lnieuwenhuis Aug 15, 2026
3c2012a
fix(web): open diff files from nested projects (#6174)
gbarros-dev Aug 15, 2026
3841ce6
fix(mobile): use tryOpenExternalUrl for markdown links in ThreadFeed …
mohamedmastouri-hue Aug 15, 2026
12ed7c0
fix(web): open the file a bare filename reference names (#6297)
Brechard Aug 15, 2026
7b638b8
fix(server): stop the provider title mirror from overwriting real thr…
repparw Aug 15, 2026
1c5b7b6
fix(shared): match source-control providers by DNS label (#6175)
gbarros-dev Aug 15, 2026
420d1ea
feat(desktop): Chrome-style hold-to-quit (#5508)
Bil0000 Aug 15, 2026
194b406
fix(gitlab): submit review comments on context lines (#6348)
tarik02 Aug 15, 2026
25dd630
fix(mobile): recover the QR pairing scanner when camera access is den…
hey-jj Aug 15, 2026
99782f2
fix(web): keep a long path from running under the folder picker butto…
Sy-D Aug 15, 2026
61bdade
fix(terminal): right-click paste works in the terminal (#5240)
StiensWout Aug 15, 2026
842493a
fix(mobile): explain iOS-only settings on Android (#4981)
danvernon Aug 15, 2026
6fdb74f
fix(web): stop counting a workflow coordinator as a working agent (#6…
Rishet11 Aug 15, 2026
461796f
fix(web): keep floating preview anchored after panel closes (#6547)
AksharP5 Aug 15, 2026
7ba5cf2
fix(web): unstick /connect after in-modal sign-in by redirecting to t…
TorbenWetter Aug 15, 2026
dbd68fa
fix(web): keep send reachable while a turn is running on mobile (#4781)
AMohamedAakhil Aug 15, 2026
0429bb3
fix(web): reject unsupported composer image types at attach time (#6574)
mdshzb04 Aug 15, 2026
43c1fee
Make ClaudeTextGeneration tests hermetic on Windows (#4508)
mihneaptu Aug 15, 2026
09d9d14
fix(web): show command output in work log (#4083)
LikoKiko Aug 15, 2026
9dabd9b
fix(web): reserve sibling column width when resizing the right panel …
Lasdw6 Aug 15, 2026
b38989c
fix(web): replace whitespace in new ref names with dashes (#6270)
jorj-pineda Aug 15, 2026
e259199
fix(client-runtime): branch list no longer resets while paging throug…
a20hek Aug 15, 2026
c0675be
fix(web): support Shift+Insert terminal paste (#5982)
aoright Aug 15, 2026
5826748
fix(web): keep the composer glass aligned with the context strip at a…
Williawar Aug 15, 2026
7297a1a
fix(codex): keep background memory out of chats (#5468)
AksharP5 Aug 15, 2026
8b849a5
fix(server): treat a missing Codex rollout as a recoverable resume er…
Rishet11 Aug 15, 2026
855218d
fix(web): hide provider Update toast action while an update is runnin…
mrmg Aug 15, 2026
7a243f5
fix(desktop): agent shells inherit a UTF-8 locale on macOS (#6236)
Linus-Boehm Aug 15, 2026
4074fcb
fix(server): ignore Claude command lifecycle messages (#6606)
naveed949 Aug 15, 2026
46e63e0
docs: mention Bitbucket user read scope needed by auth probe (#6291)
thamrx Aug 15, 2026
aff4b54
fix(server): return valid preview action results (#5966)
duncan-vc Aug 15, 2026
94c184e
fix(claude): make "Always allow for session" stick, and only for the …
kakismash Aug 15, 2026
b218bc5
fix(ssh): surface a failed remote t3 install instead of a silent 0-by…
TorbenWetter Aug 15, 2026
12d3ea7
perf(server): persist the wire projection for streaming tool.updated …
mInrOz Aug 15, 2026
028300c
fix(web): stop wrapping partial code block selections in markdown fen…
JoeJoeflyn Aug 15, 2026
ff5a50c
fix(web): hide T3 Connect toggle in web app settings (#5068)
JoeJoeflyn Aug 15, 2026
d793a1f
fix(web): show provider account accent badge in sidebar rows and hove…
vitalyiegorov Aug 15, 2026
0d4f5d8
fix(server): wait for concurrent SQLite writers instead of failing wi…
ostapondo Aug 15, 2026
2f5c368
fix(web): reject oversized prompts before provider turn start (#6602)
naveed949 Aug 15, 2026
ed0e067
feat(web): collapse the question prompt from its header (#6773)
Jardo-51 Aug 15, 2026
aa830a5
fix(shared): degrade an unknown system time zone to UTC in usage wind…
Rishet11 Aug 15, 2026
f91fd94
fix(claude): discover repo-local .agents/skills in skill discovery (#…
RoshanMhatre Aug 15, 2026
9341c8e
fix(server): let slow provider CLIs raise their discovery probe budge…
CDVolvik Aug 15, 2026
44c2542
fix(web): retain terminal PR badges after checkout switch (#4755)
sebbonit Aug 15, 2026
b40775f
fix(web): show selected model in context window tooltip (#4772)
nqrwhal Aug 15, 2026
684d105
fix(web): scale command details with code font (#6510)
Serendeep Aug 15, 2026
7ff4f85
fix(web): preserve XML-like tags in user messages (#4133)
0utsights Aug 15, 2026
7e1f689
fix(desktop): route mouse thumb buttons to the in-app browser (#4459)
akosbalogh Aug 15, 2026
0fce713
fix(web): keep the final segment of directory paths with a trailing s…
jorvarea Aug 15, 2026
412e803
Keep block code plain when copying from rendered markdown (#4468)
yashranaway Aug 15, 2026
289438f
fix(web): add web app manifest so installed app keeps its scope (#4306)
Albro3459 Aug 15, 2026
162c6a9
Skip user hooks during Claude capability probes (#4466)
yashranaway Aug 15, 2026
c6600df
fix(mobile): use Android monospace font family (#4609)
tastelessjolt Aug 15, 2026
7dcd8b8
fix(desktop): timestamps follow the OS locale instead of en-US (#6190)
brzzdev Aug 15, 2026
c0ebb61
fix(web): keep multi-select questions open after the first click (#6646)
RaitP1 Aug 15, 2026
462e7b5
fix(web): stop clipping the changed-files expand hover on Windows (#6…
mrmg Aug 15, 2026
2e0cddb
fix(server): allow long-running git pushes (#6499)
devchaudhary24k Aug 15, 2026
fa92f9a
fix(desktop): keep probing backend readiness while the process is ali…
lgwacker Aug 15, 2026
af4ebf3
fix(server): allow install scripts in npm-global provider updates (#5…
hey-jj Aug 15, 2026
8bc136c
fix: detect SSH remotes with non-git user prefixes (e.g. gitlab@) (#3…
JackatDJL Aug 15, 2026
6372eec
fix(web): describe what Ultracode does in the Reasoning picker (#6092)
delltrak Aug 15, 2026
f77d83a
fix(server): settle pending user-input requests when a Claude session…
AaronAbuUsama Aug 15, 2026
bc496d3
fix(server): stop replaying a command receipt for a different aggrega…
ostapondo Aug 15, 2026
1079676
fix(server): settle snoozed threads immediately (#5379)
0bkevin Aug 15, 2026
eaa40a2
fix(mobile): local-checkout threads record their branch so PR badges …
Zeus-Deus Aug 15, 2026
af14fc4
fix(web): contain long approval commands (#6503)
Serendeep Aug 15, 2026
68e49ad
feat(web): make right panel maximize bindable (#5091)
husseinraoouf Aug 15, 2026
ca7aa68
fix(server): respect inherited OPENCODE_CONFIG_CONTENT (#4242)
jonocodes Aug 15, 2026
f17ddd7
fix(marketing): detect Mac chip on homepage download button (#4197)
mahdibm-dev Aug 15, 2026
8d7e16c
Keep the server alive when a response write hits a dead socket (#4470)
yashranaway Aug 15, 2026
2e30513
Limit physical key fallback to non-Latin layout output (#4469)
yashranaway Aug 15, 2026
bfd2630
fix(clients): default clone destination to folder plus repo name (#5989)
inayayousfi Aug 15, 2026
e5b6745
fix(web): keep timestamp date and time in the same locale (#7081)
juliusmarminge Aug 15, 2026
dc7fcfa
feat(desktop): add signal macOS DMG installer background (#6201)
Brechard Aug 15, 2026
0a37db7
feat(web): send PR line requests to agent (#6597)
Bil0000 Aug 15, 2026
70fd3fa
chore(branding): keep adopted upstream work Pylon-first
rynfar Aug 15, 2026
46abbcf
fix(web): repair three conflict resolutions from the upstream batch
rynfar Aug 15, 2026
d502708
fix(deps): restore the lockfile entries the batch needs
rynfar Aug 15, 2026
9988487
chore: keep the UI-consistency review agent, drop upstream PR screens…
rynfar Aug 15, 2026
f24578f
docs(upstream): record the 2026-08-15 batch and advance the cursor
rynfar Aug 15, 2026
fccc704
test(web): cover the queue-follow-up branch of the running composer
rynfar Aug 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
104 changes: 102 additions & 2 deletions .agents/upstream-review.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
remote: t3code-upstream
branch: main
reviewed-through: "1add47b322ab1dfb5010bb363613650176b88088"
reviewed-through-date: "2026-08-14"
reviewed-through: "a5e29edeec34fdfab1d44e643b0d12bb924fd261"
reviewed-through-date: "2026-08-15"
---

# T3 upstream review log
Expand Down Expand Up @@ -1132,6 +1132,106 @@ identical to upstream, which rules out patch divergence as the cause.

Deferred register: unchanged and still empty.

## 2026-08-15 (full batch) — `1add47b322ab1dfb5010bb363613650176b88088..a5e29edeec34fdfab1d44e643b0d12bb924fd261`

One hundred upstream commits. `277a7cb44` / `#4899` was already adopted out of band
earlier the same day (the targeted review above), leaving 99 candidates. **93 adopted**
onto `upstream/2026-08-15-batch`, **6 skipped**. The developer's decision was "everything
except Tier C, Pylon branding wins any conflict", so the table below records the two
Pylon-first departures from a mechanical adoption rather than a per-commit list.

This is the largest batch adopted so far and it is overwhelmingly repair: **86 of the 99
candidates are `fix`**. Upstream spent the day merging its backlog of old community pull
requests, which is why so many #4xxx/#5xxx numbers land at once.

Grouped decisions, by area rather than by commit — every candidate not named as skipped
was adopted:

- **Server and orchestration (12)** — bounded thread activity hydration, the wire
projection for streaming `tool.updated`, the provider title mirror no longer clobbering
real titles, receipt replay scoped to its own aggregate, snoozed threads settling
immediately, SQLite `busy_timeout` instead of `SQLITE_BUSY`, surviving a write to a dead
socket, valid MCP preview results, a raisable discovery probe budget, install scripts in
npm-global provider updates, long-running git pushes, and files named `HEAD`.
- **Providers (11)** — six Claude fixes (session-scoped "Always allow", pending user-input
settling on stop, command lifecycle messages ignored, hooks skipped during capability
probes, repo-local `.agents/skills` discovery, hermetic Windows tests), two Codex, one
spanning Codex/Cursor/Grok, OpenCode config inheritance, and the Ultracode description.
- **Web (38)** — the global styling refactor, panels, sidebar, theme, markdown, transcript,
and eight composer fixes.
- **Desktop (7)**, **mobile (5)**, **source control and pull requests (7)**, **SSH (2)**,
**terminal (2)**, **marketing (1)**, **shared (1)**.

Four Pylon-authored commits close the batch: `70fd3fa2b` rebrands what the batch dragged
in, `46abbcf18` repairs three conflict resolutions, `d50270899` restores the lockfile, and
`998848720` corrects two keep/drop calls.

**The lockfile nearly shipped broken.** Resolving the styling-refactor conflict reverted
`pnpm-lock.yaml` to its `origin/pylon` state, silently undoing what the Windows
update-install pick had added one commit earlier. The branch was then requiring
`msgpackr-extract` and `@electron/asar` without locking either, and recording the _old_
`@ff-labs/fff-node` patch hash against the _new_ patch file — the one that fixes asar
unpacking. `@t3tools/scripts` failed to typecheck and all 53 of its tests failed to load.
Regenerated with Pylon's pinned pnpm in `d50270899`. **Whenever a conflict resolution runs
`git add -A`, check `pnpm-lock.yaml` separately.**

**Watch item for the next batch:** upstream `e58cbb9e7` / `#6663` amends `#6665`, which
this batch adopted, tightening the theme selector to
`html[data-theme-id]:not([data-theme-id=""])`. It sits just past this cursor. No Pylon code
path was found that sets `data-theme-id` to the empty string, so this is drift-closing
rather than a known defect.

| Change set | Upstream | Decision | Pylon reference | Rationale or revisit condition |
| ---------- | ----------------------------------- | -------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| G1 | `d7abd7f3b` + `804cba430` / `#6657` | skipped | `—` | A feature and its own revert, both inside this range. Verified they cancel exactly (`git diff d7abd7f3b^ 804cba430` is empty), so adopting the pair is 32 conflicting files for a net no-op. |
| G2 | `e25021af7` / `#4128` | skipped | `—` | AUR packaging: `t3code-bin` / `t3code-nightly-bin` PKGBUILDs pointing at `pingdotgg/t3code` releases, plus a publish workflow needing T3's AUR SSH secrets. Entirely T3 distribution infrastructure. Revisit only as a Pylon-owned `pylon-bin`. |
| G3 | `e9ae134c5` | skipped | `—` | Routes feature requests to `pingdotgg/t3code` Discussions. T3 repository governance; Pylon's README and CONTRIBUTING are its own. |
| G4 | `2fc676239` / `#3929` | skipped | `—` | Strips a stray newline from the `CLAUDE.md` symlink target. Pylon's symlink is already 9 bytes (`AGENTS.md`, no trailing newline), so this is already true here. |
| G5 | `db3278f97` / `#4542` | skipped | `—` | **Pylon already fixed this.** Upstream lifts the mobile hero's Grok mark clear of the headline by moving it to `top: 44px` centred; Pylon did the same thing independently in `ad1693bb3` at `top: 150px` left-aligned, tuned against Pylon's own resized hero (`b732d74ed`). Taking upstream's coordinates would apply T3's geometry to different artwork. The cherry-pick reduced to empty and was dropped. |
| G6 | `ad117235b` (partial) / `#6201` | adopted | `dc7fcfafa` | DMG installer backgrounds and the production macOS icon pipeline. **Mechanism adopted, artwork rebranded** in `70fd3fa2b`: upstream's SVGs carry a "T3 CODE" wordmark and "Drag T3 Code to Applications". The pipeline itself is correct for Pylon unchanged, because `assets/prod/black-macos-1024.png` is already Pylon artwork despite the compatibility-named file. Upstream's retirement of `apps/desktop/resources/icon.*` was taken with it. |

Two further Pylon-first departures inside adopted commits, both recorded here because a
future reader will otherwise read them as mistakes:

- **`7afa184a9` / `#4781`** ("keep send reachable while a turn is running on mobile").
Upstream removes its early `if (isRunning) return stopButton` and shows the real send
button beside stop on mobile viewports. Pylon already solved the same problem
differently, with a dedicated queue-follow-up button shown on _every_ viewport — but
gated on `supportsSessionInputQueueFollowUp`, a **provider capability**, so providers
without a session input queue still had upstream's bug. The two were composed rather
than chosen between: the running branch now prefers Pylon's queue affordance and falls
back to upstream's plain send when the provider has no queue. Upstream's stop-button
sizing condition (`showSendWhileRunning && hasSendableContent`) was taken as-is; it now
also governs the queue case, so on a mobile viewport with a queue-capable provider and
an empty composer, stop renders 32px beside a disabled 36px queue button. Pre-existing
mismatch, narrowed rather than introduced — worth tidying if the row ever looks wrong.
- **`d5465aebf` / `#4755`** ("retain terminal PR badges after checkout switch"). Upstream's
import of lucide's `TerminalIcon` was taken during conflict resolution and then removed:
Pylon renders that indicator as `DotMatrix state="terminal"`, not a lucide glyph with
`animate-status-pulse`, which Pylon's taste rules forbid.

**Verification.** Typecheck clean across all nine packages (`t3`, web, contracts, shared,
client-runtime, mobile, desktop, scripts, marketing). `vp lint` exits 0 with three warnings,
all in upstream-authored code and none in a Pylon resolution. `vp fmt --check` clean over
2,898 files. Tests: web 2,758 in 283 files; client-runtime 658; shared 355; contracts 342;
scripts 53; server orchestration/provider/persistence/vcs/pullRequest/mcp/sourceControl.
`node scripts/export-pylon-brand-icons.mjs --check` reports 39 files current.

Two test notes for whoever runs these next:

- **`apps/server/src/provider/accountDrainEndToEnd.test.ts` hangs for 120s and fails.** It
fails **identically on a clean `origin/pylon` worktree**, so it is pre-existing and not
batch fallout. Not investigated further here.
- **`scripts/build-desktop-artifact.test.ts` fails when run from inside Pylon.** The
cross-architecture probe test asserts no spawned command carries
`ELECTRON_RUN_AS_NODE=1`, but an Electron host exports that variable and the code under
test spreads `process.env`. Run it with `env -u ELECTRON_RUN_AS_NODE`; 53/53 pass. CI is
unaffected.

**No integration pass in a real client.** No browser, desktop, or mobile run — the batch
touches the composer, sidebar, theme, DMG chrome, and the PWA manifest, so a web pass is
the obvious next step.

## Deferred register

_The register is currently empty. DEF-1 and DEF-2 were adopted on 2026-08-11
Expand Down
82 changes: 82 additions & 0 deletions .macroscope/check-run-agents/ui-consistency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
title: UI Consistency
model: claude-opus-5
effort: high
input: full_diff
tools:
- browse_code
- git_tools
- github_api_read_only
- modify_pr
include:
- "apps/web/src/**/*.ts"
- "apps/web/src/**/*.tsx"
- "apps/web/src/**/*.css"
conclusion: failure
showToolCalls: true
---

# UI consistency review

Review changed web UI code and directly affected call sites for consistency with the shared component system, Tailwind ownership, and the behavioral constraints below. Apply these rules when a pull request creates, moves, or modifies controls or styling. Do not demand unrelated repository-wide cleanup.

The goal is not to minimize CSS or class counts at any cost. The goal is to put each behavior in the smallest correct owner while preserving interaction, theming, accessibility, layout, and browser behavior.

## Shared controls and variants

- Prefer the core UI primitives in `apps/web/src/components/ui` over native controls or locally reconstructed primitives. In ordinary product UI, a raw `<button>` that recreates `Button`, a raw input that recreates `Input` or `InputGroup`, or a local trigger that recreates `Select`, `Toggle`, or `Menu` is a concrete finding.
- Do not flag raw elements that intentionally implement a semantic row, tab, resize handle, swatch, image target, editor surface, or another interaction whose behavior or geometry differs from the core primitive.
- When multiple call sites repeat the same durable geometry or treatment, prefer a named primitive size or variant. Examples include compact controls, micro icon actions, muted ghost actions, and glass actions. Keep contextual layout, width, and color at the call site.
- Flag large call-site class strings that override a primitive's core height, radius, padding, focus ring, cursor, hit target, or base state colors. Prefer extending the primitive contract when the same pattern is genuinely shared.
- Preserve accessibility and interaction semantics during migrations: focus-visible rings, disabled behavior, loading state, keyboard behavior, pointer cursor, `aria-*`, Base UI or Radix render/close props, and coarse-pointer hit targets.
- Do not require tests for a tiny visual-only class migration. Require focused tests when primitive composition changes behavior, prop forwarding, state transitions, keyboard handling, or width/defaulting logic.

## CSS and Tailwind ownership

- Ordinary one-owner presentation belongs in the owning TS or TSX module as static Tailwind classes or owner-level CSS variables. Examples include local geometry, spacing, typography, backgrounds, borders, simple vendor pseudo-elements, and component-only positioning.
- Keep global CSS when it is genuinely reusable or behaviorally complex: generated markdown or imperative DOM, custom elements and shadow roots, masks, shared or complex pseudo-elements, animations, glass composition, runtime theme variables, safe-area calculations, scrollbar-lane preservation, Electron drag regions, and browser/vendor integration. Simple owner-local pseudo-elements may still belong in the owning module.
- Before calling a selector dead, trace literal, dynamic, generated, imperative, test, custom-element, and shadow-root consumers. Search both the emitted class string and any class-valued field names through their final DOM sink. A helper returning a class is not proof that it is rendered, and a missed downstream property read can make a deletion unsafe.
- Flag duplicate declarations only after comparing cascade layer, selector specificity, inheritance, runtime theme scope, media/variant scope, and the final owning element. Textually identical declarations are not necessarily behaviorally redundant.
- When moving CSS into Tailwind, preserve selector scope and cascade ownership. A utility at the owner is preferable to a fragile global override that depends on stylesheet order.
- Do not request moving complex global behavior into arbitrary Tailwind merely to reduce `index.css`. Do not preserve ordinary one-owner CSS merely because it already exists globally.

## Themes and generated CSS

- Use the project variants for theme-only declarations:
- dark-only declarations use `@variant dark`;
- light-only declarations use `@variant light`;
- raw `.dark` should remain only in the `dark` and `light` custom-variant definitions.
- Preserve custom themes and runtime token bridges. Removing a variable or selector is safe only when all runtime, inspector, generated, and theme-palette consumers are accounted for.
- Inspect emitted production CSS after unusual variants, arbitrary selectors, nested pseudo-elements, or attribute matching. Source syntax that looks valid is insufficient.
- Flag malformed or empty emitted selectors such as empty `:is()` or `:not(:is())`, selector branches that can never match their own class attribute, and transformations that silently drop the intended rule.
- Prefer source-level logic over clever selectors when behavior depends on consumer-provided class strings. Preserve `MenuPopup`'s current defaulting contract: a string `className` containing a `w-*`, `min-w-*`, or `max-w-*` utility after variant prefixes are stripped suppresses `min-w-32`; a string without one and a functional/non-string `className` keep the default. Arbitrary width values count as width utilities, and the consumer class must be merged last so it retains control. Do not replace this with a raw class-attribute substring selector.
- Do not fail solely because a valid emitted selector is verbose or because a source rule uses an intentional custom property.

## Scroll and virtualized lists

- `ScrollArea` owns and masks its Base UI viewport. A virtualized list usually owns a native scrolling element and cannot automatically reuse viewport-specific `ScrollArea` behavior.
- Repeated native or virtualized overflow fades should use the shared virtualized-scroll-fade contract rather than component-named mask selectors.
- Preserve runtime top and bottom overflow state. Do not replace dynamic fades with an always-on static mask.
- Preserve fade geometry and keep the native scrollbar lane opaque so the track and thumb stay visible and usable. A visually similar mask that fades the scrollbar is a regression.
- Verify actual scroll behavior when changing virtualizers, masks, overflow ownership, or scrollbar selectors. Source-level class comparison is not enough.

## Visual and layout preservation

- Preserve responsive geometry, titlebar insets, panel and inline-preview modes, desktop Electron layout, light and dark contrast, clipping, radius, and composable shadows.
- For meaningful visual changes, prefer available real-app evidence using the actual component and state. A mock recreation does not validate the real component. Light and dark evidence is useful when theme-sensitive styles change, but missing or inaccessible evidence alone is not a finding; report only a concrete regression supported by the diff, code, or available artifacts.
- Do not treat a screenshot as proof of keyboard, overflow, scrollbar, responsive, or runtime-theme behavior. Pair visual evidence with source, computed-style, emitted-CSS, or interaction checks as appropriate.
- Be alert to shared primitive color indirection. When a primitive routes icon color through a CSS variable, ensure migrated contextual icons retain their intended tone, including pressed and disabled states.

## Change discipline

- Review the pull request's changed scope and directly affected consumers. Do not turn a focused PR into a demand for unrelated legacy cleanup.
- Prefer the smallest durable contract over a component-specific workaround or a broad abstraction with one consumer.
- Preserve intentional exceptions and comments that explain browser, virtualizer, theme, or Electron constraints.
- If a proposed cleanup cannot prove ownership or semantic equivalence, ask for evidence or leave it unchanged rather than guessing.
- Select verification gates according to the changed behavior: typecheck or focused tests for typing and interaction contracts, production build and emitted-CSS inspection for Tailwind or selector transformations, and real-app evidence for meaningful visual behavior when available. These gates are complementary when applicable, but do not require every gate for tiny visual-only migrations or fail solely because an artifact the configured tools cannot produce is absent.

## Reporting

Report only concrete violations introduced by changed lines or behavior, plus pre-existing behavior that the patch directly makes relevant or worsens. Touching a large file does not make unrelated retained issues reportable. Prefer precise inline comments on the smallest relevant line range. Explain the broken behavior or ownership rule, not merely the preferred syntax, and state the smallest expected fix. A clear consistency or regression risk may fail the check. Do not fail for optional aesthetic preferences, harmless class ordering, or unrelated legacy code.

This check defaults to failure. When there are no findings, stop immediately and make the entire final response exactly `All clear` on one line. Do not add a title, explanation, punctuation, Markdown, JSON, or trailing analysis, and do not continue reasoning after deciding the review is clean.
Loading
Loading