Skip to content

A2A conformance matrix

synapse a2a-conformance prints the local Agent2Agent bridge matrix. The matrix is an inventory, not a certification: it maps the bridge to the A2A 1.0.0 operation model and keeps the remaining gates visible after each independent client, conformance, webhook, and deployment receipt.

Comparison sources:

Usage

synapse a2a-conformance
synapse a2a-conformance --json
synapse a2a-conformance --status partial

Status labels:

Status Meaning
supported Covered by the local bridge and focused repository tests.
partial Implemented with a documented limitation or narrower local semantics.
unsupported Not implemented by the local bridge.
external Requires independent infrastructure, client, or operator validation.

Current bridge boundaries

The bridge currently exposes Agent Card discovery, HTTP+JSON/REST routes, JSON-RPC dispatch, bridge-local task storage, local Server-Sent Events snapshots, push-notification configuration storage, and authenticated task-scoped delivery evidence. The matrix marks these as supported or partial according to the local behavior and its limits.

The HTTP+JSON edge derives exact Host authorities from the advertised endpoint on every CLI start and enforces them before authentication and routing on every route. A present browser Origin is independently denied unless explicitly permitted with --allow-origin; origin-less clients still require the exact Host. Direct HTTP handler construction fails closed without an advertised or explicit trusted authority.

The optional gRPC row remains partial because --grpc-port starts only the custom JSON-over-gRPC SendMessage / GetTask subset, not the generated official protobuf surface. The listener is default-off. When enabled, the integrated CLI composes the selected shared bearer, native TLS/mTLS files, request-concurrency ceiling, one-MiB receive/send bounds, bounded JSON parser, finite call-deadline ceiling, and stable value-free errors into gRPC. The shared bearer is not per-client identity or a method-level ACL. See the current gRPC activation boundary.

The real-webhook row is partial: focused tests deliver to real local HTTPS receivers with a test CA, follow a real 307 proxy redirect, and block a delivery-time DNS rebinding attempt before send. Authenticated redirect tests refuse 301/302/303, cross-origin 307/308, and every HTTPS downgrade; exact same-origin 307/308 preserve the POST body and sensitive header under a bounded five-redirect policy. Remote public receivers, initial authenticated-URL HTTPS enforcement, and operator-visible deployment receipts remain external.

Expected push network failures follow a fixed, bounded three-attempt policy: immediate, 0.25 seconds, then one additional second. The bridge commits the A2A task transition before notification delivery, so exhaustion cannot rewrite task truth. A configured state file separately commits a per-update delivery id, per-attempt task/config ids, attempt number, value-free failure class, retry schedule/window, and final succeeded or dead-lettered state. URL, headers, payload, credentials, and exception text are excluded. Authenticated operators can read this SYNAPSE extension at GET /tasks/{id}/pushNotificationDeliveries or JSON-RPC tasks/pushNotificationDelivery/list; this evidence is local bridge state, not an external receiver acknowledgement or cross-replica outbox guarantee.

The deployment-threat-model row is also partial: the local review records the required exposed-bridge posture for bearer auth, TLS/proxy placement, state-file permissions, webhook egress, retention, logging, and receipts. Concrete production deployment sign-off remains external.

Independent interoperability is partial. On 2026-07-10 the official a2a-sdk==1.1.0 selected its HTTP+JSON RestTransport from the live Agent Card and completed send, get, list, and cancel. The official TCK at 5996b79 (A2A specification commit 1736957) finished its HTTP+JSON MUST run with 55 passed, 5 failed, and 175 skipped pytest cases; all Agent Card, wire timestamp, version-negotiation, media-type, AIP-193 error, and unknown-task checks exercised by the run passed. The five residual failures were response-content scenarios (four structured artifacts + one direct Message).

The bridge now answers those residual scenarios on the shipped message:send path when the request matches official TCK messageId prefixes (tck-artifact-text-*, tck-artifact-file-*, tck-artifact-file-url-*, tck-artifact-data-*, tck-message-response-*) or an explicit a2aScenario / synapseScenario metadata or configuration value. Ordinary chat sends still return an asynchronous working Task and forward into SYNAPSE. A fresh official TCK re-run is optional evidence — these claims rest on in-repo residual tests of production dispatch.

Outbound synapse a2a-client and the in-tree synapse a2a-interop-trace provide deterministic second client stack for discovery, message:send, and GET /tasks/{id} over HTTP and HTTPS (native TLS via a2a-serve --tls-certfile / --tls-keyfile, with --ca-file or --tls-insecure on the client). These clients and a2a-serve accept owner-only, same-descriptor --a2a-token-file credentials with explicit argv-over-file precedence. Outbound bearer-over-HTTP is refused outside a literal loopback IP unless the operator explicitly supplies --a2a-allow-insecure-http. Both clients also cap responses at one MiB, enforce 64-level nesting and 4,096 cumulative JSON members, sanitize peer-controlled failures, and atomically write owner-only receipts. These controls do not add certificate pinning or outbound client-certificate identity. These receipts are not certification or full conformance. An outbound external-server pass, public webhook, reverse-proxy production sign-off, durable-history, and operator receipts remain open — record them with A2A bridge validation receipts.