diff --git a/agent/context_compressor.py b/agent/context_compressor.py index b9cca84c76..e98fbb6a08 100644 --- a/agent/context_compressor.py +++ b/agent/context_compressor.py @@ -72,6 +72,16 @@ def _safe_int(value: Any) -> int | None: # with it. Context is copied per worker (``propagate_context_to_thread``), so # the pin reaches the retry's whole synchronous call chain and cannot leak # into the stalled attempt or any unrelated auxiliary call. +# +# Coverage is the single ``_generate_summary`` LLM call only. That is one call +# per compression run (its only non-recursive call site is the compress path; +# the two recursive calls are the deliberate main-model retry that must NOT +# re-issue the pin). Lean ``tail_mode`` additionally runs +# ``_build_chunk_digests``, which issues its own ``call_llm`` calls directly +# and never consults the pin — during a stall-fallback retry those digests +# still target the stalled primary and degrade to per-segment placeholders. +# Deliberate: the digest path is a best-effort augmentation, not the summary, +# and pinning it would require weakening the single-use contract below. _SUMMARY_ROUTE_PIN: contextvars.ContextVar[Optional[Dict[str, Any]]] = ( contextvars.ContextVar("hermes_summary_route_pin", default=None) ) diff --git a/agent/conversation_compression.py b/agent/conversation_compression.py index e7c032d752..05fed80da8 100644 --- a/agent/conversation_compression.py +++ b/agent/conversation_compression.py @@ -953,11 +953,18 @@ def _retry_compression_on_fallback_chain( try: retry_fence = new_fence() except Exception: - logger.debug( - "compression stall-fallback fence factory failed", + logger.warning( + "compression stall-fallback fence factory failed; the retry " + "will run on an unpublished fence (a /stop mid-retry cannot " + "serialize against its commit boundary)", exc_info=True, ) if not isinstance(retry_fence, CompressionCommitFence): + logger.warning( + "compression stall-fallback retry running on an unpublished fence; " + "hard-interrupt admission will read the aborted attempt's fence " + "rather than the retry's commit boundary", + ) retry_fence = CompressionCommitFence() idle = float(route.get("timeout") or idle_timeout_seconds) ceiling = max(float(total_ceiling_seconds), idle)