# 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.