mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-25 17:18:11 +00:00
Running any state-writing `hermes cron` CLI command as root (the default for `docker exec`) rewrote jobs.json via mkstemp + atomic_replace, leaving it root:root mode 600. The gateway's ticker (uid 1000 via PUID/PGID) was then locked out of every tick with PermissionError — silently: the liveness heartbeat stayed fresh, `hermes cron status` opened with 'Gateway is running — cron jobs will fire automatically', and in the field ~14h of scheduled jobs were skipped before a human noticed the absence of messages. Fixes, per the issue's suggested items 1 and 3: 1. Ownership preservation on save (cron/jobs.py): snapshot the owner before the atomic replace; when the writer is privileged (euid 0) and the previous owner differs, chown the rewritten file back. First-time creation inherits the cron dir's owner. Unprivileged writers never call chown. POSIX-only (guarded via os.name/getattr), best-effort — a chown failure logs a warning but never breaks the save. 0600 hardening is unchanged. 2. Zombie-ticker surfacing: the ticker loop (both single-profile and multiplex paths) now persists the failure reason to a ticker_last_error marker next to the heartbeat files on every failed tick, and clears it on the next clean tick. `hermes cron status` shows the recorded reason in its 'ticks may be failing' branch, plus an actionable ownership hint when the error is a PermissionError (recommend `docker exec -u <uid>:<gid>`). Fixes #68483 |
||
|---|---|---|
| .. | ||
| scripts | ||
| __init__.py | ||
| blueprint_catalog.py | ||
| executions.py | ||
| jobs.py | ||
| lifecycle_guard.py | ||
| scheduler.py | ||
| scheduler_provider.py | ||
| suggestion_catalog.py | ||
| suggestions.py | ||