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.
This commit is contained in:
@@ -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/<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.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.
|
||||
Reference in New Issue
Block a user