What problem does this solve?
Three of the four sleep-score contributors have problems.
Duration scores the wrong quantity. It uses SleepSession.totalMinutes, which SleepSegmentation sets from end − start — time in bed. A night with 8 h in bed and 90 min awake is credited as 8 h of sleep.
Light % is scored against a band calibrated for a no-REM decoder. Ideal 50–60% assumes REM minutes land in the light bucket. On a ring that tags REM separately, the same night reads ~20 points lower and is scored harshly for a split that is correct.
Awake % is scored at 55% of its points when the ring gives no wake signal, which quietly docks every jring night for a sensor it never had.
Proposed solution
Five contributors: duration (30, on total sleep time), deep (25), REM (20), restfulness (15), bedtime consistency (10).
Missing signals should leave the denominator rather than scoring zero — the rule readiness already follows. A jring is then scored out of 80, a first week out of 90, with coverage reported alongside. That's what makes one score comparable across hardware: an ideal night scores the same on both.
Light becomes reported-but-not-scored, since once deep and REM are both scored it is their residual.
Sleep efficiency should be left out deliberately: with totalMinutes being time in bed, efficiency works out to exactly 1 − awake %, so it would restate restfulness while looking like an independent sixth signal.
Bedtime consistency wants the user's own median bedtime over the previous nights, on an axis wrapped around midnight so 23:40 and 00:20 average to midnight rather than noon — and the night being scored must be excluded from its own baseline.
Depends on
REM plumbing (#111) — the REM contributor needs SleepSummary.remMinutes.
Area
Data / decoding / sync
What problem does this solve?
Three of the four sleep-score contributors have problems.
Duration scores the wrong quantity. It uses
SleepSession.totalMinutes, whichSleepSegmentationsets fromend − start— time in bed. A night with 8 h in bed and 90 min awake is credited as 8 h of sleep.Light % is scored against a band calibrated for a no-REM decoder. Ideal 50–60% assumes REM minutes land in the light bucket. On a ring that tags REM separately, the same night reads ~20 points lower and is scored harshly for a split that is correct.
Awake % is scored at 55% of its points when the ring gives no wake signal, which quietly docks every jring night for a sensor it never had.
Proposed solution
Five contributors: duration (30, on total sleep time), deep (25), REM (20), restfulness (15), bedtime consistency (10).
Missing signals should leave the denominator rather than scoring zero — the rule readiness already follows. A jring is then scored out of 80, a first week out of 90, with coverage reported alongside. That's what makes one score comparable across hardware: an ideal night scores the same on both.
Light becomes reported-but-not-scored, since once deep and REM are both scored it is their residual.
Sleep efficiency should be left out deliberately: with
totalMinutesbeing time in bed, efficiency works out to exactly1 − awake %, so it would restate restfulness while looking like an independent sixth signal.Bedtime consistency wants the user's own median bedtime over the previous nights, on an axis wrapped around midnight so 23:40 and 00:20 average to midnight rather than noon — and the night being scored must be excluded from its own baseline.
Depends on
REM plumbing (#111) — the REM contributor needs
SleepSummary.remMinutes.Area
Data / decoding / sync