Files
rdbms-playground/docs/handoff/20260609-handoff-59.md
T

8.7 KiB
Raw Permalink Blame History

Session handoff — 2026-06-09 (59)

Fifty-ninth handover. Continues from handoff-58 (H1a done). This session did three distinct things, in order: (1) a tracking-integrity audit + reconciliation of requirements.md against the actual code; (2) a partials sweep closing V5, H3, and a new V5a; (3) the big one — T3 compound-PK foreign-key references, designed in ADR-0043, /runda-verified twice, and implemented end-to-end across both surfaces.

§1. State at handoff

Branch: main. HEAD 4752ba2. 8 commits this session (28e75964752ba2); push is the user's step.

Tests: 2193 passing / 0 failing / 1 ignored (lib 1578, it 423, typing_surface_matrix 192; the 1 ignored is the long-standing doc-test). Clippy clean (nursery, all targets).

Requirements markers now: [ ] 19, [/] 6, [x] 59, [~] 11, [-] 3. (The [/] "partial / in progress" marker is new this session — see §2.)

This session's commits:

4752ba2 feat: compound-PK foreign-key references — grammar + tests (ADR-0043)
b14f019 refactor: relationship model to column lists for compound FK (ADR-0043)
b688592 docs: ADR-0043 implementation-readiness notes from /runda DA pass
274e2b1 docs: ADR-0043 compound-PK foreign-key references (T3); accepted
1d898ad feat: V5a show relationship/index <name> detail views
757711f feat: H3 help <command> per-command detail + general reference
8dec784 feat: V5 show tables / relationships / indexes list commands
28e7596 docs: reconcile requirements tracking with verified code state

§2. The tracking reconciliation (read this — it changes how you plan)

Planning off handoffs/requirements.md was unreliable: an audit of all 35 [ ] items against the source found ~46 % mis-marked, overwhelmingly under-claimed (tab completion I3 and syntax highlighting I4 were shipped but marked "not yet implemented"). Root cause: the binary legend — a shipped feature, a half-built one, and an untouched one all wore the same [ ].

Fix (commit 28e7596): added a [/] "partial / in progress" marker to the legend, with a dated reconciliation note. Re-marked:

  • 7 shipped-but-[ ][x]: S1, S4, S5, I1a, I3, I4, C1.
  • 9 substantially-built → [/] with explicit gap notes: S3, A1, V1, V2, V5, T3, H3, DOC1, X1.
  • Fixed a false CLAUDE.md claim ("Tier 4 is wired") — no PTY tests exist; TT4 is spec-only.

Discipline going forward: move items [ ][/][x]; keep the gap note current. Don't trust a marker without checking the code — verify empirically.

§3. The partials sweep (V5, H3, V5a)

Three small/medium, no-ADR partials closed (the others — V1, S3/V2, A1, DOC1, X1 — need an ADR / output-model redesign / new features, so were left [/], see §5):

  • V5 [x] (8dec784): show tables / show relationships / show indexes as one Command::ShowList { kind }; read-only worker show_list. 10 tests.
  • H3 [x] (757711f): help <command> per-command detail (HELP node takes an optional BarePath topic; note_help_topic renders every command sharing the entry word) + help types + friendly unknown-topic pointer. 9 tests.
  • V5a [x] (1d898ad): singular show relationship <name> / show index <name> detail — folded into ShowList { kind, name: Option<String> }. Raised + closed this session (it was the honest tracked home for V5's [<name>] clause).

§4. T3 — compound-PK foreign-key references (the big one)

ADR-0043 (docs/adr/0043-compound-pk-foreign-key-references.md, Accepted + implemented). The open leg of T3: a FK that references a parent's compound PK. The audit found single-column FK woven through ~1520 sites; it earned an ADR, not an inline build.

Four forks, all user-confirmed at the recommended option:

  • F-A reference the parent's full PK (subset/UNIQUE-target OOS), matched positionally to an equal-length child list.
  • F-B house-style uniform lists, no migration — the decisive simplifier: the user confirmed back-compat is not required (pre-release, no installed base), so project.yaml endpoints became columns: [a, b] (like primary_key: [id]), metadata TEXT cells store the list comma-joined (bare for single), and no F3 migrator / version bump was needed.
  • F-C parenthesized DSL from P.(a, b) to C.(x, y) (single bare form unchanged).
  • F-D bare table-level SQL FOREIGN KEY (x,y) REFERENCES P auto-expands to the parent's full PK when arities match.

Implementation (two commits):

  • b14f019the refactor: relationship model String → Vec<String> through all six layers (AddRelationship / SqlForeignKey AST, RelationshipSchema, metadata, project.yaml, ReadForeignKey, RelationshipEnd). Single- column behaviour preserved (one-element vecs); the existing single-column relationship suite was the regression net. This is the safe green checkpoint.
  • 4752ba2the grammar + tests: multi-column parsing on both surfaces (AR_PARENT_COLS/AR_CHILD_COLS Choice in ddl.rs; FK_*_COL_LIST Repeated in sql_create_table.rs; consume_fk_reference + the table-level/ALTER parsers collect lists). Executor: resolve_fk_parent_columns (F-A validation + F-D auto-expand + arity), per-pair check_fk_type_compat, schema_to_ddl multi-column emission, pragma_foreign_key_list read grouped by id, ordered by seq (positional pairing), auto-name joins lists, --create-fk per-column, multi-column teaching echo. 12 tests in tests/it/compound_fk.rs.

/runda ran twice (once on the ADR pre-build, once on the finished code). The post-build pass found 3 coverage gaps and they were closed: save→rebuild round-trip (the riskiest — proves comma-encode/decode + yaml + FK reconstruction survive a text→db rebuild), undo (one step), per-pair type-mismatch.

Two residuals, confirmed non-blocking (noted in code):

  1. inline col REFERENCES P(a,b) gives a generic arity error, not the ADR's tailored "use the table-level form" pointer.
  2. a compound-FK violation's friendly error names only the first column pair (the ADR-0019 facts model is single-column). Both are messaging-only; FK correctness/enforcement is unaffected.

Process note (a real scare): a broad regex script over test files (to wrap add_relationship call args + struct fields in vec![]) over-reached into lib structs it shouldn't have (RelationshipSelector::Endpoints, FailureContext/ TranslateContext — all deliberately single-column), briefly breaking the lib build. Recovered by reverting those specific sites. Lesson: scripted edits across src/ are dangerous when a field name (parent_column) is shared between the struct you're migrating and ones you're not — prefer compiler-guided manual fixes or scope the script tightly.

§5. Remaining open landscape (now trustworthy)

Still [/] partial (need design/ADR or are larger):

  • V1 relationship line-art visualization — needs a visualization ADR (the most-requested deferred item).
  • S3 / V2 multi-result tabs — output-model redesign (single buffer → tab abstraction).
  • A1 app-commands — blocked on seed (SD1) + hint (H2), both unbuilt features.
  • DOC1 reference docs — writing effort.
  • X1 logging density — broad/mechanical (~25 tracing sites today; CLAUDE.md wants "log liberally").

[ ] not started: H2 hint, SD1 seed, C4 m:n, B3 query-timeout, I1 multi-line, I1b readline, I5 cancellation, TT5 CI, TT4 PTY (spec-only), D1D3 distribution, NFR-1…7.

§6. Next job — candidates

No forced next step. By readiness:

  1. V1 relationship visualization — design-first (its own ADR). The user has flagged it repeatedly; it's the prominent open design item.
  2. X1 logging — mechanical, no ADR; brings the codebase to the CLAUDE.md "log liberally" bar.
  3. TT5 CI — test infra is solid (2193 green); no workflow yet.
  4. The two T3 residuals (§4) — small messaging polish if they bug you.

§7. How to take over

  1. Read handoffs 57 → 58 → 59, then CLAUDE.md, docs/requirements.md (now with the [/] marker + the §2 reconciliation note), docs/adr/README.md.
  2. For relationships/FK: read ADR-0043. The model is list-based (Vec<String>); single-column is the one-element case.
  3. Codebase on main at 4752ba2, clean, 8 commits unpushed.
  4. Process pins that paid off: verify the tracker against code, don't trust the marker; escalate genuine forks (the four ADR-0043 forks were the user's); /runda after planning AND after implementation (the post-build pass found 3 real gaps); scope scripted edits tightly (§4 scare). Commits user-confirmed, append-only, no AI attribution.