Skip to content

fix(ui): silent save-loss — snapshot cursor advanced before persist resolved (CWD-9) - #320

Merged
eliotlim merged 2 commits into
mainfrom
fix/cwd9-snapshot-save-loss
Aug 14, 2026
Merged

fix(ui): silent save-loss — snapshot cursor advanced before persist resolved (CWD-9)#320
eliotlim merged 2 commits into
mainfrom
fix/cwd9-snapshot-save-loss

Conversation

@eliotlim

Copy link
Copy Markdown
Collaborator

Problem

Any transient page-save failure was reported as "Saved" while silently dropping the edit: the save path advanced its snapshot cursor before awaiting persistence, so the post-failure retry recomputed an identical snapshot, hit the no-op skip, and resolved as success. Board: CWD-9 (first ship of the Concurrency & Write Durability epic OB-76).

Solution

Advance lastSnapshot.current only after onSave resolves, with a monotonic sequence guard so out-of-order resolves of overlapping saves can't regress the cursor (worst case is one redundant re-send, never loss). Deliberately minimal: no saver redesign — backoff/queueing is CWD-6/7. Two invariant comments document the unbounded-retry contract and the pageId-remount assumption.
Key file: packages/ui/src/screens/BlockPageDocument.tsx (+ new test file). New deps: none.

Before / After

No visual change — existing save-pill states only; what changed is when they're truthful.

Behavior Before After
Save fails once (transient network error) Retry no-op-skips, pill shows Saved, edit lost on reload Retry re-sends the same payload; Saved appears only after a 2xx (tested: BlockPageDocument.test.tsx "re-sends a rejected snapshot")
Save failing repeatedly Pill lies Saved after first retry Pill alternates saving/save-failed and keeps retrying (documented as unbounded until CWD-6/7)
Genuine no-change save No-op skip, no request Unchanged — regression-tested
Two saves resolve out of order n/a (cursor already advanced) Seq guard ignores the stale resolve; next save re-sends newest content

Test procedure

pnpm install && pnpm --filter @book.dev/ui test -- src/screens/__tests__/BlockPageDocument.test.tsx
pnpm verify

Review verification (Quinn): mutation test — reverting the one-line fix makes the new test fail on exactly the silent-loss assertion; interleaving probes confirmed no lost update with a mid-flight second edit.

Operational notes

None — no API/schema/config change, no deployment ordering. Deliberate deferral: retry backoff + durable queue land in CWD-6/7; conflict UX in CWD-10.


Verify: green (full pnpm verify + full pre-push suite run). Reviews cleared: code (Quinn — APPROVE; concurrency verdict CORRECT; 3 pre-endorsed findings applied in 83125ac).

🤖 Generated with Claude Code

https://claude.ai/code/session_018RUicirLRuuZvjJN13N6yN

@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
app.book.pub Ready Ready Preview Aug 14, 2026 12:56pm

Request Review

@eliotlim
eliotlim merged commit f425f24 into main Aug 14, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant