55b784597a
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.
196 lines
8.9 KiB
Markdown
196 lines
8.9 KiB
Markdown
# 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` — Status `Proposed` →
|
||
`Accepted`.
|
||
- `docs/adr/README.md` — ADR-0033 index line flipped to
|
||
`Accepted` (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 + `RETURNING`
|
||
type recovery, UPDATE-with-subquery-in-SET, cascade DELETE,
|
||
UPSERT round-trip, `RETURNING` ×3, `history.log` replay 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 INTO` target-table),
|
||
`input_render.rs` (advanced-mode DML hint-panel — added in the
|
||
`/runda` round).
|
||
- **Cross-cut matrix filled** in
|
||
`docs/plans/20260520-adr-0033-phase-3.md` — **85 ✅, 1 N/A, 0
|
||
❌**, every row a verified `file::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]:
|
||
|
||
1. **Predicate-warning-in-VALUES (matrix I7) — claim corrected.**
|
||
Predicate warnings (`eq_null` / `like_numeric` / `type_mismatch`)
|
||
fire on every DML `sql_expr` slot with **row scope** (UPDATE/
|
||
DELETE WHERE, UPDATE SET incl. CASE, INSERT…SELECT projection &
|
||
WHERE) but **not** in plain `INSERT … 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.
|
||
|
||
2. **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.log` fails on line 1. `run_replay`
|
||
> (`src/runtime.rs:1630`) feeds each whole raw line straight to
|
||
> `parse_command_with_schema` and only skips blank/`#` lines — it
|
||
> does **not** understand the `<ts>|<status>|<source>` journal
|
||
> format that `history.rs` already writes. So replay only works on
|
||
> hand-written bare-command `.commands` scripts, 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):
|
||
|
||
1. **Writer records every command, tagged `ok` / `err`** (today
|
||
`history.rs` hardcodes `ok`). `err` lines are journalled
|
||
best-effort from the runtime/app error path (a parse failure
|
||
never reaches the worker); `ok` lines stay worker-journalled,
|
||
transactionally coupled to the state change.
|
||
2. **Hydration reads all records** (ok + err) so cross-session
|
||
recall matches the in-session ring (req I2 is marked done but
|
||
only covers `ok` today — err lines are lost across sessions).
|
||
3. **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.
|
||
4. Escape/unescape parity with the existing `history.rs` helpers.
|
||
|
||
**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 `Mode`
|
||
threaded `Action`→worker, for mode-dependent *output*). Needs
|
||
its own ADR (ADR-0033 Amendment 3; `requirements.md` M4). 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.
|
||
- **`blob` value literal** — `src/dsl/value.rs` has 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_*.rs` helper names (`run_sqlinsert` etc.)
|
||
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 `380c423` and 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 `/runda` round 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
|
||
|
||
1. **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`.
|
||
2. **Baseline:**
|
||
```
|
||
cargo test # expect 1645 passing / 0 failing / 0 skipped / 1 ignored
|
||
cargo clippy --all-targets -- -D warnings # clean
|
||
```
|
||
3. **Start ADR-0034** per §4: settle plan-vs-no-plan with the
|
||
user, then a test-first pass beginning with the failing
|
||
`replay history.log` reproduction.
|
||
4. **Escalate** anything not settled in ADR-0034; the user wants
|
||
mismatches surfaced, not silently fixed.
|