hermes - ✅(Solved) Fix Background process completion and watch notifications can duplicate [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#15276Fetched 2026-04-25 06:23:16
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
labeled ×4cross-referenced ×1

Root Cause

ProcessRegistry tracks _completion_consumed so wait, poll, and read_log can avoid delivering the same completion more than once. However, successful gateway injection of an agent-facing completion notification did not update that consumed state.

Because the process was still considered unconsumed by the registry, _inject_watch_notification could later deliver a watch-pattern event for the same completed process.

Fix Action

Fixed

PR fix notes

PR #15277: fix: dedupe background process notifications

Description (problem / solution / changelog)

Closes #15276

Summary

This PR prevents duplicate agent-facing background-process notifications when notify_on_complete and watch_patterns both apply to the same process.

The fix makes successful gateway delivery of a completion notification update the same consumed state already used by wait, poll, and read_log. Watch notifications now check that state before interrupting the agent, so a process that has already delivered its completion event cannot later send a duplicate watch notification for the same completed session.

Problem

Background processes already track whether completion has been consumed, but that state was only updated through tool read paths such as wait, poll, and read_log.

When the gateway itself injected a synthetic notify_on_complete message into the agent thread, the registry still considered the completion unconsumed. If the same process also produced output matching watch_patterns, the watch path could inject another synthetic notification for that already-completed process.

Changes

  • Added ProcessRegistry.mark_completion_consumed(session_id) for explicit gateway-side completion delivery.
  • Mark completion consumed after a successful gateway notify_on_complete injection.
  • Skip _inject_watch_notification for process sessions whose completion has already been consumed.
  • Added regression coverage for:
    • direct registry marking,
    • gateway completion injection marking the process consumed,
    • watch notifications being skipped after completion consumption.

Files Changed

  • tools/process_registry.py
    • Adds the explicit consumed-state marker used by gateway delivery.
  • gateway/run.py
    • Marks completion consumed after successful synthetic completion injection.
    • Suppresses watch notifications for already-consumed process sessions.
  • tests/tools/test_notify_on_complete.py
    • Covers direct consumed-state marking.
  • tests/gateway/test_internal_event_bypass_pairing.py
    • Covers gateway completion injection and watch-notification suppression.

Behavior Notes

  • This does not change wait, poll, or read_log completion semantics.
  • Watch patterns still work for active processes before completion is consumed.
  • The new suppression only applies when a process session has already had its completion consumed or delivered.

Test Plan

uv run --extra dev pytest tests/tools/test_notify_on_complete.py tests/gateway/test_internal_event_bypass_pairing.py tests/tools/test_watch_patterns.py
python3.11 -m py_compile gateway/run.py tools/process_registry.py

Changed files

  • gateway/run.py (modified, +13/-0)
  • tests/gateway/test_internal_event_bypass_pairing.py (modified, +53/-0)
  • tests/tools/test_notify_on_complete.py (modified, +8/-0)
  • tools/process_registry.py (modified, +4/-0)

Code Example

uv run --extra dev pytest tests/tools/test_notify_on_complete.py tests/gateway/test_internal_event_bypass_pairing.py tests/tools/test_watch_patterns.py
python3.11 -m py_compile gateway/run.py tools/process_registry.py
RAW_BUFFERClick to expand / collapse

Bug Description

Hermes can deliver duplicate agent-facing background-process notifications for the same process when notify_on_complete and watch_patterns are both involved.

The duplicate path is not specific to one adapter or one command. It can affect any background process where completion delivery and watch-pattern delivery both produce synthetic [SYSTEM: ...] events for the same process session.

Steps to Reproduce

  1. Start a Hermes background process with notify_on_complete enabled.
  2. Configure one or more watch_patterns that can match the process output.
  3. Let the process produce matching output and then exit.
  4. Observe the gateway delivering an agent-facing completion notification.
  5. A later watch notification for the same process can still be injected, interrupting the agent even though the completion notification was already delivered.

Expected Behavior

  • Once the gateway successfully injects a completion notification into the agent thread, that process completion should be treated as consumed.
  • Later watch-pattern notifications for the same completed process should not interrupt the agent.
  • Existing wait, poll, and read_log completion-consumption behavior should remain unchanged.
  • Watch patterns should still fire for active processes before the completion has been consumed.

Actual Behavior

  • wait, poll, and read_log already suppress redundant completion delivery by tracking _completion_consumed.
  • Gateway-injected notify_on_complete messages were not marking the completion as consumed.
  • A watcher path could therefore still inject a related watch notification for the same process after the agent had already received the completion notification.
  • In practice this can show up as repeated synthetic system notifications or follow-up messages indicating the notification was already handled.

Affected Component

  • Gateway notification delivery
  • Background process registry / tools
  • Gateway adapters that receive synthetic process events

Messaging Platform

Gateway-related; not specific to Telegram, Discord, Slack, or WhatsApp.

Debug Report

Not available. This was identified from the background-process notification flow and covered with targeted regression tests in #15277.

Operating System

N/A; runtime behavior is platform-independent.

Python Version

N/A.

Hermes Version

Current main before #15277.

Root Cause Analysis

ProcessRegistry tracks _completion_consumed so wait, poll, and read_log can avoid delivering the same completion more than once. However, successful gateway injection of an agent-facing completion notification did not update that consumed state.

Because the process was still considered unconsumed by the registry, _inject_watch_notification could later deliver a watch-pattern event for the same completed process.

Proposed Fix

Implemented in #15277:

  • Add ProcessRegistry.mark_completion_consumed(session_id).
  • Call it after successful gateway injection of a notify_on_complete synthetic event.
  • Skip watch notification injection when the process completion is already consumed.
  • Add regression coverage for gateway completion injection, watch suppression, and direct registry marking.

Validation

The PR validates the fix with:

uv run --extra dev pytest tests/tools/test_notify_on_complete.py tests/gateway/test_internal_event_bypass_pairing.py tests/tools/test_watch_patterns.py
python3.11 -m py_compile gateway/run.py tools/process_registry.py

PR

Fix: #15277

extent analysis

TL;DR

The issue can be fixed by updating the ProcessRegistry to mark completion as consumed after successful gateway injection of a notify_on_complete synthetic event.

Guidance

  • Review the proposed fix in #15277 and apply the changes to the ProcessRegistry class.
  • Verify that the mark_completion_consumed method is called after successful gateway injection of a notify_on_complete event.
  • Test the changes using the provided validation commands to ensure the fix works as expected.
  • Check the regression test coverage to ensure the fix does not introduce new issues.

Example

No code snippet is provided as the issue already includes a proposed fix and validation steps.

Notes

The fix is specific to the ProcessRegistry class and the gateway notification delivery mechanism. The issue is not related to any specific Python version or operating system.

Recommendation

Apply the workaround by implementing the proposed fix in #15277, as it directly addresses the root cause of the issue and includes regression test coverage.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix Background process completion and watch notifications can duplicate [1 pull requests, 1 participants]