Files
rdbms-playground/docs/handoff/20260530-handoff-52.md

254 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Session handoff — 2026-05-30 (52)
Fifty-second handover. **A five-issue UI/UX bug-and-feature run** off
handoff-51's open list (#7#16). Closed **#8, #13, #12, #7, #9** —
two bounded fixes, one feature implementation (advanced-mode
`explain`), and one first-principles output-convention redesign. Two
ADRs touched: **ADR-0039 implemented**, **ADR-0040 authored**; plus
**ADR-0022 Amendment 4**.
The session is worth reading for **process**: every substantial change
went reproduce-first → design (often via the Plan agent) → `/runda` on
the design → test-first build → **live-app verification in a real TUI**
`/runda` on the implementation → commit → close. The live-app and
implementation-`/runda` passes each caught real defects a green test
suite had not (see §3).
## §1. State at handoff
**Branch:** `main`. **HEAD `8311de4`.** **Ahead of `origin/main` by
1** — only #9's commit (`8311de4`) is unpushed; #8/#13/#12/#7 were
pushed by the user between issues. **Tests: 2089 passing / 0 failing /
1 ignored** (the same pre-existing ignored doctest as prior baselines).
**Clippy: clean.** Push is the user's step.
Commits since handoff-51's `46a3128`:
```
8311de4 feat: replace the [ok] summary line with a ✓/✗ echo marker (#9)
f62ccce feat: support explain over advanced-mode SQL queries (#7)
f7ca288 fix: grow the hint panel for long prose hints (#12)
5ea69db fix: widen undo dialog and polish its summary line (#13)
d20f765 feat: give column data types a dedicated syntax-highlight colour (#8)
```
Test count moved 2051 → 2089 (+38) across the five commits.
## §2. Two process habits that paid off (read this)
1. **Live-app verification catches what tests miss.** Driving the real
binary in a tmux pane (per the standing agreement) surfaced things
green tests didn't: it confirmed #7's plan-tree rendering end-to-end
and validated #9's `✓/✗` across success/failure/skip/parse-error in
one pass. **Caveat (recurring):** the login shell is fish, which
rejects `VAR=value cmd` and bash-isms; **send `exec bash` to the
pane first**, then launch with `--data-dir <tmpdir> --log-file …`.
Isolate with `tmux -L <name>` + a `mktemp -d` data dir; tear down
after.
2. **`/runda` on the *implementation*, not just the design.** Both #7
and #9 had a design `/runda`; running it **again on the finished
diff** caught real holes each time — #7 was missing `explain insert`
execution coverage and had a duplicate-`help` entry; #9's
`PersistenceFatal` path left a dangling `running:` echo. None failed
a test. Treat the implementation `/runda` as mandatory for
substantial work.
## §3. Resolved issues
### #8 — type keywords get a dedicated highlight colour (`d20f765`)
Root cause: `Node::Ident.highlight_override` **and** the `Word`
struct's `highlight_override` were both **dead** — the walker driver
discarded the Ident's and `walk_word` hardcoded `Keyword`. So column
types (`int`, `serial`) rendered identical to identifiers. Wired both
through; added `HighlightClass::Type` + a dedicated `tok_type` theme
colour (pink/deep-magenta, distinct from keyword-purple and
identifier-teal — user chose a dedicated colour over reusing the
keyword colour). The three `IdentSource::Types` slots + the two-word
`double precision` alias (via a new `Word::type_keyword` constructor)
opt in. **ADR-0022 Amendment 4.** The `double precision` thread also
clarified that the advanced-mode SQL type *aliases* (`integer`,
`varchar`, `float`, … → the ten playground types) live in **ADR-0035
§3** (restating ADR-0030 §5) — they are accepted input spellings, not
members of the type set.
### #13 — undo dialog width + language polish (`5ea69db`)
Dialog capped at 60 cols and wrapped even a short insert; lowercase
`snapshot`/`yes`/`no`; raw ISO timestamp. Now: content-aware width
(`undo_dialog_width`, 34100, never exceeds area); capitalised
`Snapshot`/`Yes`/`No`; **local-time, human-formatted timestamp**
(`24 May 2026, 11:00`) via a **new `chrono` dependency** (user chose
the real date crate; `clock` feature only, no `unstable-locales`).
`Esc cancel` was already inline (resolved in a prior session — no
change). Reproduce-first confirmed each sub-item.
### #12 — hint panel grows for long prose hints (`f7ca288`)
The Hint panel was a fixed one row; long **prose** hints (insert
field-value hints, `parse.usage.*`) wrapped but were clipped — the
useful tail hidden. (The candidate list already scrolled horizontally.)
Now: dynamic height 1→**3 rows** (user's cap, "see how it lands"),
reclaimed when short, with an **ellipsis backstop** on row 3.
`resolve_hint_lines` pre-wraps; `render_right_column` sizes the panel.
**ADR-0022 Amendment 5.** Also **shortened** the standout offender,
`parse.usage.sql_create_table` (299 chars → terse one-liner; full
grammar stays in `help.ddl.sql_create_table`) — measured all hint
strings first and the user chose to shorten that one.
### #7 — `explain` over advanced-mode SQL (`f62ccce`, ADR-0039 implemented)
`explain` now wraps `select` / `with` (CTE) / `insert` / `update` /
`delete` in advanced mode, reusing the ADR-0028 plan tree.
**Mechanism:** a second `Advanced` `EXPLAIN_SQL` CommandNode under the
shared `explain` entry word, reusing the established `insert`/`update`/
`delete` shared-word dispatch (`decide`: SQL-first, DSL-fallback) — no
new grammar machinery. **Rejected** a `DynamicSubgrammar` mode-gate
(its resolution cache key omits `mode`, so it would serve stale
wrong-mode nodes — a real bug the Plan agent found).
`build_explain_sql` slices the inner SQL off the source (excludes the
`explain` prefix) and reuses the existing SQL builders; `do_explain_
plan` runs the carried text verbatim, no params. Advanced
`explain update`/`delete` now route through SQL (identical plan, full
SQL syntax); DSL-explain tests pinned to simple mode. WITH/CTE included
(it's a `Select`, in scope). The implementation `/runda` added 2
`explain insert` execution tests + a REGISTRY `help_id`-uniqueness
invariant test, and fixed a duplicate-`help` entry + stale usage/help
text.
### #9 — `[ok]` summary line → `✓/✗` echo marker (`8311de4`, ADR-0040)
**The substantial one.** Began as "`[ok] explain` is terse" (and
post-#7, `explain select` rendered `[ok] explain` with an *empty*
subject). The user steered it to a first-principles audit: the
`[ok] <verb> <subject>` line **duplicated** the echo line above it on
every command; its only unique signal was success-vs-error.
**Decision (ADR-0040):** retire the `[ok]` summary line and the
symmetric `"<verb> <subject>" failed:` prefix. A command's echo line
resolves `running: <input>``<input> ✓` (success) / `<input> ✗`
(runtime failure) on completion; the failure reason still renders
beneath (`[error]`-tagged). Content lines unchanged.
**Mechanics:** `EchoStatus { Pending, Ok, Err }` on the echo
`OutputLine`; executed commands push `Pending` (via `OutputLine::echo`)
and the result event resolves the **oldest** pending echo
(`mark_oldest_pending_echo`) — correct under interleaving because the
db worker is FIFO. **Scope:** executed commands only (success/runtime-
failure/skip/replay); **parse-time and pre-flight rejections keep their
`running:` + caret rendering** (they never run, and their caret is
pinned to the `running:` prefix). **App-command `[ok]` lines**
(`rebuild`/`export`/`now editing`/`replay — N`) are payload-bearing,
have no echo to mark, and stay as-is. `ok.summary` retired from catalog
+ keys; `dsl.failed` reduced to `{rendered}`.
Implementation `/runda` caught the `PersistenceFatal` arm leaving a
dangling `running:` echo (now marks `✗` before the quit banner).
## §4. ADR / docs work
- **ADR-0022 Amendment 4** (`d20f765`): dedicated type highlight class;
both dead `highlight_override` fields wired through. README index +
requirements.md I4.
- **ADR-0022 Amendment 5** (`f7ca288`): dynamic hint-panel height.
README index + requirements.md QA1-area.
- **ADR-0039 status → implemented** (`f62ccce`): + an Implementation
section recording the two-CommandNode mechanism and the rejected
`DynamicSubgrammar`. README index, requirements.md QA1, CLAUDE.md.
- **ADR-0040 — new** (`8311de4`): the completion-marker decision, the
audit, scope, and an Implementation-notes section. README index,
requirements.md (ADR-0038 echo line note), CLAUDE.md untouched (no
`[ok]` reference there).
## §5. What's open
### Bug reports still open (filed handoff-50)
| # | Title | Label |
|---|---|---|
| [10](https://github.com/oliversturm/rdbms-playground/issues/10) | `[error]` tag colour identical to `[system]` (ADR-0037 gap) | enhancement |
| [11](https://github.com/oliversturm/rdbms-playground/issues/11) | Copy output panel contents to the system clipboard | enhancement |
| [14](https://github.com/oliversturm/rdbms-playground/issues/14) | `--resume` should restore the last-used input mode | enhancement |
| [15](https://github.com/oliversturm/rdbms-playground/issues/15) | Tab completion: offer common SQL function names | enhancement |
| [16](https://github.com/oliversturm/rdbms-playground/issues/16) | Restore typing-time column-typo hint via known-function list | enhancement |
**Closed this session:** #8, #13, #12, #7, #9.
### Categorisation / notes for pickup
- **#10 (`[error]`/`[system]` tag colour)** is now the most adjacent:
ADR-0040 kept the `[error]` tag on failure-reason lines, so the
colour collision is still live and pairs naturally with the marker
work. Needs an **ADR-0037 amendment** (it owns output tag styling).
- **#15 + #16** are a pair — do **together** (shared curated
SQL-function-list infrastructure; both spawned from #6).
- **#14** ties to ADR-0015 Iter 6 (`--resume` + persistent input
history).
- **#11** clipboard copy — self-contained.
### Other tracks (from requirements.md)
- Track 2 project storage Iter 5/6 — export/import + `--resume` +
persistent input history + migration framework.
- C3a (modify relationship), C4 (m:n convenience).
- H1 friendly DB-error layer (partial); tutorial/lesson system (needs
its own ADR); V4 session log + Markdown export; I1/I1b multi-line +
readline; I3 tab-completion polish; I4 highlighting beyond input echo.
## §6. Process pins (carried forward + this session's reinforcements)
- **Reproduce-first.** Confirm every bug still reproduces on current
HEAD before designing a fix (handoff-51 §2.1). Held all session.
- **`/runda` on BOTH design and implementation** for substantial work
(this session's §2.2). Each impl pass found a real defect.
- **Live-app verification** for user-facing changes — drive the real
TUI (tmux, `exec bash` first, isolated `--data-dir`). It finds things
tests miss.
- **No easy-way-out on architectural discrepancies** (handoff-51 §2.2):
prefer the unifying fix. #8 unified both dead `highlight_override`
fields; #7 reused the shared-word dispatch rather than bolting on a
`DynamicSubgrammar`; #9 redesigned the convention rather than patch
one verb.
- **Escalate genuine design forks** — this session asked the user on
every real fork (type colour, date-crate scope, hint mechanism +
cap, WITH-in-explain, marker scope, attribution robustness). The
AskUserQuestion previews were useful for visual choices.
- **Confirm every commit** (propose message, wait). **No AI
attribution. No issue numbers in commit messages** (issue bodies +
close comments reference freely). **Push is the user's step**; the
user pushed between issues and then said "close" — close-with-summary
after that.
- **cargo-insta is NOT installed** as a subcommand. Accept pending
snapshots with `mv -f <f>.snap.new <f>.snap` after reviewing the diff.
- **GitHub issues** via `gh` CLI (Gitea/`tea` migration still later).
- Baseline to beat: **2089 / 0 / 1**, clippy clean.
## §7. How to take over
1. **Read, in order:** this file → `docs/requirements.md` (open
tracks) → `docs/adr/README.md` → the relevant ADR. For output
conventions, **ADR-0040** is now the authority on the `✓/✗` marker;
**ADR-0037** owns the `[error]`/`[system]` tag colours (#10's home).
For `explain`, **ADR-0039** (implemented) + **ADR-0028**.
2. **Baseline:** `cargo test` (2089 / 0 / 1) + `cargo clippy
--all-targets` (clean).
3. **For a bug fix:** reproduce on current HEAD first (probe-test or
live app), then failing test → fix → green → `/runda` (design and,
for substantial work, implementation) → live-verify if user-facing →
commit-with-approval → user pushes → close-with-summary.
4. **Pick next from §5.** #10 is the natural follow-on to #9 (tag
colours, ADR-0037 amendment). #15+#16 go together.
5. **Architectural notes for future readers:**
- **Echo lifecycle (ADR-0040):** echo lines carry `EchoStatus`;
`mark_oldest_pending_echo` resolves them on result events. Any new
command-result event arm MUST mark its echo (success→Ok,
failure→Err, skip→Ok) or it strands a `running:` line. The
renderer's Echo branch + the height calc both key on status.
- **`explain` (ADR-0039):** `EXPLAIN_SQL` is a second `Advanced`
CommandNode on the shared `explain` word; `build_explain_sql`
slices the inner SQL and reuses the SQL builders. Keep that.
- **Highlight overrides (ADR-0022 Am4):** both `Node::Ident` and
`Word` honour `highlight_override` now; `Word::type_keyword` is the
typed-keyword constructor.