fix(gateway): scrub _HERMES_GATEWAY from POSIX detached restart watcher too

Follow-up to the salvaged #41264 (Windows watcher): the setsid/bash detached
restart watcher on Linux/macOS inherits _HERMES_GATEWAY=1 the same way, so
the CLI's self-restart loop guard silently refuses 'hermes gateway restart'
and the gateway never comes back. Scrub the marker from the watcher env on
the POSIX branch as well, and extend the setsid test to assert it.
This commit is contained in:
teknium1 2026-06-10 20:54:32 -07:00 committed by Teknium
parent 264ac72b67
commit cb2c13055e
3 changed files with 14 additions and 0 deletions

View file

@ -4338,12 +4338,20 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
f"while kill -0 {current_pid} 2>/dev/null; do sleep 0.2; done; "
f"{cmd} gateway restart"
)
# Same marker scrub as the Windows watcher above: this watcher runs
# `hermes gateway restart` from outside the gateway, but it inherits
# _HERMES_GATEWAY=1 from us, and the CLI's self-restart loop guard
# refuses to run when that marker is set — silently (DEVNULL), so the
# gateway stops and never comes back.
watcher_env = os.environ.copy()
watcher_env.pop("_HERMES_GATEWAY", None)
setsid_bin = shutil.which("setsid")
if setsid_bin:
subprocess.Popen(
[setsid_bin, "bash", "-lc", shell_cmd],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
env=watcher_env,
start_new_session=True,
)
else:
@ -4351,6 +4359,7 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew
["bash", "-lc", shell_cmd],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
env=watcher_env,
start_new_session=True,
)

View file

@ -75,6 +75,7 @@ AUTHOR_MAP = {
"129007007+HeLLGURD@users.noreply.github.com": "HeLLGURD",
"290859878+synapsesx@users.noreply.github.com": "synapsesx",
"dirtyren@users.noreply.github.com": "dirtyren",
"470766206@qq.com": "youjunxiaji",
"mharris@parallel.ai": "NormallyGaussian",
"roger@roger.local": "mollusk",
"ted.malone@outlook.com": "temalo",

View file

@ -200,6 +200,7 @@ async def test_launch_detached_restart_command_uses_setsid(monkeypatch):
monkeypatch.setattr(gateway_run.sys, "platform", "linux")
monkeypatch.setattr(gateway_run, "_resolve_hermes_bin", lambda: ["/usr/bin/hermes"])
monkeypatch.setattr(gateway_run.os, "getpid", lambda: 321)
monkeypatch.setenv("_HERMES_GATEWAY", "1")
monkeypatch.setattr(shutil, "which", lambda cmd: "/usr/bin/setsid" if cmd == "setsid" else None)
def fake_popen(cmd, **kwargs):
@ -218,6 +219,9 @@ async def test_launch_detached_restart_command_uses_setsid(monkeypatch):
assert kwargs["start_new_session"] is True
assert kwargs["stdout"] is subprocess.DEVNULL
assert kwargs["stderr"] is subprocess.DEVNULL
# The watcher must NOT inherit the gateway marker, or the CLI's
# self-restart loop guard refuses to run `hermes gateway restart`.
assert kwargs["env"].get("_HERMES_GATEWAY") is None
def test_windows_gateway_venv_imports_add_site_packages(monkeypatch, tmp_path):