Shared wire protocol types for the AgentD ecosystem
A tiny Go module containing the shared wire protocol types used by both the AgentD daemon and AgentD relay server. By importing from a single source of truth, wire format drift between repos is impossible — the Go compiler enforces type identity.
| File | Types | Purpose |
|---|---|---|
envelope.go |
RelayEnvelope |
Encrypted message envelope (sid, seq, enc, tid) |
control.go |
ControlMessage, ControlType (18 constants), 17 payload structs |
Relay control protocol |
policy.go |
PolicyJSON, PolicyMatchJSON |
Policy rule wire format |
capabilities.go |
AgentCapability |
Per-agent feature flags the daemon emits to the PWA (MCP reconnect, session-scoped approvals, free-text replies, etc.) |
codex_sandbox.go |
CodexSandboxMode |
Shared Codex per-session sandbox literals for daemon and PWA runtime controls |
replay.go |
ReplayRequest, ReplayCompletePayload, SessionSnapshotRequest, SessionSnapshotPayload |
Durable session journal replay recovery and daemon-owned active-session snapshots |
trace.go |
NewTraceID(), ValidTraceID() |
W3C-compatible trace ID generation |
register · join · heartbeat · ack · error · sync_policies
status_update · audit_entry · deactivate_developer · client_connected
client_count · key_rotate · entitlement_update · entitlement_violation
push_notify · push_notify_result
terminate_session · terminate_session_ack
RegisterPayload · JoinPayload · AckPayload · ErrorPayload
StatusUpdatePayload · AuditEntryPayload · DeactivateDeveloperPayload
TerminateSessionPayload · TerminateSessionAckPayload
ClientConnectedPayload · ClientCountPayload · KeyRotatePayload
SyncPoliciesPayload · EntitlementUpdatePayload · EntitlementViolationPayload
PushNotifyPayload · PushNotifyResultPayload
import protocol "github.com/hishamkaram/agentd-protocol"
env := protocol.RelayEnvelope{
SessionID: "sess-123",
Seq: 1,
Encrypted: ciphertext,
TraceID: protocol.NewTraceID(),
}Both agentd and agentd-relay use type aliases to re-export these types under their internal/relay package, so existing code using relay.RelayEnvelope continues to work unchanged.
Replay recovery is daemon-owned: the PWA sends ReplayRequest{after_seq} when it detects a gap in the inner per-session AgentMessage.seq, and the daemon responds with replayed AgentMessage frames followed by replay_complete. Route-bound reconnects can request SessionSnapshotRequest first so the active chat view is rebuilt from daemon state before broad replay. RelayEnvelope.seq remains the outer transport sequence for relay delivery and is not the cursor used for UI replay.
Relay joins may also carry optional nav_session_id metadata. The relay forwards that value in ClientConnectedPayload so the daemon can prioritize the active session snapshot, while legacy clients omit the field and keep the existing replay behavior.
- Zero dependencies — only
encoding/json,time,crypto/rand,encoding/hexfrom stdlib - Backward compatible — all new fields use
omitempty; old clients produce identical JSON - W3C trace IDs — 32 lowercase hex chars, ready for OpenTelemetry upgrade
- Roundtrip tested — every type has a JSON marshal/unmarshal roundtrip test
This module follows Semantic Versioning with one
nuance: while in v0.x (initial development), wire-additive changes
bump the MINOR version, not patch — since consumers (agentd,
agentd-relay) are expected to opt in to each new field.
| Bump | Trigger |
|---|---|
MAJOR (v0.x → v1.0, v1 → v2 requires /v2 import path) |
Removed field, renamed JSON tag, removed message type |
MINOR (v0.1.0 → v0.2.0) |
Wire-additive change: new message type, new field on existing struct, new capability flag |
PATCH (v0.1.0 → v0.1.1) |
No wire-format change: doc fix, test improvement, dep bump |
See CHANGELOG.md for the per-release wire-type
inventory. Tags are pushed manually after a wire-additive PR merges to
main. Consumers may pin via the tag (v0.1.0) or via a Go
pseudo-version (v0.0.0-<timestamp>-<sha>) — both are supported.