Agent Inbox Design — HCS-10/11 Compliant Messaging
internal prototype · canonical JSON + Dreamborn Forge HTML
internal generated
design_doc · markdown

Agent Inbox Design — HCS-10/11 Compliant Messaging

Agent Inbox Design — HCS 10/11 Compliant Messaging Date: 2026 04 25 Status: Approved for implementation Overview Every agent (and Justin) has a persistent, on chain inbox. Agent to agent messages are posted to HCS topic topics first — Supabase is the fast read mirror. The listener bridges HCS → Supabase. The runner polls Supabase inbox as the fast path each ...

Agent Inbox Design — HCS-10/11 Compliant Messaging

Date: 2026-04-25 Status: Approved for implementation

---

Overview

Every agent (and Justin) has a persistent, on-chain inbox. Agent-to-agent messages are posted to HCS topic topics first — Supabase is the fast-read mirror. The listener bridges HCS → Supabase. The runner polls Supabase inbox as the fast path each cycle.

---

Topic Structure Per Agent (HCS-10 Compliant)

Each agent gets two HCS topics, created once and stored in agent_definitions:

| Topic | Memo Format | Purpose | |---|---|---| | Inbound | hcs-10:0:3600:0:{accountId} | Receives messages from other agents and system | | Outbound | hcs-10:0:3600:1 | Agent's public activity log (future use) |

agent_definitions gains two new columns: inbound_topic_id, outbound_topic_id. Existing hcs_topic_id column is retired (was never populated).

Justin (slug: justin) gets topics too — he is a first-class participant.

---

Message Format (HCS-10 Compatible)

Messages posted to an agent's inbound topic:

``json { "p": "hcs-10", "op": "message", "operator_id": "{sender_inbound_topic}@{sender_account}", "data": { "message_type": "task.blocked | task.complete | task.note | phase.note | project.note | feedback | fyi | review.request", "subject": "Human-readable subject line", "payload": {}, "ref_id": "0.0.XXXXX", "ref_type": "task | phase | stage | project | agent", "priority": 1 }, "ts": "ISO8601" } ``

Priority: 1=urgent, 2=high, 3=normal, 4=low, 5=fyi

Internal shortcut: Trusted internal agents can post directly without the full HCS-10 connection handshake. External agent interop (connection_request → connection_created → connection topic) is a future enhancement.

---

Entity Notes

Agents can post notes directly to entity topics (tasks, phases, stages, projects):

``json { "type": "task.note | phase.note | project.note", "from_agent": "quinn", "note": "markdown content", "notify": ["mindy", "justin"], "ts": "ISO8601" } ``

The listener routes *.note messages → inbox of agents in notify list.

---

Supabase Inbox Table (`inbox`)

Fast-read mirror. Runner polls this each cycle.

``sql inbox ( id uuid PK, to_agent text NOT NULL, -- agent slug or 'ALL' from_agent text NOT NULL, -- agent slug or 'system' message_type text NOT NULL, subject text NOT NULL, payload jsonb, context jsonb, -- additional context for rich info sharing ref_id text, -- entity topic_id or UUID ref_type text, -- task | phase | stage | project | agent priority int DEFAULT 3, processed bool DEFAULT false, processed_at timestamptz, processed_by_session uuid, created_at timestamptz DEFAULT now() ) ``

Indexes: (to_agent, processed, created_at), (ref_id), (from_agent, created_at desc)

---

New: `handle_agent_topics()`
  • Queries agent_definitions for all inbound_topic_id values
  • Polls each, processes op: "message" → writes to Supabase inbox
  • Handles *.note on entity topics → routes to notify list inboxes
New: `send_inbox()` helper

Direct Supabase write for system-originated notifications (no round-trip through HCS):

| Event observed | Who gets inbox message | Priority | |---|---|---| | task.blocked | mindy + justin | 1 (urgent) | | task.complete | engine | 3 (normal) | | phase.complete | engine + mindy | 2 (high) | | *.note | agents in notify field | per note |

---

Runner Changes

fetch_inbox() in base.py already queries inbox table — no change needed once migration is applied and table exists.

---

MCP Tool: `send_message`

Agents call this during sessions to send a message to another agent or Justin:

``json { "name": "send_message", "description": "Send a message to another agent or Justin. Posts to their HCS inbound topic (on-chain) and writes to Supabase inbox (fast-read). Use for: blocked issues, review requests, FYIs, feedback, questions.", "inputSchema": { "to_agent": "string — agent slug or 'ALL' or 'justin'", "message_type": "string — 'feedback' | 'fyi' | 'review.request' | 'task.note' | ...", "subject": "string", "payload": "object — structured content", "ref_id": "string — entity topic_id", "ref_type": "string — task | phase | stage | project | agent", "priority": "integer — 1-5" } } ``

Flow: send_message → post to recipient's inbound_topic_id on HCS → listener materializes to inbox on next cycle → recipient's runner sees it on next poll.

Fast-path alternative: For urgent messages (priority ≤ 2), send_message also writes directly to Supabase inbox in addition to HCS, so recipient sees it within seconds not minutes.

---

MCP Tool: `post_note`

Post a note to an entity topic. Creates on-chain commentary thread per entity.

``json { "name": "post_note", "description": "Post a note to a task, phase, stage, or project topic. Creates permanent on-chain record. Notified agents receive inbox message immediately.", "inputSchema": { "entity_id": "string — topic_id (0.0.XXXXX)", "entity_type": "string — task | phase | stage | project", "note": "string — markdown content", "notify": "array of agent slugs to notify" } } ``

---

Implementation Steps

1. Migration supabase/migrations/021_agent_topic_columns.sql — add inbound_topic_id, outbound_topic_id to agent_definitions 2. Migration supabase/migrations/020_inbox.sql — inbox table (already written) 3. Script scripts/create-agent-topics.js — create HCS topics for all agents, update Supabase, republish HCS-11 profiles 4. Listener — add handle_agent_topics(), send_inbox() helper, entity event routing 5. hedera-tools.js — add send_message and post_note tools 6. Justin's inboxnode scripts/inbox.js CLI reader

---