Quick Start
1
Default — sensible thresholds
2
Tuned thresholds — slower loop, higher tolerance
tick_interval_s to your run-loop cadence and set gap_threshold_s above your worst legitimate stall.How It Works
On LinuxCLOCK_MONOTONIC does not advance while the host is suspended, so wall-clock running far ahead of monotonic is a positive signature of a freeze the process could not otherwise observe.
Detection rule — a gap is reported only when both are true:
The second condition rejects the NTP / manual-clock-step false positive: if monotonic advanced a full tick or more, the process was alive and no recovery fires.
Choosing between Freeze-Thaw and Scale-to-Zero
Freeze-Thaw handles the involuntary suspend; Scale-to-Zero handles the intentional one.Configuration Options
WallClockGapThawPolicy constructor
ThawDecision — result of every observe() call
@dataclass(frozen=True) — assigning to a field raises.
ThawPolicyProtocol — custom detectors
@runtime_checkable protocol with a single method. Implement your own detector and pass it wherever a ThawPolicyProtocol is accepted — isinstance(policy, ThawPolicyProtocol) succeeds without inheritance.
Imports
These names export from
praisonaiagents.gateway. Top-level praisonaiagents does not re-export them. BotOS itself imports from praisonai.bots.Common Patterns
Disable in tests
enabled=False to keep the wiring in place while turning detection off — no code removal.
Custom detector implementing ThawPolicyProtocol
Log the observed freeze window
ThawDecision.gap_seconds in a hook to record how long the host was suspended.
Best Practices
Match tick_interval_s to your loop cadence
Match tick_interval_s to your loop cadence
If the run-loop ticks every 30s, set
tick_interval_s=30.0. Otherwise a legitimate stall longer than the configured interval can look like a freeze, and the “monotonic stalled” guard loses its meaning.Keep gap_threshold_s above your worst legitimate stall
Keep gap_threshold_s above your worst legitimate stall
GC pauses, cold starts, and NTP jitter shouldn’t trip the detector.
60s is a safe floor — raise it if your environment has known long stalls, lower it only when you need faster freeze detection and your loop is reliably quick.Don't rely on Loop Watchdog to catch host suspends
Don't rely on Loop Watchdog to catch host suspends
LoopWatchdog uses time.monotonic() and is deliberately blind to frozen hosts — monotonic doesn’t advance during a suspend, so the watchdog never notices. Freeze-Thaw is a separate, complementary policy that watches wall-vs-monotonic divergence.NTP corrections are not freezes
NTP corrections are not freezes
A forward wall-clock correction (NTP step / manual set) leaves monotonic advancing in step with the loop — proof the process kept running. The built-in detector already ignores this, so it never churns healthy sockets. Custom detectors must do the same or they’ll restart transports needlessly.
Related
Scale to Zero
Intentional-suspend counterpart — quiesce the gateway when idle and wake on the next message.
Loop Watchdog
Event-loop liveness watchdog — deliberately blind to host suspends.
Graceful Drain
Drain in-flight turns cleanly on shutdown before the process exits.
Liveness
Application-level connection liveness for detecting silently-dead sockets.

