ADR-0046 status -> Accepted + implemented (8 commits 9f5f76b..22bec61); README index updated; the two draft-divergent decisions recorded inline (App.relationships not SchemaCache; nav overlay partial-clear + gutter). Handoff 63 covers the full UI build across Phases A/B/C; issues #20/#21/#23 closed on Gitea.
8.4 KiB
Session handoff — 2026-06-10 (63)
Sixty-third handover. Continues from handoff-62 (C4 m:n + #19). This was a single-ADR, full-build session: it designed and implemented ADR-0046 end to end — the UI work for the three sidebar/input issues #20 / #21 / #23, all now closed on Gitea.
§1. State at handoff
Branch: main. HEAD 22bec61 (plus an uncommitted docs
finalization — ADR status flip + this handoff — see §7). Push is the
user's step.
Tests: 2263 passing / 0 failing / 1 ignored (the 1 ignored is the long-standing doc-test). Clippy clean (nursery, all targets). +26 over the handoff-62 baseline of 2237.
This session's commits (8 + the docs finalization):
22bec61 feat(ui): scroll the focused sidebar panel + refine the nav overlay (DC3 + DC2)
c9da6ff feat(ui): Ctrl-O navigation mode — peek + expand the schema sidebar (DC1/DC2/DC4)
94825d0 feat(ui): relationships sidebar panel + schema data (DB2/DB4)
386627a feat(ui): width-derived sidebar visibility — hide at <=90 cols (DB1)
41bae99 feat(ui): two-row input display on tall terminals (DA4)
e0b9470 feat(ui): horizontal-scroll long input so the cursor stays visible (DA3)
9f5f76b fix(ui): geometry-fixed hint-panel height kills the typing jump (DA1/DA2)
93266b9 docs: ADR-0046 UI sidebar nav-mode + responsive input/hint
Issues closed: #20, #21, #23 (all via ADR-0046). #22 (in-app overlay/keystroke-annotation layer for casts/lessons) remains open — its own future ADR; adjacent but out of scope here.
§2. What shipped — ADR-0046 (read it; it's the source of truth)
Three coupled UI issues, treated as one decision because they share the terminal width/height budget. Phased A → B → C.
Phase A — input & hint (#20, #23).
- DA1/DA2 (#20): the Hint panel height is now a pure function of
terminal geometry (
hint_rows→ laterpanel_heights), fixed between resizes — it no longer resizes as you type, killing the jump. Compact (<40rows) = hint 2; comfortable = hint 2, or 3 only when the column is narrow (inner < 54). This reverses issue #12's shrink-to-content sizing (its two tests were replaced by an anti-jump invariant). Long hints ellipsize at the fixed budget. - DA3 (#23): long input horizontally scrolls to keep the cursor
visible (
input_scroll_offset, pureinput_scroll_offset()helper), with muted</>edge markers; resets on submit / history. Preserves ADR-0027's 6-col indicator reserve. - DA4 (#23): on a tall terminal (
>=40rows) the input renders across two visual rows (soft-wrap of the single logical line; indicator stays on row 1). Distinct from deferred multi-line I1;expand_runs_to_cellsis the substrate I1 should reuse.
Phase B — the sidebar (#21).
- DB1: the left column is width-optional —
sidebar_visible() = width > 90, so it's hidden at <=90 (the 90-col screencasts) and the right column takes the full width. (Resize a terminal below ~90 to see it; in a normal wide terminal it shows, by design.) - DB2/DB4: a Relationships panel stacks below Tables — each
relationship is name + endpoints broken at the arrow
(
Customers.id ->/ indentedOrders.customer_id), ellipsized. The panel floors at 5 rows ("(none)") and grows to a 50%-of-column cap (relationships_panel_height). Overrides S2 (relations were to be nested in the tables list; a sibling panel is the honest shape).
Phase C — navigation mode (#21).
- DC1/DC4:
Ctrl-Oenters a navigation mode orthogonal to the input mode, cycling focus Input → Tables → Relationships → Input (Escexits). It's routed in the main key handler after the modal gate, so it's inert behind a modal; in nav mode every non-nav key is inert (the input is occluded).NavFocusenum onApp. - DC2: the focused panel is revealed (peek, even when width-hidden) and drawn as a 45-col expanded overlay, clearing the sidebar strip + a one-column gutter and leaving the base output/input/hint visible (unchanged) to the right. (Two variants were eyeballed; this partial-clear-with-gutter was chosen over a full-area clear.)
- DC3: the focused panel scrolls — Up/Down by a line, PageUp/PageDown by its visible rows; per-panel offsets clamped to content at render time, mirroring the output-panel scroll.
Ctrl-B was rejected for nav mode (it's the tmux prefix →
unreachable inside tmux); Ctrl-O is multiplexer-safe.
§3. Two decisions that landed differently from the draft
Both recorded inline in the ADR (and called out in its Status):
- Relationship data on
App, notSchemaCache(DB2).SchemaCacheis walker/completion-facing and needs only relationship names (untouched); the full records are UI-only, soApp.relationshipsmirrorsapp.tables, and it avoided editing ~23SchemaCacheliterals. Delivered viaDatabase::read_all_relationships(new worker request) +AppEvent::RelationshipsRefreshedfrom the runtime's schema refresh. - Nav overlay = partial clear + 1-col gutter (DC2), not a full-area clear — truer to "underneath keeps its layout."
§4. Process notes
- The pre-build
/rundapass earned its keep again. It caught theCtrl-B/tmux collision, aSchemaCacheretype that would have broken completion, the 2-row-input/indicator placement, the missing nav-mode key disposition + modal gate, and three unreferenced requirements (S1 evolved, S2 overridden, S4 corrected —requirements.mdupdated). - Snapshot discipline: DB1's 90-col threshold collided with the test-suite's 80-col convention — many snapshots/tests were retuned (sidebar-dependent ones now render at 110; input tests at narrower widths so the now-wider input still overflows). One masked-intent integration check (matched "Customers" in output, not the panel) was corrected.
- Each phase was committed green + clippy-clean, user-confirmed message, no AI attribution, append-only.
§5. Requirements / S-items touched
requirements.md annotated: S1 (three-region layout → left region
width-optional), S2 (overridden — relationships get a sibling
panel, not nested), S4 (corrected — the "keyboard-toggleable" hint
claim was never implemented and is struck; the panel is always-on).
§6. Remaining open landscape (unchanged from handoff-62, minus the closed items)
- TT5 CI — test infra solid (2263 green); no pipeline. Gitea Actions / Woodpecker decision + likely a Linux-first scope call.
- SD1
seedthen H2hint— the two unblockers for A1 app-commands; both net-new, own ADR. SD1 should seed m:n junctions. - V2/S3 multi-result tabs or V4 journal — larger output-model redesign, design-first, own ADR.
- C3a modify relationship — small follow-up (drop+add covers it).
- #22 overlay/annotation layer — own ADR; shares the cast + overlay space with DC2 (designed to coexist).
- Tutorial/lesson system — acknowledged in scope; needs its own ADR.
ADR-0046 OOS (deferred): true multi-line input (I1); readline shortcuts (I1b); cross-session sidebar persistence; a persistent show/hide toggle (Ctrl-O peek covers it); output as a third nav focus; relationship search/edit from the panel; a hint-area toggle.
§7. How to take over
- Read handoffs 61 → 62 → 63, then
CLAUDE.md,docs/requirements.md,docs/adr/README.md, and ADR-0046 (fully landed). - Pending: an uncommitted docs finalization (ADR-0046 status →
implemented; README index status; this handoff). Commit it as
docs: session handoff 63(the user confirms commit messages). - For UI/layout work:
src/ui.rsnow haspanel_heights,sidebar_visible,relationships_panel_height, the nav overlay, and&mut Appsidebar panels (they report scroll viewports).Appgainedinput_scroll_offset,nav_focus,relationships, and thetables_scroll/relationships_scroll(+last_*_visible) fields. - For relationship/schema-cache work: relationship names are in
SchemaCache.relationships(completion); full records are onApp.relationshipsviaDatabase::read_all_relationships+RelationshipsRefreshed. - Eyeball reminder honoured: the user reviewed the nav overlay appearance and chose the partial-clear + 1-col-gutter variant.
- Run a
cargo sweepat some point —target/has grown across this build-heavy session.