Repository navigation
Description
Problem
AutoSaveManager (pkgs/id/web/src/auto-save.ts, added by PR #1545 for #1440) coalesces a save requested while one is in flight into exactly one follow-up — but only two of its three result paths honour that follow-up:
- ok (
onSaveResult, auto-save.ts:161-169): runs the follow-up viatriggerSave(). - rate-limited (auto-save.ts:180-191): schedules a retry that "also serves as the follow-up for any edits that arrived during the failed save".
- generic error (auto-save.ts:192-206): sets state
error, reverts tounsavedafter 2s — and never acts onfollowUpRequested, and never clears it. No debounce, retry, or follow-up is pending at that point (the during-flight edit's debounce already fired and was consumed by the in-flighttriggerSaveat auto-save.ts:124-128), so autosave silently stops for that edit: the document sits atsave •until the user happens to edit again or saves manually.
Evidence (verified this run)
Probe driving the real auto-save.ts on the laptop (~/git/fleet/probe-2026-10-28-laneB-autosave there; file sha256 ba898143929b3192ebc4f4b236a5c8d6fe09569aee83df715fc9e6fa6fab01a9, byte-identical to main b2adaf4; probe + log in the goal's hidden_files/probe-2026-10-28-laneB-autosave/), run twice with identical results. Per case: edit → debounce fires → save #1 in flight; second edit during the flight; its debounce also fires during the flight (follow-up coalesced); then save #1 settles:
CTRL-OK: calls after settle = 2 (follow-up ran), state saved/idleCTRL-429(retryAfterMs: 100): calls after settle = 2 (retry ran), state saved/idleBUG-ERROR({ok: false}): calls after settle = 1, and still 1 after a further 3s wait; state =unsaved— the during-flight edit is stranded, no save is scheduled
Relevant code: coalescing at auto-save.ts:124-135 (followUpRequested = true; return), ok-branch follow-up at :162-168, retry-branch follow-up at :180-191, error branch at :192-206 (no follow-up, flag left set). A throwing saveFn lands in the same branch (auto-save.ts:151-155).
Note the stranded case is specifically when the follow-up was already consumed before the failure: an edit whose debounce is still pending when the error lands does get saved when that debounce fires. The test suite from #1440 (auto-save.test.ts) covers the ok and 429 follow-up shapes but has no generic-error case.
Why it matters
Autosave's contract after #1440 is "a save completion only marks the document saved when it covers the latest edit, and requested saves are never lost". The generic-error path breaks the second half silently: a transient failure (network blip, 500) during a save eats the next edit's autosave, and the only signal is the button reverting to save • — indistinguishable from "waiting for the debounce". The user can close the tab believing the 2s autosave had long since fired.
Acceptance criteria
- Pin the generic-error follow-up semantics in a test first: an edit that arrives during a save whose debounce fires before that save fails generically must not be stranded — it gets exactly one subsequent save attempt (a follow-up, or a re-armed debounce), OR the manager documents and tests a deliberate no-auto-retry pin in which the follow-up request is visibly dropped (flag cleared, state/behaviour intentional).
- If a follow-up is implemented: it is bounded (one attempt; a second generic failure stops again — no retry loop on a persistent outage), and
followUpRequestedis cleared on everyonSaveResultpath. - New test in auto-save.test.ts mirroring the existing ok/429 serialization tests for the generic-error shape (deferred saveFn, edit + debounce during flight, resolve
{ok: false}, assert the follow-up/strand behaviour pinned above). - Existing auto-save tests (serialization, stale-completion, 429 coalescing, saveNow) still pass.
Related: #1440 (closed by PR #1545 — this is the one result path its serialization work did not cover). Not a duplicate of #1368 (collab reconnect cap — different module/mechanism).
Activity
developing-today commentedon Oct 28, 2026
CODE-640
dezren39 commentedon Oct 28, 2026
🤖 Agent note · state: filed
47 remaining items
dezren39 commentedon Oct 28, 2026
🤖 Agent note · parked
id(web): run one bounded follow-up for edits coalesced during a gener…
dezren39 commentedon Oct 28, 2026
🤖 Agent note · done — PR merged