Files
rdbms-playground/docs/handoff/20260611-handoff-66.md
T
claude@clouddev1 30b2677bf3 docs: ADR-0048 Phase 2 implemented + handoff 66
- ADR-0048: status → Phase 1 + Phase 2 implemented; D2 amendment
  (quoted dates, no date-literal token) and the override × UNIQUE
  capacity-guard decision; phasing/Status blocks marked done.
- README index: 0048 entry updated (Phase 2 shipped, 2400 tests).
- requirements.md: SD2 → [x] (the override-hooks core + column-fill).
- handoff 66: this session's Phase 2 build + the two /runda passes.
2026-06-12 09:44:36 +00:00

7.4 KiB
Raw Permalink Blame History

Session handoff — 2026-06-11 (66)

Sixty-sixth handover. Continues from handoff-65 (ADR-0048 seed Phase 1). This session built ADR-0048 Phase 2 end to end: the set override clause (D2) and the <table>.<column> column-fill form (D1 form 2) — the two surfaces Phase 1 deliberately deferred. Designed-then-DA-vetted (a /runda pass that caught a real ADR-vs-grammar conflict), then built test-first.

§1. State at handoff

Branch: main. All Phase-2 work is in the working tree; commits are pending the user's approval (see §6). Unpushed is the normal working state.

Tests: 2400 passing / 0 failing / 0 skipped / 1 ignored (the long-standing friendly doctest). Clippy clean (nursery, all targets). +42 over handoff-65's 2358.

§2. What landed (read ADR-0048 — Status + D1/D2/D9/D13)

seed <T>[.<col>] [count] [set <overrides>] [--seed <n>].

  • set override clause (D2): four forms, comma-separated — status = 'active' (fixed), role in ('a','b') (pick-list), work_addr as email (named generator), price between 10 and 100 (range; numeric and quoted dates). Type-aware; an override drops its column from the generic-fill advisory (D13). Value slots reuse update's typed current_column_value (quoting enforced structurally — a bare word is rejected).
  • Column-fill (D1 form 2): seed users.email [set …] fills one column across existing rows (an UPDATE). Refuses PK / autogen (serial/shortid/blob) targets; empty table → friendly no-op; FK target samples the parent; UNIQUE/identifier target gets collision-free values; one undo step; set may only adjust the filled column; a row count is refused.
  • Named-generator vocabulary (D9): src/seed/vocabulary.rsKNOWN_GENERATORS + generator_for_name + is_known_generator_prefix, the single source of truth for completion, validity, and the executor.
  • Range generator: Generator::Range { low, high } in src/seed/generators.rs, interpreted per destination type; range_bounds_reason validates compatibility before generation.
  • Ambient wiring: completion (generator names after as, the set <col> and .col column slots, the set keyword); highlight (new HighlightClass::Function → existing tok_function); validity (new IdentSource::Generators — unknown generator flagged [ERR]; unknown column in set/.col flagged via the existing Columns path); help (help.data.seed); parse-error pedagogy near-miss rows; the D13 advisory's Phase-2/3 wording (points at set and the column-fill repair). Both modes (D5).

§3. The ADR amendment (a real DA find)

The pre-build /runda pass found that ADR-0048 D2's "dates stay unquoted" was impossible — this DSL has no date-literal token (Value is Number/Text; dates are quoted strings validated by bind_date). Escalated to the user, who chose quoted dates + amend the ADR (the grammar-consistent option). D2 now carries a dated amendment; the range form uses between '2023-01-01' and '2024-12-31'. This was the only divergence from the ADR text; numbers remain unquoted.

§4. Where the code lives

  • src/dsl/command.rsCommand::Seed gains target_column: Option<String> + overrides: Vec<SeedOverride>; new SeedOverride / SeedOverrideKind.
  • src/dsl/grammar/data.rsSEED_SET_CLAUSE + SEED_DOT_COLUMN grammar; SEED_GENERATOR slot (IdentSource::Generators, HighlightClass::Function); build_seed + the override fold (build_seed_overrides / parse_seed_override_tail).
  • src/dsl/grammar/mod.rsIdentSource::Generators + HighlightClass::Function.
  • src/db.rsapply_seed_overrides / seed_override_plan / seed_override_literal; do_seed_column_fill; do_seed + Database::seed + worker wiring threaded with the new params.
  • src/seed/vocabulary.rs (new); generators.rs (range generator + range_bounds_reason); mod.rs (Generator::Range).
  • src/completion.rs — generator candidates after as; generator validity. src/input_render.rs"generator" invalid-ident kind. src/theme.rsFunction → tok_function.
  • Cataloghelp.data.seed, parse.usage.seed, seed.advisory_generic (Phase-2/3 wording) in en-US.yaml; keys.rs placeholders updated.
  • Teststests/it/seed.rs (+~30: builder fold, executor set/column-fill, undo, advanced mode), src/seed/{vocabulary, generators}.rs (range + vocabulary units), src/completion.rs (generator + column validity), src/dsl/walker/highlight.rs, tests/typing_surface/mod.rs (completion slots), tests/it/parse_error_pedagogy.rs (near-miss rows).

§5. Two implementation refinements vs. the ADR (both met the contract)

  • Quoted dates (the D2 amendment, §3).
  • Value slots reuse current_column_value (the update … set typed slot) rather than the raw ADR-0026 expression operand — no spurious column-ref match, typed narrowing, consistent with update. The user-facing contract (quoted literals, type-aware) is fully met.

The seed_take_value / seed_set_error builder paths are drift-guards (the typed slots only ever match value literals, so a bare word is rejected at the grammar level) — they use the generic parse.error_wrapper, mirroring expr::build_expr.

§6. How to take over / next steps

  1. Read handoffs 64 → 65 → 66, CLAUDE.md, docs/requirements.md, docs/adr/0048-…md (Status block + D1/D2/D9/D13 + the amendment).
  2. Seed is feature-complete (SD1 + SD2). requirements.md: SD1 [x], SD2 [x]. The only open A1 gap is hint/H2 (own ADR).
  3. Commits pending approval. Suggested split:
    • feat(seed): set override clause + column-fill (ADR-0048 Phase 2) — all src/ + tests/ changes.
    • docs: ADR-0048 Phase 2 implemented + handoff 66 — ADR / README / requirements / this file.
  4. Next options (user's call): H2 hint (closes A1); TT5 CI; the larger V4 journal / tutorial ADRs; or Tier-4 PTY (TT4).
  5. Consider a cargo sweep at this milestone (target/ grows).

§7. Post-implementation /runda pass (done this session)

A DA pass over the completed code found no correctness bugs and no dropped requirements; all D1D18 acceptance criteria verified met, tests confirmed to catch regressions. One design fork was surfaced and resolved by the user:

  • Bounded override × UNIQUE column — a fixed value / too-short pick-list on a single-column-UNIQUE target used to silently cap the run (e.g. seed users 100 set email = 'x' → 1 row). Now a friendly error up front (seed_override_capacity_guard, src/db.rs), for both whole-row and column-fill; generators/ranges stay cap-based (unbounded sources). ADR-0048 D2 documents it; two tests pin it.

Remaining non-blocking edges (noted, not bugs):

  • Overriding an FK column with a literal: the override wins (D2); a non-parent value fails safely through the FK-error layer.
  • Column-fill of one column of a compound FK samples that column independently → an invalid tuple fails safely (UPDATE rejected, rollback), never corrupts. Single-column FKs / non-FK columns are exact.
  • The generator slot uses the default candidate-ladder hint (offers the vocabulary), not a dedicated prose intro — discoverability is met by completion; a prose intro is optional polish.