sillsdev / sillsdev/languageforge-lexbox

[claude] FW Lite: don't store the ClientId in the project database

Open
#2,431 0 comments 0 reactions 0 assignees View on GitHub

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 dbInstanceId in ProjectData, 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.