docs: session handoff 58 — H1a done via ADR-0042 systematic pass
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
# Session handoff — 2026-06-06 (58)
|
||||
|
||||
Fifty-eighth handover. Continues from handoff-57, whose **next job
|
||||
was H1a**. This session did exactly that, end to end: **H1a
|
||||
(strong syntax-help in parse errors) is now done and marked `[x]`**
|
||||
in `requirements.md`, via a new ADR-0042 systematic pass. The arc
|
||||
was audit → ADR → test-first matrix → four gap fixes → two
|
||||
adversarial review passes that each caught a real defect. See §2.
|
||||
|
||||
## §1. State at handoff
|
||||
|
||||
**Branch:** `main`. **HEAD `c305dc7`.** **origin/main at `10f8c2a`**
|
||||
(pushed mid-session) → **4 commits unpushed** (`649fdcb`, `1d4923b`,
|
||||
`d6e229f`, `c305dc7`). Push is the user's step.
|
||||
|
||||
**Tests: 2158 passing / 0 failing / 1 ignored** (lib 1578, it 388,
|
||||
typing_surface_matrix 192; the 1 ignored is the pre-existing one).
|
||||
**Clippy clean** (nursery, all targets, `-D warnings`).
|
||||
|
||||
This session's commits (since handoff-57's `a8d0138`):
|
||||
|
||||
```
|
||||
c305dc7 docs: mark H1a done via the ADR-0042 systematic pass
|
||||
d6e229f feat: H1a CROSS JOIN ON teaching message; advanced-SQL gaps re-verified (ADR-0042)
|
||||
1d4923b fix: H1a G3 advanced usage shows all valid forms; complete near-miss matrix (ADR-0042)
|
||||
649fdcb feat: H1a parse-error gaps G2–G4 + advanced near-miss matrix (ADR-0042)
|
||||
10f8c2a test: H1a near-miss matrix + friendlier `add 1:n relationship` label (ADR-0042)
|
||||
0e6f767 docs: ADR-0042 — continue H1a parse-error pedagogy on the grammar tree
|
||||
```
|
||||
|
||||
## §2. What happened this stretch — H1a, start to finish
|
||||
|
||||
### Audit first (the big correction)
|
||||
|
||||
The handoff-57 §6 pointer said "read ADR-0021 + ADR-0020". **Both
|
||||
are obsolete.** They specify a `chumsky`-over-tokens mechanism
|
||||
(`UsageEntry` registry, `parse.token.*` keys, a lexer) that
|
||||
**ADR-0024 deleted** — chumsky is not a dependency; the parser is
|
||||
the scannerless unified grammar-tree walker. ADR-0020/0021 are now
|
||||
marked **Superseded** (status notes + README), kept as memory.
|
||||
ADR-0021's *intent* survived and was already ~80% shipped via the
|
||||
grammar tree. **Read `docs/adr/0042-h1a-parse-error-pedagogy-grammar-tree.md`,
|
||||
not 0020/0021, for the live H1a design.**
|
||||
|
||||
### ADR-0042 + the user's three scope decisions
|
||||
|
||||
Wrote **ADR-0042** (continues H1a against the grammar tree). Three
|
||||
forks escalated and decided by the user: (1) ADR hygiene =
|
||||
superseded-notes + new ADR; (2) scope = matrix-verify + friendlier
|
||||
literal labels; (3) advanced-SQL **in scope**.
|
||||
|
||||
### The near-miss matrix (the definition of done)
|
||||
|
||||
`tests/it/parse_error_pedagogy.rs` now holds a per-command
|
||||
near-miss matrix, built **test-first** from an empirical baseline
|
||||
capture. Covers, in both modes: every entry word's bare /
|
||||
missing-clause / wrong-token cases, the app-lifecycle trailing-junk
|
||||
cases, and the **committed multi-forms** (`add index`,
|
||||
`add constraint`, `add 1:n relationship`, `drop index/constraint/
|
||||
relationship`, `show table`, `change column`, `create index`,
|
||||
`alter table add/drop`). Tests: `near_miss_matrix_simple_mode`,
|
||||
`near_miss_matrix_advanced_mode`, `near_miss_matrix_committed_multiforms`,
|
||||
plus per-gap tests.
|
||||
|
||||
### Four gap fixes (each test-first)
|
||||
|
||||
- **G1** — bare `1` cardinality literal → `` `1:n relationship` `` in
|
||||
`format_expectation` (render-only; completion still offers `1`).
|
||||
- **G2** — bare `select`'s 14-item expression first-set → "a
|
||||
projection: `*`, a column, or an expression", detected by the
|
||||
`distinct`+`all` quantifier pair (unique to a projection start;
|
||||
empirically verified non-misfiring). Render-only in
|
||||
`format_walker_error`.
|
||||
- **G3** — usage block was mode-blind. Added `usage_*_in_mode`
|
||||
(`src/dsl/grammar/mod.rs`) + mode threading through
|
||||
`render_usage_block` (`app.rs`) and the ambient usage
|
||||
(`input_render.rs`). **Decision (user, after review):** advanced
|
||||
mode shows **all forms valid in the mode, SQL-first then the DSL
|
||||
fallback forms** — DSL forms (`create table … with pk`,
|
||||
`drop column …`) remain valid input in advanced mode (verified),
|
||||
so a usage hint must not hide them. Simple mode = DSL only.
|
||||
- **G4** — `with` got its own `parse.usage.with` CTE template
|
||||
(was borrowing `select`'s).
|
||||
- **CROSS JOIN ON** — `parse.cross_join_no_on` teaches "a CROSS JOIN
|
||||
has no ON clause …" when the failing token is `on` and the most
|
||||
recent consumed join is a CROSS join. `is_cross_join_on` in
|
||||
`parser.rs`; render-only.
|
||||
|
||||
### Two adversarial review passes earned their keep
|
||||
|
||||
- Pass 1 caught **G3 over-correction**: an initial "SQL-only"
|
||||
advanced usage block *hid* valid DSL fallback forms. Escalated →
|
||||
user chose "show all valid forms" → fixed (`1d4923b`).
|
||||
- "Verify, don't trust the survey" **reversed two of three**
|
||||
advanced-SQL "gaps": INSERT…SELECT count and RETURNING scope were
|
||||
*already handled* (the Explore-survey list was wrong, twice).
|
||||
Only CROSS JOIN ON was real.
|
||||
- The matrix itself caught a regression mid-work (advanced
|
||||
insert/update/delete falling back to available-commands because
|
||||
the SQL nodes have empty `usage_ids`; fixed with a union fallback).
|
||||
|
||||
### Deferred by decision (low-priority residual)
|
||||
|
||||
At **submit** time, a non-projection expression position (bare
|
||||
`where `, `returning `, `having `, `set col=`) still renders the raw
|
||||
~14-item expression first-set; only the SELECT projection is glossed
|
||||
(G2). Low-impact because **typing-time completion already offers the
|
||||
right candidates** there. User chose to leave it. Documented in
|
||||
ADR-0042 + `requirements.md`.
|
||||
|
||||
Plus one **pre-existing caveat** (not this session's work, noted in
|
||||
ADR-0042): `insert into T (one_col) select * from Multi` isn't
|
||||
pre-caught for arity — `SELECT *` isn't expanded; the engine rejects
|
||||
it at execution (brushes ADR-0019 §OOS-2 engine-error territory).
|
||||
|
||||
## §3. ⚠️ Where parse-error pedagogy lives now (read before touching)
|
||||
|
||||
- **Usage templates:** `parse.usage.*` in `src/friendly/strings/en-US.yaml`;
|
||||
`usage_ids` on each `CommandNode` (`src/dsl/grammar/mod.rs`).
|
||||
Mode-aware selection: `usage_keys_for_input_in_mode` /
|
||||
`usage_key_for_input_in_mode`.
|
||||
- **Structural error wording:** `format_walker_error` +
|
||||
`format_expectation` in `src/dsl/parser.rs` (this is where the G1
|
||||
label, G2 projection gloss, and CROSS JOIN message live —
|
||||
render-only, they do **not** mutate the `Expectation` set the
|
||||
completion/hint layer consumes).
|
||||
- **Catalog discipline (ADR-0019):** every new key goes in
|
||||
`en-US.yaml` **and** `src/friendly/keys.rs::KEYS_AND_PLACEHOLDERS`
|
||||
(the `keys_validate_against_catalog` test enforces it).
|
||||
- **Tests:** integration parse-error tests live in `tests/it/` per
|
||||
the handoff-57 §3 rule — drop the file in `tests/it/` + add a
|
||||
`mod` line to `tests/it/main.rs`. Schema-aware diagnostics are
|
||||
tested at the walker level with a `SchemaCache` (`vschema` helper
|
||||
in `tests/it/sql_insert.rs`).
|
||||
|
||||
## §4. Carried / unchanged
|
||||
|
||||
- **arboard decisions** (handoff-55 §3): X11-only on Linux; `copy`
|
||||
reproduces `[system]` tags. One-line changes if revisited.
|
||||
- No open GitHub issues (`gh issue list` empty; the project's issue
|
||||
tracker is GitHub, not the gitea host `tea` is configured for).
|
||||
|
||||
## §5. Other tracks (from `requirements.md`)
|
||||
|
||||
Unchanged: Track 2 Iter 6 leftovers (history.log input-history
|
||||
hydration polish, migration-framework exercise); C3a modify
|
||||
relationship; C4 m:n convenience; **H1 done** (ADR-0019), **H1a
|
||||
done** (ADR-0042); H2 `hint`; H3 `help` (partial — general
|
||||
reference + `help <command>` still missing); V4 session-log /
|
||||
Markdown export; I1/I1b multi-line + readline; I3 tab completion /
|
||||
I4 syntax highlighting (the walker already exposes the hooks); TU1
|
||||
tutorial (needs ADR); TT5 CI (not configured).
|
||||
|
||||
## §6. Next job — pick one
|
||||
|
||||
No single forced next step. Candidates, roughly by readiness:
|
||||
|
||||
1. **H3 `help` completion** — the grammar tree already iterates the
|
||||
REGISTRY for the command list; the missing pieces are a general
|
||||
reference and `help <command>` per-command detail. The
|
||||
`help_id` per `CommandNode` is the hook. Small-to-medium.
|
||||
2. **I3 tab completion** — the walker's expected-set + completion
|
||||
candidates already exist (used by ambient hints); I3 is the
|
||||
**UI/UX** (cursor handling, menu, accept). Needs its own ADR.
|
||||
3. **The deferred H1a residual** (§2) — generalise the projection
|
||||
gloss to other expression positions. Low value (completion
|
||||
already covers typing-time); only if it bugs you.
|
||||
4. **CI (TT5)** — test infra is solid (2158 green); no workflow yet.
|
||||
|
||||
## §7. How to take over
|
||||
|
||||
1. Read handoffs 56 → 57 → 58, then `CLAUDE.md`, then
|
||||
`docs/requirements.md` (H1 and **H1a now `[x]`**),
|
||||
`docs/adr/README.md`.
|
||||
2. **For anything parse-error/pedagogy: read ADR-0042, not
|
||||
ADR-0020/0021** (those are superseded; chumsky is gone).
|
||||
3. Codebase on `main` at `c305dc7`, clean, 4 unpushed.
|
||||
4. Process pins that paid off this arc, again: **audit before
|
||||
assuming** (ADR-0021 was obsolete; H1a was mostly already
|
||||
shipped), **verify empirically — don't trust the docs/survey**
|
||||
(the advanced-SQL gap list was wrong twice; a regression hid in
|
||||
"looks fine"), **escalate genuine forks** (the G3 all-forms
|
||||
decision was the user's, not mine), and **test-first + matrix as
|
||||
a regression lock** (it caught a regression I introduced).
|
||||
Commits user-confirmed, append-only, no AI attribution.
|
||||
Reference in New Issue
Block a user