Sticky lifecycle
The second layer is stateful and persistent, and it is what turns a sensor
reading into an alarm console.
A persistent map records, per event identifier, when the condition was first
seen, when it was last active, whether and when it resolved, its current
lifecycle state, and a snapshot of the most recent live event payload.
Reconciliation against a fresh synthesis is a pure function — it computes the new
map and writes nothing itself.
The transitions:
| Situation | Result |
|---|---|
| Identifier not seen before | Create as active, stamp first_seen_ts |
| Still present | Refresh last_active_ts and the payload snapshot |
| No longer present | Mark recovered, stamp resolved_at |
recovered and fires again |
Revive — preserve the original first_seen_ts, clear resolved_at |
| Operator acknowledges | Remove from the map entirely |
The revive rule is the important one. A flapping sensor produces one entry per
incident, not one entry per flap. Only an explicit acknowledgement removes an
entry; a recurrence after acknowledgement correctly begins a new incident with a
fresh first_seen_ts.
Refreshing the payload snapshot on every reconciliation means severity and
summary updates flow through mid-incident — a warning that escalates to critical
is visible on the existing entry rather than creating a second one.