Make mobile Recent Work sync generation-safe and self-healing #1485

Closed
opened 2026-08-27 21:33:05 +00:00 by timmy · 0 comments
Owner

Problem

Mobile Recent/Pinned Work can discard a newer same-route update when an older request finishes: the sync drain acknowledges queued work by route rather than by the exact generation it sent. A transient delivery failure also remains pending until another lifecycle event, despite the app staying online.

Evidence on current main:

  • frontend/mobile-recent-work.js:145-157 replaces pending metadata by route.
  • frontend/mobile-recent-work.js:223-255 removes the route after an in-flight response, including a newer replacement.
  • frontend/mobile-recent-work.js:256-259 returns after failure without a bounded retry.
  • Existing tests/test_mobile_recent_work.py has no in-flight replacement or transient recovery case.

User impact

A mobile operator can see a newer title/pin optimistically, then silently lose it when an older response settles. A temporary network error can leave “Sync pending” indefinitely until connectivity or visibility changes.

Acceptance criteria

  • A response acknowledges only the exact queued generation it sent; newer same-route record and pin operations stay visible and drain next.
  • One bounded account-scoped retry is scheduled after transient failure and reset after success.
  • Online/foreground reconciliation cancels stale backoff and runs immediately without overlapping flights.
  • Switching accounts prevents old retries/responses from mutating the new account.
  • Behavioral tests cover in-flight same-route replacement and automatic retry.
## Problem Mobile Recent/Pinned Work can discard a newer same-route update when an older request finishes: the sync drain acknowledges queued work by route rather than by the exact generation it sent. A transient delivery failure also remains pending until another lifecycle event, despite the app staying online. Evidence on current main: - `frontend/mobile-recent-work.js:145-157` replaces pending metadata by route. - `frontend/mobile-recent-work.js:223-255` removes the route after an in-flight response, including a newer replacement. - `frontend/mobile-recent-work.js:256-259` returns after failure without a bounded retry. - Existing `tests/test_mobile_recent_work.py` has no in-flight replacement or transient recovery case. ## User impact A mobile operator can see a newer title/pin optimistically, then silently lose it when an older response settles. A temporary network error can leave “Sync pending” indefinitely until connectivity or visibility changes. ## Acceptance criteria - A response acknowledges only the exact queued generation it sent; newer same-route record and pin operations stay visible and drain next. - One bounded account-scoped retry is scheduled after transient failure and reset after success. - Online/foreground reconciliation cancels stale backoff and runs immediately without overlapping flights. - Switching accounts prevents old retries/responses from mutating the new account. - Behavioral tests cover in-flight same-route replacement and automatic retry.
timmy self-assigned this 2026-08-27 21:33:05 +00:00
timmy closed this issue 2026-08-27 21:55:40 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stackchain/stackchain-dashboard#1485
No description provided.