@ssheleg/agent-stack 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,94 @@ All notable changes to this project are documented here.
4
4
  Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
  Versioning: [SemVer](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.7.1] - 2026-08-14
8
+
9
+ A red `validate` could not stop a publish anywhere in this family, and one member
10
+ proved it: on 2026-08-12 `sheleg-dev` tagged v0.4.1 while its own validate run for that
11
+ exact tag **failed**, and npm served 0.4.1 four minutes later.
12
+
13
+ ### Fixed
14
+
15
+ - **The release now runs the whole validate suite before anything is published.**
16
+ `validate.yml` gained a `workflow_call` trigger and `release.yml` calls it with
17
+ `needs: validate` — the release runs *after* the real suite rather than beside a copy
18
+ of it. **Not one plant is duplicated:** each still has exactly one home.
19
+ - **A guard keeps the connection there.** It fails when the trigger, the call, or the
20
+ `needs` goes missing — calling the suite without depending on it lets the jobs run in
21
+ parallel, which looks gated and is not. Watched failing against the planted removal.
22
+
23
+ Proven end to end on `sheleg-dev` v0.4.3 before it reached here: the release run shows
24
+ `validate / validate` completing first, then `release`, then `publish`.
25
+
26
+ ## [0.7.0] — 2026-08-14
27
+
28
+ ### Added
29
+
30
+ - **`agent-interop`, a third skill — the protocol layer between processes.** The pack
31
+ could build an agent (`agent-orchestrator`) and prove it behaved (`agent-evals`), and
32
+ said nothing about how either talks to anything outside its own process. Six references:
33
+ MCP's wire surface, running many servers at once, shipping a server so a client can
34
+ actually reach it, the registry, A2A, and the gateway layer. It is its own skill rather
35
+ than a reference under `agent-orchestrator` because both existing descriptions sit at
36
+ ~91% of the 1024-character budget — measured, not estimated — and "write me an MCP
37
+ server" matches neither of their triggers.
38
+
39
+ - **`references/mcp.md`** — MCP pinned at revision `2026-07-28`, written around the part
40
+ that breaks code written from memory: the protocol is now **stateless**, the `initialize`
41
+ handshake is gone in favour of `server/discover`, and version plus capabilities ride in
42
+ `_meta` on every request. The full deprecation register with migration paths —
43
+ **sampling, roots, logging and dynamic client registration are all on the way out**,
44
+ which is precisely the set an older model reaches for first. Plus notifications as opt-in
45
+ `subscriptions/listen` streams, `ttlMs` / `cacheScope` caching, and the fact that a
46
+ failed tool arrives as `isError: true` inside a 200.
47
+
48
+ - **`references/mcp-scale.md`** — the two distinct costs of many servers and the pattern
49
+ for each: progressive discovery for *when* definitions enter context (with the published
50
+ 1–5% threshold), programmatic tool calling for *how* tools are invoked. Includes the
51
+ interaction that turns a clever discovery scheme into a regression — most providers cache
52
+ the prompt prefix **including the `tools` array**, so mutating it mid-conversation can
53
+ cost more than the definitions it removed.
54
+
55
+ - **`references/mcp-ship.md`** — mounting a server inside an existing app, transport-level
56
+ auth, client config in both forms, and the 404 that is really FastMCP's double path.
57
+ Relocated from `make-skill`, where it had been describing a protocol rather than a skill.
58
+
59
+ - **`references/a2a.md`** — A2A 1.0 under the Linux Foundation: agent cards and the
60
+ `/.well-known/agent-card.json` path, the full `TASK_STATE_*` enum with terminal states
61
+ marked, three protocol bindings with their REST method mapping, and the v0.x→1.0 rename
62
+ spelled out so inherited code is recognisable on sight.
63
+
64
+ - **`references/registry.md`** — `server.json`, reverse-DNS namespaces and the Ed25519
65
+ DNS/HTTP challenge that proves one, the publish flow with its three named failure modes,
66
+ and the registry's three refusals: no private servers, not for direct host consumption,
67
+ not designed for self-hosting.
68
+
69
+ - **`references/gateway.md`** — what a gateway must do that an API gateway does not, stated
70
+ vendor-neutrally, with agentgateway as the named reference implementation. Includes the
71
+ federation trap that bites later: `prefixMode: conditional` renames every tool the day a
72
+ second target is added.
73
+
74
+ ### Changed
75
+
76
+ - **The validator now enforces a revision stamp on protocol references** (`PROTOCOL_PINNED`
77
+ in `test/validate.py`). Prose about somebody else's specification ages silently — a
78
+ reader cannot tell last year's handshake from this year's, and a model writing code from
79
+ it is confidently wrong with no signal anywhere on the page. Every file under
80
+ `agent-interop/references/` must open with `**Spec pinned:** … · read YYYY-MM-DD`, and
81
+ the date must be a real one. Two negative self-tests, both anchored on the stamp's shape
82
+ and both asserting they planted something.
83
+
84
+ - **`test/validate.py` no longer reads `other-skill/references/x.md` as a link of its own.**
85
+ A bare `references/x.md` means this skill's file; a path-qualified one is prose about a
86
+ sibling. Without the lookbehind, stating a boundary against another skill — which
87
+ `agent-interop` must do — failed the build over a file it never claimed. The existing
88
+ dangling-link plant proves the narrowed pattern still catches the real case, and a second
89
+ plant proves it inside the new skill.
90
+
91
+ - **The installer functional test asserts every shipped skill installs**, by enumerating the
92
+ skills directory rather than naming files. `bin/agent-stack.js` already enumerated;
93
+ nothing proved it kept doing so.
94
+
7
95
  ## v0.6.1 — 2026-08-13
8
96
 
9
97
  Two CI fixes that had been sitting on `main` unreleased ship here, and the half of
package/README.md CHANGED
@@ -9,8 +9,9 @@ Part of the [ssheleg skill family](https://github.com/ssheleg/sshlg-skills).
9
9
 
10
10
  ## What is in here
11
11
 
12
- Two skills — `agent-orchestrator` for building one, `agent-evals` for proving it
13
- behaves and five references the first loads on demand.
12
+ Three skills — `agent-orchestrator` for building one, `agent-evals` for proving it
13
+ behaves, `agent-interop` for everything it talks to outside its own process — and
14
+ eleven references they load on demand.
14
15
 
15
16
  **The orchestrator** (`SKILL.md`) — what the agent reads first:
16
17
 
@@ -39,6 +40,22 @@ code checks before model judges, judges calibrated against human labels before
39
40
  they are trusted, and a corpus grown from production failures rather than
40
41
  authored up front — where every fixed failure stays a fixture permanently.
41
42
 
43
+ **The interop skill** (`agent-interop/SKILL.md`) — the protocols an agent speaks
44
+ outside its own process, and the one rule that governs all of them: a protocol claim
45
+ without a date is a guess. Every one of these specifications moved in the last twelve
46
+ months in a way that silently breaks older code — MCP replaced the `initialize`
47
+ handshake with `server/discover` and went **stateless**, deprecated **sampling, roots
48
+ and logging**; A2A renamed its wire surface between v0.x and 1.0; agentgateway
49
+ deprecated `binds` while its own overview page still teaches it. So every reference
50
+ carries a `**Spec pinned:** … · read <date>` line, and the validator fails the build
51
+ without one. Six references: `mcp.md` (the wire and the full deprecation register),
52
+ `mcp-scale.md` (progressive discovery, code mode, and the prompt-cache interaction that
53
+ undoes both), `mcp-ship.md` (mounting, and the 404 that is really a double path),
54
+ `registry.md` (`server.json`, namespace proof, the registry's three refusals),
55
+ `a2a.md` (cards, task states, three bindings), `gateway.md` (what a gateway must do that
56
+ an API gateway does not). Plus a link map, and a verdict on each neighbouring standard —
57
+ ACP, AGNTCY, AP2, Agent Skills — so an agent stops guessing.
58
+
42
59
  **`references/context-engineering.md`** — what the loop gives up when the window
43
60
  runs out: the five-rung compaction ladder and why to re-measure between rungs,
44
61
  the tool-pair boundary invariant, typed carryover blocks copied across the
@@ -122,8 +139,16 @@ audit row has to carry to prove a control was on.
122
139
  trajectory rather than a final answer, turning a production failure into a
123
140
  permanent fixture, calibrating a judge, gating a release on offline evals.
124
141
 
125
- Neither triggers for a single LLM call in a script or for prompt wording — that
126
- is not an orchestrator, and pulling this much doctrine for it is how a skill
142
+ `agent-interop`: building or consuming an MCP server, exposing or calling another
143
+ agent over A2A, publishing to the MCP Registry, or putting a gateway in front of
144
+ agent traffic. Not for designing one server's tool set — that is a design problem,
145
+ and Anthropic's `mcp-server-dev` plugin is built for it — and not for a skill's own
146
+ construction, which is `make-skill`. That boundary runs both ways: `make-skill` keeps
147
+ what changes *because you are writing a skill*, and the protocol itself is described
148
+ here and nowhere else in the family.
149
+
150
+ None of the three triggers for a single LLM call in a script or for prompt wording —
151
+ that is not an orchestrator, and pulling this much doctrine for it is how a skill
127
152
  teaches you to route around it.
128
153
 
129
154
  ---
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ssheleg/agent-stack",
3
- "version": "0.6.1",
4
- "description": "Production patterns for AI agent orchestrators tool-calling loops, multi-stage pipelines with checkpoints, LLM provider routing with fallback, four-layer memory with confidence decay plus the wallet side of reselling LLM access. This package is the installer CLI.",
3
+ "version": "0.7.1",
4
+ "description": "Production patterns for AI agent orchestrators \u2014 tool-calling loops, multi-stage pipelines with checkpoints, LLM provider routing with fallback, four-layer memory with confidence decay \u2014 plus the wallet side of reselling LLM access. This package is the installer CLI.",
5
5
  "bin": {
6
6
  "agent-stack": "bin/agent-stack.js"
7
7
  },
@@ -2,7 +2,7 @@
2
2
  "name": "agent-stack",
3
3
  "displayName": "Agent Stack",
4
4
  "description": "Two skills: agent-orchestrator \u2014 tool-calling loops, multi-stage pipelines with checkpoints, provider routing with fallback, four-layer memory, context engineering, plus the wallet side of reselling LLM access; and agent-evals \u2014 run/trace/thread evals, judges, and fixtures grown from production.",
5
- "version": "0.6.1",
5
+ "version": "0.7.1",
6
6
  "author": {
7
7
  "name": "ssheleg",
8
8
  "url": "https://x.com/sshlg93"
@@ -0,0 +1,172 @@
1
+ ---
2
+ name: agent-interop
3
+ description: >-
4
+ Use when an agent must talk to something outside its own process — building or consuming an
5
+ MCP server, exposing or calling another agent over A2A, publishing to the MCP Registry, or
6
+ putting a gateway in front of agent traffic. Carries the MCP 2026-07-28 wire surface and what
7
+ it deprecated (server/discover, stateless per-request _meta, elicitation in form and URL mode,
8
+ subscriptions/listen; sampling, roots, logging and dynamic client registration on the way out),
9
+ A2A 1.0 agent cards, task states and three bindings, registry namespaces and server.json, tool
10
+ federation, and what a gateway must do that an API gateway does not. Triggers - "MCP server",
11
+ "MCP client", "A2A", "agent card", "agent interoperability", "MCP registry", "server.json",
12
+ "agentgateway", "tool federation", "MCP-сервер", "карточка агента", "интероперабельность
13
+ агентов", "реестр MCP", "шлюз для агентов". Not for designing one server's tool set, and not
14
+ for a skill's own construction — that is make-skill.
15
+ ---
16
+
17
+ # Agent interop — the protocols an agent speaks outside its own process
18
+
19
+ `agent-orchestrator` builds the loop. `agent-evals` proves it behaves. This skill covers
20
+ everything the loop reaches that is **not in its process**: a tool server, a peer agent, a
21
+ registry, and the gateway between them.
22
+
23
+ ---
24
+
25
+ ## Rule zero — a protocol claim without a date is a guess
26
+
27
+ Every one of these specifications moved in the last twelve months, and each moved in a way
28
+ that silently breaks code written against the previous revision. Concretely, and each one
29
+ measured against the live specification rather than recalled:
30
+
31
+ - MCP replaced the `initialize` handshake with `server/discover` and made the protocol
32
+ **stateless**; a client that opens with `initialize` is speaking a revision that is on its
33
+ way out.
34
+ - MCP **deprecated `sampling`, `roots` and `logging`** — three things an older model will
35
+ reach for first, because for a year they were the interesting part of the client side.
36
+ - A2A renamed its wire surface between v0.x and v1.0, and SDKs and blog posts still document
37
+ v0.3.
38
+ - agentgateway **deprecated `binds`** in favour of `gateways` — while its own overview page
39
+ still introduces `binds` as a core concept.
40
+
41
+ So: **every reference in this skill opens with a `**Spec pinned:**` line**, and
42
+ `test/validate.py` fails the build without one. That is a mechanical check, not an
43
+ aspiration — the class of error it prevents is the one where prose reads as current
44
+ because nothing on the page says otherwise.
45
+
46
+ **Before you write wire-level code, fetch the spec.** These references tell you what to look
47
+ for and what changed; they are not a substitute for the document. Read the pinned revision,
48
+ then check whether a newer one exists. Every entry in the link map below is fetchable.
49
+
50
+ ---
51
+
52
+ ## Which protocol answers which question
53
+
54
+ | The question you actually have | The answer | Where |
55
+ |---|---|---|
56
+ | I want to give a model a capability against a live system | **MCP server** | `references/mcp.md` |
57
+ | My server is written and the client cannot connect to it | mounting and transports | `references/mcp-ship.md` |
58
+ | I want my application to consume other people's tool servers | **MCP client** | `references/mcp.md`, then `references/mcp-scale.md` |
59
+ | I have more servers than fit in a context window | client scaling patterns | `references/mcp-scale.md` |
60
+ | I want another team's *autonomous agent* to accomplish an outcome for me | **A2A** | `references/a2a.md` |
61
+ | I want my agent discoverable and callable by other agents | **A2A agent card** | `references/a2a.md` |
62
+ | I want people to find and install my MCP server | **MCP Registry** | `references/registry.md` |
63
+ | I have many servers, many clients, and a security team | **a gateway** | `references/gateway.md` |
64
+
65
+ **The one-line rule between the two big ones.** MCP connects a model to a *capability* you
66
+ control the shape of; A2A connects you to a *peer* whose insides you deliberately cannot
67
+ see. The official framing is exact and worth keeping: *"A2A is about agents partnering on
68
+ tasks, while MCP is more about agents using capabilities."* Real systems run both — an A2A
69
+ server whose internals speak MCP — and that is the recommended architecture, not a
70
+ compromise.
71
+
72
+ **The tell that you picked wrong:** if you find yourself inventing a task lifecycle, a
73
+ progress channel and a resumable handle on top of `tools/call`, you wanted A2A. If you find
74
+ yourself publishing an agent card for something that is one HTTP call with a JSON schema,
75
+ you wanted MCP.
76
+
77
+ ---
78
+
79
+ ## References
80
+
81
+ Each file opens with its own **Load this when** line and its revision stamp. This table is
82
+ an index; the trigger lives in the file, so the two cannot drift apart.
83
+
84
+ | File | Read it when |
85
+ |---|---|
86
+ | [`references/mcp.md`](references/mcp.md) | you are **building or calling an MCP server** — the layers, per-request `_meta`, `server/discover`, the three server primitives and the one surviving client primitive, notifications, caching, transports, and the full deprecation register |
87
+ | [`references/mcp-ship.md`](references/mcp-ship.md) | the server is written and **cannot be reached** — mounting inside an existing web app, transport-level auth, client config, and the 404 that is really a double path |
88
+ | [`references/mcp-scale.md`](references/mcp-scale.md) | the host has **more servers and tools than context** — progressive discovery, programmatic tool calling, cache interaction, and the security surface each one opens |
89
+ | [`references/a2a.md`](references/a2a.md) | the other side is **another agent, not a tool** — agent cards and discovery, the task lifecycle and its terminal states, three protocol bindings, streaming versus push |
90
+ | [`references/registry.md`](references/registry.md) | you are **publishing a server** or building something that consumes the registry — `server.json`, reverse-DNS namespaces and how ownership is proved, the publish flow, and the registry's three refusals |
91
+ | [`references/gateway.md`](references/gateway.md) | agent traffic needs **one controlled seam** — what a gateway must do that an API gateway does not, federation and name collisions, and where authorization actually belongs |
92
+
93
+ ---
94
+
95
+ ## Boundaries — what this skill is not
96
+
97
+ **Against `make-skill`.** `make-skill` owns the *skill author's* view: whether a job wants a
98
+ skill or a server at all, declaring a server dependency in `compatibility`, and the fact that
99
+ tool names differ per host (`mcp__<server>__<tool>` in Claude Code, `mcp__plugin_<plugin>_<server>__<tool>`
100
+ for a plugin's own server). **This skill owns the wire.** If the question is "what does the
101
+ protocol say", it is here; if it is "how does my skill declare that it needs one", it is
102
+ there. The protocol is described in exactly one of the two places, and this is it.
103
+
104
+ **Against `agent-orchestrator`.** That skill routes between *model providers* and manages the
105
+ loop's own context. This one routes between *processes*. They meet at exactly one point: an
106
+ orchestrator that federates many MCP servers is subject to `references/mcp-scale.md`, and one
107
+ that fronts them with a proxy is subject to `references/gateway.md`.
108
+
109
+ **Against `agent-orchestrator/references/governance.md`.** That file decides *whether* a
110
+ boundary may be crossed and what an audit row must carry to prove a control was applied. This
111
+ skill describes *how* the crossing is spoken. Permission there, protocol here.
112
+
113
+ **Not covered at all:** designing the tool set of one server (what tools, what schemas, what
114
+ descriptions — that is a design problem, and Anthropic's `mcp-server-dev` plugin is built for
115
+ it); prompt wording; a single LLM call in a script.
116
+
117
+ ---
118
+
119
+ ## The neighbourhood — one verdict each
120
+
121
+ Named so an agent stops guessing, with the verdict stated rather than implied.
122
+
123
+ | Thing | What it actually is | Verdict |
124
+ |---|---|---|
125
+ | **Agent Skills** (`agentskills.io`) | the open `SKILL.md` format this very file is written in — originally Anthropic's, now an open standard with wide client adoption | **Adopt, but not here.** The family owns it in `make-skill`. Relevant to interop in one way: MCP has a *Skills over MCP* extension, so a server can ship skills — see `references/mcp.md` |
126
+ | **ACP** (IBM's Agent Communication Protocol) | a former A2A competitor | **Dead as a choice.** Merged into A2A under LF AI & Data on 2025-08-29; its team stopped developing it. If you meet ACP in a doc, the answer today is A2A |
127
+ | **AGNTCY** (Cisco/Outshift → Linux Foundation, July 2025) | *not* an A2A rival — an infrastructure stack around multi-agent systems: OASF discovery, agent identity, SLIM messaging, observability. It archived its own competing protocol | **Orthogonal.** Evaluate it for identity and observability if you run many agents; it does not replace A2A or MCP |
128
+ | **AP2** (Agent Payments Protocol) | Google's payments extension **for A2A**, standardising through FIDO Alliance working groups. Signs intent as Verifiable Digital Credentials — Checkout Mandates and Payment Mandates, each with an Open and a Closed stage | **Watch, do not build on it yet.** Explicitly in progress rather than production-ready. It is the right shape for the problem — proving *this user authorized this purchase* — so track it if an agent will ever spend money |
129
+ | **"ChatGPT apps" / OpenAI's plugin surface** | checked, and it is **not a separate protocol**: an MCP server, plus Agent Skills for the workflows, plus optional UI | **Nothing new to learn.** Build the MCP server; the host packaging is the host's |
130
+ | **MCP extensions** — Tasks, MCP Apps, Skills over MCP | opt-in additions to the core protocol, negotiated per connection | **Read before inventing.** Long-running work has a durable-handle answer already; see `references/mcp.md` |
131
+
132
+ ---
133
+
134
+ ## The link map — where to go and read
135
+
136
+ Nothing here is summarised well enough to build against. These are the documents.
137
+
138
+ | Read | For | URL |
139
+ |---|---|---|
140
+ | MCP specification (current) | the normative requirements; always check the revision it serves | `https://modelcontextprotocol.io/specification/latest` |
141
+ | MCP architecture | the two layers, statelessness, the discovery exchange with real JSON | `https://modelcontextprotocol.io/docs/2026-07-28/learn/architecture` |
142
+ | MCP server concepts | tools, resources, resource templates, prompts — who controls each | `https://modelcontextprotocol.io/docs/2026-07-28/learn/server-concepts` |
143
+ | MCP client concepts | elicitation's two modes and the MRTR pattern; the deprecated client features | `https://modelcontextprotocol.io/docs/2026-07-28/learn/client-concepts` |
144
+ | **MCP deprecation register** | the authoritative list of what is on the way out and its earliest removal | `https://modelcontextprotocol.io/specification/2026-07-28/deprecated` |
145
+ | MCP client best practices | progressive discovery and code mode, with the numbers | `https://modelcontextprotocol.io/docs/2026-07-28/develop/clients/client-best-practices` |
146
+ | Build a server / build a client | the SDK-level walkthroughs | `https://modelcontextprotocol.io/docs/2026-07-28/develop/build-server`, `…/build-client` |
147
+ | MCP + Agent Skills | how skills and servers compose, and the `mcp-server-dev` plugin | `https://modelcontextprotocol.io/docs/2026-07-28/develop/build-with-agent-skills` |
148
+ | MCP registry — about, quickstart | what it is, and the exact publish flow | `https://modelcontextprotocol.io/registry/about`, `https://modelcontextprotocol.io/registry/quickstart` |
149
+ | MCP docs index for machines | fetch this first if you are an agent exploring | `https://modelcontextprotocol.io/llms.txt` |
150
+ | A2A home and specification | v1.0, the three bindings, the normative surface | `https://a2a-protocol.org/latest/`, `https://a2a-protocol.org/latest/specification/` |
151
+ | A2A key concepts / life of a task / discovery | the object model, the lifecycle, the well-known URI | `https://a2a-protocol.org/latest/topics/key-concepts/`, `…/life-of-a-task/`, `…/agent-discovery/` |
152
+ | A2A and MCP | the official statement of how they divide | `https://a2a-protocol.org/latest/topics/a2a-and-mcp/` |
153
+ | agentgateway — standalone, Kubernetes | the config model, and the Gateway API story | `https://agentgateway.dev/docs/standalone/latest/`, `https://agentgateway.dev/docs/kubernetes/latest/` |
154
+ | Source repositories | when the docs are behind the code | `https://github.com/a2aproject/A2A`, `https://github.com/modelcontextprotocol/modelcontextprotocol`, `https://github.com/modelcontextprotocol/registry`, `https://github.com/agentgateway/agentgateway` |
155
+
156
+ **Fetch the `llms.txt` first when you are an agent.** Both `modelcontextprotocol.io` and
157
+ `agentgateway.dev` publish one, and both are versioned per docs release — which is how you
158
+ find the page that exists rather than the page you remember.
159
+
160
+ ---
161
+
162
+ ## Checklist — shipping anything that speaks these protocols
163
+
164
+ - [ ] The revision you build against is **written down** — in `compatibility`, a constant, or a README line
165
+ - [ ] You read the deprecation register before using a client feature
166
+ - [ ] Version mismatch has a handled path, not a crash
167
+ - [ ] Tool output is treated as **untrusted input**, including output from your own servers
168
+ - [ ] Nothing secret is requested through an elicitation form — that is URL mode's job
169
+ - [ ] Long-running work uses a durable handle rather than a held connection
170
+ - [ ] If you federate: name collisions are resolved deliberately, not by load order
171
+ - [ ] If you publish: the namespace is one you can prove you own
172
+ - [ ] Authorization is enforced per hop, not only at the entrance
@@ -0,0 +1,209 @@
1
+ # A2A — when the other side is an agent, not a tool
2
+
3
+ **Load this when:** you are delegating an outcome to somebody else's autonomous agent,
4
+ publishing your own as callable, or choosing between A2A and MCP.
5
+
6
+ **Spec pinned:** A2A **v1.0**, `https://a2a-protocol.org/latest/specification/` · read 2026-08-13
7
+
8
+ Governance: created by Google, transferred to the **Linux Foundation**, Apache-2.0, run by a
9
+ Technical Steering Committee with AWS, Cisco, Google, IBM Research, Microsoft, Salesforce,
10
+ SAP and ServiceNow.
11
+
12
+ **The v0.x → v1.0 rename is the trap here.** The wire surface changed names between them, and
13
+ plenty of SDKs, tutorials and blog posts still document v0.3. A document that mixes the two
14
+ is wrong against at least one of them. Check every field name against the version you target.
15
+
16
+ ## Contents
17
+
18
+ - The five design principles, and what each one bought
19
+ - The object model
20
+ - Discovery — the agent card
21
+ - The task lifecycle
22
+ - Three protocol bindings
23
+ - Getting results back
24
+ - Security
25
+ - Traps
26
+
27
+ ## The five design principles, and what each one bought
28
+
29
+ Stated at announcement, and each is visible in the protocol:
30
+
31
+ | Principle | What it produced |
32
+ |---|---|
33
+ | **Embrace agentic capabilities** | agents collaborate without shared memory, tools or context — the peer is opaque by design |
34
+ | **Build on existing standards** | HTTP, SSE, JSON-RPC rather than a novel transport |
35
+ | **Secure by default** | enterprise authentication and authorization, aligned with OpenAPI's auth schemes |
36
+ | **Support for long-running tasks** | a task lifecycle that spans hours or days, with progress reported |
37
+ | **Modality agnostic** | parts carry more than text — audio, video, binary, structured data |
38
+
39
+ **The first one is the design decision that matters.** A2A's peer is deliberately a black
40
+ box: you send an outcome, not a plan. If your design needs to see inside the other agent,
41
+ A2A is the wrong protocol and you probably want an MCP server.
42
+
43
+ ## The object model
44
+
45
+ | Object | What it is | Key fields |
46
+ |---|---|---|
47
+ | **AgentCard** | JSON metadata describing identity, capabilities, endpoint, skills and auth requirements | name, description, version, provider, capabilities, skills, security schemes |
48
+ | **Task** | a **stateful unit of work** with a unique id and a lifecycle | `id`, `contextId`, `status`, `artifacts`, `history`, `metadata` |
49
+ | **Message** | one turn of communication | `role` (`user` or `agent`), parts |
50
+ | **Part** | the fundamental content container inside messages and artifacts | one of `text`, `raw` (bytes), `url`, `data` (JSON); plus optional `mediaType`, `filename`, `metadata` |
51
+ | **Artifact** | a tangible output produced during a task | `artifactId`, human-readable name, one or more parts |
52
+
53
+ **`contextId` is the piece people miss.** It is server-generated and groups multiple related
54
+ tasks across interactions — the thing that makes a sequence of delegations one conversation
55
+ rather than a pile of unrelated jobs.
56
+
57
+ **`skills[]` on an agent card is not an Agent Skills `SKILL.md`.** A2A borrowed the word
58
+ for *an advertised capability of a remote agent* — `id`, `name`, `description`, `tags`,
59
+ `examples`, `inputModes`, `outputModes`. Agent Skills are instruction folders loaded into a
60
+ model's context. Two unrelated things, one word. Keep them apart in anything you write, or
61
+ every reader loses an hour.
62
+
63
+ ## Discovery — the agent card
64
+
65
+ The standard location, following RFC 8615:
66
+
67
+ ```
68
+ https://{agent-server-domain}/.well-known/agent-card.json
69
+ ```
70
+
71
+ **Pre-0.3 deployments served `/.well-known/agent.json`** — expect both in the wild.
72
+
73
+ Top-level card fields in 1.0 — confirm against the live schema before implementing:
74
+ `name`, `description`, `version`, `provider`, `iconUrl`, `documentationUrl`,
75
+ `supportedInterfaces`, `capabilities`, `securitySchemes`, `securityRequirements`,
76
+ `defaultInputModes`, `defaultOutputModes`, `skills`, `extensions`, `signatures`.
77
+
78
+ **`capabilities` gates what you may attempt** — `streaming`, `pushNotifications`,
79
+ `extendedAgentCard`, `extensions`. Read it and branch; never assume streaming or push
80
+ exists because the docs describe them.
81
+
82
+ **Cards can be signed.** An unsigned card at a well-known URI is a claim, not proof —
83
+ verify `signatures` whenever the peer is not first-party.
84
+
85
+ A plain HTTP GET returns the card. Four discovery strategies exist, and they are not equal:
86
+
87
+ 1. **Well-known URI** — the standard, and what you should publish.
88
+ 2. **Authenticated extended cards** — fetched via `GetExtendedAgentCard`. This is the
89
+ recommended way to expose sensitive capability information: **selective disclosure by
90
+ client permission**, rather than a static public card carrying secrets.
91
+ 3. **Curated registries** — catalogues queryable by skill, tag or provider. Note the honest
92
+ gap: **the current specification does not prescribe a standard API for them**, so anything
93
+ you build against one is vendor-specific.
94
+ 4. **Direct configuration** — hardcoded URLs. Fine for a fixed pair of agents, and it does
95
+ not scale or standardize.
96
+
97
+ **Never put a secret in the public card.** That is what the extended card exists for.
98
+
99
+ ## The task lifecycle
100
+
101
+ The enum, spelled exactly as the specification defines it:
102
+
103
+ ```
104
+ TASK_STATE_UNSPECIFIED
105
+ TASK_STATE_SUBMITTED
106
+ TASK_STATE_WORKING
107
+ TASK_STATE_INPUT_REQUIRED <- interrupted, awaiting the client
108
+ TASK_STATE_AUTH_REQUIRED <- interrupted, awaiting credentials
109
+ TASK_STATE_COMPLETED <- terminal
110
+ TASK_STATE_CANCELED <- terminal
111
+ TASK_STATE_REJECTED <- terminal
112
+ TASK_STATE_FAILED <- terminal
113
+ ```
114
+
115
+ **Terminal means terminal: a task that reached completed, canceled, rejected or failed cannot
116
+ restart.** Continuing work means a *new* task, linked by `contextId`. Client code that
117
+ retries by re-sending to the same `taskId` after a failure is coding against a state machine
118
+ that does not exist.
119
+
120
+ **Interrupted is not failed.** `INPUT_REQUIRED` and `AUTH_REQUIRED` are the protocol asking
121
+ you for something and holding the work open. A client that treats every non-`COMPLETED`
122
+ status as an error abandons tasks that were waiting for one field.
123
+
124
+ ## Three protocol bindings
125
+
126
+ The specification defines three, and an agent may implement any of them:
127
+
128
+ | Binding | Section | Use when |
129
+ |---|---|---|
130
+ | **JSON-RPC** | §9 | the default; broadest tooling |
131
+ | **gRPC** | §10 | you already run gRPC and want streaming and typed stubs |
132
+ | **HTTP+JSON/REST** | §11 | plain REST clients, easiest to inspect and curl |
133
+
134
+ **A server declares which bindings it supports on its card; the client picks one.**
135
+
136
+ | Functionality | JSON-RPC / gRPC | REST |
137
+ |---|---|---|
138
+ | Send message | `SendMessage` | `POST /message:send` |
139
+ | Send streaming message | `SendStreamingMessage` | `POST /message:stream` |
140
+ | Get task | `GetTask` | `GET /tasks/{id}` |
141
+ | List tasks | `ListTasks` | `GET /tasks` |
142
+ | Cancel task | `CancelTask` | `POST /tasks/{id}:cancel` |
143
+ | Subscribe to task | `SubscribeToTask` | `POST /tasks/{id}:subscribe` |
144
+ | Create push config | `CreateTaskPushNotificationConfig` | `POST /tasks/{id}/pushNotificationConfigs` |
145
+ | Get push config | `GetTaskPushNotificationConfig` | `GET /tasks/{id}/pushNotificationConfigs/{configId}` |
146
+ | List push configs | `ListTaskPushNotificationConfigs` | `GET /tasks/{id}/pushNotificationConfigs` |
147
+ | Delete push config | `DeleteTaskPushNotificationConfig` | `DELETE /tasks/{id}/pushNotificationConfigs/{configId}` |
148
+ | Extended card | `GetExtendedAgentCard` | `GET /extendedAgentCard` |
149
+
150
+ **The v0.3.x names, so you recognize inherited code on sight:** slash-style JSON-RPC methods
151
+ — `message/send`, `message/stream`, `tasks/get`, `tasks/cancel`, `tasks/resubscribe`,
152
+ `tasks/pushNotificationConfig/{set,get,list,delete}`,
153
+ `agent/getAuthenticatedExtendedCard`. If you meet those, it is a **v0.x client**. Do not
154
+ "fix" the names to 1.0 without moving the whole contract — half-migrated is worse than
155
+ either version, and it works until it reaches the one field nobody updated.
156
+
157
+ The same drift runs through the states: 1.0 uses proto-style constants
158
+ (`TASK_STATE_COMPLETED`), v0.x used lowercase wire values (`submitted`, `working`,
159
+ `input-required`). A document showing both has been half-migrated.
160
+
161
+ ## Getting results back
162
+
163
+ Three mechanisms, matched to how long the work takes and whether you can hold a connection:
164
+
165
+ | Mechanism | Shape | Right when |
166
+ |---|---|---|
167
+ | **Request/response with polling** | `SendMessage`, then `GetTask` on an interval | always available; work measured in seconds to minutes |
168
+ | **Streaming (SSE)** | `SendStreamingMessage` / `SubscribeToTask`; needs `capabilities.streaming` | you want incremental output and can hold the connection |
169
+ | **Push notifications** | server calls a webhook you registered; needs `capabilities.pushNotifications` | work spans hours or days, or the client is not always up |
170
+
171
+ Stream events are typed: `TaskStatusUpdateEvent` and `TaskArtifactUpdateEvent`.
172
+
173
+ **Push is the one that makes long-running real.** Streaming dies with the connection;
174
+ polling for six hours is a poor use of everyone's time. If your delegated work can outlive a
175
+ request, register a push config and design for the callback.
176
+
177
+ **Design for all three failing.** A long task whose stream drops must be recoverable **by
178
+ id** — which is precisely why A2A gives tasks ids and states instead of making them
179
+ fire-and-forget calls. Polling is the floor you fall back to.
180
+
181
+ ## Security
182
+
183
+ - **Enterprise auth from the start** — the card declares its security schemes, aligned with
184
+ OpenAPI's authentication approaches: API key, HTTP auth, OAuth2, OpenID Connect, mutual
185
+ TLS. Read the card and satisfy what it declares; do not assume bearer tokens.
186
+ - **Scope the token to the task.** Authorization is per skill and per task; handing a peer
187
+ a token broader than the work is how one delegation becomes an account compromise.
188
+ - **Verify card signatures for any peer that is not first-party.** A well-known URI proves
189
+ where the file sits, not who wrote it.
190
+ - **`AUTH_REQUIRED` is a protocol state**, not an error path bolted on. Handle it.
191
+ - **The peer is opaque, and that cuts both ways.** You cannot verify how it reached its
192
+ result, so anything it returns is untrusted input to your system — the same rule as tool
193
+ output, with less recourse.
194
+ - **Trace across hops.** A chain of agents compounds errors, and policy has to be enforced at
195
+ **each hop**, not only at the entrance. See `agent-orchestrator/references/governance.md`
196
+ for the control set; this file only says which wire it rides.
197
+
198
+ ## Traps
199
+
200
+ - **Building against v0.3 field names** because that is what the tutorial showed. Check the
201
+ version.
202
+ - **Retrying into a terminal task.** New task, same `contextId`.
203
+ - **Treating `INPUT_REQUIRED` as a failure.** It is a question.
204
+ - **Publishing capability detail in the public card** instead of the authenticated extended
205
+ card.
206
+ - **Choosing A2A for something with a JSON schema and one call.** That is a tool. The cost of
207
+ A2A is a lifecycle, a card and a state machine; pay it when the other side is genuinely
208
+ autonomous.
209
+ - **Assuming a registry API is standard.** It is not, yet.