fix(status): the dead-server claim renders only when the off-box writer is armed #5552
1 changed file+25−6
Modifiedsrc/routes/status.tsx+25−6View fileUnifiedSplit
@@ -58,6 +58,15 @@ export const UPTIME_WINDOWS = {
5858/** Longest window we compute; the incidents query is bounded to it. */
5959export const UPTIME_LOOKBACK_MS = UPTIME_WINDOWS["90d"];
6060
61/**
62 * When the incident ledger began existing: the reliability build shipped
63 * the synthetic-monitor incident recorder on 2026-08-09. Figures implying
64 * watched history ("days since last incident", the 90d window) are capped
65 * or annotated against this — a page cannot honestly claim more
66 * incident-free days than there are days of records.
67 */
68export const INCIDENT_LEDGER_EPOCH_MS = Date.parse("2026-08-09T00:00:00Z");
69
6170/**
6271 * 24h uptime percentage, derived from recorded incidents.
6372 *
@@ -482,12 +491,20 @@ status.get("/status", async (c) => {
482491 uptimePctFromIncidents(incidentWindow, nowMs, UPTIME_WINDOWS["90d"])
483492 );
484493 const daysSince = daysSinceLastIncident(incidentWindow, nowMs);
485 // The query is bounded to 90 days, so "none found" means "90 or more",
486 // not "never" — say exactly that.
494 // "None found in the window" used to render "90+" — but the incident
495 // ledger has only EXISTED since the reliability build shipped the
496 // recorder (2026-08-09). Ninety incident-free days cannot be claimed
497 // from seventeen days of records; the truthful cap is the ledger's own
498 // age (owner directive 2026-08-27: complete honesty in reporting —
499 // the truth always wins).
500 const ledgerAgeDays = Math.max(
501 0,
502 Math.floor((nowMs - INCIDENT_LEDGER_EPOCH_MS) / DAY_MS)
503 );
487504 const daysSinceStr =
488505 daysSince === null
489 ? `${Math.floor(UPTIME_LOOKBACK_MS / DAY_MS)}+`
490 : String(daysSince);
506 ? String(Math.min(ledgerAgeDays, Math.floor(UPTIME_LOOKBACK_MS / DAY_MS)))
507 : String(Math.min(daysSince, ledgerAgeDays));
491508
492509 // Per-service status descriptors — kept here so the JSX is just markup.
493510 //
@@ -690,8 +707,10 @@ status.get("/status", async (c) => {
690707 <p class="status-hero-method">
691708 How uptime is measured: computed from recorded incidents —
692709 rolling 24h / 30-day / 90-day windows, overlapping incidents
693 merged, an open incident counted up to now. Incidents are
694 filed by the in-process synthetic monitor
710 merged, an open incident counted up to now. Incident
711 recording began Aug 9, 2026; windows reaching further back
712 cover only the recorded period. Incidents are filed by the
713 in-process synthetic monitor
695714 {externalWriterArmed ? (
696715 <>
697716 , and by an external heartbeat that writes incidents from
698717
c comment · e edit title · m merge · a approve · r request changes · ? shortcuts