Chapter 11

Cron, Webhooks, and Unattended Work

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.

Scheduled tasks

: time-based jobs

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.

TypeExampleWhen 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

Script-only jobs

: scripts without an LLM

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.

bashVerified
#!/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)."
fi

Delivery

Sending results where you already are

Delivery 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:

OptionBehavior
localSave to disk only — no message sent
originSend 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.

Chaining

: chaining jobs together

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.

Event triggers

Webhooks: triggering agents from external events

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.

Guardrails

What requires your approval — and what does not

When a job runs unattended, you might not be at your desk to approve a dangerous action. Design unattended jobs carefully:

Safe to automate

  • Reading files — no risk of data loss
  • Web searches — read-only, no side effects
  • Saving reports to local files — data creation, not deletion
  • Sending messages to configured channels — delivery is the intended behavior
  • Running no-agent scripts — deterministic, no model decisions

Needs approval gates in skills

  • Publishing content — the skill should say "do not publish without human approval"
  • Modifying shared files — the skill should restrict which files the agent can change
  • Running shell commands — the approval system catches these, but the skill should avoid requesting them when possible

Never automate

  • Deleting files or directories — irreversible, even with approvals
  • Sending payments or financial transactions — business logic, not agent territory
  • Merging code into protected branches — publishing is a human decision
  • Responding to customers on your behalf — brand and tone risks

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.

Setup

Setting up a scheduled job

Progress

0/8

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?

Takeaway

Unattended work is a specific category, not a general capability

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.