From 2e3131669adf1b96016fc53adf33cc69c85c1713 Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Sun, 24 May 2026 19:05:38 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20session=20handoff=2035=20=E2=80=94=20AD?= =?UTF-8?q?R-0034=20shipped;=20ADR-0006=20(undo/snapshot)=20is=20next?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- docs/handoff/20260524-handoff-35.md | 179 ++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 docs/handoff/20260524-handoff-35.md diff --git a/docs/handoff/20260524-handoff-35.md b/docs/handoff/20260524-handoff-35.md new file mode 100644 index 0000000..352f66e --- /dev/null +++ b/docs/handoff/20260524-handoff-35.md @@ -0,0 +1,179 @@ +# 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: + +- **U1** — **auto-snapshot before every destructive operation** + into a ring buffer (initial size N=10, tunable), via the engine's + online backup API. +- **U2** — **`undo` / `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* SQL** — `delete`/`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_persistence` → `tx.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 modals** — `undo`/`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/-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.md` → `docs/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.