Files
rdbms-playground/docs/handoff/20260519-handoff-18.md
T

187 lines
8.2 KiB
Markdown
Raw 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-19 (18)
Eighteenth handover. A long **implementation run** that built
two ADRs end to end:
- **ADR-0026 (complex WHERE expressions)** — steps 14 + 6;
see handoff-17 for its detail.
- **ADR-0027 (input-field validity indicator)** — all six
build-order steps, **with ADR-0026's deferred step 5 (the
§7 expression flagging) folded in** as the WARNING
severity's first triggers, exactly as the user directed.
**Headline: the validity indicator works.** A debounced
`[ERR]` / `[WRN]` marker at the input row's right edge tells a
learner — before they press Enter — whether the command would
run. `S6` and `C5a` are both satisfied; nothing from ADRs
0026/0027 is left unimplemented.
## State at handoff
**Branch:** `main`. Working tree clean. **11 commits** since
handoff-16 (`ac41938`), all local — push asynchronously, not
blocking. handoff-17 (`dfd3c51`) is mid-chain; it documents
the ADR-0026 landing and is superseded by this file.
```
a326849 ADR-0027: existing-cases sweep + docs (step F)
9e10997 runtime: debounce the validity indicator (ADR-0027 step E)
1a9d950 ui: validity indicator rendering + warning theme colour (ADR-0027 step D)
73c7470 walker: expression WARNING diagnostics (ADR-0027 step C, folds ADR-0026 §7)
827b47f walker: schema-existence ERROR diagnostics (ADR-0027 step B)
e22f933 walker: diagnostics-severity model + input_verdict (ADR-0027 step A)
dfd3c51 chore: handoff 17 — ADR-0026 complex WHERE expressions implemented
a50c6cd WHERE expressions: matrix cells + predicate_tail grammar fix (ADR-0026 step 6)
f75f71b WHERE expressions: wire into update/delete/show data + SQL gen (ADR-0026 steps 3-4)
59e6a54 grammar: WHERE-expression fragment + Expr AST + build_expr (ADR-0026 step 2)
f0b2043 walker: add Subgrammar node + recursion-depth cap (ADR-0026 step 1)
```
**Tests:** **1099 passing, 0 failing, 1 ignored** (`cargo
test` — up from 1039 at handoff-16). The ignored test is the
long-standing `` ```ignore `` doc-test in
`src/friendly/mod.rs`. Typing-surface matrix: **161 cells**.
**Clippy:** clean (`cargo clippy --all-targets -- -D
warnings`, nursery group).
## §1. ADR-0026 — recap (detail in handoff-17)
Complex WHERE expressions work end to end: `update` /
`delete` / `show data` take a full boolean expression
(`AND`/`OR`/`NOT`, the six comparisons, `LIKE`/`IN`/`BETWEEN`/
`IS [NOT] NULL`, parentheses); it compiles to parameterised
SQL; `show data` gained `where` and `limit`. The §3 builder
realization (option 1) and the as-built deviations are in
ADR-0026's "As-built notes". **Step 5 (the §7 diagnostic
flagging) was deferred at handoff-17 and is now done — see
§2.**
## §2. ADR-0027 — the validity indicator
Six steps, one commit each (`e22f933`..`a326849`):
- **A — diagnostics model.** `Severity` (Error/Warning,
ordered) and `Diagnostic { severity, span, message }` in
`walker::outcome`; a `diagnostics` field on `WalkResult`.
`walker::input_verdict(source, schema)` is the indicator's
entry point — the highest severity across the parse
outcome and the diagnostics, or `None` for clean / empty
input.
- **B — schema-existence ERRORs.** `MatchedKind::Ident` now
carries its `IdentSource`. A post-walk pass over a
structural `Match` flags an unknown table (`Tables` ident)
or unknown column (`Columns` ident, scoped to the table in
scope) as an ERROR — *new behaviour*: such names used to
parse cleanly and fail only at execution.
- **C — expression WARNINGs (ADR-0026 §7 folded in).** A
type-mismatched comparison, or `= NULL` / `!= NULL`, in a
WHERE expression yields a WARNING — computed post-walk from
the built `Command`'s `Expr` against the table's column
types. The command still parses and runs (§7 permissive
posture unchanged).
- **D — rendering.** `[ERR]` / `[WRN]` at the input row's
right edge; new amber `theme.warning`. The rightmost six
columns are reserved unconditionally so the typed command
never shifts when the indicator appears.
- **E — debounce.** The runtime event loop time-boxes `recv`
while a recompute is owed: a keystroke hides the indicator
and arms a 1 s window; once typing pauses that long the
verdict is computed and shown. `update()` stays pure.
- **F — sweep + docs.** `input_verdict` tests confirm the
schema check fires across the identifier-taking commands.
## §3. Architectural delta (vs. handoff-17)
### Diagnostics
- `walker::outcome::{Severity, Diagnostic}`;
`WalkResult::diagnostics: Vec<Diagnostic>` (re-exported as
`walker::{Severity, Diagnostic}`).
- `walker::input_verdict(source, schema) -> Option<Severity>`
— the indicator entry point.
- `MatchedKind::Ident` gained `source: IdentSource`.
- Diagnostics are computed **post-walk** in `walk()` —
`schema_existence_diagnostics` over the matched path,
`expr_warnings` over the built `Expr` — not emitted
incrementally (keeps them off the speculative-rollback
paths). See ADR-0027 "As-built notes".
### App / runtime / ui
- `App::input_indicator: Option<Severity>` — the indicator's
visible state; `App::input_validity_verdict()` — the pure
verdict (simple mode only; advanced mode is raw SQL).
- `runtime::run` event loop: a `tokio::time::timeout`-based
debounce (`INDICATOR_DEBOUNCE`, 1 s).
- `ui::render_input_panel` reserves a fixed six-column right
strip and renders the `[ERR]`/`[WRN]` label.
- `theme.warning` — amber, light + dark.
### Catalog
- New `diagnostic:` section — `unknown_table`,
`unknown_column`, `type_mismatch`, `eq_null`.
## §4. Known follow-ups (none blocking)
- **Diagnostic highlight / hint wiring.** ADR-0027 §2 says
highlighting and the hint panel "read the individual
diagnostics". The indicator and the model ship; routing a
diagnostic's span into the per-byte highlight overlay, and
its message into the hint panel beyond the existing
parse-error path, is not yet done — the build order did
not enumerate it as a step. WARNING spans are currently
coarse (the whole WHERE clause) because the `Expr` AST
carries no source spans; precise per-literal spans would
come with that wiring. Recorded in ADR-0027 "As-built
notes".
- **Debounce timing is integration-level, not unit-tested**
— it is async event-loop glue. The pure pieces
(`input_verdict`, `input_validity_verdict`, the indicator
rendering) are covered.
- **LIKE-on-a-numeric-column** is not flagged — `LIKE` is a
text-pattern test and "mismatch" there is fuzzier; a
future WARNING-model extension. Compare / Between / In
type-mismatch and `= NULL` are flagged.
## §5. What's next
- **ADR-0028 — query plans (`explain`).** The last of the
handoff-16 design trio, still unimplemented. `show data …
where` (now real) is the filtered query whose plan flips
between a full scan and an index search; the diagnostics
model and the `OutputLine` span-styling ADR-0028 describes
are both now easier to reach.
- The §4 follow-ups, if the user wants the diagnostic
highlight/hint detail wired now rather than later.
Other open clusters are unchanged from handoff-16/17 §3
(snapshot/undo `U`-series; constraints `C3` — `CHECK` can
reuse ADR-0026's expression grammar; `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
1. **Read this file, then handoff-17** (ADR-0026 detail),
then handoff-16 (the design trio).
2. **Read `CLAUDE.md`** — working-style rules.
3. **Read `docs/adr/0027-input-validity-indicator.md`** —
especially its "As-built notes" (post-walk diagnostics,
the pre-rendered message, the `timeout` debounce, coarse
spans, the deferred highlight/hint wiring).
4. **Run `cargo test`** — 1099 passing, 0 failing, 1 ignored.
5. **Run `cargo clippy --all-targets -- -D warnings`** — clean.
6. **Pick the next work from §5** — ADR-0028 is the natural
pick; prioritisation is a user decision, so ask.
### Note on the typing-surface matrix
`tests/typing_surface/` is **161 cells**. The validity
indicator is *not* matrix-covered — the matrix harness
(`assess`) drives parse / hint / completion, not the
debounced indicator; `input_verdict` is covered directly by
walker unit tests instead. After any grammar/walker change
the matrix-snapshot discipline from handoff-17 still applies.