Conversation
|
Reviewed at b99a5fc. Full 18-check roster green. This is ambitious and mostly very good. The FNV-1a constants are right, the I worked through the heart-rate tail math, since that is where the risk concentrates. Recording Four things:
Minor: the unlock observer is removed after Approving after a rebase. I would rather have (2) and (3) in before merge than after, since both the key name and the fingerprint format are persisted and changing either later means a one-off rewrite for every install. (1) and (4) I am happy to take as follow-ups if you would rather keep this moving. |
…ting unchanged batches
b99a5fc to
da2dcdf
Compare
|
Sequencing decided: #959 goes in first, then this. #959 is the staged HealthKit consent work and it restructures the authorization and type-set region of What that means when you rebase. The conflict will be in One interaction worth checking rather than assuming. After #959, a write path can be a no-op because its stage was never consented to, not because there was nothing to write. Your fingerprint cache records "this batch is written" after a successful save, so the question to satisfy yourself on is whether any path can reach Nothing else changes for this PR. The two things I asked for before merge still stand and are independent of the sequencing: the fingerprint key is not per-strap while the heart-rate cursor three lines above it is documented as per-strap, and the vitals fingerprint rests on I rebased this branch onto current main earlier today, so the parity side is already settled: a plain |
…int per strap; fingerprint vitals by value The rebase onto ryanbr#2294 dropped the closing brace of nightIsStillOpen and of its test, so StrandImport and both app builds failed. The written-batch key now carries the strap id like hrWriteCursorKey, and the vitals fingerprint uses the value each sample was built from (bit pattern, fixed unit per metric) instead of HKQuantity's description. The unlock observer is removed in deinit.
|
Pushed The two items you wanted before merge:
Minor: the unlock observer is now removed in I'll do (4), moving the tail-window selection into |
… unchanged batches (ryanbr#2298)
Adapt the lock-deferral portion of ryanbr/noop PR ryanbr#2298 by @Iskrata (0fbebd0). Test coalescing, relock, foreground consumption, and teardown using an injectable notification center. Preserve existing HR reconciliation; omit the broader fingerprint and tail-caching changes.
What this PR does
Apple Health write-back runs after every completed offload, about every 10 minutes while a strap is connected. It rewrote a lot that had not changed, and while the phone was locked it could only fail. This PR:
Protected health data is inaccessible), but each locked run still read fourteen days from the store before failing. The run is now owed, and it happens once onprotectedDataDidBecomeAvailableNotification.HealthWriteback.batchFingerprint: FNV-1a over sorted per-sample descriptors, stable across launches). An identical batch skips the delete and the save. Any batch older thanunchangedRewriteIntervalSeconds(24 h) is rewritten regardless, so anything removed in the Health app comes back within a day. A workout read that failed or hit its cap never counts as unchanged, so the iOS: workouts NOOP stops tracking are never deleted from Apple Health, so they linger as duplicates #2210 orphan pass still gets its complete window.Why
On one install the strap log showed
health: write-back step failed — Protected health data is inaccessibleon every overnight offload. On unlocked runs, the same fourteen days of sleep and vitals were deleted and re-added every ten minutes with no change in the store.Type of change
How it was tested
HealthWritebackTests: the fingerprint ignores order but sees every changed value, dropped sample and descriptor boundary; the skip holds only for an identical batch written within the interval.NOOPiOSbuilds.doc_comment_lint.pyis clean;parity_ratchet.py --base upstream/main --offlinereports 0 errors.Android: Health Connect has no locked-device restriction like this, so the first change is iOS-only. Whether the Android exporter has the same unchanged-batch and 48 h HR rewrite cost is something I'll check and follow up on with its own tests.
Checklist
docs/CONTRIBUTING.mdStrand.xcodeproj/) or any secrets/keystores