docs: handoff 72 — H2 hint corpus verified (4 fixes + parse guard)
ci / gate (push) Successful in 2m59s
ci / gate (push) Successful in 2m59s
This commit is contained in:
@@ -0,0 +1,113 @@
|
|||||||
|
# Session handoff — 2026-06-15 (72)
|
||||||
|
|
||||||
|
Short, focused handover. Continues from handoff-71, which asked the next
|
||||||
|
session to run a **systematic semantic verification pass over every
|
||||||
|
`hint` block** (handoff-70 shipped H2 / ADR-0053, but a user smoke-test
|
||||||
|
found a wrong hint and implicated the whole corpus). **That pass is now
|
||||||
|
done.** Four content errors fixed, a durable parse-guard added, two stale
|
||||||
|
docs corrected. Commit `5a37437`.
|
||||||
|
|
||||||
|
## §1. State
|
||||||
|
|
||||||
|
**Branch:** `main`, clean, all committed (local; **push pending** — your
|
||||||
|
step). **2500 pass / 0 fail / 1 ignored** (the long-standing `friendly`
|
||||||
|
doctest), **clippy clean** (nursery, all targets). The +1 vs handoff-71's
|
||||||
|
2499 is the new guard test. Open Gitea issues unchanged: **#35–#38**.
|
||||||
|
|
||||||
|
## §2. The verification pass (commit `5a37437`)
|
||||||
|
|
||||||
|
Method: cross-checked every `hint.cmd.*` example against its
|
||||||
|
`parse.usage.*` template, ground-truthed every concept claim against the
|
||||||
|
authoritative ADR **and a named existing test** (not grep+extrapolation —
|
||||||
|
the trap handoff-71 §3 warned about), and parse-validated all 49 command
|
||||||
|
examples via a new guard.
|
||||||
|
|
||||||
|
### Four content errors fixed (`src/friendly/strings/en-US.yaml`)
|
||||||
|
|
||||||
|
| Block | Bug | Fix |
|
||||||
|
|---|---|---|
|
||||||
|
| `cmd.create_table` | Example `with pk id(serial), name(text), email(text)` declares a **3-column compound PK**, not a PK + regular columns. Every `with pk` column is a key member — confirmed by the grammar test comment *"Every `create table` column is a primary-key column"* (`ddl.rs`), ADR-0005. | Single-column PK + `add column` for the rest; `what`/`concept` aligned. |
|
||||||
|
| `cmd.save` | `save as my-shop` **does not parse** — `build_save` yields `AppCommand::SaveAs` with **no inline name**; `save as` opens a path-entry modal (`iteration4b` tests). | Example → `save as`; `what` de-implied; added an accurate temp-vs-named-auto-save `concept`. |
|
||||||
|
| `cmd.import` | Target `shop-copy` **does not parse** — the `as <target>` slot is an `IdentSource::NewName` ident that tokenises only up to the hyphen. (The zip path is a BarePath and *does* accept hyphens, hence `export my-shop.zip` is fine.) | → `shop_copy`. |
|
||||||
|
| `err.foreign_key.child_side.concept` | Offered `on delete set null/cascade` as the remedy — but `error_hint_class` maps child_side to **insert/update** violations; `on delete` governs the **parent** direction. The tier-1 hint (line 64) correctly omits it. | Corrected: parent must exist first; clarified `on delete` is the *other* direction. |
|
||||||
|
|
||||||
|
### Durable guard added
|
||||||
|
|
||||||
|
`every_cmd_hint_example_parses_in_its_mode` (`src/dsl/grammar/mod.rs`,
|
||||||
|
in the `hint_key_tests` module). **Catalog-driven** — it iterates
|
||||||
|
`catalog().keys()` for `hint.cmd.*.example` rather than the REGISTRY, so
|
||||||
|
an orphaned/mis-keyed block can't slip past; floor-asserts ≥49 examples.
|
||||||
|
Each parses in its taught mode (advanced for the SQL surface, simple
|
||||||
|
otherwise). It caught the `save` and `import` errors **test-first** (red
|
||||||
|
before the YAML fix). Registered the new `hint.cmd.save.concept` key in
|
||||||
|
`keys.rs` (the `keys_validate_against_catalog` test requires every catalog
|
||||||
|
key be declared).
|
||||||
|
|
||||||
|
### Verified correct (not changed)
|
||||||
|
|
||||||
|
All other `cmd`/`err` blocks. Notably the guard-*concept* claims were each
|
||||||
|
confirmed against a named runtime test, not assumed:
|
||||||
|
`drop_column_refuses_primary_key` / `…_column_in_a_relationship`,
|
||||||
|
`drop_table_with_inbound_relationship_errors`,
|
||||||
|
`add_not_null_column_without_default_to_populated_table_is_refused`. The
|
||||||
|
corrected `create_table` story stays coherent with the `Customers`-
|
||||||
|
referencing examples (id serial PK → `add column` name/email → `insert`
|
||||||
|
skips the auto id).
|
||||||
|
|
||||||
|
## §3. Docs corrected (same commit)
|
||||||
|
|
||||||
|
Discovered while verifying `create_m2n` (which **is** implemented —
|
||||||
|
`db.rs::do_create_m2n_relationship` + `tests/it/m2n.rs`):
|
||||||
|
|
||||||
|
- **CLAUDE.md** carried two **stale "deferred" claims**, both already
|
||||||
|
implemented. Removed/updated: (a) the at-a-glance project-format line
|
||||||
|
said export/import (Iter 5) + `--resume`/input-history/migration (Iter
|
||||||
|
6) were "pending" — all `[x]` in `requirements.md` (ADR-0015); (b) the
|
||||||
|
"Things deliberately deferred" list still had the **m:n convenience
|
||||||
|
(C4)** bullet and the same project-storage bullet. `requirements.md`
|
||||||
|
was already correct (C4 done 2026-06-10, ADR-0045), so only a
|
||||||
|
verification-pass note was appended to its **H2** entry.
|
||||||
|
|
||||||
|
## §4. Scope note — what the guard does *not* do
|
||||||
|
|
||||||
|
The bug class here is **semantic** (an example that parses and runs but
|
||||||
|
misrepresents the prose — e.g. `create_table`). The guard enforces only
|
||||||
|
the **syntactic floor**: examples parse in their mode. It backstops
|
||||||
|
future typos/clause-drift but cannot police meaning. Semantic correctness
|
||||||
|
of the current corpus rests on this session's review (recorded in the
|
||||||
|
commit + requirements.md H2). A stronger-but-brittler option was offered
|
||||||
|
to the user and **not built pending their call**: per-form assertions
|
||||||
|
that each example resolves to the *expected command shape* (e.g.
|
||||||
|
create_table → single-column PK). `hint.err.*` examples are fix-recipe
|
||||||
|
prose, not runnable, so they're verified by review only — inherent.
|
||||||
|
|
||||||
|
## §5. Next session — start here
|
||||||
|
|
||||||
|
The hint corpus is now trustworthy. Open roadmap (verify against the CI
|
||||||
|
merge first, per handoff-70 §5):
|
||||||
|
|
||||||
|
1. **Push** (your step) — this commit + the still-unpushed backlog from
|
||||||
|
handoffs 70/71 (the CI merge + all of H2).
|
||||||
|
2. **#35 (cargo fmt gate)** — the natural pairing with the merged CI; the
|
||||||
|
user wanted it done once, before first publication. The tree is **not**
|
||||||
|
fmt-clean (~1800 pre-existing diffs).
|
||||||
|
3. Other `requirements.md` open items: **TT4** PTY tier-4 (unwired),
|
||||||
|
**I1** multi-line input, **I5/B3** in-flight cancellation, **V4**
|
||||||
|
session journal (own ADR), **TU1** tutorial system (own ADR).
|
||||||
|
4. Hint follow-ups if wanted: **#37** clause-concept hints, **#38**
|
||||||
|
diagnostic route + `diagnostic.*` blocks, **#36** `help` advanced-SQL.
|
||||||
|
|
||||||
|
## §6. How to take over
|
||||||
|
|
||||||
|
1. Read handoffs 70 → 71 → 72, `CLAUDE.md`, `docs/requirements.md`.
|
||||||
|
2. Confirm green: `cargo test` (**2500 / 1 ignored**) + `cargo clippy
|
||||||
|
--all-targets` (clean).
|
||||||
|
3. For anything in the `hint` area, read **ADR-0053** first. For the
|
||||||
|
corpus, `src/friendly/strings/en-US.yaml` (`hint.cmd.*` / `hint.err.*`)
|
||||||
|
is the content; the guard in `src/dsl/grammar/mod.rs` is the regression
|
||||||
|
net.
|
||||||
|
4. Workflow unchanged: phased, test-first, `/runda` + DA before commits,
|
||||||
|
ADR amendment + README index-upkeep for decided-area changes, confirm
|
||||||
|
commit messages with the user.
|
||||||
|
5. Consider a `cargo sweep` at this milestone (`target/` grows; see
|
||||||
|
CLAUDE.md "Build hygiene").
|
||||||
Reference in New Issue
Block a user