crossmate

A collaborative crossword app for iOS
Log | Files | Refs | LICENSE

commit bf1b6f354240c7e142a3823b1ceaa0c0c68ab539
parent b34d2e41ba6e9192a8c9d505cc10889fe1a1b47f
Author: Michael Camilleri <[email protected]>
Date:   Wed, 10 Jun 2026 13:07:47 +0900

Fix incorrect comment

Diffstat:
MCrossmate/Sync/RecordApplier.swift | 14++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/Crossmate/Sync/RecordApplier.swift b/Crossmate/Sync/RecordApplier.swift @@ -242,10 +242,16 @@ extension SyncEngine { // fresher local cursor drop the baseline and re-report the same moves as // a duplicate catch-up banner. The etag guard above already rejects // genuinely stale fetches. Adopting the cursor here is *not* monotonic: - // `noteIncomingReadCursor` recomputes the account horizon as the max over - // our devices' Player leases, so a leaving sibling's past horizon cannot - // collapse another sibling's live presence lease, yet a clean close still - // lowers it once no sibling leases above it. + // `noteIncomingReadCursor` adopts the inbound value directly under + // last-writer-wins, so a leaving sibling's past horizon *can* pull the + // account horizon back below another sibling's live presence lease. + // That collapse is bounded and self-healing: the still-present device + // re-asserts its lease as soon as it processes the inbound close + // (AppServices' incoming-cursor drain re-runs `publishReadCursor` + // ahead of the 5-min refresh floor), and a foreground device marks + // inbound peer moves read on arrival regardless. Keeping "A left + // while C is still here" representable without the dip would need + // per-device Player rows, which don't exist (one row per author). let incomingReadAt = RecordSerializer.parsePlayerReadAt(from: record) entity.readAt = incomingReadAt let incomingReadThrough = RecordSerializer.parsePlayerReadThrough(from: record)