max / goingson
| 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 | sync_changelog ADD COLUMN hlc_wall INTEGER; |
| 15 | sync_changelog ADD COLUMN hlc_counter INTEGER; |
| 16 | |
| 17 | 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 |