Files
rdbms-playground/docs/handoff/20260610-handoff-63.md
claude@clouddev1 18303784a0 docs: session handoff 63 + ADR-0046 marked implemented (#20/#21/#23)
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.
2026-06-10 21:30:00 +00:00

160 lines
8.4 KiB
Markdown

# 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` → later `panel_heights`), **fixed
between resizes** — it no longer resizes as you type, killing the
jump. Compact (`<40` rows) = 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`, pure `input_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 (`>=40` rows) 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_cells` is 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 ->` / indented `Orders.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-O`** enters a navigation mode orthogonal to the
input mode, cycling focus **Input → Tables → Relationships → Input**
(`Esc` exits). 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). `NavFocus` enum on `App`.
- **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):
1. **Relationship data on `App`, not `SchemaCache`** (DB2). `SchemaCache`
is walker/completion-facing and needs only relationship *names*
(untouched); the full records are UI-only, so `App.relationships`
mirrors `app.tables`, and it avoided editing ~23 `SchemaCache`
literals. Delivered via `Database::read_all_relationships` (new worker
request) + `AppEvent::RelationshipsRefreshed` from the runtime's
schema refresh.
2. **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 `/runda` pass earned its keep again.** It caught the
`Ctrl-B`/tmux collision, a `SchemaCache` retype 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.md` updated).
- **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)
1. **TT5 CI** — test infra solid (2263 green); no pipeline. Gitea Actions
/ Woodpecker decision + likely a Linux-first scope call.
2. **SD1 `seed`** then **H2 `hint`** — the two unblockers for **A1**
app-commands; both net-new, own ADR. SD1 should seed m:n junctions.
3. **V2/S3 multi-result tabs** or **V4 journal** — larger output-model
redesign, design-first, own ADR.
4. **C3a modify relationship** — small follow-up (drop+add covers it).
5. **#22 overlay/annotation layer** — own ADR; shares the cast + overlay
space with DC2 (designed to coexist).
6. **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
1. Read handoffs 61 → 62 → 63, then `CLAUDE.md`, `docs/requirements.md`,
`docs/adr/README.md`, and **ADR-0046** (fully landed).
2. **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).
3. **For UI/layout work:** `src/ui.rs` now has `panel_heights`,
`sidebar_visible`, `relationships_panel_height`, the nav overlay, and
`&mut App` sidebar panels (they report scroll viewports). `App` gained
`input_scroll_offset`, `nav_focus`, `relationships`, and the
`tables_scroll` / `relationships_scroll` (+ `last_*_visible`) fields.
4. **For relationship/schema-cache work:** relationship *names* are in
`SchemaCache.relationships` (completion); full records are on
`App.relationships` via `Database::read_all_relationships` +
`RelationshipsRefreshed`.
5. **Eyeball reminder honoured:** the user reviewed the nav overlay
appearance and chose the partial-clear + 1-col-gutter variant.
6. Run a `cargo sweep` at some point — `target/` has grown across this
build-heavy session.