Scores without receipts
Readiness, strain, body battery: single numbers with unpublished formulas. You can't check them, and they don't tell you how sure they are.
A personal project · built for one person · used every day
Body Signals learns how your body usually behaves and tells you, in plain words, when it shifts. Every model has to pass a test before it can say anything. When the data can't support an answer, it says “I don't know yet”.
I built it for myself, not as a product: it reads my own Apple Watch and I use it every day — a short briefing on Telegram each morning, quick logs during the day, and a private dashboard when I want the full story.
01 · The problem
Readiness, strain, body battery: single numbers with unpublished formulas. You can't check them, and they don't tell you how sure they are.
A heart rate that's normal for most people can be high for you. Population ranges are wide, so they miss the changes that matter for you.
They answer “should I train hard today?”. Most people want to know why they feel off this week, and what in their routine actually changes it.
02 · The approach
Every signal is judged against your own rolling baseline: medians and robust spread, weekday habits, and seasonal drift once there's a year of data. Nothing is graded against a population chart.
Each model is tested on simulated people where the truth is known, and on simulated people with no effect at all. If a model can't beat a simple baseline, it isn't shown. Uncertainty is always shown as a range.
Patterns are called associations, with false-discovery control. To find out if a habit really helps, the system runs a randomized N-of-1 experiment: your days are randomly split, and you are your own control group.
03 · See it
A simulated person, generated in your browser. Twice we planted something real: a week of the body fighting something off, then a lasting shift up. Switch between a population range and their own normal and see which one notices.
The illustrative population range is 45–75 bpm. The personal band uses the previous 28 nights (median ± 2 robust SD). The streak detector is a one-sided CUSUM, the same kind of detector studied for early warning on smartwatches.
04 · Regularity
The Sleep Regularity Index compares every minute of your day with the same minute 24 hours earlier. In a large cohort study, sleep regularity was a stronger predictor of mortality than sleep duration. Drag the sliders and watch four weeks of sleep change.
05 · Architecture
06 · The engine
A Kalman-filtered latent state that combines seven overnight signals into one 0–100 number, with an 80% range.
Stays quiet unless the shared factor predicts new days better than any single signal.
Bayesian online changepoint detection proposes dates. A test that accounts for autocorrelation confirms them.
Stays quiet unless 2+ signals move together. One bad week is not a phase.
Cosinor fit on minute-level heart rate: when the body rests, when it peaks, and how bedtime moves it.
Stays quiet about energy windows when the daily curve is flat.
Forecasts tomorrow's overnight values, scored day by day without peeking against “tomorrow = today”.
Stays quiet until it beats the naive baselines by a margin.
14 days in randomized, balanced blocks. The analysis is Bayesian with a sceptical prior, and adherence takes one tap.
Stays quiet until the end. No peeking at interim effects.
Sleep Regularity Index and social jetlag, with block-bootstrap intervals.
Stays quiet about change unless the intervals of the two windows don't overlap.
The 7-night average of ln(HRV) compared with a band built from the 60 nights before it.
Stays quiet unless it's low for 5 days in a row, by a margin that matters.
A one-sided CUSUM catches several nights in a row with the heart above your normal.
Never an alarm and never a diagnosis. One night alone can't trigger it.
07 · Validation
The numbers below come from synthetic people with known ground truth: planted habit effects, illness episodes and level shifts, plus negative-control worlds where nothing happens. All runs are seeded and reproducible. These are not results on anyone's real data.
What didn't work is documented too: pure BOCPD gave up to 1.9 false alarms per 100 days, and a bootstrap that ignored neighbouring nights made intervals too narrow. Both were replaced and the numbers re-measured on fresh seeds.
08 · Privacy
09 · Built with