Skip to content

docs(product): design leader/mnemonic keyboard chords, focus-context-gated (RIG-2484) - #544

Open
rigel-mintaka wants to merge 1 commit into
mainfrom
compass-ux/rig-2484-leader-chords
Open

docs(product): design leader/mnemonic keyboard chords, focus-context-gated (RIG-2484)#544
rigel-mintaka wants to merge 1 commit into
mainfrom
compass-ux/rig-2484-leader-chords

Conversation

@rigel-mintaka

Copy link
Copy Markdown
Contributor

Designs adoption of Linear's leader/mnemonic keyboard-chord model in Compass, focus-context-gated. Matt ratified the leader-vs-modifier fork (2026-08-23); this record designs the HOW and ships as its own PR to freeze on merge, per the design workflow.

What this designs

Builds on the SHIPPED discoverability net (all merged to main): RIG-2482 ? overlay (#526), RIG-2483 Cmd/Ctrl+K palette + point-of-use chips (#529), RIG-2529 tier-3 scope gate (#519). Every chord this record adds is already findable (overlay) and has a fallback (palette).

  • A1 — the collision guard is already built: modifier-less chords inherit the editable-target guard (dispatch.ts:117-122); focus context, not a per-route switch, is the surface-awareness mechanism (Linear/Slack/Zulip converge). Wave 1 extends the guard to <select>/combobox widgets so a bare letter never steals native typeahead.
  • A2 — sequences authored as space-separated segments in the existing KeymapEntry.chord ("G B"), no new field; collision-free because the Space key is already the "Space" token; the leader-prefix set is derived from the table.
  • A3 — the leader runtime is pending-leader closure state inside the one installKeymap handler (never a second listener): guard-first ordering, arm/complete/disarm/fall-through, LEADER_TIMEOUT_MS.
  • A4 — wave-1 allocation G B/G L/G D/G S (all four commands already registered by the shipped spine), zero bare letters.
  • A5 — asymmetric hardening of the shipped helpers: shortcutForAria skips sequence rows (WAI-ARIA has no sequential-press grammar), shortcutFor formats them ("G then B") so point-of-use display is preserved.
  • A6 — additive coexistence: keep all existing Mod+* bindings.

Plan

T1 (sequence-grammar helpers) → T2 (four G * rows + display/aria hardening, landed together so every commit is green) → T3 (leader runtime + <select> arm-guard) → T4 (dispatcher doc header + ledger). Each task carries red-green tests; the timeout test uses Bun fake timers (verified to fire setTimeout under the pinned Bun 1.4.0, so no clock-injection seam is added).

Process

  • Red-teamed by a design-critic pass (0 blocking-fork; 8 improvements + 4 nits folded, including the <select> typeahead hazard, the display-vs-aria asymmetry, and the T1/T3 resequencing).
  • Corrects a prior draft that grounded against a stale tree predating the net; all file:line cites re-verified against current main.

Ledger-impact: appends DL-240..DL-244 (leader/mnemonic adoption, sequence authoring, leader runtime, aria-skip hardening refining DL-234, wave-1 allocation); additive over DL-152/222/223/224/229/230/234, no rows superseded.

Spec-impact: none.

Refs RIG-2484

Co-authored-by: Matt Wilkinson matt@rigel.build

@linear-code

linear-code Bot commented Aug 23, 2026

Copy link
Copy Markdown

RIG-2484

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-ux-rig-2484-leader-c.compass-eng-docs.pages.dev

Deployed from compass-ux/rig-2484-leader-chords at 9a540c4.

Changed pages:

…gated (RIG-2484)

Designs adoption of Linear's leader/mnemonic keyboard-chord model in Compass, focus-context-gated. Matt ratified the leader-vs-modifier fork (2026-08-23); this record designs the HOW and ships as its own PR to freeze on merge, per the design workflow.

## What this designs

Builds on the SHIPPED discoverability net (all merged to main): RIG-2482 `?` overlay (#526), RIG-2483 Cmd/Ctrl+K palette + point-of-use chips (#529), RIG-2529 tier-3 scope gate (#519). Every chord this record adds is already findable (overlay) and has a fallback (palette).

- **A1** — the collision guard is already built: modifier-less chords inherit the editable-target guard (`dispatch.ts:117-122`); focus context, not a per-route switch, is the surface-awareness mechanism (Linear/Slack/Zulip converge). Wave 1 extends the guard to `<select>`/combobox widgets so a bare letter never steals native typeahead.
- **A2** — sequences authored as space-separated segments in the existing `KeymapEntry.chord` (`"G B"`), no new field; collision-free because the Space key is already the `"Space"` token; the leader-prefix set is derived from the table.
- **A3** — the leader runtime is pending-leader closure state inside the one `installKeymap` handler (never a second listener): guard-first ordering, arm/complete/disarm/fall-through, `LEADER_TIMEOUT_MS`.
- **A4** — wave-1 allocation `G B`/`G L`/`G D`/`G S` (all four commands already registered by the shipped spine), zero bare letters.
- **A5** — asymmetric hardening of the shipped helpers: `shortcutForAria` skips sequence rows (WAI-ARIA has no sequential-press grammar), `shortcutFor` formats them (`"G then B"`) so point-of-use display is preserved.
- **A6** — additive coexistence: keep all existing `Mod+*` bindings.

## Plan

T1 (sequence-grammar helpers) → T2 (four `G *` rows + display/aria hardening, landed together so every commit is green) → T3 (leader runtime + `<select>` arm-guard) → T4 (dispatcher doc header + ledger). Each task carries red-green tests; the timeout test uses Bun fake timers (verified to fire `setTimeout` under the pinned Bun 1.4.0, so no clock-injection seam is added).

## Process

- Red-teamed by a design-critic pass (0 blocking-fork; 8 improvements + 4 nits folded, including the `<select>` typeahead hazard, the display-vs-aria asymmetry, and the T1/T3 resequencing).
- Corrects a prior draft that grounded against a stale tree predating the net; all file:line cites re-verified against current main.

Ledger-impact: appends DL-240..DL-244 (leader/mnemonic adoption, sequence authoring, leader runtime, aria-skip hardening refining DL-234, wave-1 allocation); additive over DL-152/222/223/224/229/230/234, no rows superseded.

Spec-impact: none.

Refs RIG-2484

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka
rigel-mintaka force-pushed the compass-ux/rig-2484-leader-chords branch from 78fa1f8 to 9a540c4 Compare August 24, 2026 02:30
rigel-mintaka added a commit that referenced this pull request Aug 24, 2026
…-2530)

Design record for a coaching keyboard-discoverability tooltip layer: a reusable `CoachTip` component that shows a control's label plus its keyboard chord on hover AND focus, adopted across command-backed chrome so mouse and keyboard users passively learn the shortcuts — Linear's discoverability move. This is the deferred RIG-2530, refining DL-234's point-of-use net; distinct from RIG-2484's chord *mechanics* (this is the coaching/push layer, not the reference/pull one).

## What's here

- `docs/designs/product/compass-coaching-tooltips/design.md` — the frozen-quality design record (Problem · Global Constraints · Approach A1-A5 · Alternatives · Plan T1-T3 · Resolved decisions D1-D5 · Deferred).
- Ledger delta in `DECISIONS.md`: DL-245 (Kobalte-v2-alpha `Tooltip` adoption), DL-246 (sequence-aware chord rendering via `shortcutFor`), DL-247 (the `title=` convert/keep boundary + the two sidebar-toggle registrations). All Active, refining DL-234, no row superseded.

## Approach

`CoachTip` builds on the installed Kobalte v2-alpha `Tooltip` primitive (a tooltip's hard parts are DL-150's a11y-hard scope), styles the existing `.cx-tooltip` box, reveals on hover and focus, and resolves its chord only via `shortcutFor` (DL-234 single-derivation, never hand-authored). Forward-compatible with RIG-2484 leader chords: it renders `Ctrl+B` through `ShortcutChip` today and `G then B` as plain text automatically once #544 lands — never blocked on it. The adoption sweep converts the seven command-backed `title=` sites (removing the native `title`, keeping `aria-keyshortcuts`); every other `title=` stays native.

## Design pass

Drafted by a design subagent, red-teamed by a design-critic (Kobalte v2-alpha `Tooltip` API verified exact against installed `node_modules` types; Solid-v2 component shape confirmed; the `title=` census verified complete). One load-bearing fork ruled by Matt: the two topbar sidebar-toggle chords (`Mod+\`, `Mod+Shift+\`) are dead today (keymap rows, no registration), so the record registers `sidebar.toggleLeft`/`sidebar.toggleRight` beside their existing store behavior and coaches all seven sites, rather than shrinking the sweep to five live ones.

## CI note

Base `fb234f33` carries a pre-existing DL-239 duplicate (two lanes collided on the id: #538/RIG-2453 and #524/RIG-2490), which reds the fail-closed `design-ledger-gate` on every ledger-touching PR. #560 (RIG-2602) fixes it. This PR's ledger gate goes green on rebase once #560 merges; its own delta (DL-245..247) introduces no new duplicate.

Spec-impact: none. Refs RIG-2530

Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka added a commit that referenced this pull request Aug 24, 2026
…-2530)

Design record for a coaching keyboard-discoverability tooltip layer: a reusable `CoachTip` component that shows a control's label plus its keyboard chord on hover AND focus, adopted across command-backed chrome so mouse and keyboard users passively learn the shortcuts — Linear's discoverability move. This is the deferred RIG-2530, refining DL-234's point-of-use net; distinct from RIG-2484's chord *mechanics* (this is the coaching/push layer, not the reference/pull one).

## What's here

- `docs/designs/product/compass-coaching-tooltips/design.md` — the frozen-quality design record (Problem · Global Constraints · Approach A1-A5 · Alternatives · Plan T1-T3 · Resolved decisions D1-D5 · Deferred).
- Ledger delta in `DECISIONS.md`: DL-245 (Kobalte-v2-alpha `Tooltip` adoption), DL-246 (sequence-aware chord rendering via `shortcutFor`), DL-247 (the `title=` convert/keep boundary + the two sidebar-toggle registrations). All Active, refining DL-234, no row superseded.

## Approach

`CoachTip` builds on the installed Kobalte v2-alpha `Tooltip` primitive (a tooltip's hard parts are DL-150's a11y-hard scope), styles the existing `.cx-tooltip` box, reveals on hover and focus, and resolves its chord only via `shortcutFor` (DL-234 single-derivation, never hand-authored). Forward-compatible with RIG-2484 leader chords: it renders `Ctrl+B` through `ShortcutChip` today and `G then B` as plain text automatically once #544 lands — never blocked on it. The adoption sweep converts the seven command-backed `title=` sites (removing the native `title`, keeping `aria-keyshortcuts`); every other `title=` stays native.

## Design pass

Drafted by a design subagent, red-teamed by a design-critic (Kobalte v2-alpha `Tooltip` API verified exact against installed `node_modules` types; Solid-v2 component shape confirmed; the `title=` census verified complete). One load-bearing fork ruled by Matt: the two topbar sidebar-toggle chords (`Mod+\`, `Mod+Shift+\`) are dead today (keymap rows, no registration), so the record registers `sidebar.toggleLeft`/`sidebar.toggleRight` beside their existing store behavior and coaches all seven sites, rather than shrinking the sweep to five live ones.

## CI note

Base `fb234f33` carries a pre-existing DL-239 duplicate (two lanes collided on the id: #538/RIG-2453 and #524/RIG-2490), which reds the fail-closed `design-ledger-gate` on every ledger-touching PR. #560 (RIG-2602) fixes it. This PR's ledger gate goes green on rebase once #560 merges; its own delta (DL-245..247) introduces no new duplicate.

Spec-impact: none. Refs RIG-2530

Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka added a commit that referenced this pull request Aug 24, 2026
…-2530)

Design record for a coaching keyboard-discoverability tooltip layer: a reusable `CoachTip` component that shows a control's label plus its keyboard chord on hover AND focus, adopted across command-backed chrome so mouse and keyboard users passively learn the shortcuts — Linear's discoverability move. This is the deferred RIG-2530, refining DL-234's point-of-use net; distinct from RIG-2484's chord *mechanics* (this is the coaching/push layer, not the reference/pull one).

## What's here

- `docs/designs/product/compass-coaching-tooltips/design.md` — the frozen-quality design record (Problem · Global Constraints · Approach A1-A5 · Alternatives · Plan T1-T3 · Resolved decisions D1-D5 · Deferred).
- Ledger delta in `DECISIONS.md`: DL-245 (Kobalte-v2-alpha `Tooltip` adoption), DL-246 (sequence-aware chord rendering via `shortcutFor`), DL-247 (the `title=` convert/keep boundary + the two sidebar-toggle registrations). All Active, refining DL-234, no row superseded.

## Approach

`CoachTip` builds on the installed Kobalte v2-alpha `Tooltip` primitive (a tooltip's hard parts are DL-150's a11y-hard scope), styles the existing `.cx-tooltip` box, reveals on hover and focus, and resolves its chord only via `shortcutFor` (DL-234 single-derivation, never hand-authored). Forward-compatible with RIG-2484 leader chords: it renders `Ctrl+B` through `ShortcutChip` today and `G then B` as plain text automatically once #544 lands — never blocked on it. The adoption sweep converts the seven command-backed `title=` sites (removing the native `title`, keeping `aria-keyshortcuts`); every other `title=` stays native.

## Design pass

Drafted by a design subagent, red-teamed by a design-critic (Kobalte v2-alpha `Tooltip` API verified exact against installed `node_modules` types; Solid-v2 component shape confirmed; the `title=` census verified complete). One load-bearing fork ruled by Matt: the two topbar sidebar-toggle chords (`Mod+\`, `Mod+Shift+\`) are dead today (keymap rows, no registration), so the record registers `sidebar.toggleLeft`/`sidebar.toggleRight` beside their existing store behavior and coaches all seven sites, rather than shrinking the sweep to five live ones.

## CI note

Base `fb234f33` carries a pre-existing DL-239 duplicate (two lanes collided on the id: #538/RIG-2453 and #524/RIG-2490), which reds the fail-closed `design-ledger-gate` on every ledger-touching PR. #560 (RIG-2602) fixes it. This PR's ledger gate goes green on rebase once #560 merges; its own delta (DL-245..247) introduces no new duplicate.

Spec-impact: none. Refs RIG-2530

Co-authored-by: Matt Wilkinson <matt@rigel.build>
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.

1 participant