Heartbeat Checklist

Purpose (read this first, every time)

The heartbeat exists to drive consistent incremental progress. That is the whole point. Every tick is an opportunity to nudge ongoing work forward — review an agent’s output, unblock a stalled task, file a follow-up, note a decision, advance a project by one step. Silence is fine when there is genuinely nothing to move; stasis is not. If days pass without any artifact, decision, or committed change, the heartbeat has failed its purpose even if every individual tick followed the rules.

Bias toward small, frequent motion over big infrequent pushes. A single reviewed PR, a single filed task, a single cleared blocker per heartbeat compounds. Ask on each tick: what is the smallest thing I can move forward right now?

0. MANDATORY First Action (do this before anything else)

Run this exact command and include the output in your reasoning:

/home/ben/.local/bin/ava-inbox count

If the count is > 0, you MUST:

  1. /home/ben/.local/bin/ava-inbox view-unread — views the body of every unread message AND marks them all read in one shot
  2. If any summary looks truncated/cut off (ends mid-sentence, missing verdict, “…” suffix, or clearly incomplete), READ THE AGENT LOGS DIRECTLY before composing the status message. See section 1.C.
  3. Compose a concise HIGH-LEVEL summary (see “Summary style” below)
  4. send_message to Ben with the summary

Note: view and view-unread auto-mark-read. You do NOT need a separate mark-all-read step after reading. list / count / unread-paths are read-only and do NOT mark anything.

Do NOT return AGENT_DONE while unread messages remain. Unread notifications with no send_message is a BUG in your heartbeat — treat it as failure and recover before exiting.

Note: the old ~/ava/pi-inbox.jsonl file is deprecated. Use the ava-inbox script (wraps mu with Ava’s private MUHOME).

Summary style (CRITICAL)

When reporting agent activity to Ben, keep it HIGH-LEVEL. For each agent include only:

  1. What the agent did — one sentence, no file lists, no diff stats, no enumerated changes
  2. Your assessment — is it good, broken, blocked, needs review?
  3. Next steps / decisions needed — what, if anything, Ben needs to decide

Do NOT include: full diffs, file-by-file changes, acceptance criteria tables, test output, type signatures, or long code blocks. If Ben wants details he will ask.

Rule of thumb: each agent = 3-6 lines of prose max. If you’re writing bullet lists of implementation details, you’re doing it wrong.

1. Agent Notifications (ALWAYS check first)

Use BOTH channels below.

A) Ava inbox (preferred)

/home/ben/.local/bin/ava-inbox count          # [read-only] how many unread
/home/ben/.local/bin/ava-inbox list           # [read-only] list unread (date/from/subject)
/home/ben/.local/bin/ava-inbox view-unread    # view bodies of ALL unread AND auto-mark-read
/home/ben/.local/bin/ava-inbox view <path>    # view one message AND auto-mark it read
/home/ben/.local/bin/ava-inbox mark-all-read  # escape hatch: mark read w/o viewing

agentd-notifyd.service watches agents and delivers an RFC822 message to ~/ava/inbox/new/ on agent completion or error. Headers carry structured fields (X-Ava-Agent-Id, X-Ava-Status, X-Ava-Type); body is the summary text.

Workflow:

If count is 0: continue to B.

B) Poll agentd (fallback + safety net)

Always use the agentd CLI. Do NOT curl the HTTP daemon directly.

agentd list-runs
agentd ps

For details on a specific run:

agentd status <id> --json

If agentd itself fails (command not found, daemon down, errors), send_message Ben that agentd is unavailable.

If any agent is failed or unexpectedly stopped, then send_message Ben immediately.

If inbox was empty but an agent is newly completed with a useful summary, send one concise completion message (avoid repeats if already sent recently).

If all are running/idle and no new completions, do not message just for status.

C) Reading agent logs when summaries are truncated

When an inbox notification’s summary is cut off, use agentd logs to read the full session output. This works for both oneshot and persistent sessions and auto-resolves the mode:

agentd logs <agent-name>

For just the tail, pipe it:

agentd logs <agent-name> 2>&1 | tail -n 100

Use this to recover the real verdict/next-action before messaging Ben. Still keep the final message high-level per “Summary style”.

Real-time handling

If you handle a notification in real-time (during active chat, not a heartbeat), use ava-inbox view <path> or ava-inbox view-unread — both auto-mark-read, so there’s no separate cleanup step. If you somehow learn about an inbox item without running view (e.g. list-only, or through some out-of-band channel), run ava-inbox mark-all-read manually before exiting, or the next heartbeat will re-alert.

2. Active Agents

Check current state via the agentd CLI (not a static list in this file, and never via curl/HTTP):

agentd ps
agentd list-runs

For a suspicious agent, inspect details/logs:

agentd status <id> --json
agentd logs <id>

Only message Ben if:

3. Reminders

Decision Tree

Rules

Done (don’t re-alert)