{"repo":"NousResearch/hermes-agent","public_id":"13242","display_label":"Gateway process detection falsely matches CLI ancestor PIDs","summary":"These issues and PRs address a bug where the gateway's running-instance detection incorrectly identifies the invoking CLI process (or its ancestor chain) as an already-running gateway. Multiple fix approaches target PID scanning logic to exclude ancestor processes.","subsystem":null,"counts":{"members":6,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":4},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":19586},"resolution":{"state":"resolved","by":"pr-19586"},"freshness":{"state":"verified","last_verified_at":"2026-05-04T08:38:42+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.3333333333333333},"fix_edges":[{"issue_number":13242,"pr_number":19586,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true}],"members":[{"kind":"issue","number":13242,"title":"gateway run detects calling CLI process as running gateway instance (self false positive)","url":null,"state":"closed"},{"kind":"pr","number":13250,"title":"fix(gateway): exclude CLI invocations from _looks_like_gateway_process (Closes #13242)","url":null,"state":"closed","close_reason":{"category":"silent_close","implication":"active"},"merged":false},{"kind":"pr","number":13273,"title":"fix(gateway): exclude CLI invoker ancestor chain in _append_unique_pid","url":null,"state":"closed","close_reason":{"category":"stale_abandoned","implication":"active"},"merged":false},{"kind":"pr","number":14177,"title":"fix(gateway): ignore invoking CLI ancestor during PID scan","url":null,"state":"closed","close_reason":{"category":"stale_abandoned","implication":"active"},"merged":false},{"kind":"pr","number":19146,"title":"fix: exclude ancestor PIDs from gateway process scan (#13242)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#19586","number":19586}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":19586,"title":"fix(gateway): exclude ancestor PIDs from gateway process scan","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["hermes_cli/gateway.py"],"fix_hunks":[{"file":"hermes_cli/gateway.py","hunks":["@@ -237,6 +237,26 @@ def _graceful_restart_via_sigusr1(pid: int, drain_timeout: float) -> bool:\n     return False\n \n \n+def _get_ancestor_pids() -> set[int]:\n+    \"\"\"Return the set of PIDs in the current process's ancestor chain.\n+\n+    Walks from the current PID up to PID 1 (init) so that process-table scans\n+    never match the calling CLI process or any of its parents.  This prevents\n+    ``hermes gateway status`` from falsely counting the ``hermes`` CLI that\n+    invoked it as a running gateway instance (see #13242).\n+    \"\"\"\n+    ancestors: set[int] = set()\n+    pid = os.getpid()\n+    # Cap iterations to avoid infinite loops on exotic platforms.\n+    for _ in range(64):\n+        ancestors.add(pid)\n+        parent = _get_parent_pid(pid)\n+        if parent is None or parent <= 0 or parent in ancestors:\n+            break\n+        pid = parent\n+    return ancestors\n+\n+\n def _append_unique_pid(pids: list[int], pid: int | None, exclude_pids: set[int]) -> None:\n     if pid is None or pid <= 0:\n         return","@@ -252,6 +272,10 @@ def _scan_gateway_pids(exclude_pids: set[int], all_profiles: bool = False) -> li\n     a live gateway when the PID file is stale/missing, and ``--all`` sweeps can\n     discover gateways outside the current profile.\n     \"\"\"\n+    # Exclude the entire ancestor chain so the CLI process that invoked this\n+    # scan (e.g. ``hermes gateway status``) is never mistaken for a running\n+    # gateway.  See #13242.\n+    exclude_pids = exclude_pids | _get_ancestor_pids()\n     pids: list[int] = []\n     patterns = [\n         \"hermes_cli.main gateway\",\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}