Files
2026-05-28 12:44:47 +00:00

13 KiB

Session handoff — 2026-05-28 (49)

Forty-ninth handover. ADR-0038 is done — and twice DA-audited. Every catalogue row of the DSL → SQL teaching echo is implemented, every echo round-trips per line per the §1 copy-paste contract, every §6 category-3 line surfaces, the §4 de-emphasised styled-runs rendering polish landed in 2aab457, and a closing /runda Devil's- Advocate pass over the polish (6840b92) pinned three minor wiring gaps. Docs in sync. If you continue, pick a fresh feature; if you're triaging, ADR-0038 won't surprise you.

§1. State at handoff

Branch: main. HEAD 6840b92. Tests: 2020 passing, 0 failing, 0 skipped, 1 ignored. Clippy: clean (--all-targets -D warnings, nursery).

Commits since handoff-48's df5c4e2:

6840b92 test: /runda round 2 — pin TeachingEcho kind + cat-3 prose wiring
63b2927 docs: session handoff 49 — ADR-0038 done, M4 + ADR statuses in sync
2aab457 feat: DSL→SQL teaching echo — §4 styled-runs polish (ADR-0038)

The first version of this handoff went out with 63b2927 at HEAD; this amendment (committed after 6840b92) records the closing /runda round 2 below.

§2. ADR-0038 — done

The feature shipped across five commits, the last of which is the §4 polish:

Commit Phase What
handoff-46 04c8e42 1 (start) channel + create-table slice
90479cb 1 (rest) Bucket A renderer — every single-statement DDL row + show data + --all-rows fall-throughs; create-table contract-gap fix
275c726 2 Bucket B — resolved-name + multi-statement (auto- and user-named add index, positional drop index, add/drop relationship in both selector forms, drop column --cascade, add relationship --create-fk)
e6ad1ae 3 category-3 prose — change column --dont-convert caveat (the other two cat-3 lines were already in place via client_side.* keys)
2aab457 4 (polish) §4 styled-runs rendering — OutputKind::TeachingEcho with dimmed prefix + advanced-mode lex of the SQL; OutputStyleClass::Hint for every cat-3 prose line

Plus two /runda Devil's-Advocate passes — 5cb105b after Phase 3 (doc-drift + Bucket C explicit no-echo tests) and 6840b92 after the polish (kind assertions on every echo arm + the broader-scope client_side notes pinning, see §3a below). Neither pass escalated.

ADR-0037 and ADR-0038 both Accepted with implementation notes referencing every shipping commit.

§2a. /runda round 2 findings (closed by 6840b92)

A second Devil's-Advocate pass over the polish surfaced three test-coverage gaps the polish itself had left behind. All three were closed in 6840b92; tests-only commit (+98 lines in src/app.rs), no production code touched.

  • bucket_a_success_events_render_the_teaching_echo_beneath_ok and bucket_b_multi_line_echo_renders_one_line_per_statement_beneath_ok only checked line text. After the polish, every echo line is pushed via push_teaching_echo and carries OutputKind::TeachingEcho — and the kind is what fires ui::render_output_line's dim-prefix + advanced-lex branch. A regression to plain System would leave the text intact while silently breaking the styling. The assert_echo_beneath_ok helper now pins kind == TeachingEcho on every event arm the bucket_a test covers (six arms in one shot); the bucket_b test pins it on each of the three multi-statement lines.
  • add_column_client_side_notes_render_as_category_three_prose (new) pins the broader-scope polish: handle_dsl_add_column_success's illuminating client_side_notes (shortid / serial auto-fill, per client_side.auto_fill_* keys) now route through push_category_three_prose, producing a System line with a whole-text Hint span. The closely-related caveat path was already pinned by polished_echo_carries_teaching_echo_kind_and_caveat_a_hint_span; this completes the cat-3 prose coverage symmetrically.

What the round-2 pass verified clean (no action needed) — kept here as a flight log so the next session doesn't re-walk the same ground:

  • All four OutputKind matches in ui.rs (tag_len, tag, Echo- branch detection, body_style) handle the new variant; no other code matches on OutputKind.
  • OutputStyleClass::Hint resolution works on both light + dark (hint_class_resolves_to_muted_foreground).
  • ADR-0028 §7 OOS "no re-styling existing output" is not violated: ADR-0038 takes ownership of styling its own cat-3 content; the broader-scope was user-confirmed and recorded.
  • The hybrid styling (custom path for SQL via lex_to_runs + styled_runs for prose) follows the precedent established by OutputKind::Echo / ADR-0022 §5; ADR-0028 §5 anticipates this ("any output line may now carry rich styling").
  • Replay bypass unchanged; no AI attribution anywhere; clippy clean.

Acceptable observations the round-2 pass left documented but not fixed — none warranted escalation:

  • The 2aab457 commit message and the en-US.yaml comment overstate the reason TEACHING_ECHO_LABEL became a const ("i18n template couldn't provide that"). Reality: simpler + avoids resolving i18n per render (a hot path). Historic — not amending; this handoff is the more accurate forward-looking reference.
  • The two rendering-path tests (teaching_echo_line_renders_dim_prefix_and_lexed_sql, category_three_prose_line_renders_all_dim) only use the dark theme; the rendering logic is theme-agnostic and the class resolution is pinned for both, so this is pedantic-incomplete rather than a real gap.
  • No full-pipeline integration test driving submit → spawn → render (same observation as §4 below, restated for completeness).

§3. What the polish (Phase 4) does, in shape

Per ADR-0038 §4 + §6, the de-emphasised styled-runs treatment landed in 2aab457. The user-confirmed scope (per session discussion) went slightly beyond §4's "echo + caveat" to cover the existing illuminating cat-3 notes too — visual consistency for every cat-3 prose line, matching §6's "de-emphasised prose line" wording.

The polish in code:

  • OutputKind::TeachingEcho (new). Lines with this kind go through a custom ui::render_output_line branch that mirrors the OutputKind::Echo simple-mode input-echo path: strip the canonical crate::echo::TEACHING_ECHO_LABEL ("Executing SQL: "), render the prefix dimmed (theme.muted), then lex the rest in Mode::Advanced via input_render::lex_to_runs_in_mode and emit one span per token. Tag stays [system] for visual consistency with other system output.
  • OutputStyleClass::Hint (new), resolved to theme.muted by output_span_style. Carried on category-3 prose lines as a single styled-runs span covering the whole text (so the body renders dimmed; the [system] tag keeps its kind tint).
  • crate::echo::TEACHING_ECHO_LABEL (new pub const) — the fixed byte boundary the ui.rs branch needs. The label moved out of the echo.executing_sql i18n key (now retired in en-US.yaml + keys.rs; a comment in en-US.yaml points future locales at re-introducing it).
  • App-side helpers: App::push_teaching_echo(sql) builds the TeachingEcho line; App::push_category_three_prose(text) builds a System line with a whole-text Hint span. note_ok_summary and handle_dsl_change_column_success / handle_dsl_add_column_success use these instead of plain note_system for the echo, the DontConvert caveat, and the illuminating client-side notes.

Where each rendering rule lives:

Line Built by Renders as
[ok] verb subject note_ok_summary via note_system [system] tag + system green body (unchanged)
Executing SQL: <sql> (one per echo line) push_teaching_echo [system] tag + dimmed prefix + token-coloured SQL
[client-side] N row(s) were transformed … push_category_three_prose (auto_fill_, transformed) [system] tag + whole-body dim
[client-side] --dont-convert kept … push_category_three_prose (caveat path) [system] tag + whole-body dim
structure render, row counts, etc. note_system unchanged

Coverage: four new tests landed with the polish itself (2aab457) — ui::tests::teaching_echo_line_renders_dim_prefix_and_lexed_sql (asserts the dim prefix span + keyword-coloured SQL spans confirm advanced-mode lex), ui::tests::category_three_prose_line_renders_all_dim (whole-text Hint coverage), ui::tests::hint_class_resolves_to_muted_foreground (theme resolution across both palettes), and app::tests::polished_echo_carries_teaching_echo_kind_and_caveat_a_hint_span (App-side wiring kinds + styled_runs shape on the caveat path). The pre-existing echo tests pass unchanged — the text content is identical, only styling changed. The /runda round 2 (6840b92) added three more (see §2a): kind assertions on every event arm covered by the bucket_a / bucket_b multi-statement tests, plus a focused test pinning the broader-scope client_side_notespush_category_three_prose path on add column.

§4. Notable observations carried over from handoff-48

These are the same ones flagged before the polish — none became blockers, the polish didn't introduce new ones.

  • Unquoted-identifier round-trip caveat. Echo style is bare identifiers (matching the original create-table echo aesthetic). A user-created column or table named after a SQL keyword (e.g. ORDER, SELECT) would produce an echo whose round-trip is fragile. Pre-existing limitation; the §1 contract is only formally violated for this edge case. Fix is identifier-quoting if it ever bites a learner.
  • No full-spawn integration test for the echo pipeline. Coverage is layered (pure renderers + runtime-helper unit tests with real Database + App-level rendering tests + ui.rs styling tests). The unwired glue is small; a Tier-3 end-to-end test would complete the picture, not blocking.
  • Pure-Command Schema commands double-compute echo. echo_for is called for every command; the Schema arm recomputes via build_schema_echo (whose catch-all redelegates to command_to_sql). Minor inefficiency, no behaviour bug.

§5. What's next

Up to you. ADR-0038 won't pull on any more rope. Candidate features:

  • ADR-0039 — EXPLAIN over advanced-mode SQL queries (Accepted, implementation deferred). Self-contained: lets explain wrap the advanced SQL commands (Select/SqlInsert/SqlUpdate/ SqlDelete) in addition to the DSL ShowData/Update/Delete it already covers (ADR-0028). Test-first when picked up.
  • Other tracks from requirements.md — see the file for the pending list. Likely candidates: track 2 (project storage Iter 5/6 — export/import + --resume + persistent input history + migration framework), C3a (modify relationship), C4 (m:n convenience), H1/H1a (friendly error layer + syntax-help in parse errors), the tutorial/lesson system, V4 session log + Markdown export, the remaining input UX items (I1/I1b multi-line + readline shortcuts, I3 tab completion polish, I4 syntax highlighting beyond input echo).
  • Polish-spawned ideas from this session — none currently outstanding; the OutputStyleClass vocabulary now has Hint and could grow further if another consumer needs it.

§6. Process pins (unchanged)

  • Confirm every commit (propose message, wait). No AI attribution.
  • Test-first; green + clippy-clean is the only acceptable end state; current baseline 2020 / 0 / 1.
  • Keep docs lockstep: ADR + README.md index + requirements.md. This session's polish commit ships alongside this handoff and the three doc-update edits (M4 / ADR-0038 Status / ADR-0037 + ADR-0038 README index entries).
  • Round-trip every catalogue row (the §1 copy-paste contract; for multi-statement, per line).

§7. How to take over

  1. Read, in order: this file → requirements.md for the open tracks → the relevant ADR for whatever feature you pick up. ADR-0038 / ADR-0037 are done and well-documented; touch them only to amend if a real correction comes up.
  2. Baseline: cargo test (2020 / 0 / 1) + cargo clippy --all-targets -- -D warnings (clean).
  3. For a fresh feature: write the ADR (or extend an existing one), run /runda over the design before building, then build test-first.
  4. The ADR-0028 styled-runs vocabulary is now richer: Neutral, Efficient, Expensive, AutomaticIndex, Hint. Adding a new consumer? Pattern is one variant per semantic class, theme-resolved in ui::output_span_style, used via OutputLine::styled or a dedicated kind + custom render branch (as TeachingEcho does for the dim-prefix + lex-rest case).