Heartbeat: Proactive AutonomyNEW
Give an agent a standing checklist it works through on a schedule — with noise suppression, approval ceilings, and notifications only when something actually happened.
Cron fires a fixed prompt at a fixed time. Heartbeat is the other kind of autonomy: the agent wakes up on an interval, works through a standing checklist, and reports back only if it actually did something. Nothing in the inbox, no failing builds, nobody waiting on a reply? The agent says so quietly, the session is archived, and you never see it. Something real happened? You get a badge and a push notification.
That noise suppression is the whole point. A cron job that runs "check my inbox" every 30 minutes produces 48 sessions a day, 46 of which say "nothing new." A heartbeat produces only the two that matter.
The HEARTBEAT.md checklist
Each agent has its own HEARTBEAT.md — a plain Markdown checklist the agent reads on every run. The contract is simple: work through the list, and if nothing needs doing, reply with exactly HEARTBEAT_OK. That reply is what triggers noop detection and keeps quiet runs out of your way.
A typical checklist mixes every-run items with less frequent ones:
# Heartbeat checklist
## Every run
- Check the inbox for unread messages flagged urgent. Summarize and notify me if any.
- Check CI status on the main branch. If a build is red, investigate and notify me.
## Once per day (mornings)
- Review today's calendar. If a meeting lacks an agenda, draft one and notify me.
## Rules
- If none of the above produced action, reply HEARTBEAT_OK.
- Never send external email without approval.Edit the checklist from the agent's detail page in the Dashboard (the Heartbeat panel has a built-in editor) or via the REST API.
Scheduling
Two host-level keys control heartbeats globally:
| Key | Default | Meaning |
|---|---|---|
Sophon:Heartbeat:Enabled | true | Master switch — when false, no scheduled heartbeats run anywhere |
Sophon:Heartbeat:IntervalMinutes | 30 | Default cadence for agents that don't set their own |
Per-agent settings live in the agent's heartbeat config:
| Setting | Default | Meaning |
|---|---|---|
heartbeat.enabled | false | Turn the schedule on for this agent |
heartbeat.intervalMinutes | host default | Cadence in minutes; leave unset to inherit the host default |
heartbeat.activeFromLocalTime / activeToLocalTime | unset | Daily active window in HH:mm. Overnight ranges (22:00 → 06:00) are supported. Outside the window, the next run defers to the window start |
An agent with enabled: true, intervalMinutes: 15, and a 07:00–22:00 window runs every 15 minutes during the day and stays silent overnight — the first morning run fires at 07:00.
Sessions and context
Each run needs a session to think in. You control how heavy that is:
useIsolatedSession(defaulttrue) — every tick gets a fresh session. Cheap, predictable, no state carried between runs. Set tofalseto reuse one persistent "Heartbeat" session, which gives the agent memory of previous runs (useful for "remind me again if it's still broken" logic) at the cost of a growing context.useLightContext(defaultfalse) — skip memory expansion and most history when assembling the run's context. Much cheaper per tick. Use it when the checklist is self-contained and doesn't need long-term memory.suppressNoop(defaulttrue) — when the run reportsHEARTBEAT_OK, the session is archived immediately. Noop runs never clutter your session list. Turn it off only if you want to audit every tick.
Approval safety
Auto-approval has a hard ceiling. With autoApprove: true, the heartbeat session can self-approve tool calls up to Medium risk only. High and Critical actions — shell commands, destructive operations — always page you, and if the approval times out unanswered, the action is rejected. Know what the ceiling does not cover: messaging tools such as message.send are Medium risk, so an auto-approving heartbeat can send messages — including email — on your behalf. If you want email held for human approval, say so explicitly in the agent's HEARTBEAT.md rules, as in the example checklist above.
autoApprove(defaultfalse) — when off, a heartbeat run gates exactly like an attended session: High and Critical actions raise an approval request, and because nobody is watching an unattended run, that request usually times out and is rejected. Turn it on for checklists that are supposed to act (archive email, write calendar events, update memory): the session then self-approves anything that asks for approval at Medium risk or below — such as plan approvals when planning is enabled — while High and Critical still page you and reject on timeout. See Approval Gates & Risk Levels for what falls where.allowPlanning(defaultfalse) — heartbeat runs skip the planning step by default, because a generated plan would sit waiting for plan approval that nobody is around to give. Re-enable it only if you also run attended, or your plans never hit Medium+ steps.
Heartbeat runs execute under a synthetic identity on a dedicated heartbeat channel, isolated from your own conversations.
Notifications and tracking
When a run takes action (anything other than HEARTBEAT_OK), notifyOnAction (default true) emits:
- a session badge so the actioned session is easy to find — best-effort, because heartbeat runs execute under a synthetic identity rather than your account, so the badge may not reach every device on every deployment; treat push and
message.sendas the alert paths that always reach you, and - a push notification in the
heartbeatcategory — it respects per-device preferences and quiet hours like any other category, and deep-links straight into the heartbeat session. See Push Notifications.
Every run — scheduled or manual, actioned or noop — lands in the task ledger with origin heartbeat, its status, a session reference, and any error message.
Failures back off: consecutive failed runs stretch the interval exponentially, up to a 6-hour cap, and the backoff resets on the first success. The Dashboard heartbeat panel shows last run, next run, consecutive failures, backoff status, and the last error, so a silently broken checklist is visible at a glance.
Run it now & API
Use the Run now button on the Dashboard heartbeat panel to test a checklist before enabling the schedule — it ignores the enabled flag, active window, and due time.
The same surface is available over REST:
GET /api/agents/{id}/heartbeat # checklist + config + run state
PUT /api/agents/{id}/heartbeat # replace HEARTBEAT.md content
PUT /api/agents/{id}/heartbeat/config # replace heartbeat config
POST /api/agents/{id}/heartbeat/run # manual run-now triggerPOST .../run returns 202 Accepted when the run starts, 409 Conflict if a run is already in flight, 400 Bad Request if the agent has no HEARTBEAT.md, and 404 Not Found for an unknown agent.
Use cases
- Morning inbox triage — summarize what arrived overnight, flag anything urgent.
- Meeting prep — 30 minutes before each meeting, pull the agenda and related docs.
- Repo / CI watchdog — notify on red builds or stale PRs, stay silent on green.
- Follow-up nudges — surface conversations where someone is waiting on your reply.
- Daily standup digest — collect yesterday's completed tasks into a short summary.
- End-of-day shutdown ritual — file loose notes, draft tomorrow's top-three list.
Where to go next
- Cron & Scheduled Jobs — fixed prompts at fixed times, and when to prefer them
- Tasks — where every heartbeat run is tracked
- Approval Gates & Risk Levels — the risk model behind the auto-approve ceiling
- Push Notifications — configuring the
heartbeatcategory