handoff-19 §2 now records the two bugs as fixed (was "queued next"): the optional trailing-flag completion fix (f239ca5) and the --resume temp-project pointer fix (3a40ae2). §5 drops them from "what's next" — ADR-0028 is now the natural next pick. State/§6 updated to 10 commits and 1131 tests; requirements.md test baseline → 1131.
11 KiB
Session handoff — 2026-05-19 (19)
Nineteenth handover. A focused implementation run that finished ADR-0027 and then fixed two manual-testing bugs. The §4 "known follow-ups" from handoff-18 are all done: ADR-0027's §2 always specified that "highlighting and the hint panel read the individual diagnostics" — handoff-18 shipped the indicator and the model but left that wiring as a follow-up. It is now wired. Two unrelated bugs the user found mid-run (§2) are also fixed.
Headline: the diagnostics are visible where they happen.
An unknown table / column (ERROR) and a dubious comparison
(WARNING — type mismatch, = NULL, and now LIKE on a
numeric column) are overlaid on the input field globally
and explained in the hint panel — not just summarised by the
[ERR] / [WRN] indicator.
State at handoff
Branch: main. Working tree clean. 10 commits since
handoff-18 (39b92a7), all local — push asynchronously, not
blocking.
<this file> docs: handoff 19 update — both manual-testing bugs fixed
3a40ae2 runtime: don't record an unmodified temp as the --resume target
f239ca5 walker: keep optional trailing flags completable after `--`
0e5f226 docs: handoff 19 — ADR-0027 highlight/hint wiring finished
c1c9f6c runtime: extract the indicator debounce into a tested state machine
400fb71 ui: surface diagnostics in the ambient hint panel (ADR-0027 §2)
bbfb70c ui: overlay diagnostic spans on the input field (ADR-0027 §2)
437b2f2 walker: flag LIKE on a numeric column (ADR-0027 Amendment 1)
3912fb5 walker: precise per-literal spans for expression WARNINGs
426e801 command: Operand carries a source span
Tests: 1131 passing, 0 failing, 1 ignored (cargo test — up from 1100 at handoff-18). The ignored test is the
long-standing ```ignore doc-test in
src/friendly/mod.rs. Typing-surface matrix: 161 cells,
unchanged (one cell's input was corrected — see §3).
Clippy: clean (cargo clippy --all-targets -- -D warnings, nursery group).
§1. What this run did — the three §4 follow-ups
handoff-18 §4 listed three "known follow-ups (none blocking)". The user reviewed them, judged §4-item-1 to be unfinished ADR-0027 scope (the §2 Decision text, not an optional extra), and asked for all three — including the small ADR amendment item 3 needs. All three are done.
Item 1 — diagnostic highlight + hint wiring
§2 of ADR-0027: the indicator is the summary; highlighting and the hint panel carry the where and why. Built across four commits:
Operandcarries a source span (426e801). Each WHERE-expression operand now records the byte range of the terminal it was built from.Operand'sPartialEqis hand-written to ignore the span — it is editor metadata — soCommandequality stays whitespace- and position-independent and the largeExprtest corpus needed no assertion changes.- Precise per-literal WARNING spans (
3912fb5). The old WARNING span was coarse — the whole WHERE clause.predicate_warningsnow anchors each WARNING to exactly the offending literal operand;where_clause_spanis gone. - Highlight overlay (
bbfb70c).render_input_runsoverlays the walker's schema-aware diagnostics: ERROR in the error colour, WARNING intheme.warning. Newoverlay_spancovers a token's whole byte range (the olderoverlay_errorhit only the run at a single byte). The overlay is global — every flagged token is coloured wherever it sits, not just under the cursor, which is exactly the gap §Context described. The pre-existing cursor-local invalid-identifier overlay is kept (it covers in-progress idents, which produce no diagnostics); the two are additive and idempotent. - Hint panel (
400fb71).ambient_hintsurfaces a diagnostic's message.walker::input_diagnosticsis non-empty only for a command that structurally parses, so a non-empty result means "complete and submittable, but wrong" — checked early, ahead of slot hints and completions, so a flawed-but-parsing command no longer shows the misleading "Submit with Enter". The diagnostic under the cursor wins, else the most severe.
Item 2 — debounce test coverage (c1c9f6c)
The indicator debounce was two locals in the event loop with
no unit coverage. The decision logic is now the
IndicatorDebounce state machine in runtime — note_event
/ settle / is_armed / visible, 7 unit tests for the
keystroke / settle cycle (including: a background event
mid-typing must not cancel the owed recompute). No behaviour
change; the tokio timer and terminal stay in the loop. A
PTY-tier test of the actual timing remains the one
integration-level gap (consistent with ADR-0008's four-tier
strategy).
Item 3 — LIKE on a numeric column (437b2f2)
A genuinely new WARNING trigger, so it needed an ADR change:
ADR-0027 Amendment 1. LIKE is a text-pattern match;
against an int / real / decimal / serial column it
runs but is almost never intended. New Type::is_numeric,
catalog key diagnostic.like_numeric. Scope is deliberately
numeric-only — bool and the text-/blob-backed types are
not flagged; rationale is in the amendment. docs/adr/ README.md updated per the index-upkeep rule.
§2. Two manual-testing bugs — both fixed
Mid-run the user reported two bugs from manual testing and
deferred the fixes; both are now done (commits f239ca5,
3a40ae2). They are unrelated to ADR-0027.
add 1:n relationship— optional flag not completable after--(f239ca5). Typingadd 1:n relationship from X.a to Y.b --to start--create-fkmade completion go empty: the trailing--turns the parse into a trailing-junkMismatch, and the Mismatch arm of the completion expected-set resolution returned only[EndOfInput]— the skipped optional-flag expectations, carried intail_expected, were dropped.completion_probeandexpected_at_inputnow mergetail_expectedinto a Mismatch's expected set; the fix covers the whole optional-trailing-flag class (--create-fk,--cascade,--force-conversion/--dont-convert). This also resolved the "wrong usage hint" symptom: with--create-fkoffered as a candidate the hint panel shows candidates, not the parse-error usage block. The audit (the user's requested scan) foundusage_key_for_inputcorrect for every multi-form command —add/drop/show, including the digit-ledadd 1:n relationship— so the "showsadd column" symptom was not a code bug in the current tree; it is now regression-locked. (The[ERR]on the non-existent column is the schema-existence diagnostic working — left intact.)--resumerecorded an unpersisted temp (3a40ae2). An empty temp is created on launch but auto-deleted on quit while still empty (ADR-0015); the unconditional startupwrite_last_projectrecorded its path anyway, so a later--resumeresolved to a deleted directory. All three resume-pointer writes are now gated on!project.is_unmodified_temp()(startup, on-switch, and a new on-quit write — the quit write is where a launch-temp the user filled with content finally gets remembered). The "no previous project" friendly error the user asked for already existed (project.resume_no_previous) — verified, no change needed.
§3. Architectural delta (vs. handoff-18)
Command AST
Operandis now a struct-variant enum —Column { name, span }/Literal { value, span }— carrying a bytespan.PartialEqis hand-written to ignorespan(see the type docs);Eqstill derived.Operand::span()accessor;Operand::NO_SPANfor programmatically-built operands (RowFilter::eq).
Walker
walker::input_diagnostics(source, schema) -> Vec<Diagnostic>— the sibling ofinput_verdict; the shared entry point for the highlight overlay and the hint panel.predicate_warningsemits per-literal spans;pair_type_mismatchreturns(message, span);where_clause_spanremoved.like_numeric_warning— theLIKE-on-numeric WARNING (Amendment 1).Predicate::Likeis no longer a no-op arm.
ui / input_render
render_input_runsoverlays diagnostics (overlay_span, new).ambient_hinthas a diagnostic branch right after the Tab-cycle memo;pick_hint_diagnosticchooses cursor-local, else most-severe.
runtime
IndicatorDebouncestate machine replaces theindicator_pendinglocal;app.input_indicatormirrors itsvisiblefor the renderer.
Types / catalog
Type::is_numeric(). New catalog keydiagnostic.like_numeric(+friendly::keysregistry entry).
§4. Docs touched
- ADR-0027 — new "Follow-up" section (the §2 wiring
completed) and "Amendment 1" (
LIKEon a numeric column); the three stale "As-built notes" bullets updated to point at them. docs/adr/README.md— ADR-0027 line notes Amendment 1.docs/requirements.md— test baseline (→ 1125) and theS6entry note the completed wiring + amendment.
§5. What's next
- ADR-0028 — query plans (
explain). The last unimplemented member of the handoff-16 design trio; Accepted, not started.show data … whereis the filtered query whose plan flips between a full scan and an index search. The diagnostics model and theOutputLinespan-styling ADR-0028 describes are both easier to reach now. - The §2 bugs are done — nothing pending there.
Other open clusters unchanged from handoff-16/17/18
(snapshot/undo U-series; constraints C3; C4 m:n;
C3a; C1 table rename; H1; SD1; TT5 CI; V4; I1;
TU1). Prioritisation is a user product decision — ask.
§6. How to take over
- Read this file, then handoff-18 (ADR-0026/0027 implementation), then handoff-17 / handoff-16 as needed.
- Read
CLAUDE.md— working-style rules. - Read
docs/adr/0027-input-validity-indicator.md— especially the new "Follow-up" and "Amendment 1" sections. - Run
cargo test— 1131 passing, 0 failing, 1 ignored. - Run
cargo clippy --all-targets -- -D warnings— clean. - Pick the next work from §5 — ADR-0028 is the natural pick (the §2 manual-testing bugs are already fixed); prioritisation is a user decision, so ask.
Note on the typing-surface matrix
tests/typing_surface/ is 161 cells, unchanged. One
cell — where_expression::complex_and_or_expression_parses
— used a column (t) that does not exist in its schema; the
new schema-existence diagnostic correctly flagged it, which
revealed the cell was not testing what it claimed. Its input
was corrected to a real column and the snapshot regenerated.
The matrix-snapshot discipline from handoff-17/18 still
applies: a failing cell with correct new behaviour →
update its snapshot; with wrong behaviour → the cell
earned its keep.