Add rolling 24h activity rollup to daily health heartbeat #1

Merged
paul merged 1 commits from daily-heartbeat-24h-summary into main 2026-07-01 09:39:39 +00:00
Owner

What

The daily ✅ Daily health — N/N tracked services up heartbeat was a bare point-in-time snapshot — it said nothing about whether anything went down or needed operational support during the preceding window. Intra-day events (self-recovered blips, sustained-outage remediations) were reported only as separate real-time messages, which are easy to miss.

This adds a rolling "past 24h" rollup line to the heartbeat.

How

  • New state["since_heartbeat"] tally with per-service recovered / incidents maps, accumulated across cycles and flushed (and reset) only when a heartbeat is actually sent.
  • Self-recovered blips counted once per DOWN→UP window.
  • Sustained outages counted once — at the cycle the down-streak first crosses down_confirmations — so a multi-hour outage isn't tallied every 5-minute cycle.
  • Wording is autonomy-mode-neutral ("sustained outage(s)").

Example output:

Daily health — 18/18 tracked services up.
Past 24h: 1 sustained outage(s) (gitea ×1); 2 self-recovered blip(s) (grafana ×1, db ×1).

Notes

  • Stdlib-only, byte-compiles clean, summary rendering unit-tested across the empty / blips-only / mixed / outages-only cases.
  • Backward-compatible with existing state.json — the new key is initialized via setdefault, no reset required.

🤖 Generated with Claude Code

## What The daily `✅ Daily health — N/N tracked services up` heartbeat was a bare point-in-time snapshot — it said nothing about whether anything went down or needed operational support during the preceding window. Intra-day events (self-recovered blips, sustained-outage remediations) were reported only as separate real-time messages, which are easy to miss. This adds a rolling "past 24h" rollup line to the heartbeat. ## How - New `state["since_heartbeat"]` tally with per-service `recovered` / `incidents` maps, accumulated across cycles and flushed (and reset) only when a heartbeat is actually sent. - Self-recovered blips counted once per DOWN→UP window. - Sustained outages counted once — at the cycle the down-streak first crosses `down_confirmations` — so a multi-hour outage isn't tallied every 5-minute cycle. - Wording is autonomy-mode-neutral ("sustained outage(s)"). Example output: > ✅ **Daily health** — 18/18 tracked services up. > Past 24h: 1 sustained outage(s) (gitea ×1); 2 self-recovered blip(s) (grafana ×1, db ×1). ## Notes - Stdlib-only, byte-compiles clean, summary rendering unit-tested across the empty / blips-only / mixed / outages-only cases. - Backward-compatible with existing `state.json` — the new key is initialized via `setdefault`, no reset required. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
paul added 1 commit 2026-07-01 09:39:04 +00:00
The daily " Daily health — N/N up" message was a bare point-in-time
snapshot: it said nothing about downtime or operational support during
the preceding window. Self-recovered blips and sustained-outage
remediations were reported only as separate real-time messages, easy to
miss.

Accumulate a per-service tally in state["since_heartbeat"] and fold it
into the heartbeat line, then reset on send:
- self-recovered blips counted once per DOWN→UP window
- sustained outages counted once, at the cycle the down-streak first
  crosses down_confirmations (so a long outage isn't tallied each cycle)

Wording is autonomy-mode-neutral ("sustained outage(s)"). Existing state
files without the key are initialized via setdefault, so no reset needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
paul merged commit 46a1ec1e01 into main 2026-07-01 09:39:39 +00:00
paul deleted branch daily-heartbeat-24h-summary 2026-07-01 09:39:44 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: paul/semprini-maintainer#1