personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add startup grace period to supervisor health checks

Fixes false "offline" alerts on startup by adding an ever_received flag
to track whether we've received at least one observe.status event. Health
checks now return healthy (empty list) until the first status is received,
giving the observer time to start up before alerting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+20 -2
+11 -2
tests/test_supervisor.py
··· 14 14 15 15 # Reset state for clean test 16 16 mod._observe_status_state["last_ts"] = 0.0 17 + mod._observe_status_state["ever_received"] = False 17 18 mod._observe_status_state["activity_active"] = False 18 19 mod._observe_status_state["screencast_recording"] = False 19 20 mod._observe_status_state["files_growing"] = False 20 21 21 - # No status received yet - both should be stale 22 + # Startup grace period: no status ever received - returns healthy (no alerts) 23 + stale = mod.check_health(threshold=60) 24 + assert stale == [] # Grace period - don't alert until first status received 25 + 26 + # After first status received, stale timestamp triggers alerts 27 + mod._observe_status_state["ever_received"] = True 28 + mod._observe_status_state["last_ts"] = 0.0 # Very old timestamp 22 29 stale = mod.check_health(threshold=60) 23 30 assert sorted(stale) == ["hear", "see"] 24 31 25 - # Simulate receiving a status event (user inactive) 32 + # Simulate receiving a fresh status event (user inactive) 26 33 mod._observe_status_state["last_ts"] = time.time() 27 34 mod._observe_status_state["activity_active"] = False 28 35 stale = mod.check_health(threshold=60) ··· 57 64 58 65 # Reset state 59 66 mod._observe_status_state["last_ts"] = 0.0 67 + mod._observe_status_state["ever_received"] = False 60 68 mod._observe_status_state["activity_active"] = False 61 69 mod._observe_status_state["screencast_recording"] = False 62 70 mod._observe_status_state["files_growing"] = False ··· 71 79 mod._handle_observe_status(message) 72 80 73 81 assert mod._observe_status_state["last_ts"] > 0 82 + assert mod._observe_status_state["ever_received"] is True # Grace period ended 74 83 assert mod._observe_status_state["activity_active"] is True 75 84 assert mod._observe_status_state["screencast_recording"] is True 76 85 assert mod._observe_status_state["files_growing"] is True
+9
think/supervisor.py
··· 103 103 # Observe status state for health monitoring (updated from observe.status events) 104 104 _observe_status_state: dict = { 105 105 "last_ts": 0.0, # Timestamp of last observe.status event 106 + "ever_received": False, # Whether we've received at least one status event 106 107 "activity_active": False, # Whether user is active (not idle/locked) 107 108 "screencast_recording": False, # Whether screencast is running 108 109 "files_growing": False, # Whether screencast files are growing ··· 219 220 Health is derived from the last observe.status Callosum event: 220 221 - hear: Stale if no status received within threshold 221 222 - see: Stale if active AND (not recording OR files not growing) 223 + 224 + During startup grace period (before first status event received), 225 + returns empty list to avoid false alerts while observer is starting. 222 226 """ 227 + # Grace period: don't alert until we've received at least one status event 228 + if not _observe_status_state["ever_received"]: 229 + return [] 230 + 223 231 now = time.time() 224 232 stale: list[str] = [] 225 233 ··· 1038 1046 1039 1047 # Update observe status state for health checking 1040 1048 _observe_status_state["last_ts"] = time.time() 1049 + _observe_status_state["ever_received"] = True 1041 1050 1042 1051 activity = message.get("activity", {}) 1043 1052 _observe_status_state["activity_active"] = activity.get("active", False)