39b92a7558
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.
220 lines
9.8 KiB
Markdown
220 lines
9.8 KiB
Markdown
# 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 1–4 + 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.
|