A2A 1.0-alpha migration — spike findings
Spike branch: feature/a2a-1.0-alpha-spike. Bumped @a2a-js/sdk ^0.3.13 → 1.0.0-alpha.0. Result: installs clean (430 pkgs); tsc --noEmit surfaces 129 errors that map 1:1 to the A2A 1.0 breaking changes. This doc is the grounded input for ADR-0006 + the blog post.
Blast radius — contained to the A2A layer
| File | Errors | Role |
|---|---|---|
src/executor/executors/a2a-executor.ts | 61 | A2A client — heaviest (transport removal, Part, request shapes, method renames) |
src/api/a2a-server.ts | 11 | A2A server — event discriminators, Part, push store, ServerCallContext |
src/storage/push-notification-store.ts | 2 | PushNotificationStore interface changed |
src/api/agent-card.ts | 2 | AgentCard restructure |
src/plugins/skill-broker-plugin.ts | 2 | Card consumption |
| Source subtotal | ~78 | only ~5 source files |
src/api/__tests__/a2a-server.test.ts | 36 | assertions on old shapes |
src/api/__tests__/agent-card.test.ts | 13 | card-shape assertions |
| (other tests) | 3 | extension-registry, push-store |
Key finding: the A2A layer was well-encapsulated, so a protocol-version rewrite touches only ~5 source files. The bus contract insulated the rest of the codebase entirely.
Breakage classes (by TS code → migration cause)
- TS2339 ×65 ("property does not exist") —
Part.kind/Part.textgone (Part redesign → JSON-member discrimination),status-update.finalgone (closure = done),task.statusaccess. - TS2367 ×16 ("comparison no overlap") — old state strings (
"completed") +"status-update". - TS2820 ×6 — event discriminator rename
"status-update"→"statusUpdate". - TS2345 ×10 ("arg not assignable") —
SendMessageRequest/GetTaskRequestshapes changed. - TS18048 ×8 —
task.statusnow optional (stricter null safety). - TS2322 ×7 —
Roleenum ("user"→ROLE_USER), PushNotificationStore type. - TS2551/2724 —
setTaskPushNotificationConfig→createTaskPushNotificationConfig; renamed exports. - TS2554 —
ServerCallContextnow a mandatory 2nd arg (#405).
Migration delta reference (0.3 → 1.0)
- Methods:
message/send→SendMessage,tasks/get→GetTask, +ListTasks. - States: kebab →
TASK_STATE_*SCREAMING_SNAKE. - Role:
user/agent→ROLE_USER/ROLE_AGENT. - Part: no
kind; member discrimination;file.fileWithUri→url;mimeType→mediaType. - AgentCard:
url/preferredTransport/additionalInterfaces/protocolVersion→supportedInterfaces[]. - Stream events: drop
final; wrapped discrimination (taskStatusUpdate/taskArtifactUpdate). - SDK: JSON-RPC client removed (#353),
A2AExpressAppremoved (#363),ServerCallContextmandatory (#405), Node 18 dropped (#368). - Errors: RFC 9457 →
google.rpc.Status. OAuth implicit/password removed, +DeviceCode/PKCE. AgentCard JWS signatures.
Fleet risk
0.3↔1.0 backward-compat is an OPEN upstream issue (a2a-js #452). Rollout decision: flag day — coordinated cutover of the whole fleet at once. No dual-stack. Requires the census (every A2A node's current SDK/version) to be complete before the cutover window.