M3 is display — and the first honest number. Four steps.
What changed: GET /api/monitors/{id}/stats answers did we look and
what did we see as separate numbers. Expected slots come from wall-clock
× interval — not from stored rows, which is the whole point: a monitor that
stored nothing can’t claim 100% coverage of nothing. Missed slots never enter
the success denominator, and an undefined denominator returns null, which
the dashboard renders as “no data” — not a guessed percent.
Proof: domain tests, the check_stats store test, and the API test
stats_separates_coverage_from_success. Live: a flaky target showed 0%
success while a healthy one showed 100% — and a window of misses reports 0%
coverage with undefined success, never “down by silence”.