diff --git a/docs/handoff/20260518-handoff-16.md b/docs/handoff/20260518-handoff-16.md new file mode 100644 index 0000000..3f2d9a6 --- /dev/null +++ b/docs/handoff/20260518-handoff-16.md @@ -0,0 +1,193 @@ +# Session handoff — 2026-05-18 (16) + +Sixteenth handover. This session was a **design run**: +three interlocking ADRs were designed and committed — +**ADR-0026** (complex WHERE expressions), **ADR-0027** +(input-field validity indicator), **ADR-0028** (query +plans / `EXPLAIN QUERY PLAN`) — plus one small code fix +(the `with pk` column-spec syntax). + +**Headline: nothing from the three ADRs is implemented +yet.** This was deliberate design-ahead, chosen by the +user. The next session's job is **implementation**, and +**ADR-0026 is the keystone** — start there (see §3). + +## State at handoff + +**Branch:** `main`. Working tree clean. Four commits since +handoff-15 (`f4eedf3`), all local — the user pushes +asynchronously, so do not treat them as blocking: + +``` +d9a98bb Grammar: with-pk column specs use name(type), matching add column +9aa7e2e docs: add ADR-0028 — query plans (EXPLAIN QUERY PLAN) +032a050 docs: add ADR-0027 — input-field validity indicator +6e42a11 docs: add ADR-0026 — complex WHERE expressions +``` + +**Tests:** **1039 passing, 0 failing, 1 ignored** (`cargo +test`) — unchanged from handoff-15's baseline. The `with +pk` fix is syntax-only, so the count did not move. The +ignored test is the long-standing `` ```ignore `` doc-test +in `src/friendly/mod.rs`. Typing-surface matrix: **152 +cells** (two renamed, none added/removed). + +**Clippy:** clean (`cargo clippy --all-targets -- -D +warnings`). + +## §1. What shipped + +### ADR-0026 — Complex WHERE expressions (`6e42a11`) + +The `C5a` design. A **stratified, recursive expression +grammar** — `AND` / `OR` / `NOT`, comparisons (`= != <> +< <= > >=`), `LIKE`, `IS [NOT] NULL`, `IN`, `BETWEEN`, +parentheses — for `update` / `delete` / `show data` +filters. `show data` gains an optional `where` and an +optional `limit ` (a limit implies an implicit +primary-key `ORDER BY`). + +Key decisions (settled with the user — do not +re-litigate): + +- **In-grammar recursion (option B).** A new + `Subgrammar(&'static Node)` `Node` variant lets the + grammar reference a fragment (incl. itself); the + expression grammar is stratified to avoid left + recursion. *Not* the opaque-leaf / pass-through + approach. +- **`MatchedPath` stays flat.** The expression fragment + carries its own AST-fragment builder, invoked by the + walker as it recurses — structured output "selectively", + only where the grammar is recursive. A new recursive + `Expr` AST. +- **SQL generation** is parameterised (`?`-bound, + type-converted literals); no raw-text pass-through. The + displayed SQL renders literals inline and `<>` for + inequality. +- **Permissive type handling.** Type-mismatched + comparisons and `= NULL` are *flagged* (highlight + + hint), never block submission, and still run — this + *relaxes* the current bind-time rejection. + +### ADR-0027 — Input-field validity indicator (`032a050`) + +A debounced `[ERR]` / `[WRN]` marker at the input row's +right edge, summarising — before submit — whether the +current command would run. Backed by a **walker +diagnostics-severity model**: ERROR = known to fail (parse +error, unknown table/column); WARNING = valid but likely +not intended (type mismatch, `= NULL`). Advisory only — +**never blocks submission**. ~1 s debounce; the marker +strip is reserved unconditionally (6 columns). Needs a new +`warning` theme colour. The WARNING severity has **no +triggers until ADR-0026 is implemented**. + +### ADR-0028 — Query plans (`9aa7e2e`) + +`QA1` + `QA2`. An `explain` prefix command over `show +data` / `update` / `delete` running `EXPLAIN QUERY PLAN` +(which never executes — so explaining a destructive +command is safe). Renders an annotated tree; engine +`detail` text verbatim; an annotation taxonomy (full scan +/ index search / covering index / PK lookup / **automatic +index** — the standout teaching moment / temp B-tree). +Introduces a **styled-output-line mechanism** — `OutputLine` +gains optional per-span styling, realising the per-span +theming ADR-0016 deferred (its OOS-3). The explained SQL +is shown above the tree as standard, copy-pasteable SQL. + +### with-pk grammar fix (`d9a98bb`) + +`create table … with pk` column specs changed from +`name:type` to `name(type)`, matching `add column`'s +`col(type)` — column-type syntax is now consistent across +the DSL. One grammar node (`COL_SPEC`: `:` → `( … )`); +`build_create_table` was unaffected (reads columns by +role). Swept the test suite, the friendly catalog's usage +templates, ADR-0009's example, and `requirements.md`. The +`:` separating table from column in `add column` / +`drop column` is unchanged. + +### Docs + +- New **`docs/simple-mode-limitations.md`** — a running + list of what simple-mode DSL queries cannot express that + advanced SQL can, seeded from ADR-0026 §10. It feeds the + future `Q4` SQL-subset spec. Grow it as new boundaries + surface. +- `requirements.md`: `C5a` `[~]` → `[ ]`; `QA1` / `QA2` + updated and the stale QA1 note reconciled; new `S6` (the + validity indicator) and a new **Documentation** section + with `DOC1`. + +## §2. Notes for the next agent + +- This session produced **no implementation** of the three + ADRs. Each ADR has an `## Implementation notes` section + with a step-by-step build order — follow it. +- The three ADRs **interlock**. ADR-0026's `Subgrammar` + node is reused by ADR-0028's `explain`. ADR-0027's + "general mechanism, single current consumer" shape is + echoed by ADR-0028's styled-output-line mechanism. +- **Loose end:** `CLAUDE.md`'s "Things deliberately + deferred" list still says `QA1` "needs its own QA2 + rendering ADR" — that ADR (0028) now exists. Reconcile + the CLAUDE.md list against ADRs 0026/0027/0028 when + convenient (a small edit). +- The two follow-up ADRs the validity-indicator discussion + spawned are *done* — ADR-0027 is the indicator ADR; the + `with pk` fix is the other. No tracked follow-ups remain + open from this session. + +## §3. What's next — implement ADR-0026 first + +The three ADRs must be **implemented**. Recommended order: + +1. **ADR-0026 (C5a) — the keystone.** Its build order: + (1) the `Subgrammar` node; (2) the expression grammar + fragment + `Expr` AST + the fragment-builder; (3) wire + into `update` / `delete` / `show data`; (4) `Expr` → + parameterised SQL + implicit PK `ORDER BY` for `limit`; + (5) schema-aware type-mismatch / `= NULL` flagging in + the walker; (6) typing-surface matrix cells. +2. **ADR-0027** and **ADR-0028** — in either order after + 0026. ADR-0027's WARNING severity and ADR-0028's + index-flipping plan payoff both depend on 0026's + `show data … where`. + +Other open clusters (unchanged from handoff-15 §4): + +- **Snapshot / undo** (`U1`/`U2`) — designed in ADR-0006, + not built. +- **Constraints** (`C3` — `NOT NULL` / `UNIQUE` / `CHECK` + / `DEFAULT`). `CHECK` can now reuse ADR-0026's + expression grammar — the ordering problem that paused + the constraints discussion this session is resolved. +- **m:n convenience** (`C4`), **modify relationship** + (`C3a`), **table rename** (`C1`). +- **Friendly error layer** (`H1`), **seeding** (`SD1`), + **CI** (`TT5`), **session log + Markdown export** + (`V4`), **multi-line input** (`I1`), **tutorials** + (`TU1`). + +Prioritisation is a user product decision — ask. + +## §4. How to take over + +1. **Read this file, then handoff-15** for the chain. +2. **Read `CLAUDE.md`** — the working-style rules. This + session escalated every design fork to the user before + drafting each ADR. +3. **Read the three new ADRs — `0026`, `0027`, `0028`** — + including each one's `## Implementation notes`. Then + `docs/simple-mode-limitations.md`. +4. **Read `docs/requirements.md`** — reconciled this + session. +5. **Run `cargo test`** — 1039 passing, 0 failing, 1 + ignored. +6. **Run `cargo clippy --all-targets -- -D warnings`** — + clean. +7. **Start implementing ADR-0026** (§3). The three ADRs + are design-complete; the forks are settled in the ADR + text — build to them, don't re-open them.