[claude] Sync: duplicated ClientId causes silent, permanent divergence — add detection and reconciliation
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 14
- Forks
- 4
- Avg merge
- 3d 21h
- Merged PRs (30d)
- 3
Description
[Claude-drafted]
Sync exchanges commits purely on (ClientId → latest commit timestamp) (SyncState, QueryHelpers.GetMissingCommits). This assumes each ClientId is a single writer with append-only history. If two replicas ever write under the same ClientId (copied SQLite file, restored device backup), their histories fork and commits are permanently stranded in both directions — each side believes the other already has everything below its head. Nothing detects this: commit hashes never cross the wire ([JsonIgnore]), hash only id + parentHash, and are rewritten locally.
Repro: copy a project DB to a second client, edit + sync on both. The project eventually becomes unsyncable: an edit arrives for an entity whose creating commit is stranded, and SnapshotWorker throws on every subsequent sync.
Proposal (layered):
- Tripwire: in
AddRangeFromSync, receiving a commit authored by the local ClientId that isn't already in the local DB proves the ID is duplicated → surface loudly; the app should switch to a fresh ClientId so the fork stops growing. - Detect: extend
SyncStateentries with a commit count + order-independent digest of that client's commit IDs, compared over the shared range (≤ the lower head). Mismatch ⇒ divergence, even when heads differ. Must stay compatible with timestamp-only clients. - Repair: on divergence for a ClientId, exchange that client's full commit-ID list, diff, send missing commits both ways.
AddRangeFromSyncalready handles past-insertion (dedup, hash rewrite, snapshot replay), so the merge converges. Open question: auto-repair with loud logging vs. requiring user attention.
Prevention (keeping writer identity out of the copyable DB) is the app's job: sillsdev/languageforge-lexbox#2431.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading SyncState and QueryHelpers.GetMissingCommits to understand timestamp-based exchange, then trace AddRangeFromSync and SnapshotWorker through the reported failure. The issue proposes detection and reconciliation for duplicated ClientIds, but leaves the repair policy open; done requires an agreed behavior that detects divergence and prevents the stranded-commit failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, sqlite
- Domain
- databases, distributed-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100