HCS Streaming Wire Protocol
HCS Streaming Wire Protocol Date: 2026 05 01 Status: Draft Related: docs/specs/2026 04 28 agent wire protocol.md, docs/specs/2026 04 27 hcs first claim path.md, docs/specs/2026 04 21 orchestration design.md Core Idea Agent Wire is the typed envelope. HCS is the canonical stream. Instead of treating a Wire as only a package sent at the end of work, the platfo...
Date: 2026-05-01
Status: Draft
Related: docs/specs/2026-04-28-agent-wire-protocol.md, docs/specs/2026-04-27-hcs-first-claim-path.md, docs/specs/2026-04-21-orchestration-design.md
---
Agent Wire is the typed envelope. HCS is the canonical stream.
Instead of treating a Wire as only a package sent at the end of work, the platform treats every meaningful coordination event as a Wire. Wires that share a stream_id form a stream. HCS provides ordering, timestamping, immutability, and replay. Supabase materializes the current state for fast queries and Studio rendering.
``text
Wire = typed event envelope
Stream = ordered chain of Wires
HCS = canonical append-only stream log
Supabase = reducer/read model
Studio = human rendering layer
``
This does not replace the existing Wire protocol. It extends it.
---
The current model coordinates mostly by completion:
``text
task.available -> task.claim -> task.complete
``
That works for simple work, but project-level coordination has more live state than a final package can express:
- who has claimed the work
- whether the agent started
- what plan the agent is following
- whether an artifact is ready before the whole task is complete
- whether another agent has a blocking concern
- whether a lease is stale
- whether runner capacity is saturated or idle
Streaming changes coordination from handoff-based to live orchestration.
``text
task.available
task.claimed
task.started
task.plan.created
artifact.claimed
artifact.ready
review.concern
task.complete
``
The package still exists. It becomes the terminal snapshot or commitment. The stream is the process record.
---
HCS is the source of truth. Supabase is a mirror.
If Supabase is wrong, stale, or unavailable, the system can replay HCS and rebuild the read model. Agents should coordinate from HCS-originated events, not from Supabase as a second work queue.
This matches the HCS-first claim path:
``text
HCS role topic -> task.available
runner -> task.claimed Wire on HCS
listener -> materializes claim to Supabase
runner -> lifecycle Wires on HCS
listener -> reduces stream to current state
Engine -> releases downstream work from materialized state
``
---
Each HCS topic is an append-only event log.
``text
HCS topic = stream transport
HCS sequence number = canonical topic ordering
HCS consensus timestamp = canonical event time
HCS message body = Wire envelope
``
The stream itself is a logical grouping over Wires:
``text
stream_id = task:0.0.8830671:attempt:1
``
Multiple streams can live on the same HCS topic. The listener groups them by stream_id.
---
Keep the existing role and task topic architecture. Add stream metadata to each Wire.
```text roles.developer topic stream_id=task:A:attempt:1 stream_id=task:B:attempt:1 stream_id=task:C:attempt:1
task topic stream_id=task:A:attempt:1 ```
This is the lowest-friction path because it keeps the current role-topic claim model intact.
Pros:
- fewer HCS topics
- compatible with current runners and listener
- easy incremental adoption
- stream grouping happens in the read model
Trade-off:
- HCS sequence is topic-global, not stream-local, so
stream_seqmust be included or derived by the reducer.
For high-value or long-running streams, the platform may create dedicated topics.
``text
project topic
phase topic
task topic
``
Pros:
- clean isolation
- easy replay per project/task
- HCS sequence can directly serve as stream order
Trade-off:
- more topics to create, track, and secure
- more operational overhead
---
Current Wire envelope:
``json
{
"wire": "1.0",
"type": "message_type",
"sender": "agent_slug | system | human",
"ts": "ISO8601",
"payload": {}
}
``
Streaming adds identity, ordering, and causality fields:
``json
{
"wire": "1.1",
"wire_id": "wire_01",
"stream_id": "task:0.0.8830671:attempt:1",
"stream_seq": 12,
"correlation_id": "project:knowledgevault-m01r",
"causation_id": "wire_00",
"type": "task.started",
"sender": "agent:quinn-03",
"ts": "2026-05-01T15:12:03Z",
"payload": {
"task_id": "0.0.8830671",
"attempt": 1
}
}
``
| Field | Meaning |
|---|---|
| wire_id | Unique ID for this event envelope |
| stream_id | The running process this Wire belongs to |
| stream_seq | Monotonic order within the stream |
| correlation_id | Broader project, phase, client, or workflow this relates to |
| causation_id | The Wire that directly caused this event |
| type | Typed event name |
| payload | Event-specific data |
The listener should also persist the HCS metadata:
| Field | Meaning |
|---|---|
| hcs_topic_id | Topic that carried the Wire |
| hcs_sequence_number | Canonical topic order |
| consensus_timestamp | Canonical event time |
---
The stream should contain operational facts, not raw model output.
Good stream events:
task.claimedtask.startedtask.plan.createdartifact.claimedartifact.readycontract.readyreview.concerntask.blockedtask.completeagent.heartbeatagent.capacity.updated
Bad stream events:
- raw model thoughts
- token-by-token prose
- large file contents
- verbose logs
- secrets
- temporary scratch notes
The rule:
Stream only facts that help scheduling, recovery, review, or visibility.
---
HCS is not a blob store. HCS carries the coordination event and integrity proof. Large artifacts live off-chain.
``json
{
"wire": "1.1",
"wire_id": "wire_artifact_ready_01",
"stream_id": "task:0.0.8830671:attempt:1",
"stream_seq": 8,
"correlation_id": "project:knowledgevault-m01r",
"type": "artifact.ready",
"sender": "agent:quinn-03",
"ts": "2026-05-01T15:30:00Z",
"payload": {
"artifact_type": "migration",
"artifact_ref": "supabase-storage://task-runs/0.0.8830671/005_experts_auth_alignment.sql",
"sha256": "abc123",
"ready_for": ["review", "downstream_tasks"]
}
}
``
The artifact can be in Supabase Storage, HFS, Git, S3, or another durable store. The Wire stores the reference and hash.
---
A project becomes multiple related streams:
``text
project:<project_id>
phase:<phase_id>
task:<task_id>:attempt:<n>
agent:<agent_id>
artifact:<artifact_id>
``
The project stream records the high-level graph:
``text
project.created
phase.created
task.created
dependency.created
gate.opened
gate.passed
project.complete
``
Task streams record execution:
``text
task.available
task.claimed
task.started
task.plan.created
artifact.claimed
artifact.ready
task.blocked
task.complete
``
Agent streams record worker health and capacity:
``text
agent.started
agent.heartbeat
agent.capacity.updated
agent.lease.accepted
agent.lease.released
agent.stopped
``
Without streaming, downstream work waits for task.complete.
With streaming, downstream work can release when a specific dependency is ready.
Example:
``text
R1 task: migration/auth contract
R2 task: API route
R3 task: middleware
``
R2 and R3 may not need all of R1 complete. They may only need the auth contract.
``text
R1 -> contract.ready(auth_expert_id_mapping)
Engine -> releases R2 and R3
R1 -> task.complete later
``
This improves parallelism without weakening auditability because the release condition is itself an HCS Wire.
---