Some work does not need you in the loop every time. A weekly keyword scan. A watchdog that checks your site every 15 minutes. A webhook that fires when a pull request lands. These tasks run on a schedule or in response to an event — whether or not you are at your desk.
Automate the gathering, not the judgment. Cron and no-agent mode handle data collection and reporting. Decisions — what to publish, what to change, what to pursue — stay with you.
The cron scheduler is one of the continuous services from Chapter 5. When a job is due, it runs, saves output, and optionally delivers results. Jobs live in ~/.hermes/cron/jobs.json with atomic writes. Hermes understands natural-language scheduling — tell your agent what you want and it translates.
| Type | Example | When to use |
|---|---|---|
| Duration | "30m" | One-shot reminders, deferred tasks |
| Interval | "every 2h" | Periodic checks, recurring reports |
| Cron expression | "0 9 * * 1" | Any standard cron schedule |
| Timestamp | "2026-06-15T10:00" | Calendar launches, deadline reminders |
Set no_agent to true and the scheduler skips the entire agent loop — no model call, no token cost. The script runs, its stdout is delivered. Empty output means silent (nothing to report). Non-zero exit means error (alert delivered). If no_agent is true but no script is set, Hermes rejects the job at creation time.
#!/usr/bin/env bash
# ~/.hermes/scripts/site-watchdog.sh
# Healthy → no output (silent). Down → alert delivered.
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
https://your-website.com)
if [ "$STATUS" != "200" ]; then
echo "⚠️ Site alert: your-website.com returned \
HTTP $STATUS (expected 200)."
fiDelivery uses the same gateway infrastructure from Chapter 5. When a cron job finishes, the scheduler can send the result to any configured platform. The deliver setting controls where:
| Option | Behavior |
|---|---|
| local | Save to disk only — no message sent |
| origin | Send to the channel where the job was created |
| "slack", "telegram", … | Send to a named platform (with optional chat/thread target) |
| "slack,telegram" | Multiple targets, comma-separated (or "all" for every configured platform) |
If the agent decides there is nothing worth reporting, it responds with [SILENT] — the scheduler skips delivery and saves output locally for audit. You only get messages when there is something to act on.
The context_from setting loads the most recent output of a referenced job into the current job's prompt before the agent starts. The agent sees the prior results as context — no manual handoff, no file coordination. Each job runs on its own schedule; leave enough buffer between chained jobs so the upstream job finishes first.
Your Monday pipeline: 9 AM research (cron) → 10 AM SERP analysis (context_from) → 11 AM content brief → your review. By noon you have a brief in Slack. The unattended part gathered the data; your judgment handles the decision to proceed.
Cron handles time-based schedules. Webhooks handle the events that happen when they happen — a GitHub pull request, a Stripe payment, a form submission. The webhook platform runs an HTTP server that receives POST requests, validates them, transforms the payload into an agent prompt using a template, and runs the agent with configured skills and delivery settings.
Each webhook route defines which events to accept (filtered by request headers), a prompt template that formats the incoming JSON into a readable prompt, optional skills to load for the agent, and where to send the response. A deliver_only option skips the agent entirely — the rendered template is delivered directly, useful for push notifications where speed matters more than interpretation. Every route requires an HMAC secret for signature validation — requests without a valid signature are rejected before the payload is processed.
When a job runs unattended, you might not be at your desk to approve a dangerous action. Design unattended jobs carefully:
For unattended work, add a fourth guardrail: restrict the toolsets available to the cron job via enabled_toolsets. A keyword scan only needs web search and file writing — disable everything else. The agent cannot call a dangerous tool because the tool is not in its schema. This is safer than relying on the approval system when you are not around to respond.
You set up a weekly keyword scan that runs every Monday at 9 AM and delivers results to Slack. The scan runs successfully for three weeks. On the fourth week, you get no message. What are the three most likely causes, and how would you diagnose each?
On-demand sessions — CLI, messaging, API — are human-in-the-loop. Unattended work is a separate category with specific mechanisms: cron for scheduling, no-agent mode for watchdogs, webhooks for events, delivery for results. Each has its own safeguards — restricted toolsets, the approval system, skill-encoded judgment gates, and the silent marker for noise reduction.
The boundary between what to automate and what to keep manual is the most important design choice you make when setting up unattended work. Cron handles the routine. You handle the judgment. That division is what makes unattended work safe and useful.