From 5177575c89668b6369b41e927bb085d070bb5cbd Mon Sep 17 00:00:00 2001 From: Moiz Amjad Date: Tue, 2 Jun 2026 12:30:27 +0500 Subject: [PATCH 1/3] fix(file_safety): log ignored resolution errors in write-deny guard Silent except: pass blocks in is_write_denied made path-resolution failures invisible when the guard was deciding whether a write target was denied. Add debug logging so operators can see which paths and Hermes dir lookups are being skipped without changing behavior. --- agent/file_safety.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/agent/file_safety.py b/agent/file_safety.py index e9fa487e834f1..fef23a548750d 100644 --- a/agent/file_safety.py +++ b/agent/file_safety.py @@ -118,7 +118,12 @@ def is_write_denied(path: str) -> bool: real = os.path.realpath(base) if real not in hermes_dirs: hermes_dirs.append(real) - except Exception: + except Exception as exc: + logger.debug( + "Ignoring write-deny hermess-dir resolution error for %s: %s", + base, + exc, + ) continue for base_real in hermes_dirs: @@ -126,7 +131,13 @@ def is_write_denied(path: str) -> bool: try: if resolved == os.path.realpath(os.path.join(base_real, name)): return True - except Exception: + except Exception as exc: + logger.debug( + "Ignoring write-deny control-file resolution error for %s/%s: %s", + base_real, + name, + exc, + ) continue try: mcp_real = os.path.realpath(os.path.join(base_real, mcp_tokens_dir_name)) From 9d7bb9d45ae82a8b4be3a219d2c0e97a7c52ac5c Mon Sep 17 00:00:00 2001 From: Moiz Amjad Date: Tue, 2 Jun 2026 12:56:11 +0500 Subject: [PATCH 2/3] fix(context_references): log fallback metadata read errors in _file_metadata --- agent/context_references.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/agent/context_references.py b/agent/context_references.py index 50a33a1d75774..2b788c284c667 100644 --- a/agent/context_references.py +++ b/agent/context_references.py @@ -496,7 +496,12 @@ def _file_metadata(path: Path) -> str: return f"{path.stat().st_size} bytes" try: line_count = path.read_text(encoding="utf-8").count("\n") + 1 - except Exception: + except Exception as exc: + logger.debug( + "Falling back to size metadata for %s after read failure: %s", + path, + exc, + ) return f"{path.stat().st_size} bytes" return f"{line_count} lines" From 85cddc76e28416cf13faed9a93b9da67590746b9 Mon Sep 17 00:00:00 2001 From: Moiz Amjad Date: Thu, 4 Jun 2026 12:29:45 +0500 Subject: [PATCH 3/3] fix: update current_turn_user_idx after preflight compression When preflight context compression replaces the messages list with a compressed [summary, ...tail] structure, the current_turn_user_idx set earlier (line 567) becomes stale. This causes memory/plugin context injection to target the wrong message, potentially corrupting tool results or the summary message itself. The fix scans the compressed messages list to locate the current turn's user message and updates both current_turn_user_idx and agent._persist_user_message_idx to the correct position. This ensures that ephemeral context (memory prefetch, plugin hooks) is injected into the correct user message after compression events. --- agent/conversation_loop.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/agent/conversation_loop.py b/agent/conversation_loop.py index 8be763513fff1..ff6b567b5fd15 100644 --- a/agent/conversation_loop.py +++ b/agent/conversation_loop.py @@ -678,6 +678,18 @@ def run_conversation( agent._last_content_with_tools = None agent._last_content_tools_all_housekeeping = False agent._mute_post_response = False + # Fix: update current_turn_user_idx after compression. + # Compression replaces the messages list with [summary, ...tail], + # making the old index stale. Find the current turn's user + # message in the compressed list so memory/plugin context + # injection at line 954 targets the correct message. + for _new_idx in range(len(messages) - 1, -1, -1): + _msg = messages[_new_idx] + if (isinstance(_msg, dict) and _msg.get("role") == "user" + and _msg.get("content") == user_message): + current_turn_user_idx = _new_idx + agent._persist_user_message_idx = _new_idx + break # Re-estimate after compression _preflight_tokens = estimate_request_tokens_rough( messages,