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_okandbucket_b_multi_line_echo_renders_one_line_per_statement_beneath_okonly checked line text. After the polish, every echo line is pushed viapush_teaching_echoand carriesOutputKind::TeachingEcho— and the kind is what firesui::render_output_line's dim-prefix + advanced-lex branch. A regression to plainSystemwould leave the text intact while silently breaking the styling. Theassert_echo_beneath_okhelper now pinskind == TeachingEchoon 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 illuminatingclient_side_notes(shortid / serial auto-fill, perclient_side.auto_fill_*keys) now route throughpush_category_three_prose, producing a System line with a whole-text Hint span. The closely-related caveat path was already pinned bypolished_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
OutputKindmatches inui.rs(tag_len, tag, Echo- branch detection, body_style) handle the new variant; no other code matches onOutputKind. OutputStyleClass::Hintresolution 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_runsfor prose) follows the precedent established byOutputKind::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
2aab457commit message and theen-US.yamlcomment overstate the reasonTEACHING_ECHO_LABELbecame 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 customui::render_output_linebranch that mirrors theOutputKind::Echosimple-mode input-echo path: strip the canonicalcrate::echo::TEACHING_ECHO_LABEL("Executing SQL: "), render the prefix dimmed (theme.muted), then lex the rest inMode::Advancedviainput_render::lex_to_runs_in_modeand emit one span per token. Tag stays[system]for visual consistency with other system output.OutputStyleClass::Hint(new), resolved totheme.mutedbyoutput_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 theecho.executing_sqli18n 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_summaryandhandle_dsl_change_column_success/handle_dsl_add_column_successuse these instead of plainnote_systemfor 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_notes →
push_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_foris called for every command; the Schema arm recomputes viabuild_schema_echo(whose catch-all redelegates tocommand_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: letsexplainwrap the advanced SQL commands (Select/SqlInsert/SqlUpdate/SqlDelete) in addition to the DSLShowData/Update/Deleteit 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/I1bmulti-line + readline shortcuts,I3tab completion polish,I4syntax highlighting beyond input echo). - Polish-spawned ideas from this session — none currently
outstanding; the OutputStyleClass vocabulary now has
Hintand 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.mdindex +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
- Read, in order: this file →
requirements.mdfor 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. - Baseline:
cargo test(2020 / 0 / 1) +cargo clippy --all-targets -- -D warnings(clean). - For a fresh feature: write the ADR (or extend an existing
one), run
/rundaover the design before building, then build test-first. - 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 inui::output_span_style, used viaOutputLine::styledor a dedicated kind + custom render branch (asTeachingEchodoes for the dim-prefix + lex-rest case).