A2A Learnables Extension, Version 1
Extension URI: https://rsaxb.com/a2a/learnables/v1
Status: Draft. Published 2026-08-17.
Editors: RSA Cross Border.
Independent extension. Not published by, endorsed by, or affiliated with the
A2A project. It is published under a URI its authors control, which the
A2A extension governance
permits without registration. The a2aproject URI prefixes are reserved for
artifacts that have been through that project's process; this one has not.
Feedback: the reference implementation and the issue tracker are maintained by RSA Cross Border. Comments are welcome.
Paragraphs marked Rationale are non-normative and may be skipped.
1. Abstract
A2A lets an agent say what it can do, and lets it stop and ask a human. It does not let an agent say what it can be taught, and it does not say what becomes of the human's answer once the task that prompted it ends. Today that answer is spent once: a person identifies a sender, the task completes, and the next message from that sender asks the same question.
This extension defines:
- how an agent declares its learnable surface on its Agent Card — what it recognises, how it decides today, and what shape an answer must take;
- how an agent attaches a teachable proposal to a question, so a client can offer "remember this" without knowing the agent's internals;
- the semantics of absorbing a lesson — refusal, idempotence, versioning, and the rule that a lesson never mutates a definition a running task is pinned to;
- a show-back operation, so a person sees what the agent now makes of the same input instead of the word "saved".
It does not define who stores the agent's knowledge, or over what transport a lesson is written. In many deployments that party is not the agent.
2. Status of this document
This is a Draft. Field names and semantics MAY change.
A stable release of this URI is announced by setting status to stable in the
extension descriptor (Appendix A). Breaking changes are published under a new
URI, never by amending this one (§15).
3. Conformance
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174) when, and only when, they appear in all capitals.
Three roles carry requirements:
- a conformant agent publishes a declaration under this extension's URI;
- a conformant client reads that declaration and renders questions from it;
- a conformant authority absorbs lessons into the agent's knowledge.
One implementation MAY fill more than one role.
4. Motivation
A2A specifies the moment an agent cannot decide: the task moves to
input-required, a human answers, the task resumes. It does not specify the
moment after. The answer was evidence about the world, and there is nowhere to
put it. Implementations resolve that in one of three ways:
- Discard it. The same question is asked again tomorrow.
- Write it into a prompt or config, then redeploy. The knowledge reaches production days after the person who held it answered.
- Let the agent self-modify. Fast and unauditable: nobody can say what the agent knew when it decided, and nothing can be undone.
This extension describes a fourth: the agent publishes what it can be taught, the client holding the human decides what is written, and the write produces a new immutable version carrying an author and a reason.
The agent proposes, the client decides, the authority records.
5. Terminology
Learnable — something in an agent's knowledge that a human's answer may extend. It owns its own vocabulary and its own idea of a valid answer.
Collection — the named set a learnable belongs to, e.g. customers.
Entry — one member of a collection, e.g. northgate. A lesson is written
into an entry.
Lesson — one human-supplied value addressed to one entry, with an author.
Lesson field — one input a client must collect to build a usable lesson value. The agent describes these; the client renders them.
Definition — the versioned, addressable unit of agent knowledge a client resolves before starting a task. Its internal structure is out of scope.
Authority — the party holding definitions and writing lessons into them. MAY be the agent; in the reference deployment it is a separate control plane.
Show-back — read-only re-evaluation of an input under the current definition.
6. Extension declaration
6.1 The AgentExtension entry
A conformant agent MUST declare the extension in capabilities.extensions with
uri set to this document's extension URI, and required set to false.
Rationale. Nothing here changes the meaning of a core A2A request, so refusing clients that do not understand it would refuse them for no reason.
The declaration is carried in params:
{
"capabilities": {
"extensions": [
{
"uri": "https://rsaxb.com/a2a/learnables/v1",
"description": "Publishes what this agent can be taught: which customer a message belongs to, and what kind of message it is.",
"required": false,
"params": {
"learnables": [
{
"collection": "customers",
"entry": "customer",
"skills": ["triage_inbound", "recheck_message"],
"teaches": "which customer a message belongs to",
"how": "Each customer carries marks - text that gives them away. Every mark that matches scores; the highest score wins if it clears the identification margin. Nothing matches, nothing is claimed.",
"decidedBy": "rules",
"lessonFields": [
{
"name": "pattern",
"label": "Text that gives it away",
"kind": "text",
"help": "An address, a reference, a phrase. Matched without regard to case; regular expressions work if you want one."
},
{
"name": "where",
"label": "Where to look for it",
"kind": "choice",
"choices": ["from", "subject", "body", "attachments", "any"],
"default": "from",
"help": "Narrower is safer. 'any' matches the whole message."
}
]
}
]
}
}
]
}
}
params.learnables MUST be an array of Learnable Descriptors
(§6.2). It MAY be empty, which asserts
that the agent understands the extension and currently has nothing to teach.
6.2 The Learnable Descriptor object
| Field | Type | Required | Meaning |
|---|---|---|---|
collection | string | yes | The collection's name in the agent's knowledge. MUST be unique within one declaration. |
entry | string | yes | Singular noun for one member, for rendering. "customer". |
skills | string[] | no | Skill ids this learnable affects. Absent means all of them. |
teaches | string | yes | What a person is deciding, in their words, not the agent's. |
how | string | yes | How the agent decides today, in prose. MUST NOT be a placeholder. |
decidedBy | string | yes | "rules", "model", or "hybrid". |
lessonFields | LessonField[] | yes | The shape of a usable answer. MAY be empty only if the collection accepts an empty value. |
Rationale. how is required because somebody is about to change how software
decides something that matters, and is entitled to know what it does now, from
the thing doing it. decidedBy is required because it changes what a client may
honestly promise: under "rules" a taught mark takes effect deterministically,
under "model" it is one example among many and the effect is statistical.
6.3 The LessonField object
| Field | Type | Required | Meaning |
|---|---|---|---|
name | string | yes | Key this field occupies in a lesson value. MUST be unique within one learnable. |
label | string | yes | Human label. MUST be non-empty and comprehensible to somebody who has never read the agent's source. |
kind | string | yes | Input kind. Open string, not an enumeration. This version defines "text" and "choice". |
choices | string[] | no | Permitted values. REQUIRED when kind is "choice". |
default | string | no | Value to prefill. With kind: "choice", MUST appear in choices. |
help | string | no | One or two sentences under the input. |
A client that encounters an unrecognised kind MUST render the field as
"text". It MUST NOT drop the field and MUST NOT fail.
Rationale. This is the load-bearing rule of the extension. A client rendering
blind from lessonFields needs no change when an agent that reads spreadsheets
asks to be taught a column instead of a pattern; a client that hard-codes one
agent's fields must be edited and released. A dropped field, meanwhile, produces
a lesson the agent will refuse at the moment somebody is trying to fix something.
7. Activation
The declaration in §6 is data-only. A client MAY read it without activating anything, and an agent MUST publish it whether or not any client activates.
The teach block (§8) and show-back
(§11) are profile behaviour. A client MUST request them by
including the extension URI in the A2A-Extensions request header, and a
conformant agent MUST echo activated URIs in the response header.
A2A-Extensions: https://rsaxb.com/a2a/learnables/v1
An agent MUST NOT emit a teach block to a client that has not activated the extension.
Activation is not authorization; see §13.2.
8. The teach block
When an agent moves a task to input-required because it could not decide
something a learnable covers, it MAY attach a teach block to the question,
carried in the Message's metadata and keyed by this extension's URI:
{
"role": "agent",
"parts": [{ "text": "I can't tell whose shipment this is. Who should it go to?" }],
"metadata": {
"https://rsaxb.com/a2a/learnables/v1": {
"teach": {
"collection": "customers",
"entries": ["northgate", "alhamra", "gulftrade"],
"suggested": { "pattern": "billing@origin.example", "where": "from" },
"suggestionLabel": "the address this message came from",
"lessonFields": [ "...as declared on the card..." ]
}
}
}
}
| Field | Type | Required | Meaning |
|---|---|---|---|
collection | string | yes | MUST name a collection declared on the card. |
entries | string[] | yes | Entries a lesson could be written into. MAY be empty when the client is expected to create one. |
suggested | object | no | A prefill for the lesson value. |
suggestionLabel | string | no | Where the suggestion came from, in a person's words. |
lessonFields | LessonField[] | no | Repeats the card's fields so a client can render without a second fetch. |
Keys of suggested MUST be a subset of the applicable lessonFields names.
A suggested value MUST NOT be wider in scope than the evidence it was drawn
from.
Emitting a teach block MUST NOT change how the agent handles the answer to the underlying question. A client MAY ignore the block entirely, and the task MUST proceed identically.
Rationale. A suggestion is displayed for confirmation, and most people confirm,
which makes its scope a correctness property rather than a convenience. The
reference implementation shipped a defect here: a reference extractor matched
PA-2026-0901 as PA-2026, so confirming what looked like one shipment's
reference would have taught the directory to claim every reference issued that
year.
9. The Lesson object
{
"collection": "customers",
"entry": "northgate",
"value": { "pattern": "billing@origin\\.example", "where": "from" },
"taughtBy": "dana@warehouse.example",
"reason": "Northgate's billing desk sends the pre-alerts"
}
| Field | Type | Required | Meaning |
|---|---|---|---|
collection | string | yes | MUST name a declared collection. |
entry | string | yes | The entry to write into. |
value | object | yes | Opaque to everything except the learnable. Keys SHOULD be lessonFields names. |
taughtBy | string | yes | Identifies the human. MUST NOT be a service account standing in for one. |
reason | string | no | Why, in the person's words. |
Every party between the client and the learnable MUST treat value as
opaque. No transport, authority, or storage layer may read a named key out of it.
Rationale. The moment one of them reads value.pattern, adding a learnable
that is not about text — a column mapping, a threshold, a unit of measure —
requires a coordinated release of every component in the chain. The reference
implementation enforces this by construction: its control plane contains no field
named pattern, and its regression suite drives a ColumnMapping learnable,
whose value has no pattern key, through the identical code path.
10. Absorption semantics
These requirements constrain the effect of a write, not its implementation.
10.1 The learnable judges the value
The authority MUST delegate validation to the learnable being taught and MUST NOT apply its own idea of a valid value. A refusal MUST carry a human-readable reason authored by the learnable:
"billing@origin\\.example("is not a usable pattern: missing ), unterminated subpattern at position 24
and not 400 Bad Request: invalid value. The learnable compiled the value; it is
the only party that knows why the value failed.
10.2 Idempotence
Absorption MUST be idempotent. A lesson duplicating knowledge the entry
already holds MUST report learned: false, MUST NOT produce a new
version, and MUST NOT be treated as an error.
Rationale. Two people answering the same way is the normal case, not a fault.
10.3 Versioning and pinning
A lesson that changes anything MUST produce a new immutable version of the definition, and MUST NOT modify one in place. Therefore:
- a task running against version n MUST run against version n to completion, even if n+1 is activated mid-flight;
- the new version MUST appear in an activation history carrying
taughtByandreason; - the change MUST be undoable by the same mechanism that undoes any other activation.
Rationale. Without pinning, "the agent learns" and "the agent changes unpredictably under a running task" describe the same behaviour.
10.4 The result
{
"learned": true,
"describes": "matches 'billing@origin\\.example' in the from",
"definitionVersion": 12,
"versionId": "sha256:9f2c...",
"previousVersionId": "sha256:41ab..."
}
| Field | Type | Required | Meaning |
|---|---|---|---|
learned | boolean | yes | Whether anything changed. |
describes | string | yes | What was learned, phrased by the learnable. |
definitionVersion | integer | yes | Monotonic version after the write. |
versionId | string | no | Content-addressed identifier of the new version. |
previousVersionId | string | no | What it replaced. |
describes MUST be produced by the learnable, not composed by the authority
from field names.
Rationale. The authority does not know that where: "from" means "on the
from-line", so it can only emit something like customers.northgate.pattern set
— which nobody can audit six months later.
11. Show-back
A conformant agent SHOULD expose a read-only operation that re-evaluates a previously seen input under the currently active definition.
It MUST NOT ask a question, MUST NOT propose an action, and MUST NOT be pinned to an earlier version.
The report MUST distinguish settled from unsettled, and when unsettled SHOULD say what it saw:
{
"customer": {
"settled": true,
"winner": "northgate",
"reads": "Reads as Northgate Motors Ltd, on billing@origin.example",
"candidates": [
{ "name": "northgate", "label": "Northgate Motors Ltd", "score": 0.333,
"matched": ["billing@origin\\.example"] },
{ "name": "alhamra", "label": "Al Hamra Trading", "score": 0.0, "matched": [] }
]
}
}
An implementation MUST NOT report the outcome of a lesson using only the success of the write.
Rationale. The case this exists for is the other one:
{ "customer": { "settled": false, "reads": "Still cannot tell whose this is." } }
A rule that is saved, valid, and does not do what its author meant. learned: true is true and useless; the unsettled reading is what lets them fix it in the
next minute rather than the next shipment.
12. Writing a lesson: transport
The transport for writing a lesson is out of scope. The agent recognises, the client holds the human, and a third party may hold the definitions; specifying "POST the lesson to the agent" would exclude that topology. Two profiles are recognised.
12.1 External authority (RECOMMENDED)
The agent declares learnables and proposes teach blocks. The client sends the lesson to an authority it already talks to. The agent learns of the change by resolving the active definition on its next task.
An agent in this profile MUST NOT treat a lesson as accepted merely because it proposed it, and MUST NOT hold local state that a client's decision not to teach would leave stale.
12.2 Self-owning agent (OPTIONAL)
An agent that owns its definitions MAY expose a method extension, declaring
teachMethod in params:
{
"uri": "https://rsaxb.com/a2a/learnables/v1",
"params": {
"teachMethod": "rsaxb.learnables.Teach",
"learnables": ["..."]
}
}
The method takes a Lesson (§9) and returns a result (§10.4). A client MUST NOT call it without having activated the extension. An agent exposing it MUST still satisfy every requirement in §10, including versioning and reversibility.
13. Security considerations
A lesson is a durable, tenant-wide change to automated decision-making, submitted through a text box by somebody doing another job.
13.1 Over-broad values
The dominant risk is not a malicious lesson but a well-meant one that matches far
more than its author believed: a mark on invoice, or a pattern one character
from matching every reference in a year.
Implementations SHOULD evaluate a proposed lesson against a corpus before accepting it and SHOULD report the match count to the person. Implementations MUST NOT present a suggestion whose scope exceeds the evidence it was drawn from (§8).
13.2 Authorization
The A2A-Extensions header is a negotiation mechanism and carries no authority.
An authority MUST authorize the writer independently and MUST scope every
lesson to exactly one tenant.
Rationale. An unscoped lesson is a cross-tenant leak with extra steps: a mark taught by customer A, applied to customer B's traffic, silently routes B's shipments into A's name.
13.3 Untrusted pattern compilation
Where a learnable compiles a supplied value into an executable matcher — a regular expression, a query, a template — the implementation:
- MUST validate at absorption time and refuse with a reason, rather than at match time inside a running task;
- SHOULD bound evaluation time or use a non-backtracking engine. A regular expression accepted from a text box is a denial-of-service vector against every future message.
13.4 Attribution and reversal
Every lesson MUST be attributable to an identified human and MUST be reversible. Which rules were in force when this decision was made, and who put them there MUST be answerable from stored state, without reconstructing deploy history.
14. Privacy considerations
Lesson values routinely contain personal data: the most useful mark for identifying a customer is often an individual's work address.
Implementations:
- MUST treat a lesson value as carrying the same data classification as the content it was drawn from;
- SHOULD record
taughtByas a stable internal identifier rather than embedding personal data in an audit trail with a different retention period; - MUST be able to deactivate and tombstone every version containing a personal identifier, where that identifier cannot be removed from a historic version.
Rationale. Content-addressed immutable versions are excellent for auditability and hostile to erasure. This document does not resolve that tension; it requires that an implementation resolve it deliberately.
15. Versioning
The extension URI is the version. Any change that would break a client reading
params — a removed field, a narrowed type, a changed meaning — MUST be
published under a new URI ending in a higher version segment.
The following are not breaking and MUST NOT change the URI:
- new optional fields on any object defined here;
- new
kindvalues, since §6.3 requires unknown kinds to degrade to"text"; - new
decidedByvalues.
An agent MAY declare several versions simultaneously during a migration. A client SHOULD use the highest version it understands.
16. Relationship to core A2A
Nothing here changes the meaning of a core A2A message. A client ignoring this
extension sees one extra entry in capabilities.extensions and one extra key in
a question's metadata, both ignorable by construction — which is why required
is fixed at false.
Three parts of core A2A are load-bearing and are used as specified, not redefined:
capabilities.extensions— the declaration lives inparams;input-required— the state in which a teach block is emitted;metadata— the augmentation channel, keyed by URI.
Appendix A. JSON Schema
The machine-readable descriptor and JSON Schema for the objects above are served
at https://rsaxb.com/a2a/learnables/v1/extension.json, whose $defs define
LearnableDescriptor, LessonField, TeachBlock, Lesson, and LessonResult.
Appendix B. Worked example
A pre-alert application, an email agent, and a control plane: three processes, no redeploy between the first step and the last.
-
The application fetches the agent's card and reads one learnable: collection
customers, two lesson fields. -
A message arrives from
billing@origin.example. No mark matches. The task moves toinput-required, and the question carries a teach block withsuggested: { "pattern": "billing@origin.example", "where": "from" }. -
The application renders the fields blind: a text box labelled "Text that gives it away", prefilled, and a select labelled "Where to look for it", defaulted to "from". Neither string appears in the application's source.
-
Dana answers and leaves the teach box ticked. The application posts a Lesson to the control plane. The agent is not involved.
-
The control plane hands the value to the learnable, which validates it, absorbs it, and phrases the audit line. A new version is published:
v12 taught by dana@warehouse.example "northgate learned: matches 'billing@origin\.example' in the from" reason: Northgate's billing desk sends the pre-alerts -
The application calls show-back and displays Reads as Northgate Motors Ltd, on billing@origin.example — the effect, not the word "Saved".
-
The next message from that address is never asked about. The task that asked the original question was pinned to v11 and finished on v11. Nothing was restarted; nothing was redeployed.
Appendix C. Changelog
| Version | Date | Change |
|---|---|---|
| v1 draft | 2026-08-17 | Initial publication. |
References
- A2A Protocol Specification
- A2A Extensions
- A2A Extension & Binding Governance
- RFC 2119 / RFC 8174 — requirement keywords
