The Heartbeat Protocol
The 7-step autonomous loop — self-heal, propose, plan, advance, automate, reflect, remember.
What Is a Heartbeat?
A heartbeat is a scheduled, self-directed execution cycle. Unlike a cron job that runs a fixed script, a heartbeat triggers a reasoning loop that decides what to do based on current state.
OpenClaw’s approach (verified from source): The agent reads HEARTBEAT.md — a simple checklist file in the workspace. The prompt is: “Read HEARTBEAT.md if it exists. Follow it strictly. If nothing needs attention, reply HEARTBEAT_OK.” Default interval: 30 minutes. The model decides autonomously what to do based on the checklist.
Flowwink’s evolution: FlowPilot replaces the freeform checklist with a structured 7-step protocol, backed by a PostgreSQL objective/plan system. The heartbeat is no longer just a checklist — it’s an autonomous operating cycle with self-healing, proactive planning, execution, and reflection.
Traditional Cron: Schedule → Script → Result
Agent Heartbeat: Schedule → Reason → Decide → Act → Learn → Repeat
The agent wakes up, looks at the current state of the business, decides what needs attention, and acts. Then it reflects on what happened and saves what it learned.
Heartbeat in Action — A Day with FlowPilot
To make this concrete, here’s what an actual heartbeat cycle looks like for a mid-size B2B company:
00:00 — FlowPilot wakes up
The flowpilot-heartbeat edge function fires. The agent loads context in parallel:
Context loaded:
├── Soul: "Growth-focused B2B marketing agent"
├── Memories: 30 most recent (including: "Blog posts with data viz get 3x engagement")
├── Objectives: 3 active (1 in-progress, 2 pending)
├── Site stats (7d): 2,140 page views, 12 new leads, 3 bookings
├── Recent activity: Newsletter sent 2 days ago (34% open rate)
├── Automations: 4 enabled (2 due now)
└── Self-heal report: 0 skills quarantined
Step 1: Self-Heal
No failing skills. Clean bill of health.
Step 2: Propose
The agent analyzes the stats:
- Blog output dropped to 1 post this month (target: 4)
- Lead conversion rate is 3.2% (down from 4.1% last month)
- Newsletter engagement is strong (34% open rate)
New objective created: “Publish 2 more blog posts this month”
Step 3: Plan
The agent decomposes the new objective into steps:
Objective: "Publish 2 more blog posts this month"
├── Step 1: research_content (topic: "AI trends in B2B marketing")
├── Step 2: write_blog_post (draft)
├── Step 3: seo_audit_page (optimize)
└── Step 4: publish_scheduled_content (schedule for Thursday)
Step 4: Advance
The agent executes the first step: research_content. It searches the web for trending topics, analyzes competitor content, and saves a content brief. The plan is now 25% complete — it will pick up at Step 2 in the next heartbeat.
Step 5: Automate
Two automations are due:
- Daily lead qualification: Scans the 2 new leads from today, scores them, generates qualification summaries. Lead #1 scores 78 (high — suggests creating a deal). Lead #2 scores 34 (low — personal email, no company domain).
- Weekly analytics digest: Compiles 7-day stats into a summary for the admin.
Step 6: Reflect
The agent looks at its last 7 days:
- 14 actions executed, 12 succeeded, 2 failed (both were API timeouts on web search)
- Blog posts published last week got 450 views — above average
- Lead qualification accuracy: “Scores > 70 had 60% conversion rate”
Learning persisted: “API timeouts on web search are common between 02:00-04:00 UTC. Avoid scheduling research-heavy tasks during this window.”
Step 7: Remember
Three new memories saved:
fact:blog_performance: “Posts with data visualizations get 3x engagement”context:scheduling: “Avoid web search between 02:00-04:00 UTC”preference:lead_threshold: “Score > 70 = suggest deal creation”
00:47 — Heartbeat complete
HEARTBEAT REPORT (fp_m2x7k9_abc123):
- Self-heal: 0 skills quarantined
- Proposed: 1 new objective ("Publish 2 more blog posts")
- Planned: 1 objective decomposed (4 steps)
- Advanced: 1 step executed (research_content — content brief saved)
- Automated: 2 automations executed (daily lead qual, weekly digest)
- Reflected: 7-day performance analyzed, 1 learning persisted
- Remembered: 3 new memories saved
- Duration: 45s | Tokens: 12,400 | Status: HEARTBEAT_OK
The admin sees this in the Activity Feed the next morning, and the report itself feeds into the next heartbeat’s context. No action needed — FlowPilot handled it.
You’ve now seen each step do its job. Here’s the implementation payload behind them.
Step 1: Self-Heal
runSelfHealing(supabase)
│
├── Query agent_activity for recent failures per skill
├── Skills with 3+ consecutive failures → quarantine (disable)
├── Disable linked automations
└── Return healing report
Step 2: Propose
The gap heuristics that trigger a new objective:
Input: Site stats (7 days), recent activity, current objectives
│
├── Low blog output? → propose_objective("Increase blog output")
├── Lead conversion dropping? → propose_objective("Improve lead qualification")
├── New competitor detected? → propose_objective("Competitive analysis")
└── No action in 3+ days? → propose_objective("Re-engage audience")
Step 3: Plan
decompose_objective() breaks an objective into executable steps, stored in the objective’s progress.plan JSON. Steps persist between heartbeats — the agent picks up where it left off.
Step 4: Advance
advance_plan(objective_id, chain=true)
│
├── Load current plan state
├── Find next pending step
├── Execute via agent-execute (one skill per heartbeat)
├── Update step status (done/pending/failed)
└── Multi-step plans advance across successive heartbeats
Priority scoring determines which objectives get advanced first:
| Factor | Score |
|---|---|
| Overdue deadline | +50 |
| Deadline < 1 day | +40 |
| Priority: critical | +35 |
| In-progress plan (>0%, <100%) | +15 |
| Near completion (>70%) | +10 |
Step 5: Automate
automation-dispatcher
│
├── Query agent_automations WHERE next_run_at <= now
├── For each DUE automation:
│ ├── Execute linked skill with stored parameters
│ ├── Update last_run_at, compute next_run_at
│ └── Log result to agent_activity
└── Signal dispatcher: evaluate conditions on recent signals
Automations can be triggered by:
- Cron: Fixed schedule (daily, weekly, hourly)
- Event: Database trigger (new lead, form submission)
- Signal: Condition evaluation (lead score ≥ 50)
- External: Webhook ingestion
Step 6: Reflect
reflect()
│
├── Query agent_activity for last 7 days
├── Analyze: successful actions, failures, patterns
├── Identify: what worked, what didn't, what to try
├── Auto-persist top learnings to agent_memory
└── Return reflection summary
Step 7: Remember
memory_write({
key: "lesson:blog_engagement_2026-04",
category: "fact",
content: "Posts with data visualizations get 3x more engagement
than text-only posts. Prioritize stats blocks.",
importance: 0.8
})
Everything these steps consume — soul, memories, objectives, stats, automations, the self-heal report — arrives through the parallel context load you saw at 00:00, injected via the 6-layer prompt compiler (chapter 19 owns the compiler).
Scheduling
The heartbeat frequency is admin-configurable:
| Job | Default Schedule | Configurable |
|---|---|---|
flowpilot-heartbeat | Hourly | Frequency + hours + timezone |
flowpilot-followthrough | Every 5 minutes | Fixed (engine plumbing) |
flowpilot-daily-briefing | 07:00 local | Hour + timezone |
flowpilot-learn | 03:00 local | Hour + timezone |
automation-dispatcher | Every minute | Fixed |
publish-scheduled-pages | Every minute | Fixed |
Why a cadence dial, not a fixed pulse? The reasoning cycle is the expensive part, and in July 2026 production put a number on it: an hourly heartbeat on the full reasoning tier burns roughly three million prompt tokens a day — $6–7 per instance. That measurement turned the cadence into an owner decision with two dials: how often the heartbeat fires (default is now every three hours) and which model tier it wakes up with (fast, about five times cheaper, or reasoning, the full brain). Three named configurations cover the range — economy (three-hourly × fast, ~$1–2/day), proof (three-hourly × reasoning — what the production proof week runs), and peak observation (hourly × reasoning, for short intensive audits). What must never wait on the dial is completing what a human already approved: that is the follow-through sweep’s job, and it runs every five minutes as a deterministic pass — no reasoning, no tokens, just finishing the chain. (FlowPilot 2.0 also runs the same follow-through as a pre-pass at the start of every heartbeat, so the operator sees the completed results in its own context.)
Safety Guards
The heartbeat has multiple safety mechanisms:
| Guard | Threshold | Behavior |
|---|---|---|
| Wall-clock timeout | 120s | Hard abort |
| Anti-runaway | 2+ consecutive tool errors | Session abort |
| Token budget | 80k tokens | Stop reasoning |
| Iteration cap | 8 tool rounds | Stop after N rounds |
| Pre-budget flush | 80% budget used | Extract facts, focus on completion |
These prevent the heartbeat from:
- Running forever (timeout)
- Cascading failures (anti-runaway)
- Burning through API credits (token budget)
- Getting stuck in loops (iteration cap)
The Continuation Nudge
There’s a fifth failure mode not covered by the table above: the agent stalls mid-task — it generates neither a tool call nor a final answer. This happens when the model produces a reasoning block without a conclusion, effectively going silent.
FlowPilot detects this and injects a continuation nudge — a system message inserted into the conversation that prompts the agent to either act or conclude:
System: "It looks like you paused mid-task. Please either:
1. Call the next appropriate tool to continue, or
2. Provide a summary of what you've accomplished and any blockers.
Do not leave the task incomplete without explanation."
The nudge fires after detecting N consecutive turns with no tool call and no HEARTBEAT_OK signal. Maximum 2 nudges per session — if the agent still doesn’t respond meaningfully, the session aborts and logs a stall event.
Without the nudge, stalls are invisible: the heartbeat appears to have run, token costs are incurred, but nothing actually happened.
Autonomous vs Automations — Two Different Things
A common source of confusion: autonomous operation and automations are not the same.
| Autonomous (Heartbeat) | Automations | |
|---|---|---|
| Who decides? | The agent reasons about what to do | A predefined rule triggers execution |
| What runs? | The full ReAct loop (reason → plan → act) | A specific skill with stored parameters |
| When? | On schedule (cron, owner-set cadence) | When due (cron, event, signal) |
| Example | ”I notice leads are dropping — let me research and write a blog post" | "Every day at 09:00, qualify new leads” |
| Thinking | Full LLM reasoning | None — deterministic execution |
Autonomous = the agent thinks. It looks at the current state, decides what needs attention, creates plans, and executes them. This is the heartbeat’s Steps 2-4 (Propose, Plan, Advance).
Automations = the agent executes. Predefined rules that say “run skill X with parameters Y when condition Z is met.” No reasoning, no planning — just execution. This is Step 5 (Automate).
How they work together:
- The autonomous cycle identifies patterns: “We should be publishing more blog posts”
- It creates an automation: “Every Monday, research trending topics”
- The automation runs on schedule, but the agent reviews results and adjusts
The agent can also create, modify, and disable automations. This is part of its self-evolution capability (Law 4).
The heartbeat is the agent’s metabolism. Just as a heartbeat sustains life by circulating blood, the agent’s heartbeat sustains autonomous operation by cycling through healing, planning, executing, and learning.
Next: when multiple heartbeats run simultaneously — how to prevent agents from colliding and how to see inside them when things go wrong. Concurrency & Observability →