Phase 3 of the ADR-0030 SQL surface (DML) is implemented and verified through sub-phase 3k; mark ADR-0033 Accepted in the ADR and the README index (index-upkeep rule). Add handoff 34 tracking the close-out and teeing up ADR-0034 (history journal + replay filter) as the next job. 1645 passing / 0 failing / 0 skipped / 1 ignored. Clippy clean.
8.9 KiB
Session handoff — 2026-05-23 (34)
Thirty-fourth handover. This session completed ADR-0033
sub-phase 3k — the Phase-3 verification sweep — closing Phase 3
of the ADR-0030 advanced-mode SQL surface. A user-invoked
/runda round hardened the matrix attributions and closed two
small coverage gaps. ADR-0033 is now Accepted.
The next session (or the continuation of this one) starts the ADR-0034 implementation. See §4.
§1. State at handoff
Branch: main. Tests: 1645 passing, 0 failing, 0 skipped,
1 ignored (the unchanged friendly/mod.rs doctest). Clippy:
clean (cargo clippy --all-targets -- -D warnings).
Latest committed (local-only):
380c423 test+docs: 3k Phase-3 verification sweep — e2e DML + filled cross-cut matrix
origin/main is at 6b8888f (3h), so 10 commits are
local-only (the 3i series, handoff-32, 3j d5c7f63, handoff-33
a5cdb00, and this session's 3k 380c423). Unpushed commits are
a normal working state; pushing is the user's step — do not prompt
about it.
Uncommitted at the moment of writing this handoff (the ADR-0033 acceptance flip + this handoff doc):
docs/adr/0033-sql-dml-grammar.md— StatusProposed→Accepted.docs/adr/README.md— ADR-0033 index line flipped toAccepted(same-edit index-upkeep rule).docs/handoff/20260523-handoff-34.md— this file.
These three should be committed together (proposed message in §8).
§2. What shipped this session (3k)
Authoritative detail lives in the phase-exit report:
docs/handoff/20260523-phase-3-verification.md — read it for
the filled matrix, the requirements-to-test mapping, and the DA
review. Summary:
tests/sql_dml_e2e.rs(new) — 11 Tier-3 end-to-end DML tests (parse-in-Advanced → worker → persist/history): INSERT… SELECT cross-table, all-ten-type multi-row INSERT +RETURNINGtype recovery, UPDATE-with-subquery-in-SET, cascade DELETE, UPSERT round-trip,RETURNING×3,history.logreplay of Phase-3 forms, the full §13 OOS rejections, a trailing-;guard, and the[WRN]validity indicator driven by a SQL DML diagnostic.- Cross-cut gap-fill in
src/:walker/mod.rs(5 inherited-diagnostic cross-cuts — DELETE/UPDATE WHERE schema-existence, like-numeric on DELETE WHERE, the corrected row-scoped predicate slots),highlight.rs(DML-keyword highlight),completion.rs(INSERT INTOtarget-table),input_render.rs(advanced-mode DML hint-panel — added in the/rundaround). - Cross-cut matrix filled in
docs/plans/20260520-adr-0033-phase-3.md— 85 ✅, 1 N/A, 0 ❌, every row a verifiedfile::function. - ADR-0033 → Accepted (this handoff's commit).
§3. Decisions settled this session (do not re-litigate)
Both escalated and user-confirmed before any matrix/test edit
(via AskUserQuestion); recorded in the phase-exit report §4 and
the matrix footnotes [d]/[e]:
-
Predicate-warning-in-VALUES (matrix I7) — claim corrected. Predicate warnings (
eq_null/like_numeric/type_mismatch) fire on every DMLsql_exprslot with row scope (UPDATE/ DELETE WHERE, UPDATE SET incl. CASE, INSERT…SELECT projection & WHERE) but not in plainINSERT … VALUES— a VALUES literal has no row to compare against. This matches ADR-0033 §8.4 ("WHERE and CASE"); the original "(e.g. = with NULL in VALUES)" example was an over-statement. Backed by new row-scoped tests. -
Auto-snapshot (ADR-0006 / ADR-0033 §10) — N/A, deferred. ADR-0006 auto-snapshot/undo is unimplemented for both the DSL and SQL paths (the U-series). The "same as DSL" parity holds vacuously; Phase 3 introduces no regression. The matrix row is N/A, not red.
The /runda round additionally corrected the A6 attribution
(the hint-panel tests ran in Simple mode via ambient_hint, which
defaults to Mode::Simple; added an advanced-mode DML hint test)
and closed OOS-5/OOS-6 (INDEXED BY / multi-statement — both
parse-reject; a single trailing ; still parses).
§4. ADR-0034 — the NEXT job
Implement ADR-0034 (docs/adr/0034-history-journal-and-replay-filter.md,
Accepted). This is the user's standing "extra tasks after
Phase 3" item; it subsumes the old TASK #8 + TASK #9 and fixes a
real, currently-broken behaviour verified this session:
replay history.logfails on line 1.run_replay(src/runtime.rs:1630) feeds each whole raw line straight toparse_command_with_schemaand only skips blank/#lines — it does not understand the<ts>|<status>|<source>journal format thathistory.rsalready writes. So replay only works on hand-written bare-command.commandsscripts, never on the actual journal. No test catches this (existing replay tests + the new 3k e2e replay test all use bare-command scripts).
Concrete work (ADR-0034 §§1–4):
- Writer records every command, tagged
ok/err(todayhistory.rshardcodesok).errlines are journalled best-effort from the runtime/app error path (a parse failure never reaches the worker);oklines stay worker-journalled, transactionally coupled to the state change. - Hydration reads all records (ok + err) so cross-session
recall matches the in-session ring (req I2 is marked done but
only covers
oktoday — err lines are lost across sessions). - Replay learns the journal format: detect the
<iso8601>|<status>|prefix, extract+unescape<source>, skip non-ok; bare commands still replay as-is. Detection by the leading timestamp+status prefix so a|inside a bare command isn't misread. - Escape/unescape parity with the existing
history.rshelpers.
Test-first (global rule): the first move is a failing test
that replays an actual history.log (with the <ts>|ok| prefix)
and currently dies on line 1 — then make it green. Also add an
err-line round-trip test (write → hydrate-reads-it →
replay-skips-it).
Open question to settle with the user first: ADR-0034 has no plan doc (unlike Phases 2–3). It is smaller; a lightweight phased pass in one session may suffice. The user said we can "continue in this session afterwards with the ADR-0034 plan" — so the immediate next action is to produce that plan (or confirm a plan-less test-first pass), then implement.
§5. Other tracked deferred items (nothing lost)
- ADR-0006 auto-snapshot / undo (U-series) — surfaced by 3k's N/A matrix row; implement for both DSL and SQL worker handlers so parity is real, not vacuous.
- M4 — execution-time mode side-channel (three-way
ModethreadedAction→worker, for mode-dependent output). Needs its own ADR (ADR-0033 Amendment 3;requirements.mdM4). Not a prerequisite for anything above. - Phase 4 — DDL as SQL (
CREATE/DROP/ALTER TABLE,CREATE/DROP INDEX). The next ADR-0030 roadmap phase, but no ADR exists yet (latest is 0034) — needs its own ADR before implementation. blobvalue literal —src/dsl/value.rshas no blob literal yet; the 3k all-types test inserts NULL for blob (type still round-trips). Pre-existing gap.- Q1 / Q2 (SQL subset completeness; polished out-of-subset
rejection message naming the construct) — multi-phase, still
[ ]; the 3k OOS tests assert rejection only, not message quality (Q2 is "Implementation pending"). - Cosmetic:
tests/sql_*.rshelper names (run_sqlinsertetc.) keep their dev-word-era spelling though they parse the real words.
§6. Process pins (unchanged, still binding)
- Confirm every commit. Propose the message; wait for the
go-ahead. (The 3k commit
380c423and the acceptance flip were both user-approved.) - Push is the user's step. Never push; never prompt about it.
- No AI attribution in commits (global rule).
- Probe, don't reason. This session's catalog sub-agents
fabricated test names and mis-attributed dispatch/inherited-
diagnostic rows; every matrix row was re-verified by reading the
actual test. The
/rundaround caught a mode mismatch the same way. Reproduce/print before concluding. - Escalate ADR-vs-implementation mismatches; never classify work "out of scope" without user confirmation. Both 3k findings (I7, auto-snapshot) were escalated, not silently resolved.
§7. How to take over
- Read, in order: this file →
docs/handoff/20260523-phase-3-verification.md(the Phase-3 close-out) →docs/adr/0034-history-journal-and-replay-filter.md(the next job) →CLAUDE.md→docs/requirements.md. - Baseline:
cargo test # expect 1645 passing / 0 failing / 0 skipped / 1 ignored cargo clippy --all-targets -- -D warnings # clean - Start ADR-0034 per §4: settle plan-vs-no-plan with the
user, then a test-first pass beginning with the failing
replay history.logreproduction. - Escalate anything not settled in ADR-0034; the user wants mismatches surfaced, not silently fixed.