From #445 review (comment). Confirmed still valid at HEAD. Target: L2 videre-host (src/registry.rs).
poll_status_transitions prunes expired watches at the top of every cadence (prune_expired, registry.rs:558), then for each watched intent resolves its venue. A dead venue skips the rest of the loop (else { continue; }, registry.rs:573) before ever reaching record_polled_status, which is the only place expires_at is pushed out (registry.rs:638).
So a venue that stays down across multiple backoff cycles never has its watches' eviction deadline refreshed. If the outage outlasts watch_limit.expiry, prune_expired evicts the pending watch for an intent whose venue is merely mid-recovery, silently dropping status tracking for that intent rather than just delaying it.
The same skip-the-refresh shape exists on the encode-failure return None at registry.rs:628 (tracked separately as #438).
Options
- Refresh
expires_at on the dead-venue skip (and the encode-failure path) so the deadline tracks liveness. A permanently-dead venue then never expires its watches, so this wants an independent upper bound (intent age, or a max consecutive-miss count) to keep memory bounded.
- Or explicitly document the interaction with the watch-expiry policy at the skip site so the eviction is a stated tradeoff, not a surprise.
Acceptance criteria
- Either the dead-venue skip refreshes/bounds the watch deadline deliberately, or the expiry-vs-outage interaction is documented at the skip site.
poll_status_transitionsprunes expired watches at the top of every cadence (prune_expired,registry.rs:558), then for each watched intent resolves its venue. A dead venue skips the rest of the loop (else { continue; },registry.rs:573) before ever reachingrecord_polled_status, which is the only placeexpires_atis pushed out (registry.rs:638).So a venue that stays down across multiple backoff cycles never has its watches' eviction deadline refreshed. If the outage outlasts
watch_limit.expiry,prune_expiredevicts the pending watch for an intent whose venue is merely mid-recovery, silently dropping status tracking for that intent rather than just delaying it.The same skip-the-refresh shape exists on the encode-failure
return Noneatregistry.rs:628(tracked separately as #438).Options
expires_aton the dead-venue skip (and the encode-failure path) so the deadline tracks liveness. A permanently-dead venue then never expires its watches, so this wants an independent upper bound (intent age, or a max consecutive-miss count) to keep memory bounded.Acceptance criteria