Repository navigation
Analytics (W3): leave low-quality SpO₂ candidate readings out of the night, one read for every surface - #40
Merged
Merged
Conversation
…night (W03-007) A byte-82 reading counts only when at least two thirds of its measured seconds carry an in-band value and at least three fifths of those sit within 2 points of its median. Loose-strap readings, mixed with the strap's own codes, no longer become the night's low or its dips. A night whose readings all fail is a night with no reliable reading, not nil. The stored series gain spo2_candidate_windows_low_quality, the marker of a gated night; latest() shows such a night instead of skipping to an older one. Oracle re-captured (28 cases) and matched by an independent Python twin; 108 real sessions across 15 backups agree between the two.
…-007 V2) Spo2CandidateSeries.Night.readingsNote keeps a reading left out as low quality apart from a reading of codes only, so a codes-only night no longer reads "passed the quality check" beside "none passed". Adds boundary tests at the 30-second shape and narrows the trace helper's claim to identical inputs.
The series writer stores the low-quality count and deletes a gated night's stale mean and minimum only after a persist that landed. The strap-estimate card says "no reliable reading" when every reading failed, names readings left out, calls them "Low readings" and plots only reliable readings. The Today Blood Oxygen tile resolves its night through the same funnel instead of the sparkline's last value. The strap-log line names what it left out. Translations for all nine locales.
…eads Messungen The shared "Readings" label read "Lesungen" (readings of a text) beside "Messungen" in the captions under it.
…ds (W03-013) Both quality gates are ratios, and one in-band second of one measured passes both, so a reading a session edge cuts to a fragment could still become the night's low. A reading now needs ten in-band seconds (a third of the strap's reading) before the ratios judge it. No real reading moves: on 15 backups every reliable reading has twenty or more.
…009, W03-011, W03-012, W03-015 … W03-018) Spo2CandidateSeries.Read holds every candidate series and answers the newest night, a given day's night and the nightly means, leaving out a mean left on a night with no reliable reading. Repository loads it once; the Health card and tile, classic and Liquid Today and the Metric Explorer resolve through it. The Health tile stops carrying an older mean past a newest night with no reliable reading; Today and Liquid round with meanRounded; Liquid names a night with no reliable reading; Today drops its second mean read and a misplaced doc block.
… readings (W03-010) A night with no reliable reading now carries why: readings that had values and failed the quality check, or readings that were codes only. Only the first keeps the loose-strap note; the second says that none of the night's readings produced a value.
…tor (W03-014) The chart's merge gave each second to the first strap id with any row there, so a row without a byte-82 value could hide another strap's reading, and it ran on the main actor. A second now goes to the first id that reported a nonzero byte, and the merge and resolve run in a detached task.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Out-of-phase W3 fix of the whole-project review, from the owner's 2026-09-30 strap export: two nights of low SpO₂ candidate readings that turned out to be a strap-fit problem, not desaturation. W03-007 adds a reading-quality gate to the byte-82 candidate. It is followed by the fixes from its independent V2 review and from a
/code-review xhighpass (W03-009 … W03-022). One commit per fix; the tracker rows are indocs/review/workstreams/W03-analytics.md.What the data showed
The strap measures byte 82 in 30-second readings about every 20 minutes of band SLEEP. Across 192 in-session readings of one MG:
docs/PROTOCOL_SENSORS.md§Byte 82 measurement windows records this as observation, not meaning.What the literature says (research summary, cited as found)
Fixes
W03-007 (S3): a reading counts only when the strap reported it well
A reading counts when all three hold:
The gate judges how the reading was reported, never whether it is low: a steady, well-covered low reading stays a low reading. On the good-fit nights 80–100 % of readings pass, and the night's figures barely move anywhere between one half and four fifths coverage.
spo2_candidate_windows_low_quality, which also marks a gated night. A gated night's stale mean and minimum are deleted after a persist that landed.W03-013 (S3): a floor of 10 in-band seconds
Both gates are ratios, so a reading cut to one second by a session edge passed both. No real reading moves: on 15 backups every reliable reading has 20 or more in-band seconds.
W03-009, W03-011, W03-012, W03-015 … W03-018: one read for every surface
The Health tile, classic and Liquid Today, and the Metric Explorer each resolved the candidate night on their own. The Health tile carried an older night's mean past a newest night with no reliable reading. Today rounded half-to-even (
%.0f) where the card rounds half away from zero.Spo2CandidateSeries.Read(package, tested) now holds every candidate series and answers:Repository.spo2CandidateSeriesloads it once, concurrently, and every surface resolves through it. Leftover means are therefore handled on the read side, rather than by widening a delete across computed ids (W02-005 showed how a delete over the shared canonical id loses data).Smaller fixes
Recorded, not fixed
Validation
%.0fprints 96 for 96.5, where the card shows 97./code-review xhigh(14 findings, each re-verified before its fix).StrandTests2,128, 0 failures.Strandbuilds, andNOOPiOSbuilds (without the watch app; no watchOS runtime on this Mac).doc_comment_lint, the protocol source-reference check and the diff-scoped i18n gate pass.