fix(health): hold a still-open night out of Apple Health until it closes - #2294
Conversation
|
Reviewed at dcab53c. Full 18-check roster green,
The tests are boundary-exact on both sides of both thresholds ( Four things, none of them blocking:
Approving. If you want to take (1) in this PR I would happily wait for it, otherwise it is a good follow-up. One scheduling note: this and #2298 both create the |
…ut of Apple Health until it closes
dcab53c to
e7d69cb
Compare
…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.
What this PR does
Stops Apple Health write-back from exporting a night that the strap may still be recording.
A night is detected from whatever has synced so far, so a pass during the night ends it at the newest sample. That truncated night was then written to Apple Health as if it were finished. A reader took its end as the wake, and its day's vitals had been scored from part of the night. On one install, a night slept to 09:36 was in Health as ending at 06:53 until a later write-back replaced it. Replaying the stager over the same data confirms the detector itself is right: with data to 06:54 it ends the night at 06:54, and with the full data at 09:36.
HealthWriteback.nightIsStillOpen(endTs:newestHeartRateTs:now:)treats a computed night as open when it ends withinopenNightMarginSeconds(20 min) of the strap's newest heart rate. AfteropenNightMaxHoldSeconds(2 h) it counts as closed anyway, so a strap taken off at wake does not hold the night back indefinitely.HealthKitBridge.writeBackleaves open nights out of the sleep, heartbeat and vitals writes and skips their day's vitals rows. The next write-back after the night closes writes them normally.hrFingerprint(deviceId: noopDeviceId, …)). An Apple Watch still recording therefore cannot make a strap night that stopped at its sync frontier look finished.Type of change
How it was tested
HealthWritebackTests: a night ending at the newest heart rate is open, a night with heart rate 20 min past its end is closed, and the 2 h hold limit.doc_comment_lint.pyis clean.parity_ratchet.py --base upstream/main --offlinereports 0 errors after recording the new Swift-only helper inparity_dispositions.json.Swift-only. The Android Health Connect exporter does not hold an open night.
Checklist
docs/CONTRIBUTING.mdStrand.xcodeproj/) or any secrets/keystores