ADR-0027 gains a "Follow-up" section recording the completed §2 highlight + hint wiring and precise per-literal WARNING spans; the three stale As-built bullets point at it. requirements.md test baseline → 1125 and the S6 entry notes the completion + Amendment 1. handoff-19 records the run and queues the two deferred manual-testing bugs (add 1:n relationship completion/usage hint; --resume / last_project) as the next session's first work.
10 KiB
Session handoff — 2026-05-19 (19)
Nineteenth handover. A focused implementation run that finished ADR-0027: 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.
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. 7 commits since
handoff-18 (39b92a7), all local — push asynchronously, not
blocking.
<this file> docs: handoff 19 + ADR-0027 follow-up/amendment notes
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: 1125 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 — NOT fixed, queued next
Mid-run the user reported two bugs from manual testing and explicitly deferred the fixes. These are the top of the next session's queue. They are unrelated to ADR-0027.
add 1:n relationship— missing completion + wrong usage hint. Typingadd 1:n relationship from Artists.album_id to Albums.id --does not offer--create-fk. Separately, the ambient hint at the end ofadd 1:n relationship from … to …shows the wrong usage block —add column …— becausegrammar::usage_key_for_input(commit151ed08) disambiguatesadd column/add indexbut not the1:n relationshipform, so it falls back to the firstaddform. Same class of bug151ed08fixed; the fix is to teachusage_key_for_inputthe relationship form, plus wire the--create-fkflag completion. (The user confirmed the[ERR]shown for the non-existent column in that input is correct and welcome — that is this run's schema-existence diagnostic working. Do not touch it.)--resumepoints at an unpersisted temp project. An empty temp project is created on launch but, by design (ADR-0015), not persisted when it has no content — yetlast_projectstill records its path, so a later--resumefails with a confusing "path does not exist". The user asked for: (a)last_projectupdated only once a path is truly persisted with content; (b) a friendly error when--resumefinds nolast_projectat all.
Both are recorded as tasks (#7, #8 in this session's task list) with full repro detail.
§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
- The two §2 bugs —
add 1:n relationshipcompletion / usage hint, and--resume/last_project. The user deferred these explicitly; they are first in line. - ADR-0028 — query plans (
explain). Still 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.
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— 1125 passing, 0 failing, 1 ignored. - Run
cargo clippy --all-targets -- -D warnings— clean. - Start with §5.1 — the two manual-testing bugs. They were deferred mid-run with the user's agreement; they are the committed next step, ahead of ADR-0028.
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.