Agent Self-Scheduling

SkillProductivity

How to make an AI coding agent run on a schedule, loop, or interval — cron jobs, heartbeats, self-starting/self-terminating loops, recurring autonomous checks. Use when the user asks to "run every N minutes/hours", "check something on a regular interval", "schedule a task", "run on a loop", "self-start", "heartbeat", "cron job for an agent", or wants an agent to fire periodically without manual launching. Covers two camps — one-shot agents you wrap in an external clock (Claude Code, Codex, Pi) vs agents with a built-in scheduler daemon (Hermes).

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Agent Self-Scheduling skill

What this skill tells your AI

The instructions your AI receives, as published by matyasstoch/david-skills in skills/autonomous-ai-agents/agent-self-scheduling/SKILL.md and read by ahel’s review.

Make an agent run periodically. First question: does the agent have a built-in scheduler, or do you own the clock?

Decision: pick the camp first

  • Need it NOW, agent has no scheduler, or sub-minute polling → Camp A (external clock).
  • Want managed recurring jobs, isolated sessions, chaining, loop safety → Camp B (Hermes built-in).

Universal floor: ALL cron is 1 minute (5-field expr, no seconds) — every camp. For sub-minute / sub-second you MUST use a dumb while ...; sleep N; done loop, a TS extension, or a webhook/event hook. Never put an LLM on a tight timer.


Camp A — One-shot agents, you own the clock

These run once and exit (amnesiac unless resumed). You schedule them externally.

One-shot invocations:

claude -p "PROMPT" --output-format json --allowedTools "Read,Edit,Bash"  # Claude Code
codex exec --json "PROMPT"                                                # Codex
pi run "PROMPT"                                                           # Pi.dev (Mario Zechner; MIT; read/write/edit/bash + TS SDK)

Wrap in a clock — three options:

# 1. cron (>= 1 min). Floor is 1 minute, 5 fields, NO seconds.
*/10 * * * * cd /path/to/project && pi run "check X and report" >> ~/agent.log 2>&1

# 2. systemd timer (Linux, survives reboot, better logging) — OnUnitActiveSec=10min

# 3. dumb loop (sub-minute, or when cron unavailable)
while true; do pi run "check X"; sleep 30; done

Camp A gotchas (all three break unattended runs if ignored):

  • Permissions block unattended runs. Pass --allowedTools (Claude) or a sandbox/auto-approve flag (Codex) or the run hangs on a prompt forever.
  • Use structured JSON output, not prose (--output-format json / --json) so the wrapper can parse the result deterministically.
  • Each run is amnesiac. No memory across runs unless you resume: codex exec resume --last. Otherwise persist state to a file the next run reads.

Pi specifics: Pi has NO built-in loop/scheduler/heartbeat by design — only the agent reasoning loop (not time-based). OpenClaw's runtime is built ON Pi but is a separate project. To schedule Pi: external cron/systemd, a while-sleep loop, or a TS extension for agent-side timers.

cmux (orchestration layer — NO scheduler)

cmux has NO scheduler/timer/watch/cron. It is visibility + orchestration only. Primitives: list-workspaces, read-screen (non-interruptive — safe to poll), send. An MCP wrapper cmux-agent-mcp exists.

Three ways to make cmux loop:

  • Orchestrator-driven — the orchestrator runs sendsleepread-screen on its own clock.
  • Dumb wrapper — external while true; ...; sleep N; done.
  • Event-driven (preferred over polling) — use cmux notify + OSC 9/99/777 terminal hooks so work fires on a real signal instead of a timer. Cheaper and more responsive than read-screen polling.

Camp B — Hermes (built-in scheduler daemon)

Hermes ships a gateway that ticks every 60s and runs due jobs in fresh, isolated sessions. No external cron needed.

State-check first — is the gateway running?

hermes gateway install            # user-level
hermes gateway install --system   # survives reboot (boot-time)

Create jobs (CLI or /cron add in TUI):

hermes cron create "every 1h" "summarize new emails and report" --skill himalaya
hermes cron create "0 9 * * *" "post daily standup"      # cron expr
hermes cron create "30m" "one-shot reminder in 30 min"   # one-shot delay

Schedule formats: one-shot delays (30m, 2h), recurring (every 30m, every 1d), cron (0 9 * * *), ISO timestamps.

Hermes-unique capabilities:

  • Zero-token / no-agent mode — run a script on schedule, deliver its stdout verbatim. No LLM cost. Use for watchdogs/heartbeats where the script produces the exact message.
  • Chainingcontext_from injects an upstream job's last output into a downstream job; combine with a working dir to pipeline jobs.
  • Self-terminating loops — a recurring job can stop itself when a condition is met.
  • Fresh self-contained sessions — each run starts clean; the prompt must carry all needed context (no chat history).
  • Loop safety — cron-run sessions CANNOT create more cron jobs (prevents runaway recursion). Don't try to schedule from inside a scheduled job.
  • Persistent /goal loop — long-running autonomous loop with pause/resume, separate from cron.

Heartbeat pattern (proactive self-check)

A heartbeat = a fast recurring tick that gates slower per-task checks, so one loop handles many intervals at different cadences.

  • In Camp B: a recurring Hermes job (e.g. every 5m) whose prompt/script checks a task list and only acts on tasks whose own interval is due. Use no-agent mode + a script for zero token cost when nothing's due.
  • In Camp A: same idea via a while-sleep loop that reads a tasks file and per-task last_run timestamps.
  • Save tokens: define active-hours and skip ticks outside them; skip the tick entirely when there's nothing due (stay silent — don't emit empty noise).

Verify it actually fires (do this before reporting success)

  1. Camp A: check the log file grows after one interval, or run the wrapped command once by hand and confirm clean JSON exit (0).
  2. Camp B: hermes cron list shows the job; check next_run; trigger once with a run-now to confirm it executes and delivers.
  3. Confirm permissions/sandbox flags are present (Camp A) — the #1 silent failure is a hung permission prompt.
  4. For heartbeats, confirm a tick with nothing-due stays silent (no spam).

Pitfalls

  • Cron CANNOT do sub-minute. Don't promise every 30s via crontab — use a loop.
  • Camp A unattended hangs without explicit tool allowlists / sandbox.
  • Don't schedule a job from inside a scheduled Hermes job (loop safety blocks it).
  • Each scheduled run is a fresh/amnesiac session — pass all context in the prompt or persist to a file.

Signals

GitHub stars
59
Forks
11
Last commit
Jun 2026
Advanced
Catalog kind
skill
Gateway key
agent-self-scheduling-matyasstoch
Source
github.com/matyasstoch/david-skills