From 6e67841a9a45c8160bc85846001004edbca97386 Mon Sep 17 00:00:00 2001 From: ethernet Date: Tue, 18 Aug 2026 17:55:29 -0400 Subject: [PATCH] refactor(goals): share one dropped-write warning across managers Review fixups for #88965. The goal, loop, and heartbeat managers each had a copy of the same WARNING text. The shared _warn_dropped_write helper in goals.py keeps the three logs identical and greppable as one bug class. The _warm_goals_session_db parameter is now label. The old name ctx said context, but the value is a log label. --- gateway/run.py | 4 ++-- hermes_cli/goals.py | 23 +++++++++++++++++------ hermes_cli/heartbeat.py | 9 +++------ hermes_cli/loops.py | 9 +++------ 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/gateway/run.py b/gateway/run.py index b5d49dbcb3..8895660879 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -20998,7 +20998,7 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew except Exception: return 20 - async def _warm_goals_session_db(self, ctx: str) -> None: + async def _warm_goals_session_db(self, label: str) -> None: """Warm the goals SessionDB cache off-loop (best-effort). A cold cache runs the state.db init on the loop thread behind the @@ -21013,7 +21013,7 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew await self._run_in_executor_with_context(_warm_goals_db) except Exception as exc: - logger.warning("%s: session DB warm-up failed: %s", ctx, exc) + logger.warning("%s: session DB warm-up failed: %s", label, exc) async def _get_goal_manager_for_event(self, event: "MessageEvent"): """Return a GoalManager bound to the session for this gateway event. diff --git a/hermes_cli/goals.py b/hermes_cli/goals.py index 39870322af..61e952d44c 100644 --- a/hermes_cli/goals.py +++ b/hermes_cli/goals.py @@ -811,6 +811,22 @@ def _get_session_db() -> Optional[Any]: return db +def _warn_dropped_write(manager: str, kind: str, session_id: str) -> None: + """Log a dropped state write at WARNING. + + The reply already told the user that the state was set. A silent + drop makes that reply a lie. One shared message keeps the goal, + loop, and heartbeat logs greppable as one bug class. + """ + logger.warning( + "%s: %s for %s not persisted — session DB unavailable " + "(bootstrap window exceeded, in-memory state still active)", + manager, + kind, + session_id, + ) + + def load_goal(session_id: str) -> Optional[GoalState]: """Load the goal for a session, or None if none exists.""" if not session_id: @@ -838,12 +854,7 @@ def save_goal(session_id: str, state: GoalState) -> None: return db = _get_session_db() if db is None: - logger.warning( - "GoalManager: goal for %s not persisted — session DB " - "unavailable (bootstrap window exceeded, in-memory state " - "still active)", - session_id, - ) + _warn_dropped_write("GoalManager", "goal", session_id) return try: db.set_meta(_meta_key(session_id), state.to_json()) diff --git a/hermes_cli/heartbeat.py b/hermes_cli/heartbeat.py index 872fbdd806..11df286869 100644 --- a/hermes_cli/heartbeat.py +++ b/hermes_cli/heartbeat.py @@ -184,12 +184,9 @@ def save_heartbeat(session_id: str, state: HeartbeatState) -> None: return db = _get_session_db() if db is None: - logger.warning( - "HeartbeatManager: heartbeat for %s not persisted — session " - "DB unavailable (bootstrap window exceeded, in-memory state " - "still active)", - session_id, - ) + from hermes_cli.goals import _warn_dropped_write + + _warn_dropped_write("HeartbeatManager", "heartbeat", session_id) return try: db.set_meta(_meta_key(session_id), state.to_json()) diff --git a/hermes_cli/loops.py b/hermes_cli/loops.py index 7368d85b2e..0ee3c31b1c 100644 --- a/hermes_cli/loops.py +++ b/hermes_cli/loops.py @@ -415,12 +415,9 @@ def save_loop(session_id: str, state: LoopState) -> None: return db = _get_session_db() if db is None: - logger.warning( - "LoopManager: loop for %s not persisted — session DB " - "unavailable (bootstrap window exceeded, in-memory state " - "still active)", - session_id, - ) + from hermes_cli.goals import _warn_dropped_write + + _warn_dropped_write("LoopManager", "loop", session_id) return try: db.set_meta(_meta_key(session_id), state.to_json())