{"repo":"NousResearch/hermes-agent","public_id":"1830","display_label":"Gateway process detection and restart corrections","summary":"These items address bugs where the gateway's --replace and restart logic could not detect script-style gateway processes, potentially allowing duplicate instances and missed shutdowns, with additional corrections for silent outages on Windows.","subsystem":"gateway","counts":{"members":3,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":1},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":1908,"merged_at":"2026-03-18T10:13:21+00:00"},"resolution":{"state":"resolved","by":"pr-1908"},"freshness":{"state":"stale","last_verified_at":"2026-03-18T10:13:21+00:00","is_stale":true},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.6666666666666666},"fix_edges":[{"issue_number":1830,"pr_number":1908,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-03-18T10:13:21+00:00"}],"members":[{"kind":"issue","number":1830,"title":"[Bug]: gateway --replace can miss existing script-style gateway processes, allowing duplicate instances and duplicate Discord replies","url":null,"state":"closed"},{"kind":"pr","number":1831,"title":"fix(gateway): detect script-style gateway processes for --replace","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#1908","number":1908}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":1908,"title":"fix(gateway): detect script-style gateway processes for --replace","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["gateway/status.py","hermes_cli/gateway.py","tests/gateway/test_status.py"],"fix_hunks":[{"file":"gateway/status.py","hunks":["@@ -87,6 +87,7 @@ def _looks_like_gateway_process(pid: int) -> bool:\n \n     patterns = (\n         \"hermes_cli.main gateway\",\n+        \"hermes_cli/main.py gateway\",\n         \"hermes gateway\",\n         \"gateway/run.py\",\n     )","@@ -105,6 +106,7 @@ def _record_looks_like_gateway(record: dict[str, Any]) -> bool:\n     cmdline = \" \".join(str(part) for part in argv)\n     patterns = (\n         \"hermes_cli.main gateway\",\n+        \"hermes_cli/main.py gateway\",\n         \"hermes gateway\",\n         \"gateway/run.py\",\n     )"]},{"file":"hermes_cli/gateway.py","hunks":["@@ -31,6 +31,7 @@ def find_gateway_pids() -> list:\n     pids = []\n     patterns = [\n         \"hermes_cli.main gateway\",\n+        \"hermes_cli/main.py gateway\",\n         \"hermes gateway\",\n         \"gateway/run.py\",\n     ]"]},{"file":"tests/gateway/test_status.py","hunks":["@@ -42,6 +42,26 @@ def test_get_running_pid_accepts_gateway_metadata_when_cmdline_unavailable(self,\n \n         assert status.get_running_pid() == os.getpid()\n \n+    def test_get_running_pid_accepts_script_style_gateway_cmdline(self, tmp_path, monkeypatch):\n+        monkeypatch.setenv(\"HERMES_HOME\", str(tmp_path))\n+        pid_path = tmp_path / \"gateway.pid\"\n+        pid_path.write_text(json.dumps({\n+            \"pid\": os.getpid(),\n+            \"kind\": \"hermes-gateway\",\n+            \"argv\": [\"/venv/bin/python\", \"/repo/hermes_cli/main.py\", \"gateway\", \"run\", \"--replace\"],\n+            \"start_time\": 123,\n+        }))\n+\n+        monkeypatch.setattr(status.os, \"kill\", lambda pid, sig: None)\n+        monkeypatch.setattr(status, \"_get_process_start_time\", lambda pid: 123)\n+        monkeypatch.setattr(\n+            status,\n+            \"_read_process_cmdline\",\n+            lambda pid: \"/venv/bin/python /repo/hermes_cli/main.py gateway run --replace\",\n+        )\n+\n+        assert status.get_running_pid() == os.getpid()\n+\n \n class TestGatewayRuntimeStatus:\n     def test_write_runtime_status_overwrites_stale_pid_on_restart(self, tmp_path, monkeypatch):\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}