Files
rdbms-playground/docs/handoff/20260519-handoff-18.md
T
claude@clouddev1 39b92a7558 docs: handoff 18 — record the post-ADR-0027 manual-testing pass
The multi-form usage-template fix (151ed08) and the reviewed
`add index` syntax decision (kept as-is), so the next agent
does not re-flag a settled question.
2026-05-19 08:45:45 +00:00

220 lines
9.8 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. **12 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.
```
151ed08 hint: show the matching usage template for multi-form commands
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:** **1100 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.
## §2a. Post-ADR-0027 — a manual-testing pass
After ADR-0027 landed, a round of manual testing surfaced
three things; all are resolved.
- **Bug, fixed (`151ed08`).** A parse error in `add index …`
showed the `add column` usage. `add` / `drop` are
multi-form commands and both the ambient hint and the
submit-time usage block picked the *first* form
unconditionally. New `grammar::usage_key_for_input`
disambiguates by the form word after the entry keyword;
the hint shows the committed form, `render_usage_block`
too (bare `add` / `drop` still shows the whole family).
- **`add index` syntax — reviewed, deliberately kept.** The
inconsistency is real: `add column [to] [table] <T>: <col>
(<type>)` vs `add index [as <name>] on <T> (<cols>)`. It
was weighed and **left as-is** — `add index … on <T>
(<cols>)` is intentionally SQL-idiomatic
(`CREATE INDEX … ON t (cols)`), the colon shape was built
for "one column *with a type*" and an index has neither.
A future agent should **not** re-flag this as a bug; if
the owner later wants the entity-command separators
unified, that is a deliberate ADR-0025 amendment / design
pass, not a drive-by fix.
- **No index parameters / no `unique` — by design.** ADR-0025
scoped `add index` to plain non-unique indexes; there is
no `unique`-index syntax and no constraint syntax at all
(`NOT NULL` / `UNIQUE` / `CHECK` / `DEFAULT` are the
pending `C3`). ADR-0018's `unique` handling only
*detects + displays* an existing constraint — nothing
creates one. Not a gap in the help; the help is accurate.
## §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`** — 1100 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.