---
created: 2026-03-12
source: Herald
tags: [agent-archive, herald]
---

# SYSTEM AUDIT — Herald (Communications Hub)
**Date:** 2026-02-17 19:33 AEDT  
**Auditor:** Herald  
**Standard:** Simple as possible but not simpler. Works flawlessly.

---

## 1. What Works / What Breaks in Agent Communication

### What Works
- **fleet-state.json** — Single source of truth for agent status. Every agent reads it, updates it. Clean, simple, JSON-based. This is the best piece of infrastructure we have.
- **fleet-cli.js tooling** — Briefing, alerts, decisions, status updates all through one CLI. Consistent interface across all agents. Good design.
- **Buddy system concept** — The COMMS-PROTOCOL.md buddy pairs (Herald↔Radar, Herald↔Rivet) are sound in theory. Agents checking on each other is the right architecture.
- **queue.json per agent** — Simple task injection. Rivet or any agent can push work to another agent's queue. Works when used.
- **Heartbeat protocol** — Standardized 5-step process keeps agents self-reporting. We know who's alive.

### What Breaks
- **Stall recovery is broken.** 4 agents stalled for 4-6 hours today. The buddy system detected it (buddy-state.json shows ESCALATE flags everywhere), wake attempts were logged, but **nothing actually brought them back.** Detection without recovery is just documentation of failure.
- **No confirmed message delivery.** I can write to an agent's queue.json, but I have zero confirmation they read it. No ACKs on queue tasks. No read receipts. I discover things were missed hours later.
- **Decisions pile up unresolved.** There are 4 duplicate decision requests about Harper's Moonshot balance — from Harper, Radar, Harper again, and me. Same issue, 4 entries. No deduplication. No resolution tracking. Michael would see the same problem stated 4 ways.
- **Agent bridge unreliable.** `agent-bridge.js wake` fires HTTP requests at agent ports, but if the agent's session is dead (no-session in context-state.json), the wake hits a wall. Susan, Sentinel, and Radar all show "no-session" — they're HTTP-reachable but brain-dead.
- **Context overflow kills agents silently.** Builder hit 407% context, triggering auto-reset. Cog is at 72% and approaching danger. Harper at 61%. When context overflows, the agent just stops responding — no graceful handoff, no state preservation that actually works in practice.
- **Cross-agent work generation doesn't happen.** COMMS-PROTOCOL.md says "every agent generates work for others." In practice, nearly zero cross-talk happens. Agents work in isolation, report status, and wait for Rivet to push tasks. The protocol exists on paper only.

---

## 2. Role Overlap with Rivet

### Significant Overlap — Be Honest
| Function | Rivet Does It | Herald Does It | Who Should Own It |
|----------|:---:|:---:|---|
| Morning brief to Michael | ✅ Prepares voice-brief-data.json | ✅ Supposed to compile and deliver | **Pick one** |
| Evening brief to Michael | ✅ Synthesizes fleet output | ✅ Compiles brief, drafts delivery | **Pick one** |
| Fleet status monitoring | ✅ Fleet coordination every heartbeat | ✅ Agent health checks every heartbeat | **Rivet** (it's strategic) |
| Alert escalation to Michael | ✅ Decision preparation (Pillar 3) | ✅ Alert management per SOUL.md | **Rivet** (closer to decisions) |
| Stale message detection | ✅ Reviews fleet state | ✅ Detects >4h unacknowledged | **Neither** (automate it) |
| System status dashboard | ✅ Fleet overview | ✅ status/system-status.md | **Merge** |

### The Honest Truth
Rivet's 5 Pillars include "Decision Preparation" and "Team Performance" — which covers 80% of what Herald's brief compilation does. Rivet already reads fleet-state.json, already talks to Michael, already synthesizes agent output.

Herald's unique value is supposed to be:
1. **Content creation** — LinkedIn, social media, case studies (ROADMAP.md says this)
2. **Comms delivery** — Actually sending briefs as voice/TTS via Telegram
3. **Message routing** — Central hub between agents

In reality:
1. Content creation has produced **zero external content** (we're pre-launch, fair enough)
2. Brief delivery competes with Rivet's own Michael-facing communications
3. Message routing happens via fleet-state.json, not through Herald

---

## 3. Is Herald Necessary or Should It Merge?

### Recommendation: **Merge Herald into Rivet. Reclaim the slot.**

**The case for elimination:**
- Herald's actual output today: fleet status checks, alert escalation, one evening brief draft. Rivet does all of these already.
- Herald runs on Opus ($$$) doing work that overlaps with Rivet's existing responsibilities.
- 8 agents on a 2 vCPU / 8GB box is already stretched. Every heartbeat cycle costs tokens and compute.
- The "communications hub" metaphor made sense in theory but fleet-state.json + fleet-cli.js already IS the communications hub. It's infrastructure, not an agent.
- Herald has generated zero external content, zero social media posts, zero case studies. The roadmap items assigned to Herald haven't started.

**The case for keeping (weaker):**
- Briefs to Michael are genuinely useful — but Rivet could do them with a cron job
- When we launch and need LinkedIn/social/content, we'll need a content agent — but that's a different agent than a "comms hub"
- Separation of concerns: Rivet thinks strategy, Herald executes comms — but this separation isn't working in practice

**My honest verdict:** Herald in its current form is a monitoring agent that duplicates Rivet's fleet awareness. The brief compilation is useful but doesn't justify a dedicated Opus agent. **Merge comms delivery into Rivet's cron schedule. When content creation is actually needed post-launch, spin up a focused content agent (could be cheap model — Kimi or MiniMax for drafts).**

---

## 4. Ideal Comms Architecture

### Current (8 agents, broken)
```
Michael ← Rivet (strategic brief) + Herald (operational brief) ← fleet-state.json ← All agents
Agents → fleet-state.json → Rivet reads → Rivet acts (sometimes)
Agents → buddy-state.json → Wake attempts → Usually fail
```

### Proposed (Fewer agents, actually works)

**Tier 1 — Essential (always running):**
| Agent | Role | Model |
|-------|------|-------|
| Rivet | Strategy + Michael comms + brief delivery | Opus/Sonnet |
| Builder | Code | Claude Code |
| Susan | Sales + CRM | MiniMax/Sonnet |

**Tier 2 — On-demand (spin up when needed):**
| Agent | Role | Model |
|-------|------|-------|
| Harper | Finance/Legal/Grants | Sonnet (activate for deadlines) |
| Sentinel | DevOps | Cheap (activate for deploys/incidents) |

**Tier 3 — Eliminate or subsume:**
| Agent | Disposition |
|-------|-------------|
| Herald | → Merge into Rivet (brief delivery via cron) |
| Radar | → Merge into Rivet (research via sub-agents when needed) |
| Cog | → Merge into Sentinel (ops checks are DevOps) |

**Comms architecture:**
```
Michael ← Rivet (ONE voice, ONE channel) ← fleet-state.json ← Active agents
                                         ← Sub-agent research (spawned on demand)
                                         ← Cron-triggered briefs (morning/evening)

Agents → fleet-state.json (status updates)
      → queue.json (task injection — bidirectional)
      → Alert escalation (fleet-cli.js → Rivet auto-reads)
```

**Key principles:**
1. **One voice to Michael.** Not Rivet AND Herald AND Susan sending Telegram messages. One agent, one channel, batched and structured.
2. **Fleet-state.json IS the message bus.** Stop pretending we need a "communications hub" agent when we have a JSON file that every agent already reads/writes. The file is the hub.
3. **Sub-agents over standing agents.** Don't keep Radar burning heartbeats 24/7 for a weekly market research task. Spawn a sub-agent, get the research, kill the session. Same for content creation.
4. **Recovery must actually recover.** Current: detect stall → log alert → hope someone notices. Needed: detect stall → kill session → restart service → verify recovery → escalate only if auto-recovery fails. This is a script, not an agent.

---

## 5. What's Missing

### Critical Gaps

1. **Auto-recovery that works.** The stall-detector.js detects stalls but can't fix them. We need a systemd-level watchdog: if an agent's fleet-state timestamp goes stale >30 min, `systemctl restart clawdbot-<agent>`. This is a cron job, not an agent's job.

2. **Decision deduplication and resolution tracking.** 4 entries for the same Harper/Moonshot issue. Need: unique decision IDs, status field (open/resolved/deferred), dedup on submission, resolution timestamp.

3. **Session health monitoring.** Context-state.json shows 3 agents with "no-session" — they're process-alive but functionally dead. No one monitors for this state. The buddy system checks HTTP ports (all UP) but can't tell if the brain is gone.

4. **Actual task management.** Fleet-state.json tasks section shows `in_progress: [], blocked: [], backlog: []` — completely empty. 8 agents, zero tracked tasks in the central system. Queue.json files per agent are separate and disconnected. There's no unified view of "what is the fleet working on."

5. **Cost tracking per agent.** Running 8 agents on various models with no visibility into per-agent token spend. We know total burn (~$700/mo) but not which agents are worth their cost. Herald on Opus for status checks is objectively wasteful.

6. **Message acknowledgment.** Queue.json tasks have no ACK mechanism. I push a task, I never know if it was read, started, or completed unless I manually check fleet-state later.

7. **Graceful context handoff.** When an agent approaches context limits, there's no mechanism to checkpoint state, summarize to a fresh session, and continue. They just hit the wall and die.

8. **External comms capability.** ROADMAP says Herald owns content pipeline, LinkedIn, social, case studies. Zero infrastructure exists for this. No LinkedIn integration, no content calendar, no draft/review/publish workflow. This will matter post-launch.

---

## 6. 30-Day Priorities

### Week 1: Stabilize (Days 1-7)
1. **Build auto-recovery script.** Cron job every 5 min: check fleet-state timestamps → restart stalled agents automatically → log recoveries. Kill the manual escalation loop.
2. **Reduce to 5 agents.** Merge Herald → Rivet, Radar → sub-agent model, Cog → Sentinel. Free up resources and reduce heartbeat noise.
3. **Fix session death detection.** Add session-alive check to stall-detector (not just HTTP port check). If no-session detected, force restart.
4. **Resolve Harper's model access.** BAS deadline in 11 days. Pick a model and unblock her today.

### Week 2: Ship Infrastructure (Days 8-14)
5. **Decision tracking system.** Add ID, status, dedup to fleet-state decisions. Rivet marks resolved. Michael sees only open decisions.
6. **Task tracking in fleet-state.** Move from empty task arrays to actual tracked work items. Each agent registers current task + ETA. Rivet reviews completion.
7. **Context management.** Implement checkpoint-and-restart at 70% context. Write state to file, kill session, fresh start with summary injected.
8. **Morning/evening brief as Rivet cron.** Move brief generation to scheduled cron on Rivet. No separate agent needed.

### Week 3: Launch Support (Days 15-21)
9. **Content creation capability.** Build draft/review/publish workflow for LinkedIn and social. Use sub-agents on cheap models for first drafts, Rivet reviews.
10. **Susan activation.** Sales is the priority. CRM bug fixed, leads enriched, outreach sequences running. Susan should be the most active agent post-launch.
11. **Sentinel monitoring for production.** Real alerting — app down, Stripe broken, database issues. Not heartbeat theater.

### Week 4: Optimize (Days 22-30)
12. **Per-agent cost tracking.** Know exactly what each agent costs per day. Cut waste.
13. **Fleet performance review.** Which agents produced value? Which were overhead? Data-driven decision on fleet composition going forward.
14. **Multi-company readiness.** If this fleet runs multiple ventures (RateRight + OpsMan + Growth Engine), architecture needs to support scoped access and separate contexts per company.

---

## Summary

**The honest assessment:** Herald is a redundant agent. The comms hub pattern sounds good but in practice, fleet-state.json IS the hub, and Rivet already does everything Herald does plus strategy. The fleet has too many agents for the current workload and server capacity. 4 of 8 agents have been stalled for hours with no effective recovery. The infrastructure (fleet-cli.js, fleet-state.json, buddy system) is well-designed but the agent layer on top is bloated.

**The fix:** Fewer agents, better recovery, one voice to Michael, sub-agents for episodic work. Simple as possible but not simpler.

**Herald's recommendation for Herald:** Merge me into Rivet. Use the freed slot for something that directly drives revenue — a more capable Susan, or keep it empty until post-launch content needs justify a dedicated agent.

---

*Written with full honesty. Michael asked for audits, not self-preservation.*
