a1e4932858
handoff-19 §2 now records the two bugs as fixed (was "queued next"): the optional trailing-flag completion fix (f239ca5) and the --resume temp-project pointer fix (3a40ae2). §5 drops them from "what's next" — ADR-0028 is now the natural next pick. State/§6 updated to 10 commits and 1131 tests; requirements.md test baseline → 1131.
252 lines
11 KiB
Markdown
252 lines
11 KiB
Markdown
# Session handoff — 2026-05-19 (19)
|
|
|
|
Nineteenth handover. A focused **implementation run** that
|
|
**finished ADR-0027** and then **fixed two manual-testing
|
|
bugs**. The §4 "known follow-ups" from handoff-18 are all
|
|
done: ADR-0027's §2 always specified that "highlighting and
|
|
the hint panel read the individual diagnostics" — handoff-18
|
|
shipped the indicator and the model but left that wiring as a
|
|
follow-up. It is now wired. Two unrelated bugs the user found
|
|
mid-run (§2) are also fixed.
|
|
|
|
**Headline: the diagnostics are visible where they happen.**
|
|
An unknown table / column (ERROR) and a dubious comparison
|
|
(WARNING — type mismatch, `= NULL`, and now `LIKE` on a
|
|
numeric column) are overlaid on the input field *globally*
|
|
and explained in the hint panel — not just summarised by the
|
|
`[ERR]` / `[WRN]` indicator.
|
|
|
|
## State at handoff
|
|
|
|
**Branch:** `main`. Working tree clean. **10 commits** since
|
|
handoff-18 (`39b92a7`), all local — push asynchronously, not
|
|
blocking.
|
|
|
|
```
|
|
<this file> docs: handoff 19 update — both manual-testing bugs fixed
|
|
3a40ae2 runtime: don't record an unmodified temp as the --resume target
|
|
f239ca5 walker: keep optional trailing flags completable after `--`
|
|
0e5f226 docs: handoff 19 — ADR-0027 highlight/hint wiring finished
|
|
c1c9f6c runtime: extract the indicator debounce into a tested state machine
|
|
400fb71 ui: surface diagnostics in the ambient hint panel (ADR-0027 §2)
|
|
bbfb70c ui: overlay diagnostic spans on the input field (ADR-0027 §2)
|
|
437b2f2 walker: flag LIKE on a numeric column (ADR-0027 Amendment 1)
|
|
3912fb5 walker: precise per-literal spans for expression WARNINGs
|
|
426e801 command: Operand carries a source span
|
|
```
|
|
|
|
**Tests:** **1131 passing, 0 failing, 1 ignored** (`cargo
|
|
test` — up from 1100 at handoff-18). The ignored test is the
|
|
long-standing `` ```ignore `` doc-test in
|
|
`src/friendly/mod.rs`. Typing-surface matrix: **161 cells**,
|
|
unchanged (one cell's *input* was corrected — see §3).
|
|
|
|
**Clippy:** clean (`cargo clippy --all-targets -- -D
|
|
warnings`, nursery group).
|
|
|
|
## §1. What this run did — the three §4 follow-ups
|
|
|
|
handoff-18 §4 listed three "known follow-ups (none blocking)".
|
|
The user reviewed them, judged §4-item-1 to be unfinished
|
|
ADR-0027 *scope* (the §2 Decision text, not an optional
|
|
extra), and asked for **all three** — including the small ADR
|
|
amendment item 3 needs. All three are done.
|
|
|
|
### Item 1 — diagnostic highlight + hint wiring
|
|
|
|
§2 of ADR-0027: the indicator is the *summary*; highlighting
|
|
and the hint panel carry the *where* and *why*. Built across
|
|
four commits:
|
|
|
|
- **`Operand` carries a source span** (`426e801`). Each
|
|
WHERE-expression operand now records the byte range of the
|
|
terminal it was built from. `Operand`'s `PartialEq` is
|
|
hand-written to **ignore** the span — it is editor
|
|
metadata — so `Command` equality stays whitespace- and
|
|
position-independent and the large `Expr` test corpus
|
|
needed no assertion changes.
|
|
- **Precise per-literal WARNING spans** (`3912fb5`). The old
|
|
WARNING span was coarse — the whole WHERE clause.
|
|
`predicate_warnings` now anchors each WARNING to exactly
|
|
the offending literal operand; `where_clause_span` is
|
|
gone.
|
|
- **Highlight overlay** (`bbfb70c`). `render_input_runs`
|
|
overlays the walker's schema-aware diagnostics: ERROR in
|
|
the error colour, WARNING in `theme.warning`. New
|
|
`overlay_span` covers a token's whole byte range (the
|
|
older `overlay_error` hit only the run at a single byte).
|
|
The overlay is **global** — every flagged token is
|
|
coloured wherever it sits, not just under the cursor,
|
|
which is exactly the gap §Context described. The
|
|
pre-existing cursor-local invalid-identifier overlay is
|
|
kept (it covers in-progress idents, which produce no
|
|
diagnostics); the two are additive and idempotent.
|
|
- **Hint panel** (`400fb71`). `ambient_hint` surfaces a
|
|
diagnostic's message. `walker::input_diagnostics` is
|
|
non-empty *only* for a command that structurally parses,
|
|
so a non-empty result means "complete and submittable,
|
|
but wrong" — checked early, ahead of slot hints and
|
|
completions, so a flawed-but-parsing command no longer
|
|
shows the misleading "Submit with Enter". The diagnostic
|
|
under the cursor wins, else the most severe.
|
|
|
|
### Item 2 — debounce test coverage (`c1c9f6c`)
|
|
|
|
The indicator debounce was two locals in the event loop with
|
|
no unit coverage. The decision logic is now the
|
|
`IndicatorDebounce` state machine in `runtime` — `note_event`
|
|
/ `settle` / `is_armed` / `visible`, 7 unit tests for the
|
|
keystroke / settle cycle (including: a background event
|
|
mid-typing must not cancel the owed recompute). No behaviour
|
|
change; the `tokio` timer and terminal stay in the loop. A
|
|
PTY-tier test of the *actual timing* remains the one
|
|
integration-level gap (consistent with ADR-0008's four-tier
|
|
strategy).
|
|
|
|
### Item 3 — `LIKE` on a numeric column (`437b2f2`)
|
|
|
|
A genuinely new WARNING trigger, so it needed an ADR change:
|
|
**ADR-0027 Amendment 1**. `LIKE` is a text-pattern match;
|
|
against an `int` / `real` / `decimal` / `serial` column it
|
|
runs but is almost never intended. New `Type::is_numeric`,
|
|
catalog key `diagnostic.like_numeric`. Scope is deliberately
|
|
numeric-only — `bool` and the text-/blob-backed types are
|
|
not flagged; rationale is in the amendment. `docs/adr/
|
|
README.md` updated per the index-upkeep rule.
|
|
|
|
## §2. Two manual-testing bugs — both fixed
|
|
|
|
Mid-run the user reported two bugs from manual testing and
|
|
deferred the fixes; both are now done (commits `f239ca5`,
|
|
`3a40ae2`). They are unrelated to ADR-0027.
|
|
|
|
1. **`add 1:n relationship` — optional flag not completable
|
|
after `--` (`f239ca5`).** Typing `add 1:n relationship
|
|
from X.a to Y.b --` to start `--create-fk` made completion
|
|
go **empty**: the trailing `--` turns the parse into a
|
|
trailing-junk `Mismatch`, and the Mismatch arm of the
|
|
completion expected-set resolution returned only
|
|
`[EndOfInput]` — the skipped optional-flag expectations,
|
|
carried in `tail_expected`, were dropped.
|
|
`completion_probe` and `expected_at_input` now merge
|
|
`tail_expected` into a Mismatch's expected set; the fix
|
|
covers the whole optional-trailing-flag class
|
|
(`--create-fk`, `--cascade`, `--force-conversion` /
|
|
`--dont-convert`). This *also* resolved the "wrong usage
|
|
hint" symptom: with `--create-fk` offered as a candidate
|
|
the hint panel shows candidates, not the parse-error
|
|
usage block. The audit (the user's requested scan) found
|
|
`usage_key_for_input` **correct** for every multi-form
|
|
command — `add` / `drop` / `show`, including the digit-led
|
|
`add 1:n relationship` — so the "shows `add column`"
|
|
symptom was not a code bug in the current tree; it is now
|
|
regression-locked. *(The `[ERR]` on the non-existent
|
|
column is the schema-existence diagnostic working — left
|
|
intact.)*
|
|
2. **`--resume` recorded an unpersisted temp (`3a40ae2`).**
|
|
An empty temp is created on launch but auto-deleted on
|
|
quit while still empty (ADR-0015); the unconditional
|
|
startup `write_last_project` recorded its path anyway, so
|
|
a later `--resume` resolved to a deleted directory. All
|
|
three resume-pointer writes are now gated on
|
|
`!project.is_unmodified_temp()` (startup, on-switch, and a
|
|
new on-quit write — the quit write is where a launch-temp
|
|
the user *filled with content* finally gets remembered).
|
|
The "no previous project" friendly error the user asked
|
|
for already existed (`project.resume_no_previous`) —
|
|
verified, no change needed.
|
|
|
|
## §3. Architectural delta (vs. handoff-18)
|
|
|
|
### Command AST
|
|
|
|
- `Operand` is now a struct-variant enum —
|
|
`Column { name, span }` / `Literal { value, span }` —
|
|
carrying a byte `span`. **`PartialEq` is hand-written to
|
|
ignore `span`** (see the type docs); `Eq` still derived.
|
|
`Operand::span()` accessor; `Operand::NO_SPAN` for
|
|
programmatically-built operands (`RowFilter::eq`).
|
|
|
|
### Walker
|
|
|
|
- `walker::input_diagnostics(source, schema) -> Vec<Diagnostic>`
|
|
— the sibling of `input_verdict`; the shared entry point
|
|
for the highlight overlay and the hint panel.
|
|
- `predicate_warnings` emits per-literal spans;
|
|
`pair_type_mismatch` returns `(message, span)`;
|
|
`where_clause_span` removed.
|
|
- `like_numeric_warning` — the `LIKE`-on-numeric WARNING
|
|
(Amendment 1). `Predicate::Like` is no longer a no-op arm.
|
|
|
|
### ui / input_render
|
|
|
|
- `render_input_runs` overlays diagnostics (`overlay_span`,
|
|
new). `ambient_hint` has a diagnostic branch right after
|
|
the Tab-cycle memo; `pick_hint_diagnostic` chooses
|
|
cursor-local, else most-severe.
|
|
|
|
### runtime
|
|
|
|
- `IndicatorDebounce` state machine replaces the
|
|
`indicator_pending` local; `app.input_indicator` mirrors
|
|
its `visible` for the renderer.
|
|
|
|
### Types / catalog
|
|
|
|
- `Type::is_numeric()`. New catalog key
|
|
`diagnostic.like_numeric` (+ `friendly::keys` registry
|
|
entry).
|
|
|
|
## §4. Docs touched
|
|
|
|
- **ADR-0027** — new "Follow-up" section (the §2 wiring
|
|
completed) and "Amendment 1" (`LIKE` on a numeric column);
|
|
the three stale "As-built notes" bullets updated to point
|
|
at them.
|
|
- `docs/adr/README.md` — ADR-0027 line notes Amendment 1.
|
|
- `docs/requirements.md` — test baseline (→ 1125) and the
|
|
`S6` entry note the completed wiring + amendment.
|
|
|
|
## §5. What's next
|
|
|
|
1. **ADR-0028 — query plans (`explain`).** The last
|
|
unimplemented member of the handoff-16 design trio;
|
|
**Accepted**, not started. `show data … where` 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
|
|
easier to reach now.
|
|
2. The §2 bugs are **done** — nothing pending there.
|
|
|
|
Other open clusters unchanged from handoff-16/17/18
|
|
(snapshot/undo `U`-series; constraints `C3`; `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-18** (ADR-0026/0027
|
|
implementation), then handoff-17 / handoff-16 as needed.
|
|
2. **Read `CLAUDE.md`** — working-style rules.
|
|
3. **Read `docs/adr/0027-input-validity-indicator.md`** —
|
|
especially the new "Follow-up" and "Amendment 1"
|
|
sections.
|
|
4. **Run `cargo test`** — 1131 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 (the §2 manual-testing bugs are already fixed);
|
|
prioritisation is a user decision, so ask.
|
|
|
|
### Note on the typing-surface matrix
|
|
|
|
`tests/typing_surface/` is **161 cells**, unchanged. One
|
|
cell — `where_expression::complex_and_or_expression_parses`
|
|
— used a column (`t`) that does not exist in its schema; the
|
|
new schema-existence diagnostic correctly flagged it, which
|
|
revealed the cell was not testing what it claimed. Its input
|
|
was corrected to a real column and the snapshot regenerated.
|
|
The matrix-snapshot discipline from handoff-17/18 still
|
|
applies: a failing cell with *correct* new behaviour →
|
|
update its snapshot; with *wrong* behaviour → the cell
|
|
earned its keep.
|