Files
rdbms-playground/docs/handoff/20260526-handoff-42.md

9.0 KiB
Raw Permalink Blame History

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 ae) on top of 4h, then ran a whole-Phase-4 /runda (4a4i 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 (4a4i). 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 relrelationship (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 <name> 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 F1F3 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 F1F3 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.mddocs/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 F1F3 follow-up.