Sophon Docs
Features

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:

KeyDefaultMeaning
Sophon:Heartbeat:EnabledtrueMaster switch — when false, no scheduled heartbeats run anywhere
Sophon:Heartbeat:IntervalMinutes30Default cadence for agents that don't set their own

Per-agent settings live in the agent's heartbeat config:

SettingDefaultMeaning
heartbeat.enabledfalseTurn the schedule on for this agent
heartbeat.intervalMinuteshost defaultCadence in minutes; leave unset to inherit the host default
heartbeat.activeFromLocalTime / activeToLocalTimeunsetDaily active window in HH:mm. Overnight ranges (22:0006:00) are supported. Outside the window, the next run defers to the window start

An agent with enabled: true, intervalMinutes: 15, and a 07:0022: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 (default true) — every tick gets a fresh session. Cheap, predictable, no state carried between runs. Set to false to 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 (default false) — 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 (default true) — when the run reports HEARTBEAT_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 (default false) — 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 (default false) — 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.send as the alert paths that always reach you, and
  • a push notification in the heartbeat category — 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 trigger

POST .../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