1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//! The TUI's "is a daemon alive?" probe (dual-scheduler dedup, issue #27).
//!
//! Two signals, both required:
//! * the daemon singleton flock (`clauthd.lock`) is HELD — a dead daemon's
//! advisory lock auto-releases, so process death re-arms the TUI on the
//! very next tick;
//! * `status.json` is FRESH — a wedged-but-alive holder stops stamping
//! `generated_at`, so the TUI re-arms instead of rendering a frozen feed.
//!
//! The probe belongs to the TUI ONLY: the daemon must never probe (its own
//! held flock would read as "another daemon" — a self-stand-down). That
//! asymmetry is wired at `spawn_refresher`'s `standdown_probe` flag, not here.
use crateclauth_dir;
/// How stale `status.json` may be before the holder is presumed wedged. The
/// daemon stamps it every ~1 s loop tick, but a single tick can legitimately
/// block up to the keychain shell-out's 20 s kill deadline — the window rides
/// above that so a slow switch doesn't false re-arm the TUI mid-write.
///
/// Deliberately BELOW the daemon's own 60 s watchdog deadline: a truly wedged
/// daemon leaves a ~30 s window where the TUI has re-armed while the daemon's
/// scheduler thread may still be fetching. That overlap is bounded, merely
/// duplicative, and preferable to the alternative — waiting out the watchdog
/// would leave a refresh coverage gap instead.
const STANDDOWN_STALE_MS: u64 = 30_000;
/// Whether a live (lock-holding + publishing) daemon owns the
/// fetch/rotate/switch loop right now. Best-effort `false` on any error — the
/// TUI then runs its own refresher, which is always safe (merely duplicative).
pub
/// Pure freshness half of the probe: `body`'s `generated_at` stamp is within
/// [`STANDDOWN_STALE_MS`] of `now_ms`. An unparseable body or a missing or
/// malformed stamp reads as stale — never stand down on a feed we can't read.
/// A stamp in the FUTURE counts as fresh (clock skew must not flap the probe).
pub