Skip to content

Server-side cron jobs should not depend on dashboard clients or gateway ticker #25737

@AKC777

Description

@AKC777

Problem

Hermes can be deployed as a server-side dashboard while the human user connects from a separate client machine through a browser. In that setup, scheduled cron jobs can be created from the dashboard chat, but they may not execute unless a separate gateway/ticker process is running.

This is surprising for a server deployment: once a cron job is created on the server, it should continue to execute on the server regardless of whether the browser tab remains connected, the client laptop sleeps, or the gateway is configured.

Observed behavior

In a server deployment:

  1. User opens the dashboard from a client machine, e.g. https://server.example/chat.
  2. User asks the agent to create a one-shot cron job for unattended work.
  3. The job is persisted in ~/.hermes/cron/jobs.json with state: scheduled, enabled: true, and a valid next_run_at.
  4. The client machine sleeps / disconnects / closes the browser.
  5. If no hermes gateway process is running, the job remains scheduled and never fires.

The dashboard service can be active, yet hermes cron status reports that the gateway is not running and cron jobs will not fire automatically.

Expected behavior

For server deployments, cron execution should be owned by a durable server-side runner, not by a browser client or by an optional messaging gateway.

Expected properties:

  • A cron job created through dashboard chat should execute even if the browser disconnects immediately after creation.
  • Cron execution should not require a messaging gateway unless live adapter delivery is specifically needed.
  • The dashboard should either run a durable scheduler itself or install/manage a scheduler service/timer as part of server setup.
  • If no scheduler is active, job creation should warn loudly and should not imply that unattended execution is guaranteed.
  • hermes cron status should distinguish:
    • gateway ticker active;
    • standalone/systemd cron ticker active;
    • no ticker active.

Suggested solution

Add a first-class server-side cron runner mode, for example one of:

  1. A built-in hermes cron daemon process managed by systemd.
  2. A systemd timer installed by Hermes that runs hermes cron tick every minute.
  3. Dashboard service starts and owns the cron ticker when running in server mode.

The runner should be independent of dashboard WebSocket clients.

A possible systemd design:

# hermes-cron-tick.service
[Service]
Type=oneshot
User=hermes
WorkingDirectory=/home/hermes/.hermes/hermes-agent
Environment=HOME=/home/hermes
Environment=HERMES_HOME=/home/hermes/.hermes
ExecStart=/home/hermes/.hermes/hermes-agent/venv/bin/hermes cron tick
# hermes-cron-tick.timer
[Timer]
OnBootSec=1min
OnUnitActiveSec=60s
AccuracySec=10s
Persistent=true
Unit=hermes-cron-tick.service

Acceptance criteria

  • A server-side Hermes installation can enable cron execution that survives browser disconnects and client sleep.
  • Dashboard-created cron jobs fire without requiring a connected browser tab.
  • Cron jobs fire without requiring hermes gateway, unless adapter-specific delivery requires it.
  • hermes cron status reports all available scheduler backends, not only the gateway.
  • If no scheduler backend is active, creating a cron job through chat/dashboard warns that it will not run automatically.
  • Documentation explains the difference between dashboard, gateway, and cron runner in server deployments.

Why this matters

Unattended tasks are a core server-side use case. If a user schedules overnight work from a dashboard running on a server, the job should not depend on a laptop remaining awake or on an unrelated gateway process being active.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havecomp/cronCron scheduler and job managementcomp/gatewayGateway runner, session dispatch, deliverytype/featureNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions