From b8034682ab5b9efe6f4725a49d9bb59e3db7e723 Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Wed, 10 Jun 2026 12:24:01 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20session=20handoff=2061=20=E2=80=94=20X1?= =?UTF-8?q?=20logging=20full=20sweep=20+=20T3=20residuals=20closed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/handoff/20260610-handoff-61.md | 171 ++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 docs/handoff/20260610-handoff-61.md diff --git a/docs/handoff/20260610-handoff-61.md b/docs/handoff/20260610-handoff-61.md new file mode 100644 index 0000000..22be510 --- /dev/null +++ b/docs/handoff/20260610-handoff-61.md @@ -0,0 +1,171 @@ +# Session handoff — 2026-06-10 (61) + +Sixty-first handover. Continues from handoff-60 (Gitea migration +cleanup + V1 relationship visualization, ADR-0044). This session was +a **list-trimming pass on "easy wins"**: it closed **X1** +(comprehensive logging, full sweep) and both **T3 residuals** (the two +ADR-0043 messaging-polish items). Four commits, all green, all +user-confirmed. + +## §1. State at handoff + +**Branch:** `main`. **HEAD `5a33f2a`.** 4 commits this session +(`a8ad0c6` → `5a33f2a`) on top of session-60's 5; push is the user's +step. + +**Tests: 2211 passing / 0 failing / 1 ignored** (lib 1588, it 431, +typing_surface_matrix 192; the 1 ignored is the long-standing +doc-test). **Clippy clean** (nursery, all targets). +4 over the +handoff-60 baseline of 2207 (one test per residual at each of the +enrichment + render layers, plus the two grammar/worker tests). + +This session's commits: +``` +5a33f2a fix(fk): compound-FK violation message names every column pair +6985a43 fix(fk): inline FK referencing a compound PK points at the table-level form +0a7612e feat: comprehensive logging across parser, app, persistence, runtime (X1) +a8ad0c6 feat(db): comprehensive logging across worker + executors (X1) +``` + +## §2. X1 — comprehensive logging (closed, `[x]`) + +The full-sweep instrumentation pass the "log liberally" standard +called for. **~75 → 135 `tracing` sites** under a documented level +discipline now living in the **`src/logging.rs` module doc** (read it +before adding logs — it is the durable convention). + +**Levels:** `error` = unrecoverable; `warn` = recoverable / fallback +taken; `info` = low-volume lifecycle (worker start/exit, project +open); `debug` = the bulk, one line per *executed* command + its +decision points (off by default, opt-in `RDBMS_PLAYGROUND_LOG=debug`); +`trace` = hot paths only (per-keystroke parse, per-key input). + +**Where logs go (was a point of confusion):** always a **file** +(stdout/stderr would corrupt the TUI). Path precedence: `--log-file` +> `RDBMS_PLAYGROUND_LOG_FILE` > default `~/.rdbms-playground/ +playground.log` (append mode). Level filter is the *separate* +`RDBMS_PLAYGROUND_LOG` env var, default `info`. + +**Coverage by commit:** +- `a8ad0c6` **db.rs** (26→67): entry-`debug!` on all 34 `do_*` + executors (DDL/DML/relationship/index/read), matching the existing + `do_sql_delete`/`do_run_select` style — so the route through + *delegating* executors (e.g. `add_column` → + `add_constrained_column_via_rebuild`) is visible in the log + *sequence*. Decision-point logs: `rebuild_table_with_copy` + begin/commit (+ FK-check-failure and `foreign_keys` re-enable + failure as `warn`), `do_insert` autofill summary, `do_delete` + cascade summary, `do_create_table` FK resolution. Worker + start/exit `debug!`→`info!`. +- `0a7612e` **rest**: `persistence/mod.rs` logs every yaml/CSV/history + write (the silent-failure disk paths); `runtime.rs` + `execute_command_typed` dispatch; `app.rs` submit / + `dispatch_app_command` / ADR-0044 diagram-vs-prose render choice; + `dsl/parser.rs` parse begin/outcome at **`trace`** (the + `parse_command_inner` choke point — `completion.rs` re-parses + per-keystroke, probing candidates in a loop, so `debug` would + flood). + +**Verification:** emission proven end-to-end through the *real* worker +thread + real `logging::init` via two throwaway smoke tests (db path +and persistence path), both since deleted. The DA-honest gap: a few +internal read-only helpers (`do_find_rows_matching`, +`do_read_relationships`, `do_list_names_for`) and the thin `*_request` +wrappers are not *individually* instrumented — the wrappers delegate +to logged executors (skipped to avoid double-logging), the helpers are +low-value. Effective coverage is complete via logged entry points; it +is not literally 44/44. + +## §3. T3 residuals — both closed (ADR-0043) + +Two messaging-only items carried since handoff-59 §4; FK +correctness/enforcement was never affected. + +**#1 — inline-FK arity wording (`6985a43`).** `col REFERENCES P(a,b)` +referencing a compound PK gave the generic arity error. An inline +column-level FK is single-column by construction, so it now points at +the table-level form: *"an inline column reference can only name one +column … Use the table-level form instead: `FOREIGN KEY () +REFERENCES P (a, b)`."* Mechanism: new **`inline: bool` on +`SqlForeignKey`**, set by the single shared grammar builder +`consume_fk_reference` (true for the inline path at `ddl.rs:1560`, +false for table-level `1590` and `build_alter_fk`); threaded into +`resolve_fk_parent_columns`, which tailors the arity-mismatch message +when `inline && parent_key.len() > 1`. 6 construction sites total (2 +grammar + 1 ALTER delegate + 3 test literals) — hand-edited, **not** +the scripted sweep handoff-59 §4 warned about. The bare inline form +(`col REFERENCES P`, no parens) hits the same arity branch, so it is +covered by the same code (tested via the explicit-parens form). + +**#2 — compound-FK violation names every pair (`5a33f2a`).** +`enrich_fk_violation` (`runtime.rs`) picked only `local_columns +.first()` / `other_columns.next()`. It now gathers all pairs of the +matched relationship and carries them **comma-joined in the existing +single-column facts slots** (`column`, `parent_column`, `value`), so +the headline reads *"no parent row in `Region` has `country, code` = +`7, 8`."* No facts-model or catalog change — joined strings flow +through the existing `{parent_column}`/`{value}` placeholders. +Single-column behaviour is byte-identical (a one-element join is the +element). **Known minor awkwardness:** the *verbose hint* interpolates +`{parent_table}.{parent_column}` → `Region.country, code`, which reads +a touch oddly; the headline is clean. A perfectly-formatted compound +hint would need catalog work, out of scope for a messaging-polish +residual — flagged, not fixed. + +## §4. Remaining open landscape (unchanged except X1) + +**Closed this session:** X1 → `[x]`; both T3 residuals (ADR-0043 fully +wrapped — no residuals left). + +**Still `[/]` / `[~]` / larger (design-first, own ADR):** +- **V2 / S3** multi-result tabs — output-model redesign. +- **V3** whole-DB ER export; **V4** scrollable journal + Markdown + (also the home for diagram live-reflow, ADR-0044 OOS-1). +- **A1** app-commands — blocked on `seed` (SD1) + `hint` (H2). +- **H1a** parse-error syntax help (partial; ADR-0021). +- **DOC1** reference docs. + +**`[ ]` not started:** H2 `hint`, SD1 `seed`, C4 m:n convenience, B3 +query-timeout, I1 multi-line input, I1b readline shortcuts, I5 +cancellation, **TT5 CI** (now Gitea Actions / Woodpecker — a fresh +decision tied to the migration + ADR-0001's reopened distribution +question), TT4 PTY (spec-only), D1–D3 distribution, NFR-1…7. + +**ADR-0044 OOS for later:** OOS-7 user-configurable relationship- +display setting (always-prose / always-diagram / auto-by-width). + +## §5. Next job — candidates (by readiness) + +No forced next step. Recommended order: +1. **TT5 CI** — test infra is solid (2211 green) and now there is real + logging to surface failures; no pipeline yet. A fresh **Gitea + Actions / Woodpecker** decision (earns a short ADR; ties into + ADR-0001's reopened distribution question). Highest leverage: + protects everything else. +2. **SD1 `seed`** then **H2 `hint`** — the two unblockers for **A1** + app-commands; both are net-new, self-contained features (each its + own ADR). +3. **C4 m:n convenience** — auto-generate a junction table; depends on + relationships, which are now solid (ADR-0043/0044 done). +4. **V2/S3 tabs** or **V4 journal** — larger output-model redesign; + design-first, own ADR. V4 also unlocks diagram live-reflow. + +## §6. How to take over + +1. Read handoffs 59 → 60 → 61, then `CLAUDE.md` (Gitea/`tea` section), + `docs/requirements.md` (X1 now `[x]`), `docs/adr/README.md`. +2. **Before adding any logging:** read the level-discipline block in + the `src/logging.rs` module doc (the X1 convention). +3. **For FK/relationship work:** ADR-0043 (compound FKs) + ADR-0044 + (visualization) are both fully landed; `SqlForeignKey` now carries + `inline`. +4. Codebase on `main` at `5a33f2a`, clean, 9 commits unpushed (5 from + session 60 + 4 this session). +5. Process pins that paid off: **verify log emission end-to-end, not + just that it compiles** (throwaway smoke tests through the real + worker thread caught nothing broken but proved the stack); + **hot-path logging belongs at `trace`, not `debug`** (the parser); + **test-first on both residuals** (red → green at every layer); + **hand-edit struct-field ripples, never script them** (handoff-59 + §4's scare avoided). Commits user-confirmed, append-only, no AI + attribution.