Skip to main content

max / goingson

1.1 KB · 24 lines History Blame Raw
1 -- Hybrid logical clock for cross-device sync conflict resolution (ultra-fuzz Run #28).
2 --
3 -- Conflict resolution previously ordered by wall-clock `client_timestamp`, which let a
4 -- device with a skewed-fast clock win every conflict and made DELETE unconditionally
5 -- beat a strictly-newer edit (permanent data loss). SyncKit now orders by an HLC that
6 -- travels inside the E2E-encrypted payload. This migration adds the local clock state
7 -- and per-changelog-row HLC stamps.
8 --
9 -- The HLC's node component is always this device's id, so only (wall_ms, counter) are
10 -- persisted here. Rows are stamped lazily when first read for push or conflict
11 -- detection (see src-tauri/src/sync_service/hlc.rs), so the changelog triggers stay
12 -- unchanged.
13
14 ALTER TABLE sync_changelog ADD COLUMN hlc_wall INTEGER;
15 ALTER TABLE sync_changelog ADD COLUMN hlc_counter INTEGER;
16
17 CREATE TABLE IF NOT EXISTS hlc_state (
18 id INTEGER PRIMARY KEY CHECK (id = 1),
19 wall_ms INTEGER NOT NULL DEFAULT 0,
20 counter INTEGER NOT NULL DEFAULT 0
21 );
22
23 INSERT OR IGNORE INTO hlc_state (id, wall_ms, counter) VALUES (1, 0, 0);
24