# Session handoff — 2026-06-14 (69) Sixty-ninth handover. Continues from handoff-68 (an issue-burndown that closed #25/#26/#31/#32/#33/#34). This session **closed the four remaining open issues** — #29, #28, #27, #30 — each landed with the full phased workflow + `/runda` + Devil's-Advocate passes before commit, and each producing a new ADR. Net: **four issues closed, four commits, four new ADRs (0049–0052), +63 tests, zero regressions, the tracker is now empty.** The four interlock: **#29** added the input-field readline keys, **#27** advertises them in a state-aware status strip, and **#30**'s history recall now respects modes. **#30** also turned into a real architecture change (journaling relocation) — read §2.4 carefully before touching that area. ## §1. State at handoff **Branch:** `main`. Working tree **clean**; all work committed. The two most recent commits are local (normal working state — push is the user's step). **Tests: 2471 passing / 0 failing / 0 skipped / 1 ignored** (the long-standing `friendly` doctest). **Clippy clean** (nursery, all targets). Breakdown: 1771 lib + 500 integration (`it`) + 200 typing-surface-matrix. **+35 over handoff-68's 2436** (net: #29 +22, #28 +0, #27 +9, #30 +4 — its new history.rs/app.rs/iteration6 tests minus the 15 retired worker-journaling tests; trust the live `cargo test` count). **Commits this session:** ``` 4aeea55 feat(history): mode-tagged history + top-of-chain journaling (#30) eceedc1 feat(ui): context- and state-aware bottom keybinding strip (#27) 8ac3537 feat(render): incidental-DDL confirmations show structure only, no relationships (#28) 66c8bda feat(input): readline keymap — Esc-clear + Ctrl-A/E/W/K/U (#29) ``` **Open Gitea issues: none.** `tea issues list --state open` is empty. ## §2. Issues closed this session (all committed, tested, `/runda`-reviewed) Each closed on `git.lazyeval.net/oli/rdbms-playground` with a summary comment. ### 2.1 — #29 (`66c8bda`) — input-field readline keymap (ADR-0049) Implements the deferred **I1b** readline shortcuts: `Esc` clears a partly-typed command (only when no completion memo is alive — the memo wins first, ADR-0022); `Ctrl-A`/`Ctrl-E` = Home/End; `Ctrl-W` deletes the previous word (readline-style, UTF-8 safe); `Ctrl-K`/`Ctrl-U` kill to end/start. Cursor-only keys leave history nav intact; buffer-mutating keys end it. **DA caught** the need for the `Ctrl-O`+`Esc` (sidebar nav-exit) interaction not to clear the draft — locked with a regression test. `requirements.md` I1b → `[x]`. ### 2.2 — #28 (`8ac3537`) — incidental-DDL confirmations: structure-only (ADR-0050) Incidental-DDL confirmation echoes (`create table`, `add`/`drop`/ `rename`/`change column`, `add`/`drop index`) now render **structure only** — no `References:` / `Referenced by:` block. Relationship-subject surfaces (`show table`, `add`/`drop relationship`) keep their ADR-0044 diagrams. The prose renderer (`relationship_prose_lines` + `cols_disp`) was deleted. **Supersedes** ADR-0044 §1's incidental-DDL prose clause and the relationship-block half of ADR-0016 §5 (both annotated). ### 2.3 — #27 (`eceedc1`) — context- and state-aware keybinding strip (ADR-0051) The bottom status line is now keystrokes-only and **state-selected** by priority (sidebar focus / completion-memo / history-nav / editing / default). The editing state surfaces the #29 keys (closing ADR-0049's deferred advertisement). Mode-switch advertisements left the strip; the empty-input hint gained a simple-mode `` `mode advanced` for SQL `` pointer (advanced mode shows none — user decision). New `App::is_browsing_history()` exposes the private `history_cursor`. 15 full-panel snapshots re-accepted. ### 2.4 — #30 (`4aeea55`) — mode-tagged history + top-of-chain journaling (ADR-0052) **← read before touching journaling** Closed both the feature (advanced history reusable in simple mode) and the bug (the `:` one-shot prefix lost across sessions). Two halves: 1. **Mode-tagged history.** The `history.log` status token gains an optional `:adv` suffix (`ok` / `ok:adv` / `err` / `err:adv`); `source` stays last + canonical so replay is unaffected. The in-memory ring (still `Vec`) stores advanced entries in their `: `-prefixed simple-mode runnable form; recall **strips the `:` in advanced mode** and keeps it in simple; hydration reconstructs the prefix from the tag. App commands journal simple and are excluded from the ring's advanced flag, so they recall bare. 2. **Journaling relocation (the architecture change).** Success journaling **moved out of the worker** to the dispatch layer (`spawn_dsl_dispatch` / `run_replay` / the app-command sites), next to the already-top-level failure journaling — so the submission mode is in scope with no worker plumbing. `finalize_persistence` now writes only the **state** sources (yaml/csv); the journal write is **best-effort** (the command is already committed — consistent with the failure path). **Amends ADR-0015 §6** (history.log out of the worker tx; commit-db-last scopes yaml/csv/db only), **ADR-0034** (status tag + journaling location), **ADR-0040** (journal-write best-effort, not fatal). **Two DA findings, both resolved:** (a) the app-command `advanced` flag must exclude app commands (else `: save as` diverges); (b) the spawn journals on `outcome.is_ok()`, so journaling is now **uniform** — read commands that didn't journal before (`show tables`/`show relationships`/ `show indexes`, `show relationship `, `explain`) now do, matching ADR-0034 §1. **User-confirmed** as the more-correct behaviour (harmless on replay — reads/`explain` don't mutate). **Test migration:** 15 worker-level journaling tests were retired (the worker no longer journals — their yaml/csv/operation assertions were kept) and re-covered at the new layer: `history.rs` status-tag + `:`-reconstruct; `app.rs` recall matrix; the cross-session regression `advanced_command_journalled_then_hydrated_recalls_with_colon_in_simple` in `iteration6_resume_history`; the replay tests cover `run_replay` journaling. Plan: `docs/plans/20260613-issue-30-top-of-chain-journaling.md`. ## §3. Next session — start here The user's stated plan for the next session, in order: 1. **Pick up the ADR-0052 follow-up** (below). 2. **Check for any newly-filed open issues** (`tea issues list --state open`) — none at handoff, but check fresh. 3. **Then** take on remaining open tasks from the general requirements (`docs/requirements.md`) — see §5. ### The ADR-0052 follow-up — unwind the vestigial worker `source` plumbing When journaling moved out of the worker, the `source` that the worker threaded purely for journaling became dead. To avoid orphaning the param across ~28 handlers, the refactor **left it in place** as vestigial: - `finalize_persistence(conn, persistence, _source, changes)` — the `_source` param is now unused (kept so its ~28 callers still pass `source`, which they otherwise also use for `snapshot_then`). - `do_rebuild_from_text(conn, _persistence, _source, project_path)` — both `_persistence` and `_source` vestigial. - Three thin read-only wrappers in `db.rs` — `do_describe_table_request`, `do_query_data_request`, `do_run_select_request` — now just delegate to their non-`_request` twin (`do_describe_table` / `do_query_data` / `do_run_select`) with vestigial `_persistence` / `_source` params and one caller each (`db.rs` Request arms ~2409 / ~2749 / ~2759). **The cleanup:** remove `_source` from `finalize_persistence` + drop the arg at its ~28 callers (the callers keep `source` for `snapshot_then`, so only the `finalize_persistence(...)` call loses the arg); remove the `_persistence`/`_source` params from `do_rebuild_from_text`; and inline the three `*_request` wrappers at their single call sites (replace `do_describe_table_request(conn, persistence, source, name)` with `do_describe_table(conn, &name)`, etc.), deleting the wrappers. Purely mechanical, compiler-guided, no behaviour change. Establish the green baseline first (`cargo test`), then verify nothing moved. ## §4. Carried-over follow-up (website branch, not `main`) - **Website `seed` cast re-record** (from #34, handoff-68 §4) — still tracked on the `website` branch, not here. Likely redundant (full re-record sweep before publication). ## §5. Remaining roadmap — `docs/requirements.md` (next session's §3-step 3) With the issue tracker empty, the next work comes from the document-based requirements. Open / partial items worth weighing (the user picks): - **H2 `hint`** — the last A1 gap (contextual help for the current command); its own ADR. (`requirements.md` H2.) - **TT5 CI** — runs all tiers on Linux/macOS/Windows; no CI workflow yet (a `ci` branch reportedly exists — check its state first). Couples with **D1–D3** (cross-platform prebuilt binaries + Homebrew/Scoop). - **TT4 PTY (Tier-4)** — ADR-0008 specifies the PTY harness + four critical flows; still not wired (no PTY deps/tests). - **I1 multi-line input** (Ctrl-Enter submits, Enter inserts newline) and **I5 / B3 in-flight cancellation** (Ctrl-C cancels a running command). - **V4 session journal** — scrollable per-session log + Markdown export (the bigger UX project; own ADR). - **TU1 tutorial / lesson system** — design + ADR pending (acknowledged in scope). - Smaller partials: **C3a** modify relationship (drop+add covers it today), **C4** m:n convenience, **V3** ER-diagram export, the **NFR-*** performance/visual targets (mostly unmeasured), **N4** global rolling history (OOS for v1). No strong ordering — these are the user's call. Several need a new ADR (H2, V4, TU1); CI/release (TT5/D1–D3) is the most "shippable-product" track if that's the priority. ## §6. How to take over 1. Read handoffs 67 → 68 → 69, `CLAUDE.md`, `docs/requirements.md`. 2. Confirm green baseline: `cargo test` (expect **2471 pass / 1 ignored**) + `cargo clippy --all-targets` (clean). 3. `tea issues list --state open` — pick up anything new first. 4. Then the ADR-0052 follow-up (§3), then requirements (§5). 5. Follow the project workflow: phased (requirements → divergent → eval → execute → verify), test-first, `/runda` + DA pass before every commit, ADR amendment for any decided-area change + the README index-upkeep rule, and confirm the commit message with the user before committing. 6. Consider a `cargo sweep` at this milestone (`target/` grows across sessions; see CLAUDE.md "Build hygiene"). (`sweep.timestamp` was removed this session.)