OS Health
Five sub-scores, an unweighted mean, and the rule that makes it honest: absent is not zero.
lib/services/score_engine.dartsrc/engines/score-engine.tsOS Health is one number between 0 and 100, and the interesting part is how often it refuses to be a number at all.
It is the unweighted mean of five sub-scores. Not a weighted one — nobody has ever justified the weights on a score like this, and picking some is a way of encoding an opinion while looking like arithmetic.
The five sub-scores
| Sub-score | What it reads | Building when |
|---|---|---|
| Focus | Deep minutes against your own adaptive goal, plus completion rate | Fewer than 3 sessions |
| Consistency | The mean consistency of your qualifying habits | No habit scheduled 7+ times |
| Energy | Your own debriefs after blocks | Too few debriefs |
| Goal alignment | Sessions actually linked to a goal | Nothing linked |
| Life balance | How evenly effort spread across your life areas | Fewer than 2 active areas |
Each one is either a real 0–100 value or Building — a stated absence, rendered as an em dash, with the next action named beside it. Not "insufficient data": "log a few sessions", "add a habit", "link a session to a goal".
Focus, specifically
60% × volume + 40% × completion.
Volume is your deep minutes over the window divided by your own adaptive goal, clamped to 1 — so exceeding your goal does not inflate the score, it just stops helping.
Completion is per-session equal weight. A finished 25-minute sprint counts exactly as much as a finished 90-minute block. It is a ratio of counts, not of minutes, which is deliberate: minute-weighting it would quietly punish anyone who chooses shorter blocks.
Life balance
The number is a normalised spread: mean absolute deviation from an even split,
divided by its theoretical maximum, so it lands in 0–1 whatever the number of
areas. 0 is perfectly even; 1 is everything in one bucket. The score is
100 × (1 − spread).
The number is allowed to be blunt. The sentence next to it is not. It reads "One area held most of your effort this week" — never "unbalanced", and never "you neglected X". The distinction between an observation and a verdict is the whole product.
The composite
const available = subScores.filter((s) => !s.building);
if (available.length < 2) return null;
return round(sum(available) / available.length);
Below two available sub-scores, OS Health is null — not a low number, not a
zero, and not a placeholder. The screen shows the band word Building and the
five sub-scores underneath, which is more information than a fabricated
composite would have carried anyway.
The bands
| OS Health | Band |
|---|---|
null | Building |
< 40 | Finding your footing |
< 70 | Steady |
≥ 70 | Strong |
There is no danger red. The lowest band is called finding your footing, which is a description of a situation rather than an alarm about a person. An app that turns red at you is an app you eventually stop opening honestly.