Files
rdbms-playground/docs/handoff/20260611-handoff-64.md
T
claude@clouddev1 5d9ef6b21f docs: finalize handoff 64 — issues closed, tree clean
Bring handoff-64 current: it was written just before #22/#24 were closed
and the docs commit landed. §1 now reflects HEAD f0afec3 with both
issues closed on Gitea; §6 removes the completed finalization steps and
points the next session at the open requirements backlog (§7).
2026-06-11 12:08:12 +00:00

7.3 KiB

Session handoff — 2026-06-11 (64)

Sixty-fourth handover. Continues from handoff-63 (ADR-0046 sidebar/nav). This session closed two unrelated, website-screencast-enabling Gitea issues: #24 (vi-style load-picker navigation) and #22 (in-app demonstration overlay layer — its own ADR-0047, built end to end across three phases + a restyle).

§1. State at handoff

Branch: main. HEAD f0afec3 — all work committed, nothing pending. Unpushed (push is the user's step; normal working state).

Tests: 2290 passing / 0 failing / 0 skipped / 1 ignored (the 1 ignored is the long-standing friendly doctest). Clippy clean (nursery, all targets). +27 over the handoff-63 baseline of 2263.

This session's commits:

f0afec3 docs: session handoff 64 + ADR-0047 implemented (#22/#24)
2d0f4b2 feat(ui): flat filled rectangles for demo overlays (#22, ADR-0047 D4)
241f60c feat(ui): demo-mode step-caption stealth buffer (#22, ADR-0047 D3/D4)
2584e76 feat(ui): demo-mode keystroke badges (#22, ADR-0047 D2/D4/D5)
f879d54 feat(cli): --demo demonstration mode flag + app plumbing (#22, ADR-0047 D1)
e9eb1b1 docs: ADR-0047 — demonstration overlay layer for casts/teaching (#22)
638b4c9 feat(app): vi-style j/k/g/G navigation in the load picker (#24)

Issues closed: both #24 (vi nav) and #22 (demo overlays) are closed on Gitea with closing comments — verified via the filtered issue list. Nothing left open from this session's scope.

§2. #24 — vi-style load-picker navigation (commit 638b4c9)

Purely additive to the ADR-0015 load picker (handle_load_picker_key, LoadPickerSubMode::List): j/k mirror Down/Up (bounds- respecting, no wrap), g/G jump to first/last. Existing keys (↑↓/Enter/Esc/b) unchanged; the footer hint is left as-is at the user's request (the new keys are not advertised). No ADR (additive). Motivation: autocast (the website cast driver) can only send typeable characters — not arrow keys — so the projects demo needs j/k to drive the picker. Tests: load_picker_jk_navigates_like_arrows, load_picker_g_jumps_to_first_and_last (test-first).

§3. #22 — ADR-0047 demonstration overlay layer (read the ADR)

An in-app demonstration mode (--demo flag / RDBMS_PLAYGROUND_DEMO env, off by default, zero footprint when off) that renders two transient overlays so autocast screencasts — and live teaching, and a future guided-lesson system — can show otherwise-invisible interactions.

  • Phase A (f879d54): --demo + env → App.demo_mode, threaded through run_loop like --no-undo. --help line mentions only the visible badges; the Ctrl+] caption trigger is kept low-profile (user decision, D6).
  • Phase B (2584e76): automatic keystroke badges ([TAB]/[ENTER]/[UP]/…) over a fixed set of glyph-less keys — pure demo_badge_label(&KeyEvent), set in App::update before the modal gate (so they fire over the load picker), expired by a ~1.5 s runtime timer. The timer extends the event loop's time-boxed-recv via a new pure nearest_deadline helper; the rewrite tracks Instant deadlines and was verified not to regress the ADR-0027 indicator debounce. New App.last_output_area: Rect (set in render_output_panel) anchors the overlays.
  • Phase C (241f60c): the stealth Ctrl+] caption bufferCtrl+] (byte 0x1DChar('5')+CONTROL, verified vs crossterm 0.29) toggles an invisible buffer; typed chars accumulate without touching input/output, Backspace edits, other keys inert, a second Ctrl+] commits (empty commit dismisses). In pure-sync App::update, intercepted before the modal gate; an ordinary keystroke clears a visible caption.
  • Restyle (2d0f4b2): the overlays render as flat filled yellow rectangles (no border glyphs, one-cell text margin) — user decision, deliberately unlike the bordered panels so they pop. Shared fill_overlay_rect (borderless Block fill + inset Paragraph).

Placement: both float at the output panel's inner bottom-right, drawn last over modals, badge stacked directly above the caption when both show; caption wraps to ≤ 3 lines then ellipsises; clamp/ skip guard for tiny terminals.

Process: ADR-first (user chose), pre-build /runda (10 findings, folded in) + whole-implementation /runda (PASS, no blockers). Every fork user-confirmed via mockups/questions, incl. the two post-draft follow-ups: Ctrl+] trigger (over Ctrl+!, which autocast cannot send — not a single ASCII byte) and wrap-to-3-line captions.

§4. Two things to know about the implementation

  1. Ownership split (intentional, mirrors input/input_indicator): demo_caption/demo_caption_capturing/demo_caption_buffer are driven by App::update (input); demo_badge is set by App::update but its expiry is timed by the runtime (demo_badge_seq bumps so a repeated key restarts the timer).
  2. Ctrl-C is inert while capturing — by spec ("every other key is inert"); exit capture with Ctrl+]. User-acknowledged; flagged in the ADR. The only behaviour worth a second look if it ever annoys.

§5. Honest coverage note

Everything testable is tested (label fn, full caption FSM incl. over-modal + demo-off, nearest_deadline, all rendering, CLI parse/env). The only untested wiring is inside run_loop (the badge-timer arm/clear and app.demo_mode = demo_mode) — run_loop is not unit-testable (terminal + DB + channels), exactly the posture the existing IndicatorDebounce already takes. A future Tier-4 PTY harness (ADR-0008 TT4, still unwired) would close it.

§6. How to take over

Nothing is pending from this session — both issues are closed, all docs landed (f0afec3), tree is green. The next session returns to the open requirements backlog (§7). Suggested start: run /whatsnext (it reads this handoff), or pick from §7 below.

  1. Read handoffs 62 → 63 → 64, CLAUDE.md, docs/requirements.md, docs/adr/README.md. ADR-0047 is fully landed; revisit only for demo-overlay follow-ups.
  2. For demo-overlay work: App has demo_mode, demo_badge, demo_badge_seq, demo_caption, demo_caption_capturing, demo_caption_buffer, last_output_area. Rendering: render_demo_overlays / render_badge_box / render_caption_box / fill_overlay_rect in ui.rs; colours DEMO_OVERLAY_FG/BG in theme.rs; key handling handle_demo_caption_key + the top-of- handle_key gate; timer in runtime.rs (nearest_deadline, DEMO_BADGE_TTL).

§7. Remaining open landscape (from handoff-63, minus the closed items)

  1. Wire the overlays into the website castscasts.mjs on the website branch can now emit ^]/text/^] for captions and rely on automatic badges. Website-branch follow-up (OOS for #22's app scope).
  2. TT5 CI — 2290 green, no pipeline yet.
  3. SD1 seed then H2 hint — the unblockers for A1 app-commands; own ADRs.
  4. V2/S3 multi-result tabs / V4 journal — larger output-model redesign, own ADR.
  5. C3a modify relationship — small (drop+add covers it).
  6. Tutorial/lesson system — acknowledged in scope; needs its own ADR; ADR-0047's overlay primitive is what it will reuse.

Run a cargo sweep at some point — target/ grew across this build-heavy session.