- 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.
7.4 KiB
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>].
setoverride 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 reuseupdate's typedcurrent_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;setmay only adjust the filled column; a row count is refused. - Named-generator vocabulary (D9):
src/seed/vocabulary.rs—KNOWN_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 }insrc/seed/generators.rs, interpreted per destination type;range_bounds_reasonvalidates compatibility before generation. - Ambient wiring: completion (generator names after
as, theset <col>and.colcolumn slots, thesetkeyword); highlight (newHighlightClass::Function→ existingtok_function); validity (newIdentSource::Generators— unknown generator flagged[ERR]; unknown column inset/.colflagged via the existing Columns path); help (help.data.seed); parse-error pedagogy near-miss rows; the D13 advisory's Phase-2/3 wording (points atsetand 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.rs—Command::Seedgainstarget_column: Option<String>+overrides: Vec<SeedOverride>; newSeedOverride/SeedOverrideKind.src/dsl/grammar/data.rs—SEED_SET_CLAUSE+SEED_DOT_COLUMNgrammar;SEED_GENERATORslot (IdentSource::Generators,HighlightClass::Function);build_seed+ the override fold (build_seed_overrides/parse_seed_override_tail).src/dsl/grammar/mod.rs—IdentSource::Generators+HighlightClass::Function.src/db.rs—apply_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 afteras; generator validity.src/input_render.rs—"generator"invalid-ident kind.src/theme.rs—Function → tok_function.- Catalog —
help.data.seed,parse.usage.seed,seed.advisory_generic(Phase-2/3 wording) inen-US.yaml;keys.rsplaceholders updated. - Tests —
tests/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(theupdate … settyped slot) rather than the raw ADR-0026 expression operand — no spurious column-ref match, typed narrowing, consistent withupdate. 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
- Read handoffs 64 → 65 → 66,
CLAUDE.md,docs/requirements.md,docs/adr/0048-…md(Status block + D1/D2/D9/D13 + the amendment). - Seed is feature-complete (SD1 + SD2).
requirements.md: SD1[x], SD2[x]. The only open A1 gap ishint/H2 (own ADR). - Commits pending approval. Suggested split:
feat(seed): set override clause + column-fill (ADR-0048 Phase 2)— allsrc/+tests/changes.docs: ADR-0048 Phase 2 implemented + handoff 66— ADR / README / requirements / this file.
- Next options (user's call): H2
hint(closes A1); TT5 CI; the larger V4 journal / tutorial ADRs; or Tier-4 PTY (TT4). - Consider a
cargo sweepat 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 D1–D18 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.