Reintroduce the restart-attempt machinery that was deliberately deferred from phase 2f. The phase 2f SupervisorHandle carries head_age_threshold, advance_failure_threshold, check_interval only; the design's restart-attempt loop has no producer and was stripped (core/src/provider/supervisor.rs:52-54 documents the deferral).
Scope
StallPolicy::restart_attempt_limit: u32 and StallPolicy::restart_backoff: Vec<Duration> fields on core/src/provider/supervisor.rs:55. Defaults from the design: restart_attempt_limit = 3, restart_backoff = [2s, 10s, 30s].
SupervisorHandle::request_restart() and SupervisorHandle::restart_attempted(outcome: RestartOutcome) API. The handle owns the attempt counter; the network crate's consensus task polls request_restart() and reports back.
HealthStatus::Stalled { since: SystemTime, restart_attempts: u32 } payload at core/src/provider/event.rs:46 — currently a unit variant with an explicit deferral comment at lines 37-39. The since half is mechanical (already tracked by last_advance at supervisor.rs:86); restart_attempts lands with this issue.
- Test that exhausts
restart_attempt_limit and verifies Stalled.restart_attempts reflects the count.
Depends on phase 2.6 (#TBD) for the network-crate side to actually call request_restart — without that, this is observable only via tests.
Out of scope
event_emit_cooldown debouncing, on_exhausted: ExhaustedAction, StallHook trait — Phase 2.9.
- Multi-RPC failover on restart (the design's
.consensus_rpcs([..])) — Phase 2.10.
Reintroduce the restart-attempt machinery that was deliberately deferred from phase 2f. The phase 2f
SupervisorHandlecarrieshead_age_threshold,advance_failure_threshold,check_intervalonly; the design's restart-attempt loop has no producer and was stripped (core/src/provider/supervisor.rs:52-54documents the deferral).Scope
StallPolicy::restart_attempt_limit: u32andStallPolicy::restart_backoff: Vec<Duration>fields oncore/src/provider/supervisor.rs:55. Defaults from the design:restart_attempt_limit = 3,restart_backoff = [2s, 10s, 30s].SupervisorHandle::request_restart()andSupervisorHandle::restart_attempted(outcome: RestartOutcome)API. The handle owns the attempt counter; the network crate's consensus task pollsrequest_restart()and reports back.HealthStatus::Stalled { since: SystemTime, restart_attempts: u32 }payload atcore/src/provider/event.rs:46— currently a unit variant with an explicit deferral comment at lines 37-39. Thesincehalf is mechanical (already tracked bylast_advanceatsupervisor.rs:86);restart_attemptslands with this issue.restart_attempt_limitand verifiesStalled.restart_attemptsreflects the count.Depends on phase 2.6 (#TBD) for the network-crate side to actually call
request_restart— without that, this is observable only via tests.Out of scope
event_emit_cooldowndebouncing,on_exhausted: ExhaustedAction,StallHooktrait — Phase 2.9..consensus_rpcs([..])) — Phase 2.10.