https://rsaxb.com/a2a/expectations/v1Markdownextension.json

A2A Expectations Extension, Version 1

Extension URI: https://rsaxb.com/a2a/expectations/v1

Status: Draft. Published 2026-09-05.

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.

Companion: the Learnables extension is independent of this one. Neither requires the other; §16 says where they touch.

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

Every state change in A2A is caused by something arriving: a message, an answer, an event, a cancellation. Nothing in the protocol lets the passage of time cause one. An agent that asks a question waits for the answer indefinitely. An agent that knows a document is due on Thursday has no way to say so, and no way to be told on Friday that it did not come. The failures that cost the most in the domains A2A is being deployed into — logistics, finance, support — are absences, and an absence does not emit an event.

This extension defines:

  1. how an agent raises an expectation — a statement, attached to the work it has done, that a named fact about a named subject is due by a stated time;
  2. how an expectation is satisfied, deterministically, by a fact arriving, and how a satisfied step re-anchors the steps that depended on it;
  3. the three ways an expectation lapses — overdue, skipped, and stalled — and the requirement that each lapse becomes a new task for the agent that raised it, under the same context, rather than a silent condition;
  4. the watcher role: the party that keeps time, which in most deployments is not the agent;
  5. the rules that keep unattended, time-triggered work from acquiring authority nobody granted it, and from firing forever.

It does not define a scheduler, a cron syntax, a task deadline, or a long-running task. It does not put a clock in the agent. It says what an agent may declare about the future and what the protocol does when the future fails to arrive.

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:

One implementation MAY fill more than one role. In the reference deployment the client and the watcher are the same application; the agent is neither.

4. Motivation

A2A specifies the moment work is requested and the moments it produces something: a status, an artifact, a question. Between those moments the protocol is silent, and it has no vocabulary for the case where the next moment never comes. Implementations meet that in one of four ways, all in production somewhere:

  1. Wait. A task in TASK_STATE_INPUT_REQUIRED stays there. Nothing in the protocol expires a question, so a question nobody answers is a task nobody closes.
  2. Bolt a scheduler on. A cron job outside the protocol wakes up, queries the agent's store directly, and pokes it. The agent's knowledge of what was supposed to happen lives in the cron job's SQL, invisible to any client and to the agent itself.
  3. Give the task a deadline. A deadline bounds how long the task may run. It says nothing about the world: a customs entry can be filed on time and the release still not come.
  4. Hold the task open until the world responds. A task that stays WORKING for four days, waiting on a carrier, is a task that cannot be reasoned about, listed usefully, or resumed on a host that restarted.

The A2A maintainers have already described the shape they prefer for recurring and deferred work: not a new state, but a new task under the same context, created when the trigger fires (a2aproject/A2A#654). This extension takes that shape and specifies the trigger. The agent states what it expects and by when; a watcher holds the clock; when the clock runs out, the watcher submits a task and the agent decides what the silence means.

The agent expects. The watcher keeps time. The agent answers for the lapse.

Rationale. Two things are deliberately kept out of the agent. The first is the clock: many agents cannot hold one, being serverless, heartbeat-driven (#1667), or simply not running between requests. The second is the decision that a lapse is unimportant. An expectation the agent raised and then quietly let go is indistinguishable, in the record, from one that was met. The lapse task exists so that the decision to do nothing is itself a task with a history.

5. Terminology

Expectation — a statement raised by a task that a named fact about a named subject is due by a stated time. Immutable once raised.

Subject — the thing the expectation is about: a shipment, an invoice, a case. Identified by type and id; opaque to the watcher.

Fact — an observation that something happened, carrying a key. A fact satisfies an expectation when its key matches the expectation's satisfiedBy.

Satisfaction — the watcher recording that a matching fact arrived. Monotonic: a satisfied expectation does not become unsatisfied.

Due — the instant by which the fact is expected. Grace is the period after due during which the watcher waits before declaring a lapse.

Anchor — an earlier expectation whose satisfaction fixes this one's due time. An anchored expectation carries a projected due time at raising and a current due time once its anchor is satisfied.

Horizon — an instant after which continued silence on the subject is itself a lapse, regardless of individual expectations.

Lapse — the watcher's determination that an expectation will not be met in the ordinary way. Three kinds: overdue, skipped, stalled (§9.1).

Lapse task — the A2A task the watcher submits to the agent when an expectation lapses.

Watcher — the party holding the clock and the record of expectations. MAY be the agent; in the reference deployment it is the client application.

Withdrawal — the closing of an expectation without satisfaction and without lapse, because the task that raised it was canceled or a later task superseded it.

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. A client that does not read expectations receives the same artifacts and the same questions; it just cannot see what the agent is waiting for.

The declaration is carried in params:

{
  "capabilities": {
    "extensions": [
      {
        "uri": "https://rsaxb.com/a2a/expectations/v1",
        "description": "States what this agent expects to happen next for a shipment, and by when, so that a step that never happens is noticed.",
        "required": false,
        "params": {
          "keepsTime": false,
          "lapseSkill": "handle_lapse",
          "kinds": [
            {
              "kind": "shipment.manifest",
              "subjectType": "shipment",
              "describes": "the airline manifest for a booked shipment",
              "basis": "observed",
              "skills": ["book_shipment", "recheck_booking"]
            },
            {
              "kind": "question.answer",
              "subjectType": "task",
              "describes": "a person's answer to a question this agent asked",
              "basis": "declared"
            }
          ]
        }
      }
    ]
  }
}
FieldTypeRequiredMeaning
keepsTimebooleanyesWhether the agent runs its own clock (§12.2). false asserts that no expectation this agent raises will lapse unless a watcher makes it.
lapseSkillstringyesThe skill id a lapse task invokes. MUST name a skill on the card.
kindsExpectationKind[]yesWhat this agent expects, by kind. MAY be empty, which asserts the agent understands the extension and currently expects nothing.

6.2 The ExpectationKind object

FieldTypeRequiredMeaning
kindstringyesIdentifier for this class of expectation. MUST be unique within one declaration. Dotted names are conventional, not required.
subjectTypestringyesWhat kind of thing the expectation is about.
describesstringyesWhat is expected, in a person's words. MUST NOT be a placeholder.
basisstringyesWhere the due times for this kind come from: "observed", "contract", or "declared" (§13.3).
skillsstring[]noSkill ids whose tasks may raise this kind. Absent means any.

Rationale. basis is required because a due time is a claim about the world and a person reading a lapse is entitled to know whether it came from what the lane actually does, from what was sold, or from somebody's guess. The three produce very different amounts of noise, and the noise is the way this whole mechanism fails (§13.3).

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.

Raising expectations (§8), reporting facts (§9), and submitting lapse tasks (§10) are profile behaviour. A client or watcher 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/expectations/v1

An agent MUST NOT emit an expectation to a client that has not activated the extension.

Rationale. An expectation nobody is watching is a promise made to an empty room. The activation is how the agent learns there is a watcher; raising expectations without one produces a record that looks kept and is not.

Activation is not authorization; see §13.1.

8. The Expectation object

An agent raises an expectation by attaching it to an Artifact, in the Artifact's metadata keyed by this extension's URI. A status-update Message MAY carry one in the same way (§11).

{
  "artifactId": "booking-7f3a",
  "name": "Booking confirmation",
  "parts": [{ "text": "Booked on EK203 departing DXB 2026-09-11 02:15Z" }],
  "extensions": ["https://rsaxb.com/a2a/expectations/v1"],
  "metadata": {
    "https://rsaxb.com/a2a/expectations/v1": {
      "expectations": [
        {
          "expectationId": "exp-01J8Q0MANIFEST",
          "kind": "shipment.manifest",
          "subject": { "type": "shipment", "id": "PA-2026-0901" },
          "expects": "the airline manifest for PA-2026-0901",
          "satisfiedBy": { "factKey": "shipment.manifest.received:PA-2026-0901" },
          "dueAt": "2026-09-10T20:15:00Z",
          "grace": "PT2H",
          "basis": "observed"
        },
        {
          "expectationId": "exp-01J8Q0DEPART",
          "kind": "shipment.departure",
          "subject": { "type": "shipment", "id": "PA-2026-0901" },
          "expects": "a departure event for EK203",
          "satisfiedBy": { "factKey": "shipment.departed:PA-2026-0901" },
          "dueAt": "2026-09-11T03:15:00Z",
          "grace": "PT6H",
          "basis": "observed",
          "after": ["exp-01J8Q0MANIFEST"]
        },
        {
          "expectationId": "exp-01J8Q0ARRIVE",
          "kind": "shipment.arrival",
          "subject": { "type": "shipment", "id": "PA-2026-0901" },
          "expects": "an arrival event at DOH",
          "satisfiedBy": { "factKey": "shipment.arrived:PA-2026-0901" },
          "dueAt": "2026-09-11T05:00:00Z",
          "grace": "PT6H",
          "anchor": { "expectationId": "exp-01J8Q0DEPART", "offset": "PT1H45M" },
          "basis": "observed",
          "after": ["exp-01J8Q0DEPART"],
          "horizon": "2026-09-13T05:00:00Z"
        }
      ]
    }
  }
}
FieldTypeRequiredMeaning
expectationIdstringyesAgent-generated. MUST be unique among expectations the agent has ever raised.
kindstringyesMUST name a kind declared on the card.
subjectSubjectyes{ "type": string, "id": string }. type SHOULD match the kind's subjectType.
expectsstringyesWhat is expected, in a person's words, specific to this subject.
satisfiedByMatcheryes{ "factKey": string }. The fact key that satisfies this expectation. Exact match.
dueAtstringyesRFC 3339 instant, UTC. When anchored, the projected due time at the moment of raising.
gracestringnoISO 8601 duration after dueAt before an overdue lapse. Absent means zero.
anchorAnchorno{ "expectationId": string, "offset": duration }. When present, the current due time is the anchor's satisfaction instant plus offset (§9.3).
afterstring[]noExpectations on the same subject that are expected to be satisfied before this one (§9.1, skipped).
horizonstringnoRFC 3339 instant after which silence on the subject is a stalled lapse.
basisstringyes"observed", "contract", or "declared". MUST be truthful.
supersedesstringnoAn open expectation this one replaces (§10.3).

The following are REQUIRED of the raising agent:

Rationale. The matcher is a key and not a predicate because the watcher is the party that evaluates it, and the watcher is generic. A watcher that can evaluate "a manifest has probably been received" is a watcher with a model in it, and every property this document establishes about determinism and attribution goes with it. The key is the whole contract between the agent and the watcher, and it is enough: the party that observes the manifest arriving knows it is a manifest and knows the shipment.

8.1 Withdrawal

When the task that raised an expectation is canceled, or reaches TASK_STATE_FAILED or TASK_STATE_REJECTED, the watcher MUST withdraw every open expectation that task raised. A withdrawn expectation MUST NOT lapse and MUST remain in the record, marked withdrawn.

An expectation carrying supersedes withdraws the expectation it names at the moment it is recorded.

An agent MAY withdraw an expectation explicitly by emitting, in a later artifact under the same key, { "withdraw": ["exp-…"], "reason": "…" }.

Rationale. An expectation raised by a task that no longer exists is a lapse waiting to fire on a shipment nobody is handling. The rule is stated here rather than left to implementations because it is the one that gets forgotten, and the symptom — lapse tasks for canceled work — is what makes an operations team turn the mechanism off.

9. Facts, satisfaction, and lapse

9.1 The three kinds of lapse

A watcher MUST distinguish three ways an expectation fails, because they are three different problems:

LapseConditionWhat it usually means
overduedueAt + grace has passed and no matching fact has arrived, and nothing listed in a later expectation's after for this subject has been satisfied.The step has not happened, or has not been reported yet. The ordinary case.
skippedA fact satisfied an expectation whose after names this one, while this one is still open.The step happened and the report never reached us — or a party in the chain does not report that step and never has. A data problem wearing an operational costume.
stalledhorizon has passed, this expectation is open, and no fact of any kind has been recorded for the subject since the most recent satisfaction (or since the expectation was raised).Nothing is happening. Freight in a bonded shed waiting for a document; a query in a mailbox nobody reads.

A skipped lapse MUST be raised as soon as the condition holds. It MUST NOT wait for dueAt.

Rationale. A timeline that renders only what arrived cannot show the second kind at all: a step that was skipped looks identical to a step that has not happened yet. Only the plan knows a step was expected between the two that arrived. The third kind is where the expensive exceptions live, and it is detectable only if "nothing has happened for longer than expected" can itself become an event — which is the entire content of this extension.

9.2 Facts

A fact is reported to the watcher as:

{
  "factKey": "shipment.departed:PA-2026-0901",
  "observedAt": "2026-09-11T02:41:00Z",
  "source": "carrier-feed:emirates",
  "subject": { "type": "shipment", "id": "PA-2026-0901" }
}
FieldTypeRequiredMeaning
factKeystringyesMatched exactly against satisfiedBy.factKey.
observedAtstringyesRFC 3339 instant the fact was observed, UTC. Used for lateness; not for lapse.
sourcestringyesWho observed it. MUST be attributable (§13.5).
subjectSubjectnoThe subject the fact concerns. Used for stalled.

A fact MAY be reported by the agent, in an Artifact's metadata under "facts"; by a client, in a Message's metadata under the same key; or by any other party the watcher has authorized, over a transport this document does not specify.

On receiving a fact the watcher MUST:

A fact that satisfies an expectation after dueAt MUST be recorded as late. Lateness is a property of the record, not a lapse: a watcher MUST NOT submit a lapse task for an expectation that has been satisfied. An implementation MAY report lateness to the agent by another means.

A fact matching no open expectation MUST NOT be treated as an error.

9.3 Re-anchoring

When an expectation with an anchor is recorded, its current due time is its dueAt — the projection the agent made when it raised it. When the anchor is satisfied, the watcher MUST set the current due time to the anchor's observedAt plus offset, and MUST preserve the projected due time unchanged.

The watcher's record of an expectation therefore carries both:

FieldMeaning
projectedDueAtdueAt as raised. Never changes.
dueAtThe current due time. Changes exactly once, when the anchor is satisfied.

An overdue lapse is evaluated against the current due time.

An anchored expectation whose anchor lapses MUST NOT itself lapse as overdue on the projected time. It is evaluated only against horizon, if present, until its anchor is satisfied or it is withdrawn.

Rationale. Without re-anchoring, one late milestone turns every downstream step red and keeps it red, and the alerting is noise within a week. Without the projected time, every re-anchor forgives the previous slip and the cumulative drift disappears: nobody can say the shipment is now four hours behind where it was ever meant to be. Original plan, current plan, actuals — three tracks, even though most interfaces draw two. The last rule prevents a cascade: one lapse on a chain of six anchored steps produces one lapse task, not six.

10. The lapse task

10.1 Submission

When an expectation lapses, the watcher MUST submit a new task to the agent that raised it, by the core Send Message operation, with:

{
  "role": "ROLE_USER",
  "contextId": "ctx-northgate-sep",
  "referenceTaskIds": ["task-booking-7f3a"],
  "messageId": "lapse:exp-01J8Q0MANIFEST:skipped:2026-09-10T20:15:00Z",
  "parts": [{ "text": "PA-2026-0901 departed on EK203 at 02:41Z but no manifest was ever received." }],
  "extensions": ["https://rsaxb.com/a2a/expectations/v1"],
  "metadata": {
    "https://rsaxb.com/a2a/expectations/v1": {
      "lapse": {
        "expectationId": "exp-01J8Q0MANIFEST",
        "kind": "shipment.manifest",
        "subject": { "type": "shipment", "id": "PA-2026-0901" },
        "expects": "the airline manifest for PA-2026-0901",
        "lapse": "skipped",
        "projectedDueAt": "2026-09-10T20:15:00Z",
        "dueAt": "2026-09-10T20:15:00Z",
        "lapsedAt": "2026-09-11T02:41:07Z",
        "lastFactAt": "2026-09-11T02:41:00Z",
        "satisfiedAfter": ["exp-01J8Q0DEPART"],
        "lineage": 0
      }
    }
  }
}
FieldTypeRequiredMeaning
expectationId, kind, subject, expectsyesCopied from the expectation, so the agent need not look it up.
lapsestringyes"overdue", "skipped", or "stalled".
projectedDueAtstringyesAs raised.
dueAtstringyesCurrent due time at the moment of lapse.
lapsedAtstringyesWhen the watcher determined the lapse.
lastFactAtstringnoMost recent fact of any kind on the subject. Absent means none since the expectation was raised.
satisfiedAfterstring[]noFor skipped: the later expectations whose satisfaction revealed the gap.
lineageintegeryesHow many superseded ancestors this expectation has (§10.3).

The parts of the lapse message MUST state the lapse in a person's words. The block is for the agent; the text is for whoever reads the task history.

A watcher that missed a sweep — because it was down, or slow — MUST submit the lapse late rather than skip it. The deterministic messageId is what makes this safe.

10.2 What the agent may do

The lapse task invokes lapseSkill. Within it the agent MAY, in any combination:

The agent MUST NOT treat the lapse task as authorizing anything the origin task was not authorized to do (§13.1).

The lapse task MUST conclude in the ordinary way. It is a task, and it has a history; that is the point of it.

10.3 Extending

An agent that decides an expectation should be given more time MUST raise a new expectation carrying supersedes naming the lapsed one. It MUST NOT raise an expectation identical in kind, subject, satisfiedBy, and dueAt to one in its own lineage.

The new expectation's lineage is the lapsed one's plus one. A watcher MUST bound lineage and MUST refuse to record an expectation beyond the bound, reporting the refusal to the agent as a rejected artifact or by another means the deployment provides. The bound is a deployment choice; three is a reasonable one.

Rationale. The obvious way for this mechanism to run away is for an agent to answer every lapse by asking for more time. The identity rule stops the degenerate loop; the lineage bound stops the patient one. After the bound, the only way an expectation gets more time is that a person gives it.

11. Questions that expire

A status-update Message that moves a task to TASK_STATE_INPUT_REQUIRED or TASK_STATE_AUTH_REQUIRED MAY carry an expectation in its metadata, under the same key and in the same shape as §8, whose subject is the task itself:

{
  "expectationId": "exp-01J8Q0ANSWER",
  "kind": "question.answer",
  "subject": { "type": "task", "id": "task-booking-7f3a" },
  "expects": "someone to say whose shipment this is",
  "satisfiedBy": { "factKey": "task.answered:task-booking-7f3a" },
  "dueAt": "2026-09-09T12:00:00Z",
  "grace": "PT1H",
  "basis": "declared"
}

A watcher that is also the client MUST report the satisfying fact when it sends the answer. A watcher that is not the client satisfies the expectation on observing the origin task leave the interrupted state.

On lapse, the ordinary lapse task is submitted. The agent decides what an unanswered question means: escalate to a different person, close the origin task with a reason, or proceed under a stated default. A client MUST NOT silently discard a question because its expectation lapsed; whatever happens to it happens as a task event with a history.

Rationale. This is the smallest useful deployment of the extension, and it closes the oldest gap: input-required has no expiry in core, so a question that nobody answers is a task that stays open until somebody notices the list. With one expectation per question, the agent that asked is told it was not answered, and decides, on the record, what that means.

12. Transport and profiles

Raising expectations and submitting lapse tasks use core A2A operations and extension points; nothing new is defined. How facts reach a watcher that is not the client, and how the watcher stores its record, are out of scope.

The agent declares keepsTime: false. A client, orchestrator, or dedicated service records expectations from the agent's artifacts, receives facts, and submits lapse tasks. The agent learns that time has passed only by receiving a lapse task.

An agent in this profile MUST NOT hold local state whose correctness depends on a lapse arriving. If no watcher is present, expectations are simply never checked, and the agent's behaviour on the tasks it does receive is unchanged.

12.2 Self-timing agent

An agent that holds its own clock MAY declare keepsTime: true and act as its own watcher. It MUST still:

Rationale. The second requirement is the one a self-timing agent will want to skip: it has the clock and the task, so why not just fail the task at the deadline? Because then the record says a task failed, and not that an expectation the agent stated in advance went unmet — and because the client, which may have been holding the human, finds out from a state change with no history behind it.

13. Security considerations

A lapse task is work the agent does with nobody in the loop, triggered by the absence of anything, at a time when the person who started the original task may have gone home.

13.1 Unattended work

The lapse task MUST be authorized as any task from that watcher would be. The watcher's identity is the caller; the origin task's authority does not transfer. An action the agent proposes in a lapse task MUST pass through whatever approval the deployment requires for that action in any other task.

Implementations SHOULD treat "raised a lapse task" as an event worth surfacing to a person, even when the agent concluded that nothing was needed.

Rationale. The most consequential thing an unattended agent can do is act. The second most consequential is decide, unattended and unrecorded, not to. The first is prevented by keeping authorization where it already is; the second by making the decision a task.

13.2 Amplification and loops

A watcher MUST bound the number of open expectations per subject and per raising agent, and MUST refuse to record beyond the bound. The identity and lineage rules in §10.3 are REQUIRED, not advisory. A watcher SHOULD rate-limit lapse submissions per agent.

Rationale. The objection raised against scheduled tasks in #210 — that a public agent becomes a source of repeated requests to third parties — applies here in a narrower form. An expectation cannot recur; it fires at most once per kind. The remaining risk is volume and lineage, and both are bounded by the watcher, which is the party with an interest in bounding them.

13.3 Dishonest due times

A due time derived from a contract, or from what a lane is sold as, produces a lapse on nearly every task. Within a fortnight every reader has learned to ignore the colour, and the mechanism is an expensive noise generator with a nice interface. The lapse that mattered is then indistinguishable from the hundred that did not.

Rationale. This is the uncomfortable requirement. Encoding what the lane actually does means writing down that a lane sold as four days is a six-day lane, and having somebody senior read that. The first useful output of a deployment is usually not a lapse at all: it is the discovery that the published transit time and the real one have disagreed for a long while.

13.4 Clock trust

dueAt, observedAt, and lapsedAt are UTC instants (A2A §5.6.1). A lapse is determined against the watcher's clock. A watcher MUST NOT determine a lapse from timestamps supplied by the agent or by fact sources; it uses those for lateness and ordering only. Implementations SHOULD tolerate skew of the order of grace, and an agent SHOULD NOT raise an expectation with a grace shorter than the skew it can expect.

13.5 Forged arrivals

A fact satisfies an expectation, and an expectation that is satisfied never lapses. A party that can report facts can therefore silence the watcher for any subject whose keys it can guess.

13.6 Cancellation

Withdrawal on cancellation (§8.1) is the expectation-side counterpart of cascading cancellation (#2119). A watcher MUST withdraw on the origin task's terminal state regardless of whether the deployment propagates cancellation to delegated tasks.

14. Privacy considerations

Subjects and fact keys routinely embed identifiers — shipment references, invoice numbers, case ids — that are personal data in some jurisdictions when linked to a person. An expectation additionally reveals a plan: what is expected to happen to whom, and when.

Implementations:

15. Versioning

The extension URI is the version. Any change that would break a watcher reading an expectation or an agent reading a lapse block — 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:

An agent MAY declare several versions simultaneously during a migration. A watcher SHOULD use the highest version it understands.

16. Relationship to Learnables

The two extensions are independent. Where both are deployed:

Neither dependency is normative.

17. 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, one extra key in some artifacts' metadata, and — if a watcher is present — additional tasks in a context that reference earlier ones, all of which are ordinary A2A.

Six parts of core A2A are load-bearing and are used as specified, not redefined:

This extension is deliberately not a task deadline (#857). A deadline is the client's budget for the agent's work and belongs on the request. An expectation is the agent's statement about the world and belongs on the result. The two compose: a task with a deadline may raise expectations that outlive it.

Appendix A. JSON Schema

The machine-readable descriptor and JSON Schema for the objects above are served at https://rsaxb.com/a2a/expectations/v1/extension.json, whose $defs define ExpectationKind, Expectation, Subject, Fact, Lapse, and ExpectationRecord.

Appendix B. Worked example

A pre-alert application, a booking agent, and a carrier feed. The application is the watcher. No scheduler is deployed; the application's existing periodic sweep is enough.

  1. The application fetches the agent's card, reads keepsTime: false, and knows it must keep time.
  2. A shipment is booked. The agent's confirmation artifact raises three expectations: manifest by 20:15Z, departure by 03:15Z (after the manifest), arrival 1h45 after departure (anchored), with a two-day horizon on the subject. Every due time carries basis: "observed", because they came from what this lane has done for the last quarter, not from the airline's schedule.
  3. The carrier feed reports departure at 02:41Z. The application reports the fact. The departure expectation is satisfied, early. The arrival expectation re-anchors: current due 04:26Z, projected due 05:00Z preserved. The manifest expectation, still open, is named in the departure's after — the application raises a skipped lapse immediately.
  4. The lapse task is submitted under the booking's context, referencing the booking task, with a message id that would be the same if the sweep ran twice. The agent's handle_lapse skill reads the block: the freight has left and the manifest never came. It proposes a chase to the airline's documentation desk. The proposal passes through the same approval every outbound message in the deployment passes through. The lapse task completes with the receipt.
  5. Nothing arrives for two days. The horizon passes with no fact on the subject since 02:41Z. A stalled lapse is submitted. The agent asks a human: the freight has not arrived and nobody has said why. The question carries its own expectation, due in four hours.
  6. The record shows two tracks. The projected plan as a faint upper line; what happened solid beneath; a hole where the manifest should have been, and a flat line after departure. The application drew nothing it was not told.

Appendix C. Changelog

VersionDateChange
v1 draft2026-09-05Initial publication.

References