Files
rdbms-playground/docs/handoff/20260524-handoff-35.md
T
claude@clouddev1 2e3131669a docs: session handoff 35 — ADR-0034 shipped; ADR-0006 (undo/snapshot) is next
Records this session's close-out: ADR-0033 Phase 3 marked Accepted; ADR-0034 (history journal + replay filter, incl. Amendment 1 replay app-command skip) implemented and verified. Tees up ADR-0006's undo/snapshot half (U1/U2) as the next job with scope considerations and open design calls.
2026-05-24 19:05:38 +00:00

8.8 KiB

Session handoff — 2026-05-24 (35)

Thirty-fifth handover. This session closed ADR-0033 Phase 3 (marked Accepted) and implemented ADR-0034 (history journal + replay filter) end-to-end, including a safety fix surfaced by a /runda round. The next session starts ADR-0006 — the undo / snapshot feature (U-series). See §4.

§1. State at handoff

Branch: main. Tests: 1659 passing, 0 failing, 0 skipped, 1 ignored (the unchanged friendly/mod.rs doctest). Clippy: clean (cargo clippy --all-targets -- -D warnings).

Latest commit (local-only):

e4f2f5f feat: ADR-0034 — history journal records err + replay parses/filters the journal

origin/main is at 6b8888f (3h); 13 commits are local-only. Unpushed commits are a normal working state; pushing is the user's step — do not prompt about it.

§2. What shipped this session

  • ADR-0033 → Accepted. Phase 3 (advanced-mode SQL DML) was verified through sub-phase 3k and marked Accepted (commit 55b7845); see docs/handoff/20260523-phase-3-verification.md.
  • ADR-0034 implemented (commits 504c24c plan, e4f2f5f code). history.log is now a complete journal and replay understands it:
    • Replay parses the journal format (§3): replay history.log works (it died on line 1 before); ok records run, non-ok skip; bare .commands scripts still work.
    • Journal records failures (§1/§2): failed commands are recorded err via a new Action::JournalFailure (emitted by the pure-sync App for parse failures and worker-execution failures; runtime appends best-effort, never fatal). Hydration reads all records → typos recallable across sessions.
    • Amendment 1 — replay filters app-lifecycle commands (found via /runda; see §3).

§3. Decisions settled this session (do not re-litigate)

All user-confirmed.

  1. Replay skips app-lifecycle commands (ADR-0034 Amendment 1). A working replay history.log exposed that the journal also records save as/load/new/export/import/rebuild/mode — which would panic the worker dispatch (unreachable! on Command::App) or abort replay (the modal forms don't parse). Replay now re-applies only schema/data write commands and skips every app-lifecycle command + nested replay, classified by entry word (so modal/incomplete forms and quit skip uniformly). All skips continue — never abort; this reversed the prior nested-replay refusal (a journal containing a once-run replay must not force hand-editing, and skipping closes the infinite-loop footgun). import and nested replay emit a [skip] warning (skipping them can leave replayed state incomplete); the rest skip silently.
  2. err journalling scope. Covers parse failures of any submitted line + DSL/SQL worker execution failures (via DslFailed, which gained a source field). Deferred follow-up (A, user-confirmed): an app-lifecycle command that parses then fails at the runtime stage (e.g. save as / import failing on I/O) is not yet journalled err — those surface as their own runtime events, not DslFailed. Recorded in ADR-0034's Implementation note.
  3. Runtime event-loop glue is unit-tested, not loop-tested (user-accepted). The App emit + append_history_failure + hydration + run_replay + warnings-render are each tested; the project has no full interactive-loop harness, so the one-line runtime glue isn't end-to-end tested.

/runda also fixed: a mode(bare)/q abort bug (→ entry-word classification over the complete app set), and doc drift in requirements.md U3/U4 (U4 had said "nested replay refused").

§4. ADR-0006 (undo / snapshot, U-series) — the NEXT job

Implement ADR-0006's undo/snapshot half (docs/adr/0006-…, Accepted). The replay/journal half (U3/U4) is now done; the undo/snapshot half (U1/U2) is the last unimplemented part:

  • U1auto-snapshot before every destructive operation into a ring buffer (initial size N=10, tunable), via the engine's online backup API.
  • U2undo / redo app-level commands (both modes), each prompting for confirmation with the snapshot timestamp + a summary of the changes that will be discarded.

Why this is next (verified): it's the only Accepted, unplanned, unimplemented ADR — M4 and Phase-4/DDL both need their own ADR first (latest ADR is 0034). It also closes the Phase-3 N/A matrix row ("auto-snapshot fires for SQL DML the same as DSL" — currently vacuous because neither path snapshots).

Scope considerations for the implementer:

  • Destructive ops now span DSL and SQLdelete/drop/… and SqlDelete/SqlInsert/SqlUpdate + DDL. The snapshot trigger lives in the worker handlers (src/db.rs) and must cover both paths (this is exactly the Phase-3 parity the N/A row flagged). Mind the timing vs the existing finalize_persistencetx.commit() ordering (ADR-0015, commit-db-last / crash-recoverable state).
  • Ring-buffer storage needs a design call — where snapshots live (playground.db is a derived artifact per ADR-0015, so not there; temp dir? a snapshots subdir? memory?). ADR-0006 says "ring buffer of recent snapshots" but not where.
  • Two new app commands + confirmation modalsundo/redo join the AppCommand set; the modal flow mirrors the existing rebuild/load-picker modals. (Note: adding AppCommand variants means updating runtime::is_app_lifecycle_entry_word so replay skips them — see ADR-0034 Amendment 1.)
  • Engine-neutral user-facing strings (ADR-0002 posture): no "SQLite"/"backup API"/"PRAGMA" in notes or modal text.
  • ADR-0006 is an early design ADR. Like ADR-0033/0034, implementation will likely surface details warranting a plan doc first (recommended) and possibly an amendment. Escalate design calls (ring-buffer location, snapshot granularity, redo-after-new-work semantics) rather than guessing.

Recommended first action: read ADR-0006 in full, then produce a short plan doc (docs/plans/<date>-adr-0006-undo-snapshots.md) and confirm the open design calls with the user before coding — test-first throughout.

§5. Other tracked deferred items (nothing lost)

  • (A) App-command runtime-failure journalling (§3.2) — small ADR-0034 follow-up; recorded in ADR-0034's Implementation note.
  • 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).
  • Phase 4 — DDL as SQL (CREATE/DROP/ALTER TABLE, CREATE/DROP INDEX). Next ADR-0030 roadmap phase; no ADR exists yet — needs one before implementation.
  • blob value literal (src/dsl/value.rs) — pre-existing gap; the Phase-3 all-types test inserts NULL for blob.
  • Q1 / Q2 — SQL subset completeness; polished out-of-subset rejection message naming the construct (multi-phase, still [ ]).

§6. Process pins (unchanged, still binding)

  • Confirm every commit. Propose the message; wait for the go-ahead. (Each commit this session was 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. Both /runda rounds this session found real issues by running throwaway probes (the mode/q abort bug; the replay-app-command panic). Reproduce/print before concluding; delete probes before committing.
  • Escalate ADR-vs-implementation mismatches and scope calls. The replay app-command filter, the err-journalling mechanism (Option A), and the deferred (A) boundary were all escalated and user-confirmed, then recorded as ADR-0034 Amendment 1 / notes.
  • Keep docs in lockstep. ADR status flips update docs/adr/README.md in the same edit; behaviour changes update requirements.md (this session corrected U3/U4).

§7. How to take over

  1. Read, in order: this file → docs/adr/0006-undo-snapshots-and-replay-log.md (the next job) → docs/handoff/20260523-phase-3-verification.md (Phase-3 close) + docs/adr/0034-history-journal-and-replay-filter.md (just shipped) → CLAUDE.mddocs/requirements.md (U1/U2 are the targets).
  2. Baseline:
    cargo test    # expect 1659 passing / 0 failing / 0 skipped / 1 ignored
    cargo clippy --all-targets -- -D warnings   # clean
    
  3. Start ADR-0006 per §4: read the ADR, draft a short plan, confirm the open design calls (ring-buffer location, snapshot timing, redo semantics) with the user, then implement test-first.
  4. Escalate anything not settled in ADR-0006; the user wants mismatches and scope calls surfaced, not silently decided.