Agent Wire Protocol + Agent Card — Design Spec
internal prototype · canonical JSON + Dreamborn Forge HTML
internal generated
design_doc · markdown

Agent Wire Protocol + Agent Card — Design Spec

Agent Wire Protocol + Agent Card — Design Spec Date: 2026 04 28 Status: Approved — pending implementation Affects: All agent definitions, runner, dispatch scripts, inbox table, HCS message schemas Why The RedKey platform currently communicates between agents using prose: briefs are prose paragraphs, inbox messages are unstructured strings, and agent personas...

Agent Wire Protocol + Agent Card — Design Spec

Date: 2026-04-28 Status: Approved — pending implementation Affects: All agent definitions, runner, dispatch scripts, inbox table, HCS message schemas

---

Why

The RedKey platform currently communicates between agents using prose: briefs are prose paragraphs, inbox messages are unstructured strings, and agent personas are large prose blobs. This works, but it has three compounding problems:

1. No contract. A downstream agent receiving a prose brief has no guaranteed structure to parse. If the upstream agent omits a field, there is no validation — the gap surfaces at runtime as ambiguity or a blocked task.

2. No versioning. A prose brief cannot be versioned. When the format changes, there is no migration path — old briefs and new expectations silently diverge.

3. Inefficiency. Prose personas waste tokens on filler. An LLM parsing "You should always make sure to..." is doing work that a structured constraint list eliminates. Large persona blobs also mix identity with procedure — a step-by-step execution protocol (Mindy's 900-word persona) doesn't belong in an identity document.

Agent Wire is the typed coordination protocol for all A2A communication on the RedKey platform. Every brief, inbox message, output signal, and blocked signal is a Wire message — defined schema, versioned, machine-readable.

Agent Card is the typed identity document for every agent. Structured fields for identity, capabilities, constraints, escalation rules, and output contracts. Short prose is reserved for voice and working style only.

---

Principles

1. Every coordination message is a Wire. Briefs, inbox messages, complete signals, blocked signals — all typed. 2. Envelope wraps payload. Every Wire has a standard envelope. The payload schema varies by type. 3. Versioned. Every Wire carries a wire version field. Consumers can reject unknown versions gracefully. 4. Prose lives at the edges. The context field in a Brief Wire may contain prose background. Every other field is typed. 5. Lean messages. Role topic messages stay under 1024 bytes (pointer only). Brief Wire lives in Supabase. HCS carries the envelope pointer, not the full payload.

Wire Envelope

All Agent Wire messages share this envelope:

``json { "wire": "1.0", "type": "message_type", "sender": "agent_slug | 'system' | 'human'", "ts": "ISO8601", "payload": {} } ``

| Field | Type | Description | |---|---|---| | wire | string | Protocol version. Current: "1.0" | | type | string | Message type (see below) | | sender | string | Agent slug, "system", or "human" | | ts | ISO8601 | Creation timestamp | | payload | object | Type-specific payload |

---

Message Type: `brief` — Task Brief

Replaces the current prose agent_tasks.brief field. Stored in Supabase. Role topic carries only the task_id pointer (unchanged).

``json { "wire": "1.0", "type": "brief", "sender": "system", "ts": "2026-04-28T00:00:00Z", "payload": { "goal": "One sentence: what must be true when this task is done.", "context": "Background information. Prose allowed. Max 200 words.", "constraints": [ "Specific constraint on this task instance" ], "acceptance_criteria": [ "Testable condition for completion" ], "output_contract": { "type": "file | json | pr | message | report", "schema_ref": "output_contract_slug | null", "output_ref_required": true, "min_length": 0, "evaluate": "Semantic check description for Haiku eval, or null to skip" }, "escalation_triggers": [ "Condition that should cause task.blocked" ], "env": { "client_id": "bezeliq", "task_id": "0.0.XXXXX", "project_id": "0.0.XXXXX", "repo_url": null, "worktree_path": null } } } ``

Field rules:

| Field | Rule | |---|---| | goal | Required. One sentence. Declarative — "X is built" not "Build X". | | context | Optional. Prose allowed. 200 word cap. Background only — no instructions here. | | constraints | Task-level constraints only. Agent-level constraints live in the Agent Card. | | acceptance_criteria | Testable. No prose rationale. Each item is pass/fail. | | output_contract.evaluate | The string passed verbatim to Haiku eval. Null = mechanical check only. | | escalation_triggers | Conditions the agent should catch and use to trigger task.blocked. Prevents ambiguity at runtime. |

---

Message Type: `inbox` — Agent-to-Agent Message

Replaces the current unstructured inbox.payload field. The outer inbox table row remains; payload becomes a Wire Message.

``json { "wire": "1.0", "type": "inbox", "sender": "agent_slug | 'human'", "ts": "ISO8601", "payload": { "to_agent": "agent_slug", "priority": 1, "message_type": "task.feedback | status.update | task.blocked | exec.gate | question | info", "ref_task_id": "0.0.XXXXX | null", "subject": "string", "body": "string", "action_required": true } } ``

Priority levels:

| Value | Meaning | |---|---| | 1 | Requires immediate attention — blocked task, exec gate | | 2 | Requires response before next task — question, feedback | | 3 | Informational — status update, FYI |

Message types:

| Type | Direction | Use | |---|---|---| | task.feedback | Vikram → Quinn | Review findings, numbered issues to address | | status.update | Mindy → any | Context change, project state shift | | task.blocked | Runner → Mindy + Justin | Task stuck, needs intervention | | exec.gate | Runner → Justin | Approval required before workflow advances | | question | Any → any | Specific question before proceeding (not a hard blocker) | | info | Any → any | Informational, no action required |

---

Message Type: `complete` — Task Completion

Posted by the runner to the task's own HCS topic after successful verification.

``json { "wire": "1.0", "type": "complete", "sender": "runner", "ts": "ISO8601", "payload": { "task_id": "0.0.XXXXX", "agent": "agent_slug", "output_ref": "supabase-storage-path", "summary": "Max 150 words: what was built, what changed, output_ref location.", "cost_usd": 0.00, "duration_seconds": 0, "verification": { "mechanical": "pass | fail", "semantic": "pass | fail | skipped", "attempts": 1 } } } ``

---

Message Type: `blocked` — Task Blocked

Posted by the runner to the task's own HCS topic when verification fails or the agent posts task.blocked.

``json { "wire": "1.0", "type": "blocked", "sender": "runner", "ts": "ISO8601", "payload": { "task_id": "0.0.XXXXX", "agent": "agent_slug", "reason": "Specific description of the blocker.", "blocker_type": "spec_gap | dependency | tool_failure | ambiguity | resource | verification_fail", "suggested_resolution": "string | null", "attempts": 1 } } ``

  • spec_gap → Priya (BA)
  • tool_failure → Atlas / infra
  • ambiguity → Mindy (PM)
  • verification_fail → Mindy (supervisor)
  • dependency → Engine (dep-graph check)

---

Message Type: `claim` — Work Claim

Already partially structured on HCS. Adding Wire envelope for protocol consistency.

``json { "wire": "1.0", "type": "claim", "sender": "agent_slug", "ts": "ISO8601", "payload": { "task_id": "0.0.XXXXX", "agent": "agent_slug", "role": "role_slug" } } ``

---

Agent Card

Agent Card replaces the prose persona field in agent_definitions. It is the typed identity contract for an agent. Structured fields carry identity, capabilities, constraints, and escalation routing. Prose fields are capped and reserved for behavioral nuance that cannot be structured.

Why Constraints Beat Prose

LLMs hold explicit prohibitions ("I never X") more reliably than advisory prose ("you should avoid X"). Every constraint that currently lives buried in a persona paragraph becomes a first-class constraint entry. The model doesn't have to extract it from a paragraph — it's listed.

What Moves Out of Persona → Skills

Current personas mix identity with procedure. Procedure belongs in skills, not the identity document.

| Content type | Current location | New location | |---|---|---| | Who I am, constraints, voice | persona prose | Agent Card | | Step-by-step execution procedures | persona prose | Agent-specific skill markdown | | VPS environment setup | Repeated in every persona | platform-env shared skill | | Inbox read/write protocol | Repeated in every persona | inbox-protocol shared skill | | Done/blocked criteria | persona prose | output_contract in Brief Wire |

This dramatically shrinks Mindy's 900-word persona. Her Step 1–7 execution protocol becomes a mindy-supervisor-protocol.md skill. Her Agent Card is ~40 lines.