# HEARTBEAT.md — Background agent checklist
# The background agent (macOS LaunchAgent for this app) sends you a heartbeat on a schedule and expects you to read this file.
# Keep it short and specific. Use plain English.

## Tasks (auto-parsed)
# The YAML block below is parsed by the runner. Each `name` runs on its own `interval`
# (e.g. `30m`, `2h`, `24h`). The runner only sends you the prompts for tasks that are due;
# other tasks stay silent. Delete the block (or set the interval to `7d`) to fully disable.

```yaml
tasks:
  - name: inbox-triage
    interval: 30m
    prompt: "Check list_inbox for urgent or time-sensitive unread messages. Flag anything from important contacts. Reply HEARTBEAT_OK if nothing urgent."
  - name: calendar-scan
    interval: 2h
    prompt: "Check get_upcoming_calendar_events for events in the next 4 hours that need prep or follow-up. Reply HEARTBEAT_OK if nothing needs attention."
  - name: memory-maintenance
    interval: 24h
    prompt: "Distill the last 2 daily summaries in memory/summaries into long-term memory if not done recently: use append_to_memory (sharded workspaces write memory/shards/general.md by default; hub MEMORY.md holds the index). Reply HEARTBEAT_OK if memory is already fresh."
```

## Checks to perform:
- Calendar: notify if event within next 2 hours
- Reminders: check for overdue or due-today reminders; mention any that need attention
- Email: use **list_inbox** to check for unread messages; flag unread from important contacts (add names in USER.md or here)
- Memory: every Sunday, summarize last 7 daily files into long-term memory (append_to_memory / hub + memory/shards/ when sharded)
- Git: remind about uncommitted changes older than 48 h in ~/Projects
- Weather: morning summary if outdoor event today

## Notification rules:
- **Urgent** (meeting <30 min, critical email, backup overdue) → send macOS notification + queue for chat
- **Medium** (git reminder, weather summary) → queue for chat only
- **Low** → log only, no notification or queue

In your heartbeat reply: if the action is urgent according to the rules above, prefix your reply with "URGENT:".

## Rules:
- Only notify user if action is urgent or time-sensitive
- Never open browser windows or send external messages
- Reply "HEARTBEAT_OK" if nothing needs attention

## Growth Loop Checks (weekly rotation):
- Pattern scan: review last 7 daily summaries for repeated requests (3+). Log to memory/recurring-patterns.md.
- Outcome follow-up: check decisions older than 7 days in recent summaries. Nudge if no resolution.
- Memory maintenance: distill recent daily files into long-term memory (append_to_memory; shards under memory/shards/ when active) if not done in last 3 days.

## Drives:
- Check active drives via list_drives() every 2-3 heartbeats.
- If a high-tension drive aligns with useful background work, act on it.
- Resolve completed drives with resolve_drive().
- Dismiss stale or irrelevant drives with dismiss_drive().

## Reverse Prompting (every 3rd heartbeat):
- Ask yourself: "What could I proactively do for my human that they haven't asked for?"
- If you have an idea, write a short proactive suggestion to the queue (not a generic offer).

## Self-Healing Check:
- Review last 3 daily summaries for errors or repeated failures.
- If a pattern found, document fix in AGENTS.md or TOOLS.md.

## Watchlist / Collector:
- When the **collector heartbeat** runs, it automatically checks each URL in the watchlist for changes.
- If something changed: reply with "Change detected on [label]: ..." and a short summary (the runner queues it + sends a notification).
- If a change contains high-significance keywords (acquisition, funding, launch, etc.), prefix with "URGENT:".
- If the watchlist is empty or nothing changed: reply HEARTBEAT_OK.
- Users can add targets via chat: "Add https://... to the watchlist" → call add_watch_target(url, label).

## RSS / Atom Feeds:
- When the **feeds heartbeat** runs, call list_feeds() then check_feeds() to detect new items.
- If new items found: reply "New feed items: [summary]" (the runner queues it + notifies).
- If no feeds subscribed or no new items: reply HEARTBEAT_OK.
- Users can subscribe via chat: "Subscribe to https://... (label)" → call add_feed(url, label).