← Design · c140

review-1.md

c140 review stop 1: the scores, and the calls

2026-11-12. For: Mark. What's here:

  • the evaluation of the GPUI surface against twenty principles, scored by the plan's rubric;
  • the Surface glossary entry (brand/glossary.md);
  • three report pages: scorecard · parity · tools.

The summary is in the findings.

Nothing changed in qnative or the layer. Everything here is local and uncommitted, because another session is merging branches in both repos. One file action was taken: the ten port specs, found only in a session scratchpad under /private/tmp, were copied into rescued-specs/.

How to read it

  1. Start with the scorecard page: the twenty rows, then the verdict and the five questions.
  2. Next, the parity page answers the prompt's honest question: where one change lands, what a machine checks, what drifted, and the seed of a divergence register.
  3. Finally, the tools page has the ten skill and tool candidates, ranked.

Done, or safe to do now (no ruling needed, but say if not)

  1. The specs. Move rescued-specs/ to qnative cycles/c2.expressive-range/specs/ once the merge is done, and commit it there. Default: yes, after the merge.
  2. The bridge fixture. Copy qnative's it_contact into design's app/data/worlds/bridge/pilot.json and types.ts before anyone runs sync-bridge.sh. Default: yes, after the merge.
  3. Six small flaws in qnative, as one commit:
    • the copied .qp("mcp.tool") in harness.rs:280;
    • the empty box's 0xE8E8E8 in dark mode;
    • account.rs's GRAPE_500 on hover;
    • the inbox's unwrap_or_default (an error shown as empty);
    • cycle ids in the Sensor page's copy;
    • the scorecard's two stale rows.

    Default: yes, in a qnative session after the merge.
  4. A token drift check in qnative's CI: tokens-to-kit.mjs --check against the layer at a pinned tag. Default: yes.

The calls

  1. The second surface's name. Your prompt says "QPUIkit" and "QGUIkit". GPUI Kit is longbridge's open-source kit; our components are qnative's layer crate. Options:
    • (a) GPUI as the surface's name, as the glossary says today;
    • (b) a name of our own for the Rust layer (Q + GPUI Kit?), which c0 Call My Name could take with the app's name.

    Default: (a) until c0 rules.
  2. Dual-surface docs (the Surface entry's ask). Build the parity register (the scorecard as shared data) and a Surfaces panel on every component page, with each divergence marked flavor or gap. Where:
    • (a) a new cycle;
    • (b) inside c135, widened to the Rust twins;
    • (c) inside c132's loop.

    Default: (a), a small cycle after the merge, because c135 is about the Vue catalog.
  3. c135's scope. It puts the native components out of scope ("the kit's"), planned before D18 made the layer a drawn Rust twin. Options:
    • (a) widen c135 to both surfaces, group by group;
    • (b) leave c135 on the Vue surface and give the twins their own pass.

    Default: (a). A group is cleaned once, on both surfaces, or it drifts.
  4. Type, radius and motion tokens. Sweep the 433 literal type sizes and 52 literal radii to tokens, add motion tokens (fast, base, slow, the one easing) to both surfaces, and rewrite the motion rule in component_philosophy.md to what the web actually does (it uses 300 ms most). Default: yes, with the lint so it stays.
  5. The slot equivalents. Name the three in the layer's docs:
    • ParentElement as the default slot;
    • Option<AnyElement> as a named slot;
    • a render closure as a scoped slot.

    Then use them: ParentElement on the containers, children on UxPill, a cell closure on DataTable. The last one touches every listing page. Default: yes; DataTable first.
  6. Keyboard and focus. A pass over the six interactive pieces: jump pills, crumbs, tabs, file tree, buttons, the picker's popover. It adds a focus ring and a headless test each. Default: yes, before the pitch to the engineers.
  7. Names. Options:
    • (a) rename the Rust components to the web's names, the Data and Ux prefixes included, with aliases;
    • (b) keep the Rust names and add a rust column to the scorecard.

    Default: (a); one vocabulary is the point of a design system.
  8. What leaves the component crate.
    • The tour engine, the harness registry and the git-remote parser move out.
    • The seven pantry pieces now in the pages move in.
    • The demos move to a docs crate, per our documentation architecture.

    Default: yes, in that order.
  9. The capture manifest's surface field. Split it into surface (vue · gpui) and kind (app · mock · docs · preview). Default: yes, when the register is built.
  10. Which tools first. The tools page ranks ten. Default: build /native-port (the skill), spec-measure (the script) and the parity register (the check) first. /native-port fixes /gpui-story's wrong test crate and missing PATTERNS.md along the way.
  11. Web bugs the port fixed. Rows closing on sort, the Models initial sort and the "all-time" subtitle were fixed on GPUI only. Default: file them back to the qdash UI as todos; replicate-first runs both ways.

What was not done

  • No scores for the Vue surface. The Vue surface is the reference, not re-audited; c135 audits it. The trend column compares the two only where the evidence did.
  • Nothing built. No sketch, no captures of the report pages, no story, no deploy. The cycle's sketch and story wait for the review, so they draw what you rule.
  • Unmerged work not read. The unmerged qnative branches (c7's rail fix and others) were noted and not read. A score the merge changes gets re-read.

Ruled (2026-11-12, Mark, walked in the session)

Fourteen rulings, one per call, plus three that followed from them. Defaults were taken on ten; the four marked ◆ differ from the default.

CallRuling
D1 ◆1 · The second surface's nameQGUIkit, now. The glossary, the docs and the pages say the QGUIkit surface; GPUI Kit stays the name of longbridge's kit underneath, and GPUI the framework.
D2follows D1The crate takes the name: crates/layer → crates/qguikit, use layer:: → use qguikit:: across app, stories and devmode.
D32 · Dual-surface docsA new small cycle, opened at Stage 1 the same day as c141 Surface Docs: the parity register, a Surfaces panel per component page, each divergence a flavor or a gap.
D43 · c135's scopeBoth surfaces. Each group is cleaned once, on Vue and QGUIkit together.
D54 · TokensSweep, motion and a lint. Type and radius literals to tokens; motion tokens (fast, base, slow, one easing) on both surfaces; component_philosophy.md's motion rule rewritten to what the web does; a lint so literals cannot come back.
D6 ◆5 · SlotsName the three now, refactor later. The layer's docs map ParentElement → default slot, Option<AnyElement> → named slot, a render closure → scoped slot; APIs change when a component is next touched. Until DataTable is touched, its pre-built cells still truncate silently on a count mismatch: a gap, written down.
D7 ◆6 · Keyboard and focusAfter V1 ships. V1 goes to the engineers with keyboard access in the table only: a gap, written down for operators in the divergence register.
D87 · NamesRename to the web's names, the Data and Ux prefixes included, with aliases for a release.
D98 · What leaves the crateAll of it. The tour engine, the harness registry and the git-remote parser out; the demos to a docs crate that devmode and stories depend on; the seven pantry pieces from the pages in.
D109 · The manifest fieldSplit with the register (c141): surface (vue · qguikit) and kind (app · mock · docs · preview).
D11 ◆10 · Tools first/native-port and spec-measure. The parity register comes with c141 (D3), and the token lint with D5.
D1211 · Web bugsFile them as qdash todos, each citing the native fix: qdash-todos.md.
D13the four small itemsAll four, after the merge: the specs to qnative c2, the bridge fixture synced, the six flaws fixed, the token drift check in qnative's CI.
D14where the code work goesOne qnative cycle after the merge carries D2, D13, D9, D8 and D5, in that order, with a review stop. c140 stays the design record. The brief is handon-qnative.md.

Where each lands.

  • The glossary names QGUIkit (D1, D2).
  • The pages say QGUIkit and show each ruling beside its course correction.
  • c135's CYCLE.md records D4.
  • c141 is open at Stage 1 (D3, D10).
  • The qnative cycle starts from handon-qnative.md once the merge thread is done (D14).

Qpoint Brand Style Guide