A2A support gets an agent onto the network. Production readiness determines whether its work survives restarts, retries, partial failures, tenant boundaries, and client-specific limits.
That distinction became concrete across September 28 and 29, 2026. Atlassian made its Rovo Agent Connector generally available with A2A 1.0 support.[1][2]
The A2A Java SDK released version 1.4.0.Final with changes covering stream handling, push ordering, redirects, multi-tenant card resolution, content types, event-queue recovery, and conformance work.[5]
The JavaScript SDK merged database-backed task and push-notification stores on September 28 and released them in version 1.3.0 on September 29.[9][11]
These releases point to the work that begins after a successful protocol demo. An A2A service needs durable state, task-level authorization, retry safety, ordered delivery, recovery paths, observable operations, tested migrations, and evidence that its advertised capabilities work with real peer implementations.
TL;DR
- A2A defines Agent Cards, messages, tasks, task states, artifacts, transports, streaming, push notifications, and security declarations.[3][4]
- Protocol support does not guarantee durable tasks, idempotent side effects, ordered events, task-level authorization, or restart recovery.
- Persist task status, history, artifacts, ownership, and push configuration before scaling long-running work.[9][10][11]
- Commit accepted work before dispatching it. A task record and an outbox entry should cross the same transaction boundary.
- Treat SSE and push as delivery systems with sequence, reconnect, retry, and dead-letter behavior. They do not create exactly-once execution.[3][6][7]
- Test protocol requirements, SDK-to-SDK interoperability, and deployment failure recovery as separate gates.[12][13][16]
- Enforce each vendor's actual profile at an adapter. Atlassian's current Rovo connector supports a 55-second synchronous path and a 900-second streaming path, with Jira-specific task polling, stream resubscription, authentication, artifact, and data-sharing behavior.[2][17]
Protocol support is a compatibility contract
A2A gives clients and servers a shared application model. An Agent Card declares interfaces, protocol versions, capabilities, skills, media types, and security requirements.[3]
The core model defines messages, tasks, task states, histories, artifacts, streaming, push notifications, and task retrieval.[3]
The official bindings cover JSON-RPC, gRPC, and HTTP with JSON.[3][4]
That contract matters because two agents need to agree on fields, states, errors, transports, and capability discovery. It intentionally leaves an agent's internal memory, tools, compute, and deployment architecture to the implementation.[4]
A server can therefore be protocol-correct while storing every task in process memory. It can expose a stream while losing a terminal event during a race. It can authenticate a caller and still fail to authorize access to a specific task. It can advertise push notifications while delivering task updates out of order.
A production review should ask a stricter question: after any supported failure, can the client determine what happened and continue safely?
Make task state durable before adding scale
A2A treats a task as the core unit of action. A task has a server-generated ID, a context ID, status, history, artifacts, and metadata.[3]
Clients can retrieve tasks and resubscribe to active work.[3]
Those operations require a dependable source of truth. If task state or push configuration exists only in memory, a process restart changes the observable meaning of the protocol. A known task can disappear. A completed artifact can become unavailable. A callback can be forgotten. A worker can continue a side effect after the API loses the state needed to report it.
The JavaScript SDK's persistence release makes that boundary visible. Version 1.3.0 added database-backed task and push-notification stores with support for PostgreSQL, MySQL, SQLite, and Cloudflare D1.[9][10][11]
The persistence documentation includes explicit migrations rather than silently applying schema changes during service startup.[10]
A database alone is insufficient. Define the transaction boundary between accepting a message, creating a task, and dispatching work.
A useful pattern is:
- Authenticate and authorize the request.
- Check for a previous request with the same caller, tenant, and message ID.
- Commit the task, input message, ownership fields, and an outbox record in one transaction.
- Return an accepted task only after the transaction commits.
- Let a worker claim the outbox record and begin execution.
This avoids two common failures. Accepted work cannot live only in a queue, and queued work cannot exist without a durable task record.
A2A defines a message ID created by the message originator. It does not define that ID as an exactly-once execution guarantee.[3] Store a deduplication record scoped to the verified caller and tenant. Return the prior result when a safe retry repeats the same request. Reject reuse of an ID with different content.
Commit state before dispatching work
The smallest durable flow has four parts: request validation, one transactional commit, worker execution, and ordered event delivery.
Commit the task and dispatch intent together, then let workers and delivery components operate from durable state.
A2A client
-> authenticated request
A2A edge
-> transaction: task + message + owner + outbox
Worker
-> ordered state and artifact commits
Delivery
-> SSE or validated push
Client reconnect
-> authorize again and read authoritative task state
The task database is the source of truth. Streams and callbacks are delivery paths over committed state.
Treat streams and push as delivery systems
Streaming and push are where clean protocol diagrams meet unreliable networks.
The Java 1.4.0.Final release contains several examples.[5]
One change preserves push-notification order per task.[7]
Another prevents several completion, error, parsing, or cancellation paths from invoking more than one terminal callback in the Java client.[8]
A third adds configurable SSE parser limits and avoids advancing the last event ID after a skipped or corrupt event block.[6]
These are SDK implementation changes, not new protocol guarantees. They show the failure modes a production design must handle.
State delivery semantics explicitly:
- Validate task-state transitions before commit.
- Give events within one task a stable sequence or cursor.
- Let consumers discard duplicates and detect gaps.
- Produce one terminal application callback per stream consumer.
- Resume from a known cursor or retrieve the task's authoritative state.
- Bound push retries and record every attempt.
- Move exhausted notifications to an operator-visible dead-letter state.
Many practical delivery paths are at least once. Exactly-once side effects require idempotency at the business operation. SSE, HTTP, queues, and callback retries cannot supply that guarantee on their own.
Push notifications add a security boundary. Webhook callers should authenticate requests, apply timeouts and bounded retries, and validate callback URLs against SSRF. Receivers should verify authenticity and task ID, process duplicates idempotently, apply rate limits, and use HTTPS. Push carries a StreamResponse; clients can use GetTask to poll or retrieve final state after a notification.[3]
Bind authorization to the task and tenant
Agent Cards can declare API key, HTTP, OAuth 2.0, OpenID Connect, or mutual TLS security schemes.[3]
The A2A specification says credentials should not appear in public Agent Cards and authorization should be checked on every request, especially when a task ID is supplied.[3]
A task ID is a locator. It is not proof that a caller may read, cancel, subscribe to, or configure notifications for that task.
Persist the ownership fields required for authorization. A common model includes tenant, owning principal, agent identity, and delegated subject. Apply the same authorization boundary to task history, artifacts, cancellation, subscription, and push configuration.
If an interface uses A2A's tenant routing field, treat it as routing input until verified identity and application policy bind it to an authorization decision. The protocol keeps that value opaque and does not define its tenancy policy.[3]
Atlassian's connector adds another layer. Every request to the remote agent includes a Forge Invocation Token, which the remote service verifies against Atlassian's JWKS endpoint. Optional app-user and app-system tokens support authorized calls back to Jira.[17]
The initial work-item request can include the work item's ID, key, summary, description, invocation metadata, and the triggering comment for comment events. The remote agent must fetch additional Jira data with credentials that respect the invoking user's permissions.[17]
Test three different systems
One green integration test cannot prove production readiness. Separate the test plan into three layers.
Protocol requirements
The A2A Technology Compatibility Kit runs requirement-oriented checks across gRPC, JSON-RPC, and HTTP with JSON. It groups tests by MUST, SHOULD, and MAY requirement levels and produces reports.[12]
Run the relevant MUST checks for every binding the Agent Card advertises. Review SHOULD failures as product decisions rather than ignoring them because they are non-blocking.
Implementation pairs
The Integration Test Kit exercises SDKs and versions against each other. Its scenarios include standard requests, streaming, push notifications, and task resubscription across primary transports.[13]
This catches pair-specific failures that a server-only test suite cannot expose. A client and server can each pass isolated tests while disagreeing on translation, fallback, content types, or lifecycle behavior.
The deployed service
Restart the API and worker between task states. Drop a stream after part of an artifact. Repeat a request after a client timeout. Delay push delivery until a later state is ready. Rotate credentials during active work. Fail a migration. Run a mixed-version rolling deployment.
These tests cover the system you built. A protocol suite cannot infer its database, queue, transaction boundary, or recovery behavior.
Conformance language needs precision. Java 1.4.0.Final added ACTS-related behaviors and CI integration.[5][16]
The tagged workflow keeps the ACTS job advisory and notes that the full MUST gate is not currently passing across SDKs.[16]
The mirrored ACTS material points to active upstream conformance work.[14][15]
Describe the exact SDK version, protocol version, binding, suite revision, date, and result. Do not collapse that evidence into a generic certification claim.
Design for the client you actually have
A general A2A service can support long-running tasks through streaming, resubscription, polling, or push. A specific client or connector may expose a narrower profile.
Atlassian's Rovo Agent Connector gives synchronous calls 55 seconds and streaming calls up to 900 seconds.[2][17]
For asynchronous task lifecycles, Jira polls GetTask until the task reaches a terminal state. Streaming starts with SendStreamingMessage, can resume with SubscribeToTask, and can include TaskArtifactUpdateEvent messages.[17]
These capabilities change the adapter design. The synchronous path needs an internal deadline below 55 seconds. The streaming path needs durable task state, ordered events, and a resubscription path that can recover after disconnects. Polling and streaming should resolve against the same authoritative task record.
Keep vendor behavior at the edge. The core service should own tasks, authorization, execution, artifacts, and durable events. A Rovo adapter should handle Forge token verification, the synchronous or streaming deadline, Jira's polling and resubscription behavior, artifact updates, and permission-aware access to additional Jira data.
A production reference flow
A practical request path looks like this:
- The client retrieves the Agent Card and selects a supported A2A interface.
- The edge validates credentials, protocol version, audience, tenant, limits, and requested skill.
- The API authorizes the operation and checks for an existing deduplication record.
- One transaction creates the task, appends the input message, records ownership, and inserts an outbox item.
- The API returns the task or opens a stream after the transaction commits.
- A worker claims the outbox item and commits ordered status and artifact updates.
- A delivery component reads committed events for SSE or push, records attempts, and validates callback destinations.
- After a disconnect or restart, the client retrieves or resubscribes to the task. The server authenticates and authorizes the caller again.
- Logs, traces, and metrics carry task ID, context ID, caller, tenant, transport, protocol version, state transition, and delivery attempt without exposing credentials or sensitive payloads.
For the Rovo synchronous path, set an internal deadline below 55 seconds. For streaming, enforce the 900-second ceiling and persist enough state for polling and resubscription. Define whether unfinished work is cancelled or detached. Do not leave the caller with an ambiguous response while an untracked side effect continues.[2][17]
The production gate
Before launch, require evidence for these questions:
- Does task state survive API, worker, queue, and database restarts?
- Can a retried message avoid repeating an unsafe side effect?
- Are transitions and notifications ordered within each task?
- Can a client recover after stream loss without missing the final state?
- Does every task operation enforce tenant and principal authorization?
- Are push destinations protected against SSRF and redirect abuse?
- Do migrations have tested forward, rollback, and mixed-version procedures?
- Do advertised Agent Card capabilities match deployed behavior on every binding?
- Do protocol, cross-SDK, and deployment failure tests run in CI?
- Does each vendor adapter enforce its synchronous and streaming deadlines, lifecycle, authentication, artifact, and data-sharing rules?
- Can an operator reconstruct a task, replay a safe delivery, and stop unsafe work?
A2A production readiness is an operating property of the deployed service. The protocol makes agents reachable. Durable state, authorization, recovery, and tested delivery make their behavior dependable when the network, process, database, or peer implementation fails.
Frequently asked questions
Does A2A guarantee durable task storage?
No. A2A defines task behavior and retrieval operations. The implementation chooses how to persist tasks, histories, artifacts, ownership, and notification configuration.
Does a message ID prevent duplicate execution?
No. Use it as part of an application-level deduplication key scoped to the authenticated caller and tenant. Downstream side effects still need idempotency where possible.
Are A2A streams exactly once?
No. Implement ordering, duplicate detection, gap detection, reconnect behavior, and authoritative task retrieval. Business side effects need their own idempotency controls.
What should an Agent Card advertise?
Advertise only the versions, interfaces, transports, skills, security schemes, media types, and optional capabilities that the deployed service can support and test.[3]
How is Rovo's connector different from a general A2A client?
Rovo currently applies a 55-second synchronous limit and a 900-second streaming limit. Jira can poll tasks, resubscribe to streams, receive artifact-update events, and authenticate remote calls with Forge Invocation Tokens. Keep those behaviors in a dedicated adapter.[2][17]
Sources
[1] https://developer.atlassian.com/changelog
[2] https://developer.atlassian.com/platform/forge/manifest-reference/modules/rovo-agent-connector
[3] https://a2a-protocol.org/latest/specification
[4] https://github.com/a2aproject/A2A/blob/main/README.md
[5] https://github.com/a2aproject/a2a-java/releases/tag/v1.4.0.Final
[6] https://github.com/a2aproject/a2a-java/pull/1149
[7] https://github.com/a2aproject/a2a-java/pull/1156
[8] https://github.com/a2aproject/a2a-java/pull/1173
[9] https://github.com/a2aproject/a2a-js/releases/tag/v1.3.0
[10] https://github.com/a2aproject/a2a-js/blob/0f2e563fb134dd9cb59c3b3b978a7f02e7760d16/docs/persistent-stores.md
[11] https://github.com/a2aproject/a2a-js/pull/756
[12] https://github.com/a2aproject/a2a-tck/blob/main/README.md
[13] https://github.com/a2aproject/a2a-itk/blob/main/README.md
[14] https://github.com/a2aproject/a2a-itk/blob/main/scenarios/acts/suite.acts.yaml
[15] https://github.com/a2aproject/a2a-itk/blob/main/scenarios/acts/PROVENANCE.md
[16] https://github.com/a2aproject/a2a-java/blob/v1.4.0.Final/.github/workflows/acts.yaml
[17] https://developer.atlassian.com/platform/forge/remote-agents-in-jira — Use remote agents in Jira

Top comments (0)