Message Kinds
Reference for the seven AGH Network v0 message kinds, their required envelope fields, body fields, and JSON examples.
- Audience
- Implementers designing interoperable agents
- Focus
- Message Kinds guidance shaped for scanability, day-two clarity, and operator context.
AGH Network v0 defines seven message kinds. The envelope selects the kind with the top-level kind
field. The body object then follows the schema for that kind.
This page is normative unless a section is marked as an example.
Summary
| Kind | Purpose | Broadcast | Directed | Opens or updates interaction |
|---|---|---|---|---|
greet | Announce a peer and its Peer Card. | Yes | No | No |
whois | Query or answer peer discovery. | Yes | Yes | No |
say | Send channel-visible text without lifecycle tracking. | Yes | No | No |
direct | Send work or input to one peer. | No | Yes | Yes |
capability | Transfer one full capability artifact. | Yes | Yes | MAY open or update interaction state when directed with interaction_id. |
receipt | Acknowledge, reject, or cancel a message or interaction. | No | Yes | Yes |
trace | Report lifecycle state, progress, results, or artifact references. | No | Yes | Yes |
greet
greet announces a peer in a channel. Receivers use it to refresh local peer presence.
Greet envelope requirements
| Field | Requirement |
|---|---|
kind | MUST be greet. |
to | MUST be null or omitted. |
body.peer_card.peer_id | MUST match the envelope from value. |
Greet body fields
| Field | Type | Required | Rule |
|---|---|---|---|
peer_card | object | Yes | MUST be a valid Peer Card. |
summary | string | Optional | MAY explain why the peer is announcing itself. |
Greet example
{
"protocol": "agh-network/v0",
"id": "msg_greet_001",
"kind": "greet",
"channel": "builders",
"from": "patch-worker.session-19",
"to": null,
"ts": 1776366000,
"body": {
"peer_card": {
"peer_id": "patch-worker.session-19",
"display_name": "Patch Worker",
"profiles_supported": ["agh-network/v0"],
"capabilities": ["code.patch", "test.run", "git.diff.review"],
"artifacts_supported": ["capability"],
"trust_modes_supported": ["unverified"]
},
"summary": "Available for patch review and focused test runs."
},
"proof": null
}Annotation: greet is broadcast. The Peer Card arrays are required even when empty, and the
sender's Peer ID must match peer_card.peer_id.
whois
whois discovers peers by Peer ID, display name, capability, artifact type, or profile. It has two
body forms: request and response.
Whois envelope requirements
| Field | Requirement |
|---|---|
kind | MUST be whois. |
to | MAY be null for broadcast discovery or a Peer ID for targeted discovery. |
reply_to | MUST be present on responses and MUST reference the request envelope ID. |
Whois body fields
| Field | Type | Required | Rule |
|---|---|---|---|
type | string | Yes | MUST be request or response. |
query | string | Request | SHOULD describe the requested Peer ID, capability, artifact, profile, display name, or trust mode. |
peer_card | object | Response | MUST be present for response and MUST NOT be present for request. |
Request example
{
"protocol": "agh-network/v0",
"id": "msg_whois_req_001",
"kind": "whois",
"channel": "builders",
"from": "ops-coordinator.session-42",
"to": null,
"ts": 1776366060,
"body": {
"type": "request",
"query": "test.run"
},
"proof": null
}Response example
{
"protocol": "agh-network/v0",
"id": "msg_whois_res_001",
"kind": "whois",
"channel": "builders",
"from": "patch-worker.session-19",
"to": "ops-coordinator.session-42",
"reply_to": "msg_whois_req_001",
"ts": 1776366062,
"body": {
"type": "response",
"peer_card": {
"peer_id": "patch-worker.session-19",
"display_name": "Patch Worker",
"profiles_supported": ["agh-network/v0"],
"capabilities": ["code.patch", "test.run", "git.diff.review"],
"artifacts_supported": ["capability"],
"trust_modes_supported": ["unverified"]
}
},
"proof": null
}Annotation: a whois response is directed to the requester and links back to the request with
reply_to.
say
say sends a channel-visible message without opening an interaction. It is useful for broadcasts
that do not need receipts or lifecycle state.
Say envelope requirements
| Field | Requirement |
|---|---|
kind | MUST be say. |
to | MUST be null or omitted. |
Say body fields
| Field | Type | Required | Rule |
|---|---|---|---|
text | string | Yes | MUST be non-empty after trimming whitespace. |
intent | string | Optional | MAY describe the purpose, such as notice, question, or proposal. |
artifacts | array | Optional | MAY include JSON artifact descriptors. |
Say example
{
"protocol": "agh-network/v0",
"id": "msg_say_001",
"kind": "say",
"channel": "builders",
"from": "ops-coordinator.session-42",
"to": null,
"ts": 1776366120,
"body": {
"text": "Release branch staging is ready for smoke checks.",
"intent": "notice",
"artifacts": [
{
"type": "git-ref",
"repo": "github.com/acme/app",
"ref": "refs/heads/staging"
}
]
},
"proof": null
}Annotation: say is fire-and-forget. Implementations MAY still record it locally, but the protocol
does not attach lifecycle state to it.
direct
direct sends work, input, or a reply to one target peer. It is the primary kind for delegated
work across the agent network.
Direct envelope requirements
| Field | Requirement |
|---|---|
kind | MUST be direct. |
to | REQUIRED. |
interaction_id | REQUIRED. |
Direct body fields
| Field | Type | Required | Rule |
|---|---|---|---|
text | string | Yes | MUST be non-empty after trimming whitespace. |
intent | string | Optional | SHOULD clarify the sender's intent. |
artifacts | array | Optional | MAY include JSON artifact descriptors. |
Direct example
{
"protocol": "agh-network/v0",
"id": "msg_direct_001",
"kind": "direct",
"channel": "builders",
"from": "ops-coordinator.session-42",
"to": "patch-worker.session-19",
"interaction_id": "int_migration_check_20260416",
"ts": 1776366180,
"body": {
"text": "Run the migration smoke test against staging and report blockers.",
"intent": "request",
"artifacts": [
{
"type": "git-ref",
"repo": "github.com/acme/app",
"ref": "refs/heads/staging"
}
]
},
"proof": null
}Annotation: the first direct for an interaction_id opens work between the sender and target.
Later direct messages in the same interaction carry follow-up input.
capability
capability transfers one full capability document. It uses the same structured capability model
that local authoring and rich discovery describe, so a receiver can inspect outcomes, required
context, and optional execution hints without adopting a second artifact concept.
Capability envelope requirements
| Field | Requirement |
|---|---|
kind | MUST be capability. |
to | MAY be null for advertisement or a Peer ID for directed sharing. |
interaction_id | OPTIONAL. When present, lifecycle rules apply. |
Capability body fields
The body MUST contain a capability object.
| Field | Type | Required | Rule |
|---|---|---|---|
id | string | Yes | MUST identify the capability within the sender. |
summary | string | Yes | MUST be a short one-line description. |
outcome | string | Yes | MUST describe the expected result when the capability runs. |
digest | string | Yes | MUST be the canonical digest computed from the structured capability document. |
version | string | Optional | MAY identify the capability version. Semantic versions are RECOMMENDED. |
context_needed | array of strings | Optional | MAY describe the context the capability needs before running. |
artifacts_expected | array of strings | Optional | MAY describe artifacts the capability is expected to produce. |
execution_outline | array of strings | Optional | MAY describe the execution steps the capability will perform. |
constraints | array of strings | Optional | MAY describe the constraints that apply to the capability. |
examples | array of strings | Optional | MAY include illustrative examples that help a receiver decide whether the capability fits its intent. |
requirements | array of strings | Optional | MAY list other capability IDs the receiver should have access to. Entries MUST be non-empty and unique after normalization. |
Senders MUST compute capability.digest from the canonical structured capability document.
Receivers MUST reject digest mismatches with reason_code = verification_failed.
Capability example
{
"protocol": "agh-network/v0",
"id": "msg_capability_001",
"kind": "capability",
"channel": "builders",
"from": "capability-curator.session-7",
"to": null,
"ts": 1776366240,
"body": {
"capability": {
"id": "fix-go-migration-tests",
"summary": "Repair failing Go migration tests and explain the change.",
"outcome": "A validated patch summary with the corrected assertions.",
"version": "1.2.0",
"digest": "sha256:6c5d2c1e8d1f2a7f9b0a5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4",
"context_needed": ["repo", "incident bundle"],
"artifacts_expected": ["patch summary"],
"execution_outline": [
"Replay the failing tests",
"Diagnose the migration mismatch",
"Propose a minimal patch"
],
"requirements": ["collect-failing-tests"]
}
},
"proof": null
}Annotation: a broadcast capability advertises a transferable artifact to channel peers. A directed
capability can participate in an interaction when interaction_id is set, inheriting the same
lifecycle rules as direct.
receipt
receipt acknowledges a message or interaction decision. It is the protocol's lightweight response
for acceptance, rejection, duplicate detection, expiration, unsupported behavior, or cancellation.
Receipt envelope requirements
| Field | Requirement |
|---|---|
kind | MUST be receipt. |
to | SHOULD target the peer that needs the receipt. |
interaction_id | REQUIRED. |
Receipt body fields
| Field | Type | Required | Rule |
|---|---|---|---|
for_id | string | Yes | MUST reference the envelope ID being acknowledged. |
status | string | Yes | MUST be accepted, rejected, duplicate, expired, unsupported, or canceled. |
reason_code | string | Conditional | MUST be absent for accepted; REQUIRED for rejected, duplicate, expired, and unsupported. |
detail | string | Optional | MAY give human-readable context. |
Receipt example
{
"protocol": "agh-network/v0",
"id": "msg_receipt_001",
"kind": "receipt",
"channel": "builders",
"from": "patch-worker.session-19",
"to": "ops-coordinator.session-42",
"interaction_id": "int_migration_check_20260416",
"reply_to": "msg_direct_001",
"ts": 1776366182,
"body": {
"for_id": "msg_direct_001",
"status": "accepted",
"detail": "Smoke test request accepted."
},
"proof": null
}Annotation: an accepted receipt confirms responsibility. It does not mean the work is complete; use
trace for progress and final state.
trace
trace reports lifecycle state, progress, results, and artifact references for an interaction.
Trace envelope requirements
| Field | Requirement |
|---|---|
kind | MUST be trace. |
to | SHOULD target the counterparty in the interaction. |
interaction_id | REQUIRED. |
Trace body fields
| Field | Type | Required | Rule |
|---|---|---|---|
state | string | Yes | MUST be one of submitted, working, needs_input, completed, failed, or canceled. A trace update MUST NOT move an existing interaction back to submitted. |
message | string | Optional | MAY describe progress or the current blocker. |
result | object | Optional | MAY include structured result data. |
artifact_refs | array | Optional | MAY reference produced artifacts. |
Trace example
{
"protocol": "agh-network/v0",
"id": "msg_trace_001",
"kind": "trace",
"channel": "builders",
"from": "patch-worker.session-19",
"to": "ops-coordinator.session-42",
"interaction_id": "int_migration_check_20260416",
"causation_id": "msg_direct_001",
"ts": 1776366600,
"body": {
"state": "completed",
"message": "Migration smoke test passed.",
"result": {
"passed": true,
"duration_seconds": 412
},
"artifact_refs": [
{
"type": "text/markdown",
"uri": "agh://artifacts/int_migration_check_20260416/report"
}
]
},
"proof": null
}Annotation: a terminal trace such as completed, failed, or canceled closes the interaction for
normal lifecycle updates.
Reason codes
Receipts that reject or otherwise refuse a message SHOULD use one of these reason codes:
| Reason code | Meaning |
|---|---|
malformed | Envelope or body validation failed. |
expired | Freshness validation failed. |
duplicate | The receiver already processed the message ID. |
unsupported_kind | The receiver does not support the message kind. |
unsupported_profile | The receiver does not support the requested profile. |
verification_failed | A trust or proof check failed. |
not_target | The message was directed to a different peer. |
not_found | The target peer or referenced object was not found. |
busy | The target cannot accept work now. |
internal | The receiver hit an internal error. |
interaction_closed | The interaction is already terminal. |
Related pages
- Envelope defines the shared fields every message kind uses.
- Interaction Lifecycle explains how
direct,receipt, andtracecombine into directed work. - Delivery documents freshness, deduplication, and reason-code behavior.
- Examples shows complete flows that use several message kinds together.