v7.0
v7.0 — Sync Correctness, Async & Sleep Sync
Shipped: 2026-06-10 | Phases: 5 (46–50) | Plans: 18 | Requirements: 8/12
What's New
Upload round-trip complete; upload-sync race eliminated; HealthDataStore fully async; morning band sleep sync wired end-to-end.
Upload route pair (Phase 46)
POST /v1/ingest-frames— raw BLE frame ingest with Bearer authGET /v1/export/frames/{device_id}— cursor-paginated export; bidirectional UUID ↔ device_model lookup
device_uuid end-to-end (Phase 47)
- CoreBluetooth UUID captured at BLE connect; stored in
raw_evidence+decoded_framesSQLite columns; propagated to server on every upload
Upload sync race fix (Phase 48)
captureAllPendingRowIDspre-HTTP;markStreamsSyncedonly after2xx— eliminates blind-marking bug where interrupted uploads left rows permanently "synced" without server confirmation
HealthDataStore async migration (Phase 49)
- 60+
bridge.requestcalls converted from synchronous GCD.asynctoasync/await - All GCD dispatch queues removed from HealthDataStore scope; zero blocking calls on
@MainActor
Morning band sleep sync (Phase 50)
gravity_x/y/zextracted from V24History K18/K24 frames at BLE connect (morning, hour ≥ 4)- Cole-Kripke staging →
external_sleep_sessionsimport - Sleep V2 shows "A aguardar sincronização" / "Sincronizado da pulseira" state labels
Algorithm defaults — sleep v1, strain v1, recovery v1, readiness v1 promoted to defaults
Deferred (Phase 51 — hardware gate)
VAL-HRV-01/VAL-SLP-01: physical WHOOP device + ≥5 overnight captures required- K24 gravity offset confirmation (K33–K44 vs actual WHOOP sensor)
MoreDataStoreasync migration (18+ callers) — explicitly scoped out of Phase 49