fix(gateway,cron): reuse existing _HERMES_GATEWAY marker; tighten cron regex

Follow-up to the salvaged #30728:
- Gateway already exports _HERMES_GATEWAY=1 at startup (gateway/run.py) and
  cli.py already keys off it. Drop the redundant new HERMES_IN_GATEWAY var;
  guard stop/restart on _HERMES_GATEWAY instead. One marker for one fact.
- Drop the greedy \bgateway.*restart alternation from the cron lifecycle
  filter — it false-positived on legit prompts that merely mention an
  unrelated gateway + a restart (API/payment gateway monitoring). The
  specific 'hermes gateway (restart|stop|start)' pattern already covers the
  real command.
- Rework the two negative guard tests to sentinel the first downstream call
  so they don't drive real signal delivery (tripped the live-system guard).
- Add false-positive regression cases to test_safe_commands.
This commit is contained in:
teknium1
2026-05-30 23:05:56 -07:00
committed by Teknium
parent 5cd6c1717d
commit bd72d333dc
5 changed files with 49 additions and 28 deletions
+4 -2
View File
@@ -18,13 +18,15 @@ from hermes_cli.colors import Colors, color
# Patterns that indicate a cron job targets the gateway lifecycle.
# Matches commands that restart/stop the gateway or its service manager.
# Deliberately specific — a bare "gateway ... restart" catch-all would block
# legitimate prompts that merely mention an unrelated gateway (e.g. "summarize
# the API gateway logs and report restart events").
_GATEWAY_LIFECYCLE_PATTERNS = re.compile(
r"(?i)"
r"(hermes\s+gateway\s+(restart|stop|start))"
r"|(launchctl\s+(kickstart|unload|load|stop|restart)\s+.*hermes)"
r"|(systemctl\s+(restart|stop|start)\s+.*hermes)"
r"|(p?kill\s+.*hermes.*gateway)"
r"|(\bgateway.*restart)"
)
@@ -191,7 +193,7 @@ def cron_create(args):
combined = prompt
if script:
try:
script_text = Path(script).read_text()
script_text = Path(script).read_text(encoding="utf-8")
combined = f"{combined}\n{script_text}"
except (OSError, UnicodeDecodeError):
pass
+2 -2
View File
@@ -5424,7 +5424,7 @@ def _gateway_command_inner(args):
elif subcmd == "stop":
# Defense: refuse self-targeting gateway stop from inside the gateway.
# Prevents agent-initiated kill loops when combined with supervisor KeepAlive.
if os.getenv("HERMES_IN_GATEWAY") == "1":
if os.getenv("_HERMES_GATEWAY") == "1":
print_error(
"Refusing to stop the gateway from inside the gateway process.\n"
"This command was blocked to prevent restart loops.\n"
@@ -5509,7 +5509,7 @@ def _gateway_command_inner(args):
elif subcmd == "restart":
# Defense: refuse self-targeting gateway restart from inside the gateway.
# Prevents agent-initiated kill loops when combined with supervisor KeepAlive.
if os.getenv("HERMES_IN_GATEWAY") == "1":
if os.getenv("_HERMES_GATEWAY") == "1":
print_error(
"Refusing to restart the gateway from inside the gateway process.\n"
"This command was blocked to prevent restart loops.\n"