Chapter 8 — Transports

Status: Normative for §8.1 through §8.4. Informative for §8.5 through §8.10.


This chapter specifies the transport-agnostic requirements that any underlying transport carrying AAEP messages MUST satisfy. AAEP is deliberately transport-neutral: the same protocol semantics work over Server-Sent Events, WebSocket, local IPC, gRPC, stdio, or any other channel that satisfies the requirements here.

After the normative section, this chapter provides an informative survey of recommended transport bindings, with selection guidance. Concrete protocol-level details for each binding are in Appendix B (Transport bindings).

8.1 The transport abstraction principle

AAEP's wire format is JSON. AAEP's exchange model (events flowing from producer to subscriber, reply messages flowing from subscriber to producer) is independent of how those JSON messages are physically transmitted. A producer running in a Python process emitting JSON to stdout, a producer running in a cloud server pushing JSON over Server-Sent Events, and a producer running in a desktop application writing JSON to a Windows named pipe are all equally conforming as long as the messages they emit and accept conform to this specification and the transport they use satisfies the requirements in §8.2.

This abstraction has three important consequences:

  1. Implementers choose the transport that fits their deployment. A web application uses SSE or WebSocket. A native desktop application uses local IPC. A command-line tool spawned by a subscriber uses stdio. A high-throughput multi-tenant service uses gRPC. None of these choices change anything about the messages.

  2. Producers and subscribers can switch transports. A subscriber that fails to connect over WebSocket may retry over SSE without renegotiating its capabilities at the AAEP level. Transport selection is below AAEP.

  3. Transports can be added later. Future transports (QUIC streams, distributed pub-sub, peer-to-peer overlays) can carry AAEP without changes to this specification. Adding a transport is an extension activity (see Chapter 7 §7.1, capability 5).

8.2 Normative transport requirements

The following requirements apply to ALL transports used to carry AAEP messages. A transport that does not satisfy these requirements is non-conforming, and producers/subscribers using such a transport cannot claim AAEP conformance.

8.2.1 Message integrity

The transport MUST deliver each AAEP message to the receiver byte-identical to the form in which the sender emitted it. Any transport that may corrupt, truncate, or alter messages in transit is non-conforming.

This is typically satisfied automatically by any transport with adequate framing (HTTP, WebSocket frames, IPC message boundaries, JSON-RPC line delimiters). Implementers using raw TCP or other unframed transports MUST add their own framing.

8.2.2 Message boundaries

The transport MUST preserve the boundaries between AAEP messages. The receiver MUST be able to identify where one JSON message ends and the next begins, without parsing the JSON content itself.

Approved framing strategies include:

A transport that relies on the receiver parsing JSON to find message boundaries (no framing) is non-conforming because malformed JSON cannot be recovered from in a stream.

8.2.3 Ordered delivery within a session

The transport MUST deliver messages of a single session to a single subscriber in the order the producer emitted them. The transport MAY reorder messages across sessions or across subscribers.

If the transport cannot guarantee ordering (e.g., UDP-based transports), producers MUST emit sequence_number on every event, and subscribers MUST detect out-of-order events and either reorder them before processing or signal a protocol error to the producer.

8.2.4 At-least-once delivery

The transport MUST deliver each message at least once. Lost messages are non-conforming.

The transport MAY deliver messages more than once (duplicate delivery). Subscribers MUST be prepared to deduplicate using event_id. Producers MUST emit unique event_id values per event (per §3.2.3).

8.2.5 Connection lifecycle signals

The transport MUST provide signals to both parties when the connection terminates, whether gracefully (the other party closed) or abruptly (network failure, process crash). Both producers and subscribers MUST handle disconnection by:

8.2.6 Bidirectional capability when reply messages are required

Transports used at Conformance Level 2 or higher MUST support reply messages from subscriber to producer. SSE alone does not (SSE is one-way from server to client); SSE deployments at Level 2 MUST pair SSE for producer-to-subscriber events with HTTP POST or a separate channel for subscriber-to-producer replies.

Transports that are intrinsically bidirectional (WebSocket, gRPC bidirectional streams, IPC) MAY carry both directions on the same connection.

8.2.7 Authentication hooks

The transport MUST provide a mechanism by which one party can authenticate the other. Acceptable mechanisms include:

Transports lacking authentication mechanisms (plain HTTP, anonymous TCP, anonymous IPC over public sockets) are non-conforming for production use. They MAY be used for local development if the security implications are understood; conformance testing on such transports is permitted only with explicit warnings.

8.2.8 Confidentiality for non-local transports

Transports that traverse a network MUST encrypt traffic in transit. Acceptable mechanisms:

Transports operating purely within a single host (Unix domain sockets, Windows named pipes, stdio) MAY omit transport encryption since OS-level protections suffice. Implementers running such transports across hosts MUST add encryption.

8.3 Maximum message size

The transport MUST support messages up to at least 64 KiB in size (consistent with the AAEP envelope size limit in §3.7). Transports that impose smaller maximums are non-conforming.

The transport SHOULD support messages up to 1 MiB to accommodate large extension payloads. Producers SHOULD nevertheless prefer to split large content across multiple events rather than transmit single large events.

8.4 Transport selection in subscription handshake

The transport in use at the time of subscription is implicitly chosen by the subscriber initiating the connection. The subscription handshake (subscription.request) does not normally specify the transport, since the handshake messages themselves are travelling over the transport.

However, a producer manifest (§5.10) MAY advertise multiple supported transports. A subscriber that can choose may select based on its capabilities; producers MAY redirect a connection to a different transport (e.g., HTTP 307 redirect, WebSocket upgrade response) if the transport offered does not match the producer's preferences.

The full lifecycle of transport selection, fallback, and reconnection is documented in Appendix B.


The remainder of this chapter is informative.

The following transports are RECOMMENDED bindings. Each has trade-offs that suit different deployment contexts. Implementers SHOULD choose based on their environment rather than uniformity for its own sake.

8.5.1 Server-Sent Events (SSE)

When to use: Web applications where the agent runs server-side and the subscriber is in a browser. Particularly suited when the subscriber is a screen reader integrated into a web-based UI, a captioning overlay, or a server-rendered accessible interface.

Pros:

Cons:

Reference binding details: Appendix B §B.1.

8.5.2 WebSocket

When to use: Web applications requiring full bidirectional flow, where replies, renegotiation, or push notifications need lowest latency.

Pros:

Cons:

Reference binding details: Appendix B §B.2.

8.5.3 Local IPC: Windows named pipes

When to use: Desktop integration where the AAEP producer runs as a desktop application or service and the subscriber is a screen reader, voice control software, or other AT installed locally on Windows.

Path convention: \\.\pipe\aaep\<producer-id>

Pros:

Cons:

Reference binding details: Appendix B §B.3.

8.5.4 Local IPC: Unix domain sockets

When to use: Desktop integration on macOS, Linux, BSD where producer and subscriber share a host.

Path convention: $XDG_RUNTIME_DIR/aaep/<producer-id>.sock (Linux/BSD) or ~/Library/Application Support/AAEP/<producer-id>.sock (macOS).

Pros:

Cons:

Reference binding details: Appendix B §B.4.

8.5.5 gRPC bidirectional streams

When to use: Multi-tenant or enterprise deployments where strong typing, low latency, and binary efficiency matter more than universality.

Pros:

Cons:

Reference binding details: Appendix B §B.5.

8.5.6 stdio JSON-RPC

When to use: When a subscriber spawns a producer as a child process and communicates over stdin/stdout (or vice versa). This pattern is common for desktop assistive technology launching agent processes, and for the Model Context Protocol's local server pattern.

Format: JSON-RPC 2.0 messages framed by newline (one JSON object per line). AAEP messages are wrapped in JSON-RPC request/response envelopes.

Pros:

Cons:

Reference binding details: Appendix B §B.6.

8.6 Transport selection guidance

The following table summarizes recommended transport selection for common deployments. The advice is informative; many other combinations work.

Deployment Recommended primary transport Alternative
Browser-based subscriber, agent in cloud SSE + HTTP POST for replies WebSocket
Browser-based subscriber, agent in browser WebSocket (in-page) postMessage with framing
Desktop AT (Narrator, NVDA), local agent Windows named pipes (Windows); Unix domain sockets (macOS/Linux) stdio JSON-RPC
Desktop AT, agent in cloud WebSocket SSE + HTTP POST
Mobile screen reader, mobile agent Platform IPC (UIAccessibility on iOS, AccessibilityService on Android, AAEP transport binding TBD) stdio JSON-RPC for prototypes
Multi-tenant enterprise gRPC WebSocket with mTLS
Sandbox or browser extension subscriber postMessage with framing, WebSocket via tunnel, or HTTP+SSE stdio JSON-RPC if subprocess permissions exist
CLI debug tool stdio JSON-RPC SSE or WebSocket if debugging cloud agents
OS-level voice control Windows named pipes or Unix domain sockets Platform-specific IPC
Tests, replays, captures Newline-delimited JSON on filesystem stdio JSON-RPC

8.7 Reconnection semantics

When a transport connection fails, the subscriber MAY reconnect. The semantics of reconnection depend on the transport:

In all cases, if a subscriber reconnects while the producer is mid-session, the producer SHOULD send the subscriber an agent.state.changed event summarizing the current state to bring the subscriber up to speed.

8.8 Backpressure at the transport layer

Backpressure (Chapter 5 §5.6) is primarily a producer-level concern: the producer holds events and coalesces based on the subscriber's declared rate. However, transports also have their own buffering and flow control:

Producers SHOULD treat transport-layer write blocking as a signal to slow event emission to that subscriber, even if the negotiated rate is technically not yet reached. Subscribers SHOULD read promptly to prevent transport-layer backpressure from masking AAEP-layer rate negotiation.

8.9 Diagnostics and observability

All transports SHOULD support diagnostic mechanisms compatible with standard tooling:

The AAEP project's aaep-capture tool (in tools/aaep-capture/) provides cross-transport capture and replay for debugging.

8.10 Where to go next

Readers should now proceed to Chapter 9 (Conformance), which specifies the three conformance levels (Notification, Interactive, Negotiated) and their normative requirements.

Implementers selecting a specific transport should consult Appendix B (Transport bindings) for concrete code-level details of each binding, including header values, URL paths, error codes, and reference examples.