From 60d30dd54e836d5af75adc9f28cd3ba2f2b71403 Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Tue, 26 May 2026 14:57:07 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20session=20handoff=2042=20=E2=80=94=20AD?= =?UTF-8?q?R-0035=20Phase=204=20complete;=20whole-phase=20/runda=20follow-?= =?UTF-8?q?ups?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/handoff/20260526-handoff-42.md | 168 ++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 docs/handoff/20260526-handoff-42.md diff --git a/docs/handoff/20260526-handoff-42.md b/docs/handoff/20260526-handoff-42.md new file mode 100644 index 0000000..d9215ec --- /dev/null +++ b/docs/handoff/20260526-handoff-42.md @@ -0,0 +1,168 @@ +# Session handoff — 2026-05-26 (42) + +Forty-second handover. This session **completed ADR-0035 Phase 4**: it +shipped **sub-phase 4i** (the verification sweep — items a–e) on top of +4h, then ran a **whole-Phase-4 `/runda`** (4a–4i seen as an integrated +whole). Phase 4 (advanced-mode SQL DDL) is **done**. The `/runda` found +the integrated implementation solid; it surfaced three **error-message / +capability follow-ups** (all user-decided "track", below) — no +correctness or data bugs. + +> Note: this supersedes handoff-41, which predates 4i and still said "4i +> next". 4h + the case-insensitive-table-name fix (handoff-41's content) +> are also done and committed. + +## §1. State at handoff + +**Branch:** `main`. **HEAD `22e5bf5`.** **Tests: 1917 passing, 0 failing, +0 skipped, 1 ignored** (the `friendly/mod.rs` ` ```ignore ` doctest). +**Clippy:** clean (`cargo clippy --all-targets -- -D warnings`). + +**Unpushed commits (all of this + the prior session's work; normal):** + +``` +f7e77a8 feat: ADR-0035 4h — ALTER TABLE … RENAME TO +a95c807 fix: resolve table names case-insensitively across all executors +ca64434 docs: session handoff 41 … +1afcf4e feat: ADR-0035 4i(d) — merge shared-entry-word completions +f852610 feat: ADR-0035 4i(e) — colour DSL vs SQL completions when mixed +c2eb8cb fix: ADR-0035 4i(c) — don't pre-flag a self-referencing FK parent +22e5bf5 feat: ADR-0035 4i(a,b) — CREATE TABLE help/usage + describe table constraints; Phase 4 complete +``` + +Push is the user's step; nothing blocks. + +## §2. What shipped (4i + the Phase-4 `/runda`) + +ADR-0035 **Phase 4 is complete (4a–4i)**. 4i — the verification sweep — +landed in four commits (plan `docs/plans/20260526-adr-0035-sql-ddl-4i.md`): + +- **4i(d)** (`1afcf4e`) — **shared-entry-word completion merge.** At the + advanced-mode entry-word boundary, `completion_probe_in_mode` walks + every candidate node and unions the viable (`Incomplete`) ones' + continuations, so `drop ` offers `table·index·column·relationship· + constraint` and `drop rel` → `relationship` (was an empty dead-end). + Completion-only; the parse path is untouched; deeper positions keep the + committed walk. +- **4i(e)** (`f852610`) — **simple-vs-advanced completion colour.** Each + continuation is classified `Both`/`Advanced`/`Simple`; **only when the + list mixes modes** it is coloured (`mode_advanced`/`mode_simple`; `Both` + = token-kind) and block-ordered **Both → Advanced → Simple** + (user-chosen). Single-mode lists keep token-kind colours. `Candidate` + gained a `mode` field (typing_surface snapshots regenerated, uniform + `mode: Both`). +- **4i(c)** (`c2eb8cb`) — **self-ref FK pre-submit indicator.** + `schema_existence_diagnostics` collects the CREATE TABLE target(s) + (`NewName`/`table_name`) into `created_tables` and exempts a `Tables` + ref matching one from the unknown-table flag. (Provably scoped: the + only two `NewName`/`table_name` grammar nodes are the SQL + simple + CREATE-TABLE targets — verified in the `/runda`.) +- **4i(a,b)** (`22e5bf5`) — **(b)** `describe` of table-level constraints + (`TableDescription` gained `unique_constraints` + `check_constraints`, + rendered in a "Table constraints:" section — composite UNIQUE + table + CHECK incl. named); **(a)** CREATE TABLE help/usage skeleton refreshed + for the DEFAULT/CHECK/REFERENCES/composite-UNIQUE/table-CHECK/FK forms. + **Phase 4 docs flipped to complete** (ADR Status + §13 4i + ADR index + + `requirements.md` Q1). + +**Whole-Phase-4 `/runda` (2026-05-26).** Probed the feature combinations +no single slice tested, through the full pipeline + a *fresh* rebuild: +CREATE with FK + table CHECK + composite UNIQUE → ALTER → RENAME table → +fresh rebuild (all three still enforce); ALTER COLUMN TYPE on a column +inside a composite UNIQUE *and* a table CHECK (both preserved); +case-variant `alter`/`alter column type`/`add constraint` (all work + +round-trip). **All round-tripped** — strong evidence the two DDL +generators (`do_create_table` / `schema_to_ddl`) stay in sync across the +full feature set, metadata stays consistent, and the case-insensitivity +fix composes with every DDL path. No correctness/data bug; no ADR +divergence; vocab audit holds. + +## §3. Tracked follow-ups from the Phase-4 `/runda` (user-decided "track") + +All three are **error-message / capability** items on a rare **safe** +edge (dropping a column covered by a composite UNIQUE is correctly +*refused* — no corruption). None is a correctness or data bug. + +- **F1 — friendly message for dropping a column a composite UNIQUE + covers.** `do_drop_column`'s "an index covers it — drop the index + first" guard reads `read_table_indexes`, which filters to `origin='c'` + (explicit `CREATE INDEX`) and **excludes the UNIQUE-constraint + auto-index** (`origin='u'`). So `drop column c` when `unique (b, c)` + spans `c` falls through to the raw engine refusal instead of a friendly + message. Fix: detect the column in `schema.unique_constraints` and + refuse with a clear engine-neutral message (e.g. "cannot drop `T.c` — + it is part of a UNIQUE (b, c) constraint; recreate the table to change + it"). Message-only; small. (Interacts with F3.) +- **F2 — pre-existing generic-error rendering leaks a literal `{table}` + (broader than Phase 4).** Replay renders refused commands via + `DbError::friendly_message()` (`runtime.rs:~1202/1238`), which uses + `TranslateContext::default()` → the `error.generic.*` template comes + out with a **literal unsubstituted `{table}`** and `operation` (no + table/operation context). Affects **every** command refused during + replay (and other `friendly_message()` callsites, e.g. export) — not + Phase-4-specific. Fix needs care: it's a shared path; make the hint + degrade gracefully when no table is in context (drop the `… of + {table}` clause, or say "the table") and check snapshots. Scope it on + its own. +- **F3 — provide a way to drop a composite UNIQUE constraint (user- + raised; own ADR).** A composite UNIQUE is **anonymous** by design + (ADR-0035 §4a.2; 4g refused naming UNIQUE) — stored as a column-list + with no name, so no `drop constraint ` can target it, and it + can't be removed except by recreating the table. The user wants a way + to drop it. This is a **design decision / new capability** (likely a + new ADR or an ADR-0035 amendment): either name composite UNIQUEs, or a + positional `drop constraint unique (cols)` / `alter table T drop unique + (cols)` form, executed via the rebuild primitive. F1's message becomes + actionable once F3 lands. + +## §4. Carried follow-ups (from handoff-41, still open) + +- **H1 wording — `--create-fk` leak (4g).** `ALTER … ADD FOREIGN KEY` on + a missing child column reuses `do_add_relationship`'s error mentioning + the DSL flag `--create-fk` — off-key in SQL. Fix the SQL-path wording. +- **Case-only table rename** refusal (4h, autonomous decision) — `alter + table T rename to t` refused ("differ only in capitalization"). Left as + refuse unless the user wants it supported (would need a temp-name + two-step). +- **Column-name case strictness** — table names resolve case-insensitively + now; column names are still matched case-sensitively (wrong case → "no + such column"). Safe; a separate UX-consistency change if wanted. +- **Coverage gap — pre-4g 3-column `CHECK_TABLE` migration** in-place path + untested (can't fabricate a 3-col table via the public API). +- **H1 friendly wording** for the 4e CHECK-guard refusals + 4f + type-conversion diagnostics (engine-neutral but terse). +- The handoff-39 §8 items: app-lifecycle-command runtime-failure + journalling; M4 execution-time mode side-channel; `blob` value literal; + CI/TT5; DSL→SQL teaching echo (ADR-0030 Phase 5). + +## §5. What's next (no committed scope) + +ADR-0035 / Phase 4 of ADR-0030 is **done**. Open avenues (per +`requirements.md` / CLAUDE.md "deferred"): the SQL→English friendly layer +(H1), tutorial/lesson system, session-log + Markdown export (V4), +readline/multiline/tab-completion/syntax-highlight input polish, ER +diagram export (V3), CI (TT5), and the F1–F3 follow-ups above. None is +started; pick with the user. + +## §6. Process pins (unchanged) + +- **Confirm every commit** (propose message, wait). No AI attribution. + **Push is the user's step.** Unpushed commits are normal. +- **Escalate ambiguity / long tails.** This session surfaced and + user-decided every fork (4h scope, case-safety scope, 4i(e) colour + design, and the F1–F3 follow-ups). +- **`/runda` at planning exit AND on finished slices** — it earned its + keep repeatedly this session (the 4h CHECK-drift, the case-collision + leak, and confirming the integrated Phase 4 is sound). +- **Keep docs lockstep** — ADR status/§13 + index + requirements in the + same edit. + +## §7. How to take over + +1. **Read, in order:** this file → `CLAUDE.md` → + `docs/adr/0035-advanced-mode-sql-ddl.md` (now fully shipped) → + `docs/requirements.md`. +2. **Baseline:** `cargo test` (1917 / 0 / 0 / 1 ignored) + `cargo clippy + --all-targets -- -D warnings` (clean). +3. Phase 4 is complete; there is **no in-flight slice**. Pick the next + piece of work with the user (§5), or take an F1–F3 follow-up.