From b4441507e2bdd635fca919f61b670d179895c46d Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Mon, 15 Jun 2026 17:14:22 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20handoff=2071=20=E2=80=94=20hint=20conte?= =?UTF-8?q?nt=20needs=20a=20semantic=20verification=20pass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User smoke-test found hint.cmd.create_table is semantically wrong: the example `create table Customers with pk id(serial), name(text), email(text)` reads as a 3-column table but actually declares a compound PK (id, name, email) — everything after `with pk` is the PK column list (ADR-0005). Root cause: Phase C examples were syntax-checked but some were extrapolated, not verified to *do* what what/concept claims. Handoff specifies a full per-block semantic pass (run each example / check the ADR) + a ready-to-apply create_table fix. --- docs/handoff/20260615-handoff-71.md | 120 ++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 docs/handoff/20260615-handoff-71.md diff --git a/docs/handoff/20260615-handoff-71.md b/docs/handoff/20260615-handoff-71.md new file mode 100644 index 0000000..97fc2ec --- /dev/null +++ b/docs/handoff/20260615-handoff-71.md @@ -0,0 +1,120 @@ +# Session handoff — 2026-06-15 (71) + +Short, focused handover. Continues immediately from handoff-70 (which +shipped H2 / the contextual `hint`, ADR-0053). **A user smoke-test +surfaced a correctness bug in the hint content, and it implicates the +whole corpus.** This handoff exists so the next session does a +**systematic semantic verification pass over every hint block** — context +ran too low to do it now. + +## §1. State + +**Branch:** `main`, clean, all committed (local; push pending). **2499 +pass / 1 ignored, clippy clean.** Open issues: #35–#38 (see handoff-70). +H2 / ADR-0053 is *functionally* complete; the **content is not +trustworthy** until the pass below is done. + +## §2. The bug (confirmed) + +`hint.cmd.create_table` (in `src/friendly/strings/en-US.yaml`) reads: + +``` +What: Create a new table — its columns, their types, and a primary key. +Example: create table Customers with pk id(serial), name(text), email(text) +Concept: A table is a set of rows that share the same columns. The primary + key uniquely identifies each row; a `serial` key numbers the rows for you. +``` + +**This is wrong.** In the DSL, **everything after `with pk` is the +primary-key column list** (a possibly *compound* PK, ADR-0005). So the +example does **not** create a table with `pk=id` plus regular columns +`name`/`email` — it creates a table whose **compound primary key is +(id, name, email)**. Non-key columns are added *separately* with +`add column`. The `what` ("its columns, their types") and the example +both mislead a learner badly. + +- **Evidence:** real test usage is `create table Orders with pk + id(serial), CustId(int)` (a 2-column *compound PK*) and the common form + `create table X with pk id(int)` (single-column PK only). The usage + template `create table with pk [()[, ...]]` is itself + misleading — the `[, ...]` is the PK list, not regular columns. +- **Correct mental model:** `create table with pk ` then + `add column : ()` for each non-key column. Confirm + against ADR-0005 (compound PK) and ADR-0009 (DSL syntax) when fixing. + +## §3. Root cause — why this needs a *full* pass + +During Phase C I verified *some* examples against `parse.usage.*` +templates and real test greps, but for others I **extrapolated** beyond +verified syntax. For `create_table` I saw `... with pk id(int)` (single +col) and wrongly generalised to "pk + more columns," misreading the +`with pk` list as a column list. The examples are **syntactically** +checked but not **semantically** — i.e. not verified to *do what the +`what`/`concept` claims*. + +So the corpus needs a pass that, for **every** `hint.cmd.*` and +`hint.err.*` block, checks: +1. the `example` parses **and runs**, and +2. it actually demonstrates what `what`/`concept` says, and +3. `what`/`concept` are factually true of the real behaviour. + +**Don't trust grep+extrapolation.** Prefer: run the example in the app +(or a Tier-3 test), or check it against the authoritative ADR. + +## §4. The pass — how to do it (next session) + +The corpus lives in `src/friendly/strings/en-US.yaml` under `hint.cmd.*` +(per command form) and `hint.err.*` (per runtime error class). The +inventory and authoritative syntax sources: + +- **`hint.cmd.
`** — for each, cross-check the example against the + matching `parse.usage.` template **and** the form's ADR, and run + it. Highest-risk (extrapolated, verify first): **DDL** — `create_table` + (known wrong), `add_column`, `add_index`, `add_constraint`, + `change_column`, `drop_*`, `create_m2n`; **advanced-SQL** — confirm + each is in the supported SQL subset (`select`, `with` CTE, + `sql_insert/update/delete`, `sql_create_table`, `sql_alter_table`, + `sql_create_index/drop_index/drop_table`, `explain_sql`); **DML** — + `seed` forms, `explain`, `show_*`, `update`/`delete` (`--all-rows` / + required-WHERE wording). App commands are lower-risk (reference-style). +- **`hint.err.`** — verify the fix recipe in `example` is actually + the right remedy and `concept` matches the engine's real behaviour + (FK sides, `on delete` actions, check/not_null/unique semantics). +- Relevant ADRs: 0005 (types + compound PK), 0009 (DSL syntax), 0011 (FK + type compat), 0013 (relationships/rebuild), 0014 (data ops + + required-WHERE), 0025 (indexes), 0028/0039 (explain), 0030–0036 (SQL + subset), 0048 (seed). `docs/requirements.md` for scope. + +**Suggested method:** drive the app (`/run` or a small PTY/Tier-3 harness) +and actually execute each example; or add a test that parses+runs every +`hint.cmd.*` example and asserts success. The latter would also be a +durable regression guard — consider adding it as part of the pass (it +upgrades the comprehensiveness coverage test from "a block exists" to +"the example actually works"). + +## §5. Immediate fix ready to apply + +`create_table` is diagnosed (§2). The corrected block should make the +example a PK-only `create table` and move the regular columns to a +follow-up `add column`, e.g.: + +``` +What: Create a new table with its primary key. +Example: create table Customers with pk id(serial) +Concept: A table is a set of rows sharing the same columns. `with pk` + declares the primary key (one column, or several for a compound + key); add the other columns afterwards with `add column`. +``` + +Apply this (and re-check `create_m2n` / `add_*` while there), but only as +part of the systematic pass — a one-off fix risks leaving siblings wrong. + +## §6. How to take over + +1. Read handoffs 70 → 71, `CLAUDE.md`. +2. Confirm green: `cargo test` (2499 / 1 ignored), `cargo clippy + --all-targets`. +3. Do the §4 pass (consider the run-every-example test in §4). Test-first, + `/runda` before commit, confirm the commit message with the user. +4. Pedagogy wins — these are teaching strings; correctness and clarity + over cleverness.