Skip to content

Cross-device concurrent resume: two writers mint the same session pages and clobber each other's cloud copy #113

Description

@zo-sol

Measured on-device (2026-07-11, Seeker + desktop)

While verifying #107, the phone cross-device-resumed a session the desktop was STILL actively writing (d02a0fb7…). Both devices then appended independently:

  • Phone local tier: pages p25-p29 written 07:12-07:32Z (decrypted: the phone-side conversation, Seeker device stamp)
  • Desktop: kept appending its own p25-p29+ for the same session through the afternoon
  • Cloud now holds the desktop's content for those page keys (last flush wins); the phone's branch survives only in the phone's local tier

Why it happens

SessionStore.lastPageIndex() picks the next page from what the opener can SEE at resume time; two live writers each think they own page N. Page keys are {sessionId}__p{N} with no writer fencing, so cloud uploads for the same key race and the loser's branch silently disappears from the cloud (still present in that device's local tier — nothing is unrecoverable today, but the cloud copy is a coin flip per page).

Impact

Direction options (not decided)

  1. Single-writer lease: a tiny {sessionId}__writer blob (device id + heartbeat ts); a second opener gets read-only or forks
  2. Fork-on-conflict: second concurrent writer mints a new sessionId branching at the resume point (cheap, no coordination, matches the local-first model)
  3. Per-device page namespaces + merge-on-read (heavier, but no data ever lost)

Related: #107 (how it was found), #100 (cross-surface QA).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions