Scheduled
Cron-tagged memories hitting their trigger time.
weight: 10The heartbeat system runs 14 pure-SQL signal scans per tick — zero LLM tokens. Confluence scoring combines weak signals, adaptive cooldowns prevent spam, and quiet hours respect user rhythm.
The engine decides whether to act. The autonomy level decides how.
Each signal runs a SQL query against stored memories. No LLM call, no token cost. Signals are weighted by urgency tier for confluence scoring.
Cron-tagged memories hitting their trigger time.
weight: 10Memories with expires_at within the deadline window.
weight: 10Unresolved contradictions between stored memories.
weight: 5Interrupted sessions — mid-conversation resumption.
weight: 5Monitoring tasks overdue for check-in.
weight: 55+ new memories since last action — elevated context generation.
weight: 5Active plans and tasks (type=PLAN or ACTIVITY, state=ACTIVE).
weight: 3Plan progress detection vs recent activity.
weight: 3Unanswered questions stored in memory.
weight: 3Goal improvements, re-engagement, sentiment recovery.
weight: 3Important memories nearing decay threshold.
weight: 1Emotional trend analysis across recent memories.
weight: 1Silent entities nearing deadlines (days_silent > threshold).
weight: 1Day-of-week behavioral patterns.
weight: 1Decision flow
The heartbeat runs a 7-step decision pipeline to prevent spam, respect user rhythm, and ensure novelty. Each step can suppress or force action.
Less than 5 memories for this entity? Always act — the agent needs to establish presence and begin building context.
Deadline within 1 hour? Force immediate action, bypass quiet hours and all other filters. Time-sensitive signals cannot be suppressed.
Morning, working hours, evening, late night, quiet hours — each period has a minimum signal tier threshold. Low-urgency signals are suppressed outside working hours.
Active conversation detected (recent message within 15 minutes or plugin signal)? Only Elevated or higher signals pass through — unless memory velocity is high (5+ new memories since last action), which lowers the threshold to Normal.
Sum all signal weights. Action thresholds by autonomy level: act = 8, suggest = 12, observe = 20. Multiple weak signals combine to trigger action.
SHA256 hash of signal memory IDs. Same fingerprint within cooldown window? Suppress. If user ignores nudges (response rate < 10%), cooldown multiplies 10x.
Same topic entities surfaced recently? Suppress. Prevents the agent from repeating itself about the same deadline, task, or relationship.
Each autonomy level sets a confluence threshold and per-tier cooldown values. Higher autonomy means lower thresholds and shorter cooldowns.
Signals are collected but not delivered. The agent stays informed internally.
Use for monitoring without user-facing output. Confluence threshold: 20. Cooldowns — Normal: 4h, Elevated: 2h, Low: 8h.
threshold: 20Signals are surfaced as suggestions — the user decides whether to act.
Response-aware cooldowns prevent spam. Confluence threshold: 12. Cooldowns — Normal: 2h, Elevated: 30m, Low: 4h.
threshold: 12The agent executes automatically when policy allows.
Time-period awareness and graduated gates keep behavior in check. Confluence threshold: 8. Cooldowns — Normal: 10m, Elevated: 5m, Low: 30m.
threshold: 8The engine adjusts signal filtering based on time of day. Each period has a minimum urgency tier — signals below that tier are suppressed.
| Period | Hours | Min. tier | Behavior |
|---|---|---|---|
| Quiet hours | 23:00 - 07:00 | Immediate only | Only critical deadlines and scheduled items break through. Cooldown multiplier: 10x. |
| Late night | 21:00 - 23:00 | Elevated+ | Conflicts, continuity, and stale monitors can surface. Cooldown multiplier: 3x. |
| Morning | 07:00 - 10:00 | All signals | Proactive window — all tiers active. Cooldown multiplier: 0.5x (more responsive). |
| Working hours | 10:00 - 17:00 | All signals | Full signal processing, all tiers active. Cooldown multiplier: 1x. |
| Evening | 17:00 - 21:00 | Normal+ | Low-priority patterns and sentiment suppressed. Cooldown multiplier: 1.5x. |
The watcher does not run on a fixed cron. The interval between heartbeat checks is calculated by multiplying the base interval by four context-aware multipliers that stack together.
Adjusts check frequency based on time period.
Quiet hours: 10.0x, Late night: 3.0x, Evening: 1.5x, Working hours: 1.0x, Morning: 0.5x.
Backs off after the engine has already acted.
Acted < 5 min ago: 2.0x, Acted < 15 min ago: 1.5x, No recent action: 1.0x.
Checks more often when signals are present.
Zero signals: 3.0x (slow down), 1-3 signals: 1.0x, 4+ signals: 0.8x (speed up).
Speeds up when new memories are arriving quickly.
5+ new memories since last action: 0.7x (more frequent checks), Normal velocity: 1.0x.
Response rate
The engine tracks how often the user responds to heartbeat-initiated messages. If the response rate drops, cooldowns increase automatically.
// Response rate tracking
response_rate = heartbeat_responses / heartbeat_messages_sent
// Cooldown multiplier based on response rate
if (response_rate < 0.1) {
cooldown_multiplier = 10.0 // User is ignoring nudges
} else if (response_rate < 0.3) {
cooldown_multiplier = 3.0 // User is selective
} else {
cooldown_multiplier = 1.0 // User is engaged
}
// Effective cooldown
effective_cooldown = base_cooldown × cooldown_multiplier