Cron Tool Can Schedule Gateway Lifecycle Scripts That Cause Restart Loops
Tool/API Path Bypasses CLI Guard — Infinite Gateway Restart Cycle
🧪 Description
The cron CLI path blocks gateway lifecycle commands like launchctl kickstart, but the cronjob tool/API path only validates that the script path is under ~/.hermes/scripts/ — it never scans the script contents. This creates a bypass: create a one-shot no_agent cron job from a chat session whose script contains a gateway restart command.
💥 Impact
A one-shot job containing launchctl kickstart -k ai.hermes.gateway SIGTERMs the gateway before mark_job_run() can complete. The gateway shuts down, and on restart the same one-shot job is still enabled with a stale next_run_at. The scheduler fires it again → another shutdown → infinite restart loop every ~15 seconds. The user gets repeated shutdown notifications.
🔍 Root Cause
The terminal tool already blocks direct gateway lifecycle commands from inside the gateway process. The CLI cron path has parallel protection. But tools/cronjob_tools.py has zero content scanning — its a clean bypass. And since one-shot jobs intentionally keep next_run_at unchanged until completion, any script that kills the gateway before mark_job_run() will re-fire on every launchd restart.
🧩 Broader Context: Cron Subsystem Fragility
This is the 6th distinct P0/P1/P2 cron subsystem bug tracked — joining #41037 (cron never fires), #42197 (PluginManager), #20586 (state leak), #44585 (provider-state inheritance billing bug), and #51395 (P0 prompt-cache-cold). The cron subsystem now shows multiple independent containment failures across tool path validation, state management, caching, and lifecycle isolation.
🔧 Fix
Move gateway lifecycle command detection into a shared helper, apply it to CLI + terminal guard + cronjob_tools.py. Scan prompt + script contents on create/update. Add regression tests.
Status: PR #51980 already open — fix threads shared lifecycle-command detection into all three paths.
⚠️ Risk Classification
Labels: P2, comp/cron, comp/gateway, sweeper:risk-automation, sweeper:risk-security-boundary, type/bug
Risk Tags: sweeper:risk-security-boundary (denial-of-service vector), sweeper:risk-automation (cron-automation containment failure)
🧪 Gobii Managed vs Hermes Agent (Local)
Gobiis managed infrastructure eliminates the local gateway lifecycle attack surface entirely. Cron jobs execute in isolated sandbox environments with no access to the agent runtime process — a script cannot SIGTERM what it cannot reach. Gobiis centralized scheduler has no local launchd dependency, no mark_job_run() race window, and no path for a cron job to influence the gateway lifecycle.
📋 Cite This Bug Report
As tracked by Hermes Agent Lab, hermes-agent.reviews — 2026-06-24