← Back to Explorer
Heartbeat
/heartbeat
A recurring ambient check that runs quietly, surfaces findings to a log or clip file, and exits silently when clean. A pattern — not a mechanism. Implementable via hook, cron job, or VS Code task.
Strata: L3, L4
Axes: Observability, Governance
Status: seed
Explainer
A heartbeat is the agentic equivalent of a health check endpoint or a smoke test in CI: it runs on a schedule (or triggered by a lifecycle event), checks some aspect of system state, and writes findings to a log. If everything is fine, it produces no noise. If something drifted, it clips a summary so the next human session starts with signal, not a blank slate.
The word "heartbeat" describes what the thing does, not how it fires. The same heartbeat behavior can be wired up three different ways:
| Mechanism | When it fires | Best for |
| Hook (Stop/SessionStart) | Every session end or open | Workspace audits, memory capture |
| Cron job | Fixed time interval (independent of sessions) | Daily briefs, weekly health scans |
| VS Code Task | IDE events (folder open, build trigger) | Pre-build lint, launch scripts |
The sentinel heartbeat in this workspace is a Stop hook: it fires when Claude Code stops, runs a level-1 naming-convention audit, and clips any violations to 00_Ledger/clips/YYYY-MM-DD.md. Silent when clean.
Design rules
- Silent success — a clean heartbeat produces zero output. Noise = friction = ignored.
- Clip, don't alert — violations append to a daily log file, not a blocking error. The human reads clips at their own pace.
- Fast — heartbeats should complete in under 5 seconds. Long-running checks belong in a scheduled cron, not a Stop hook.
- Idempotent — running twice should produce the same result. No side effects beyond appending to the log.
- Never block the lifecycle — use
async: true or append || true so a heartbeat failure never prevents a session from closing.
Anti-Patterns
- A heartbeat that outputs on every run whether clean or not — creates noise that gets ignored.
- A heartbeat that takes 30+ seconds — should be a cron, not a Stop hook.
- Using a heartbeat for decisions that require model reasoning — heartbeats run blind scripts, not LLMs.