diff --git a/docs/handoff/wave-R-mastery-briefs-2026-06-12.md b/docs/handoff/wave-R-mastery-briefs-2026-06-12.md index 67ed19dd..62626946 100644 --- a/docs/handoff/wave-R-mastery-briefs-2026-06-12.md +++ b/docs/handoff/wave-R-mastery-briefs-2026-06-12.md @@ -7,11 +7,17 @@ governing spec; this pack is the per-operator cut). ## Dispatch order ``` -Echelon 1 (parallel): R0a ∥ R0b ∥ R0c -Echelon 2: R0d (after R0c merges) -Echelon 3: R1 (after all R0 merges) +Echelon 1 (parallel dispatch): R0a ∥ R0b ∥ R0c +Echelon 2: R0d (after R0c merges) +Echelon 3: R1 (after all R0 merges) ``` +**Merge order is a strict train even though dispatch is parallel:** +R0a merges FIRST (smallest PR; carries the honesty fix; lands the CI lane +that then verifies R0b/R0c). R0b and R0c merge next, either order, each +rebased on merged main before push if R0a landed meanwhile. R0d after R0c. +Never combine R0 briefs into one PR. + Brief 5 (Trace route, `wave-1-evidence-spine-briefs-2026-06-12.md`) **stays on hold** until R0 lands; it gets re-issued upgraded as the first R2 brief. @@ -80,9 +86,20 @@ workbench-ui at all** (`smoke.yml` / `full-pytest.yml` are Python-only). - single job, `timeout-minutes: 15`: pnpm setup (frozen lockfile) → `pnpm build` → `pnpm test` - Node 20, pnpm via `corepack` or `pnpm/action-setup` -5. Honesty fix (skip if R0d already merged): remove the `j/k` and `/` rows - from `KeyboardHelp.tsx` and its test expectations — the overlay must not - advertise shortcuts that do not exist. +5. Honesty fix, **unconditional**: remove the `j/k`, `/`, and + `Enter — Open selected item` rows from `KeyboardHelp.tsx` and its test + expectations — the overlay must not advertise shortcuts that do not + exist. (`Enter` is real only inside the palette, which carries its own + hint; as a global list affordance it is false until R0d.) R0d restores + these rows as real, registry-backed entries. +6. Minimal route conformance test (front-loaded from R1): + `src/app/routeConformance.test.tsx`, parametrized over the implemented + routes (Chat, Proposals, Evals, Replay). For each route, under mocked + query states, assert: empty state renders a one-line absence statement + + a next action; error state renders what-failed + mutation status + + reproducer + retry-safety; loading state renders a specific label (never + "Thinking…"). Per ADR-0162 §6. Fix routes that fail; no expected-fail + lists (a test that tolerates violations is decoration). ### Verification before push @@ -247,9 +264,14 @@ ls src/app/evidenceAddress.ts || echo "STOP: R0c not merged" 6. Wire it for real: Proposals list and Replay artifact list adopt `useListNavigation` + `SearchInput` (the `/` shortcut becomes real where mounted). -7. `KeyboardHelp.tsx`: advertise exactly the shortcuts that now work — and - only those. (If R0a removed `j/k` and `/` rows, restore them — they are - real now.) +7. `Kbd` primitive (front-loaded from R1): a small token-only component for + rendering key chords; `KeyboardHelp` and palette shortcut hints adopt it. +8. `KeyboardHelp.tsx` becomes **registry-driven**: the overlay renders its + rows from the shortcut/command registry instead of a hand-maintained + array, so advertising an unimplemented shortcut is structurally + impossible. The rows R0a removed (`j/k`, `/`, `Enter`) return here as + real registry entries. Test: every row in the rendered overlay + corresponds to a registered, handled shortcut. ### Verification before push @@ -279,27 +301,24 @@ ls src/design/components/Panel || echo "STOP: R0d not merged" ### Deliverables -1. `Kbd` primitive; adopt in `KeyboardHelp` and palette shortcut hints. -2. Typography precision: `tabular-nums` on every metric cell +1. Typography precision: `tabular-nums` on every metric cell (`MetadataTable` values, eval metrics, `turn_cost_ms`); type-scale audit against ADR-0162 §2; `text-wrap: balance` on headings. -3. Selection-state unification: one tokenized treatment for selected vs +2. Selection-state unification: one tokenized treatment for selected vs focused rows, applied across Proposals / Evals / Replay lists. -4. Hash display standard: 12-char truncation + copy + mono everywhere; +3. Hash display standard: 12-char truncation + copy + mono everywhere; consolidate `src/app/chat/CopyableHash.tsx` into `DigestBadge` and delete the duplicate (cleanup-as-you-find: imports, tests, preview entries). -5. `EvidenceChainRail` in `RightInspector`: the seven spine stages (intent → +4. `EvidenceChainRail` in `RightInspector`: the seven spine stages (intent → subject → provenance → admissibility → replay → authority → action), each rendered lit (evidence present) / dim (not applicable) / hollow (not recorded). Status derives ONLY from fields the subject carries — never inferred, never faked. "Not recorded" is an honest, visible state. -6. Empty-state glyphs: small static deterministic monochrome SVGs (inline, +5. Empty-state glyphs: small static deterministic monochrome SVGs (inline, no asset fetches). -7. `Panel` adoption in Proposals + Evals routes (Chat/Replay opportunistic). -8. **Doctrine-as-tests:** - - Route conformance test parametrized over implemented routes: empty / - error / loading each render with next-action / reproducer / - specific-label content (ADR-0162 §6, executable). +6. `Panel` adoption in Proposals + Evals routes (Chat/Replay opportunistic). +7. **Doctrine-as-tests** (route conformance shipped in R0a; extend it to any + surface this PR touches, then add): - Raw-hex scan: vitest node test walking `src/**` asserting no hex/rgb literals outside `tokens.css`. - Schema-drift gate: `scripts/dump-schemas.py` (read-only AST walk over diff --git a/docs/workbench/wave-R-mastery-revamp.md b/docs/workbench/wave-R-mastery-revamp.md index c6b3f99c..7e8e5c10 100644 --- a/docs/workbench/wave-R-mastery-revamp.md +++ b/docs/workbench/wave-R-mastery-revamp.md @@ -7,6 +7,14 @@ Refines: `wave-1-evidence-spine.md` — keeps its spine and Wave-1 deliverables sequencing with the upgraded specs below. Reviewed by: Claude Fable 5 (full re-audit of ADR-0160, ADR-0162, the shipped `origin/main` code, and the Wave 1 plan), approved by Shay. +Execution-shape review (external, via Shay, 2026-06-12): R0 confirmed as a +strict PR train, never one PR; honesty fix made unconditional in R0a; route +conformance test front-loaded R1 → R0a; `Kbd` front-loaded R1 → R0d; +KeyboardHelp made registry-driven in R0d; merge order pinned R0a-first. +Declined with reasons: full serialization of echelon-1 dispatch (file +surfaces verified disjoint; parallel dispatch retained with serial merge), +and folding the Playwright lane into R0a (ADR-0162 acceptance 5–7 needs a +dedicated, parallel-safe brief). ## Why a revamp before Wave 2 @@ -89,9 +97,18 @@ Trace is the first consumer of this substrate and building it twice is waste. - [ ] New `.github/workflows/workbench-ui.yml`: path-filtered to `workbench-ui/**`, runs `pnpm install --frozen-lockfile && pnpm build && pnpm test`, `timeout-minutes: 15` -- [ ] Remove the `j/k` and `/` rows from `KeyboardHelp.tsx` **iff** R0d has - not yet made them real at merge time (honesty gap closes from whichever - side lands first) +- [ ] Remove the `j/k`, `/`, and `Enter — Open selected item` rows from + `KeyboardHelp.tsx` **unconditionally** — the overlay must not advertise + shortcuts that do not exist. R0d restores them when they become real + (and makes the overlay registry-driven so this class of dishonesty is + structurally impossible) +- [ ] Minimal route conformance test (front-loaded from R1 on + execution-shape review): parametrized over the implemented routes + (Chat, Proposals, Evals, Replay), asserts empty / error / loading each + render with next-action / reproducer / specific-label content + (ADR-0162 §6). Minimal means existing routes only — the harness is + the contract every later route must pass; fix what fails, no + expected-fail lists ### R0b — Playwright smoke lane (pays ADR-0162 acceptance debt 5/6/7) @@ -144,15 +161,17 @@ Trace is the first consumer of this substrate and building it twice is waste. - [ ] Wire `useListNavigation` + `SearchInput` into the Proposals list and Replay artifact list now (at least two real consumers; `/` becomes real where a `SearchInput` is mounted) -- [ ] `KeyboardHelp.tsx` updated to advertise exactly the shortcuts that are - now real — and only those +- [ ] `Kbd` primitive (front-loaded from R1 — KeyboardHelp and palette + shortcut hints consume it) +- [ ] `KeyboardHelp.tsx` becomes **registry-driven**: the overlay renders + from the shortcut/command registry instead of a hand-maintained list, + so advertising an unimplemented shortcut is structurally impossible. + The rows R0a removed return here as real, registry-backed entries --- ## Wave R1 — Design mastery pass (one PR, after R0) -- [ ] `Kbd` primitive (promoted from the deferred list — KeyboardHelp and - palette hints consume it) - [ ] Typography precision: `tabular-nums` for every metric cell (`MetadataTable` values, eval metrics, turn costs); type-scale audit; `text-wrap: balance` on headings @@ -167,10 +186,7 @@ Trace is the first consumer of this substrate and building it twice is waste. with no data renders "not recorded", never a guess - [ ] Empty-state glyphs: small static deterministic monochrome SVGs - [ ] `Panel` adoption in Proposals + Evals (Chat/Replay opportunistic) -- [ ] **Doctrine-as-tests:** - - [ ] Route conformance test, parametrized over implemented routes: - empty / error / loading all render with next-action / reproducer / - specific-label content (ADR-0162 §6 becomes executable) +- [ ] **Doctrine-as-tests** (route conformance moved to R0a; the rest here): - [ ] Raw-hex scan test: no hex/rgb literals in `src/**` outside `tokens.css` - [ ] Schema-drift gate: `scripts/dump-schemas.py` (read-only AST walk @@ -241,10 +257,14 @@ R0b ─┼─(R0c)──→ R0d ──→ R1 ──→ R2 (Trace ∥ Runs ∥ Au R0c ─┘ ``` -R0a / R0b / R0c are parallel-safe (disjoint files; trivial `package.json` -merge between R0b and R0d is sequenced away). R0d follows R0c (shares +R0a / R0b / R0c are parallel-safe to **dispatch** (disjoint files; trivial +`package.json` merge between R0b and R0d is sequenced away). **Merge order +is a strict train: R0a merges first** — it is the smallest PR, carries the +honesty fix, and lands the CI lane that then verifies R0b and R0c; R0b/R0c +merge next in either order; R0d follows R0c (shares `evidenceContext`/`Shell`). R1 is one PR after all of R0. R2 routes are -mutually independent. R3 follows the R2 routes it draws data from. +mutually independent. R3 follows the R2 routes it draws data from — no +theater work starts before R0/R1 are merged and tested. ## Keyboard map after R0