# A2A Learnables Extension, Version 1

**Extension URI:** `https://rsaxb.com/a2a/learnables/v1`

**Status:** Draft. Published 2026-08-17. Last updated 2026-08-19.

**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](https://a2a-protocol.org/latest/topics/extension-and-binding-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:

1. 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;
2. how an agent **attaches a teachable proposal** to a question, so a client can
   offer "remember this" without knowing the agent's internals;
3. the **semantics of absorbing a lesson** — refusal, idempotence, versioning,
   retraction, expiry, and the rule that a lesson never mutates a definition a
   running task is pinned to;
4. 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](#15-versioning)).

## 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](https://www.rfc-editor.org/rfc/rfc2119),
[RFC 8174](https://www.rfc-editor.org/rfc/rfc8174)) 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:

1. **Discard it.** The same question is asked again tomorrow.
2. **Write it into a prompt or config, then redeploy.** The knowledge reaches
   production days after the person who held it answered.
3. **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. What is taught by that route
can be given an end date or taken back by the same route, by a person rather
than an operator ([§9.1](#91-retraction), [§9.2](#92-expiry)).

**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.

**Retraction** — a lesson that removes knowledge from an entry instead of adding
it. Authored, attributed and versioned exactly as a lesson that adds.

**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`:

```json
{
  "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](#62-the-learnable-descriptor-object)). 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](#6-extension-declaration) 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](#8-the-teach-block)) and show-back
([§11](#11-show-back)) 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.

```http
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](#132-authorization).

## 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:

```json
{
  "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

```json
{
  "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. |
| `mode` | string | no | `"teach"` or `"retract"` ([§9.1](#91-retraction)). Absent means `"teach"`. |
| `value` | object | yes | Opaque to everything except the learnable. Keys SHOULD be `lessonFields` names. Under `"retract"` it identifies knowledge to remove rather than knowledge to add. |
| `expiresAt` | string | no | RFC 3339 instant after which the lesson stops contributing ([§9.2](#92-expiry)). |
| `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.

### 9.1 Retraction

A lesson with `mode` set to `"retract"` removes knowledge from an entry instead
of adding it. `value` is still REQUIRED and still opaque: it identifies what to
remove, and only the learnable knows how to match it.

- A retraction **MUST** carry `taughtBy` on the same terms as any other lesson,
  and **SHOULD** carry `reason`.
- A retraction that changes anything **MUST** produce a new immutable version
  ([§10.3](#103-versioning-and-pinning)) and **MUST** appear in the activation
  history.
- An authority **MUST NOT** require that a retraction come from the person who
  taught the knowledge being removed.
- An authority **MUST NOT** implement retraction by rolling back a definition
  version.
- An authority that does not implement retraction **MUST** refuse a lesson
  carrying `mode: "retract"` with a reason, and **MUST NOT** absorb it as a
  teach.

*Rationale.* Rolling back and retracting are easy to confuse, because both end
with knowledge gone. They are not the same operation. A rollback removes
everything its version contained, and everything taught since stands on it: a
mark taught in March that a policy change invalidated in August cannot be undone
by returning to February. Retraction removes one thing and moves the definition
forward, which is the only shape that survives more than one person teaching the
same entry. The last rule is the dangerous one — an authority that ignores an
unrecognised `mode` absorbs an attempt to forget as an instruction to learn.

### 9.2 Expiry

`expiresAt` states when a lesson stops being true. After that instant the lesson
**MUST NOT** contribute to any decision.

- Expiry **MUST NOT** change `definitionVersion`. What a definition does is a
  function of its version and the time it is evaluated at, and an implementation
  **MUST** be able to state both for a past decision
  ([§13.4](#134-attribution-and-reversal)).
- An implementation **MUST** fix one evaluation time for the duration of a task,
  established when the task resolves its definition, so that a lesson expiring
  mid-flight does not change an answer under a running task
  ([§10.3](#103-versioning-and-pinning)).
- An expired lesson **MUST** remain visible in the entry, marked expired. It is
  not deleted, and the version that introduced it is not rewritten.
- A client **SHOULD** let a person set an expiry at the moment they teach, and
  **MUST NOT** apply a default expiry it has not shown them.
- An authority that does not implement expiry **MUST** refuse a lesson carrying
  `expiresAt` rather than absorb it without one.

```json
{
  "collection": "customers",
  "entry": "northgate",
  "value": { "pattern": "ops-cover@thirdparty\\.example", "where": "from" },
  "expiresAt": "2026-09-30T23:59:59Z",
  "taughtBy": "dana@warehouse.example",
  "reason": "A third party is covering Northgate's desk until the end of September"
}
```

*Rationale.* The person answering the question usually knows the answer is
temporary at the moment they give it, and until now the schema had nowhere to
put that. The alternative is that somebody remembers, in October, to go looking
for a rule they did not write. The last requirement matters for the same reason
as its counterpart in [§9.1](#91-retraction): an authority that silently drops
`expiresAt` turns a cover arrangement into a permanent one.

## 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.

The same holds in the other direction: a retraction ([§9.1](#91-retraction))
naming knowledge the entry does not hold **MUST** report `learned: false` and
**MUST NOT** be treated as an error.

*Rationale.* Two people answering the same way is the normal case, not a fault.
Two people removing the same stale mark is that case arriving later.

### 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 `taughtBy`
  and `reason`;
- the change **MUST** be undoable by the same mechanism that undoes any other
  activation. Undoing an activation is not retraction
  ([§9.1](#91-retraction)): it removes everything that version contained.

*Rationale.* Without pinning, "the agent learns" and "the agent changes
unpredictably under a running task" describe the same behaviour.

### 10.4 The result

```json
{
  "learned": true,
  "describes": "matches 'billing@origin\\.example' in the from",
  "conflicts": ["alhamra already claims '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**. |
| `conflicts` | string[] | no | Knowledge already held that this lesson contradicts, phrased by the learnable ([§10.5](#105-contradiction)). Absent or empty asserts none was detected. |
| `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.

### 10.5 Contradiction

Where a learnable can determine that an absorbed lesson contradicts knowledge the
entry or collection already holds, the result **MUST** report it in `conflicts`,
phrased by the learnable.

- The authority **MUST NOT** detect or resolve contradictions itself. It cannot
  read `value` ([§9](#9-the-lesson-object)), so it cannot know that two lessons
  say opposite things.
- A contradiction **MUST NOT**, on its own, cause a refusal. Somebody teaching a
  changed policy is the ordinary case, not an error. A learnable MAY still refuse
  under [§10.1](#101-the-learnable-judges-the-value) where the result would be
  unusable.
- An implementation **MUST NOT** resolve a contradiction silently by
  accumulation. Where both the old knowledge and the new remain in force, the
  result **MUST** say so, and a client **SHOULD** offer the retraction
  ([§9.1](#91-retraction)) that removes the old one.

*Rationale.* The failure this exists for is not the refused lesson but the
accepted one. Under a scoring learnable like the one declared in
[§6.1](#61-the-agentextension-entry), teaching that a mark now identifies a
different customer adds a second claim rather than replacing the first: both
match, the margin decides between them, and the answer that was correct in March
competes with the one taught in August. The write was valid, `learned` is `true`,
and the agent now decides worse than it did before. Nobody finds out until a
shipment goes out in the wrong name.

## 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:

```json
{
  "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:

```json
{ "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`:

```json
{
  "uri": "https://rsaxb.com/a2a/learnables/v1",
  "params": {
    "teachMethod": "rsaxb.learnables.Teach",
    "learnables": ["..."]
  }
}
```

The method takes a Lesson ([§9](#9-the-lesson-object)) and returns a result
([§10.4](#104-the-result)). A client **MUST NOT** call it without having
activated the extension. An agent exposing it **MUST** still satisfy every
requirement in [§10](#10-absorption-semantics), 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](#8-the-teach-block)).

### 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.

### 13.5 Stale knowledge

A lesson that was correct when it was taught does not stay correct. Policies
change, cover arrangements end, and an exception outlives the reason for it. A
lesson that has gone stale behaves exactly like an over-broad one
([§13.1](#131-over-broad-values)) — it claims traffic it should not — except
that no validation catches it, because nothing about it was invalid when it was
written.

Implementations:

- **MUST** provide a path by which somebody other than a lesson's author can
  retract it ([§9.1](#91-retraction));
- **SHOULD** record when a lesson last contributed to a decision, so that
  knowledge which no longer earns its place can be found rather than waited for;
- **SHOULD** offer an expiry ([§9.2](#92-expiry)) at the moment of teaching,
  where the person indicates the answer is temporary.

*Rationale.* Learning is only useful if forgetting is designed too. The rest of
this document makes a lesson durable, attributable and reversible; without an end
date, a retraction and a way to find what has gone quiet, "durable" is the only
one of those that operates by itself.

## 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 `taughtBy` as 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 `kind` values, since [§6.3](#63-the-lessonfield-object) requires unknown
  kinds to degrade to `"text"`;
- new `decidedBy` values.

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 in `params`;
- **`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.

1. **The application fetches the agent's card** and reads one learnable:
   collection `customers`, two lesson fields.
2. **A message arrives** from `billing@origin.example`. No mark matches. The task
   moves to `input-required`, and the question carries a teach block with
   `suggested: { "pattern": "billing@origin.example", "where": "from" }`.
3. **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.
4. **Dana answers and leaves the teach box ticked.** The application posts a
   Lesson to the control plane. The agent is not involved.
5. **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
   ```

6. **The application calls show-back** and displays *Reads as Northgate Motors
   Ltd, on billing@origin.example* — the effect, not the word "Saved".
7. **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. |
| v1 draft | 2026-08-19 | Added retraction (§9.1), lesson expiry (§9.2), contradiction reporting (§10.5) and stale-knowledge considerations (§13.5). |

## References

- [A2A Protocol Specification](https://a2a-protocol.org/latest/specification/)
- [A2A Extensions](https://a2a-protocol.org/latest/topics/extensions/)
- [A2A Extension & Binding Governance](https://a2a-protocol.org/latest/topics/extension-and-binding-governance/)
- [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) / [RFC 8174](https://www.rfc-editor.org/rfc/rfc8174) — requirement keywords
