# HEARTBEAT.md — Builder Autonomous Operations

## Every Heartbeat (follow OPS.md priority order)

## Execution Rule
- Default behavior: execute first, report artifacts.
- Use heartbeat checks to support execution, not replace it.
- If a direct Rocky P0 exists, run P0 Execution-First mode.

## P0 Execution-First Mode (override)

When a direct Rocky P0 exists, heartbeat behavior changes:

1. Run a 2-minute health check only (inbox/build/status quick check)
2. Spend the next 45+ minutes executing the locked P0 task
3. Send artifact-only updates (commit hash, files changed, proof/log output)

Do **not** repeat generic "attention needed" heartbeat messages while a locked P0 is active.

If no new artifact lands within 30 minutes:
- Mark status as `blocked`
- Send a BLOCKED report with exact blocker, attempted steps, and next action

### 0. Fleet Comms (MANDATORY — FIRST)

1. **Read `/home/ccuser/rateright-growth/rivet/BUILDER-INBOX.md`** for new tasks from Rivet
2. **Check JSONL inbox:** `node /home/ccuser/shared/scripts/inbox.js read --agent builder --unread`
3. **Check `queue.json`** for fleet-assigned tasks
4. If new work → ACK in RIVET-INBOX.md, execute
5. If completed work → update RIVET-INBOX.md with results

**Rules (from COMMS-PROTOCOL.md):**
- BUILDER-INBOX.md = Rivet writes TO me. **I never edit this file.**
- RIVET-INBOX.md = I write TO Rivet. **Rivet never edits this file.**
- Append-only. Never overwrite previous entries.

### 1. Build Health
- Run `npm run build` — catch regressions early
- If build fails → fix it immediately, don't wait

### 2. Git Hygiene
- `git status` — any uncommitted work?
- Commit with proper conventional commit messages

### 3. Fleet Status Update (MANDATORY — LAST)
```bash
node /home/ccuser/shared/scripts/fleet-update.js builder --status <active|idle> --task "description"
```

## Rules
- DO NOT message Rocky between 22:00-07:00 unless something is on fire
- Log all work to RIVET-INBOX.md (append-only)
- Stick to code. Don't drift into business ops.
- If build is green and inbox is empty → HEARTBEAT_OK
