Skip to content

fix(cron): block gateway lifecycle commands on job update - #51980

Open
zhonghui5207 wants to merge 1 commit into
NousResearch:mainfrom
zhonghui5207:codex/block-cron-gateway-lifecycle-scripts
Open

fix(cron): block gateway lifecycle commands on job update#51980
zhonghui5207 wants to merge 1 commit into
NousResearch:mainfrom
zhonghui5207:codex/block-cron-gateway-lifecycle-scripts

Conversation

@zhonghui5207

@zhonghui5207 zhonghui5207 commented Jun 24, 2026

Copy link
Copy Markdown

Summary

  • close the remaining cronjob tool update-path bypass for gateway lifecycle commands
  • reuse the current shared cron.lifecycle_guard.check_gateway_lifecycle implementation
  • validate the effective stored-plus-updated prompt and script before persisting a partial update
  • preserve remediation: an update may replace or clear previously stored unsafe content
  • cover launchd and systemd scripts, lifecycle prompts, stored unsafe jobs, and script clearing

Root Cause

Current main already protects job creation in cron.jobs.create_job, but tools.cronjob_tools.cronjob(action="update") only validates a replacement script path before calling update_job(). It does not scan the script contents, and unrelated partial updates do not revalidate lifecycle content already stored on the job.

That leaves an update-only route for scheduling commands such as:

launchctl kickstart -k gui/501/ai.hermes.gateway
systemctl --user restart hermes-gateway.service

The fix merges the current update over the stored job for the two execution-content fields, then calls the existing shared lifecycle guard immediately before update_job().

Fixes #51976

Test Plan

python -m pytest \
  tests/hermes_cli/test_gateway_restart_loop.py \
  tests/tools/test_cronjob_tools.py \
  tests/cron/test_cron_script.py \
  tests/cron/test_cron_no_agent.py -q

Result on current main: 203 passed, 1 pre-existing deprecation warning.

@alt-glitch alt-glitch added type/bug Something isn't working comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery tool/terminal Terminal execution and process management sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-automation Sweeper risk: may affect CI, automerge, label sync, or maintainer automation P2 Medium — degraded but workaround exists labels Jun 24, 2026
@zhonghui5207
zhonghui5207 marked this pull request as ready for review June 25, 2026 11:21
@lkz-de

lkz-de commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Independent systemd reproduction (twice in one day) plus a suggested systemctl --user regression test over in #51976. This PR would have blocked our exact case — the agent created a no_agent cron job whose script ran systemctl --user restart hermes-gateway.service, which the shared lifecycle regex matches. +1 to landing it; the script-contents scan on the cronjob tool's create/update path is the missing defense.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for documenting both the launchd and systemd reproductions. Current main has already salvaged the create-path portion in b48cacb97: cron/jobs.py:1147-1153 invokes the shared cron.lifecycle_guard.check_gateway_lifecycle, and tests/hermes_cli/test_gateway_restart_loop.py:450-484 covers the model-tool create path.

Problems

  • The update bypass remains on current main: tools/cronjob_tools.py:897-903 validates only the replacement script path, then tools/cronjob_tools.py:959 persists it without a lifecycle-content check.
  • The submitted helper placement is stale. Current main's guard is cron/lifecycle_guard.py:112-141; adding gateway/lifecycle_guard.py would duplicate the established implementation and miss its current path-resolution and decoding behavior.

Suggested changes

  • Port only the update protection onto current cron.lifecycle_guard.check_gateway_lifecycle, checking the effective stored-plus-updated prompt/script before update_job().
  • Keep the launchctl/systemd regression cases, but place coverage with the current lifecycle-guard tests.

Automated hermes-sweeper review.

@teknium1 teknium1 added the sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform label Jul 15, 2026
@zhonghui5207
zhonghui5207 force-pushed the codex/block-cron-gateway-lifecycle-scripts branch from 49c759d to 9ea9128 Compare July 15, 2026 09:36
@zhonghui5207 zhonghui5207 changed the title [codex] Block cron gateway lifecycle scripts fix(cron): block gateway lifecycle commands on job update Jul 15, 2026
@zhonghui5207

Copy link
Copy Markdown
Author

Reworked this on current main per the sweeper review. I removed the stale duplicate helper/create/terminal changes and kept only the remaining update-path protection. The update flow now computes the effective stored-plus-updated prompt and script, passes both through cron.lifecycle_guard.check_gateway_lifecycle, and only then calls update_job(). Remediation by replacing or clearing unsafe content remains allowed. Regression coverage now lives with the lifecycle-guard tests and covers launchd, systemd, prompt updates, stored unsafe content on unrelated updates, and clearing an unsafe script. Focused result: 203 passed; full tests/cron: 693 passed. Commit: 9ea9128.

@alt-glitch alt-glitch added needs-decision Awaiting maintainer decision before any implementation and removed comp/gateway Gateway runner, session dispatch, delivery tool/terminal Terminal execution and process management sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data labels Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management needs-decision Awaiting maintainer decision before any implementation P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-automation Sweeper risk: may affect CI, automerge, label sync, or maintainer automation type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cron tool can schedule gateway lifecycle scripts that cause restart loops

4 participants