sillsdev / sillsdev/languageforge-lexbox
[claude] FW Lite: don't store the ClientId in the project database
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 9
- Forks
- 8
- Avg merge
- 2d 13h
- Merged PRs (30d)
- 49
Description
[Claude-drafted]
ProjectData.ClientId — the identity FW Lite uses to author new Harmony commits — lives inside the project's SQLite file. Copying the DB (second machine, restored backup, duplicated folder) therefore copies the authority to write as that client, which violates Harmony's single-writer-per-ClientId invariant and permanently forks sync (see sillsdev/harmony#79).
The goal is to move ClientId authority out of the copyable DB so that a copied/restored DB naturally gets a fresh identity. Minting extra ClientIds is cheap (one SyncState entry — same cost as a re-download today), so designs should fail toward new IDs, never toward reusing one.
One possible shape (illustrative, not a settled design):
- A random
dbInstanceIdinProjectData, written once at create/download. - An app-local record
{dbInstanceId → clientId, lastOwnWriteWatermark}outside the project folder. - On open: no record for this
dbInstanceId→ this install never wrote this DB → fresh ClientId. Record exists but the DB's newest own commit is older than the watermark → DB was rolled back/replaced → fresh ClientId.
Whatever the mechanism, it needs careful per-platform thought: "app-local storage" and backup/restore semantics differ across Windows, Android, iOS, and web (e.g. Android auto-backup and iCloud restores may clone the app-local record along with the DB), which changes what each platform's variant actually protects against. Cases no local scheme can catch (full-device restore) fall back to the harmony-side tripwire.
fw-headless and seeded downloads: fw-headless maintains its own CRDT DB per project and must follow the same rule — its ClientId can't live in that DB either. Beyond correctness, that unlocks a fast path for initial project downloads: instead of pulling the full commit history and replaying it from scratch (today's GetChanges from an empty SyncState), the server could stream a ready-made DB (snapshots and projected tables included) and the client would then do a normal sync, playing back only the commits newer than the seed — almost always FAR fewer. Streaming a DB is only safe once the DB carries no writer identity.
Related hygiene, optional: LocalResource paths and ProjectData.Role/LastUserName/LastUserId are also install/user-local state living in the copyable DB; they could move to the same app-local record if ProjectData is being touched anyway.
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 tracing ProjectData.ClientId, SyncState, fw-headless's CRDT database, and the GetChanges path; read the Harmony single-writer constraint in sillsdev/harmony#79. Compare copy, restore, and seeded-download behavior across the listed platforms. Done means writer identity is outside the copyable database, copied or rolled-back databases get fresh ClientIds, and fw-headless follows the same rule.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, sqlite
- Domain
- backend, databases, distributed-systems
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100