Skip to main content

UNMAPPED markers

The specification marks with UNMAPPED each rule of A2A it does not hold, in a YAML comment beside the place the rule belongs. ess/ has 41 markers: 40 name a construct ESS lacks (an ESS gap), 1 an open question. Each row links the marker's line and shows its first sentence; the comment there carries the source quote and, for an ESS gap, the refusal ESS gave.

The HTTP+JSON routes ESS cannot serve at A2A's path are on HTTP+JSON routes.

ess/components.yaml​

LineKindMarker
10ESS gapthe binding itself. ESS 0.67.0 binds a command to an HTTP route (ess-http/1), one method and path each, while JSON-RPC sends every method to one endpoint and dispatches on the body's method.
33ESS gapno authored scenario holds -32601 or -32602. An act expects one refusal, refused: not_granted; there is none for an input the declaration rejects or for an unknown command, and a scenario naming an undeclared command is refused by name.
59ESS gappush delivery. Section 4.3.3: "When a task update occurs, the agent sends an HTTP POST request to the configured webhook URL", and the same section: "Agents MUST attempt delivery at least once for each configured webhook".
74ESS gapthe stream transport. Section 11.7: "REST streaming uses Server-Sent Events", answering Content-Type: text/event-stream with one data: line per StreamResponse; JSON-RPC streams over SSE too (section 9.4.2), gRPC as a server stream (10.7).

ess/domains/discovery.yaml​

LineKindMarker
229ESS gapthe exactly-one rule of the oneof. ESS 0.67.0 has no externally tagged union (a union without tag: is refused: "missing field tag").
292ESS gapthe exactly-one rule of the oneof, as for OAuthFlows above.

ess/domains/tasks.yaml​

LineKindMarker
58ESS gapthe exactly-one rule. ESS 0.67.0 validates it as a type invariant (any: [all: [defined(text), not defined(raw), …], …]), but Part is reachable from the typed responses of GetTask, CancelTask, SubscribeToTask and SendMessage, and synthesis then refuses each returning outcome: "ESS-SYNTH-001: … …
120ESS gapa2a.proto, Artifact.artifact_id: "It must be unique within a task", and Artifact.parts: "Must contain at least one part." The second validates as a type invariant (parts.count >= 1), but synthesis refuses it: "record invariant on a response type a2a.tasks.Artifact has no executable observer".
363ESS gapthe natural identity is the struct (task_id, config_id). ESS 0.67.0 refuses both ways to create one: instance: {task_id: input.task_id, id: input.id} gives "invalid type: map, expected a string", and a struct identity published by the creating event gives SYNTH-001 "a struct held by reference has …
404ESS gapthe per-row boundary (which tasks and configurations this client may see); ESS 0.67.0 grants a whole view to an actor.
428ESS gapthe summary is the only place ESS 0.67.0 carries the code, and nothing reads it.
579ESS gapESS 0.67.0 answers a command when its outcome commits. Missing construct: an answer deferred until later commands (StartWorking, Complete, RequireInput, …) move the created row into a named set of states.
604ESS gaptask-not-found, task-terminal, context-mismatch and continued depend on message.taskId, a member of the message input.
656ESS gapa2a.proto, SendMessageConfiguration.task_push_notification_config: "Configuration for the agent to send push notifications for task updates.
714ESS gaptask-not-found, task-terminal, context-mismatch and continued depend on message.taskId, a member of the message input.
785ESS gapa2a.proto, SendMessageConfiguration.task_push_notification_config: "Configuration for the agent to send push notifications for task updates.
826ESS gapa2a.proto, GetTaskRequest.history_length: "The server MUST NOT return more messages than the provided value, but MAY apply a lower limit." Nothing below bounds the returned task.history by it.
984ESS gapnothing emits a2a.tasks.TaskSubscriptionResponse. Subscribing changes no task, and a preserving outcome that emits is refused: "ESS-COMMAND-004: a preserving outcome declares no assignment, event or error".
1025open questionA2A v1.0.1 is silent on a second create with an id a configuration of the same task already carries; created then adds a second row with that pair.
1029ESS gapassigned writes row and config_id as two independent {generated: true} values; ESS 0.67.0 has no construct to generate the id once and reuse it in the stored field and the event payload, so nothing checks they agree.
1057ESS gapa task of another tenant, or of one when the request has none (and the reverse), answers TaskNotFound, as GetTask other-tenant says.
1150ESS gapthe rule is on the configuration's tenant, not the task's. ESS 0.67.0 refuses a when_subject: guard beside this row-set guard: "ESS-COMMAND-009: a2a.tasks.GetTaskPushNotificationConfig selects on a row set (when_related: {entity, where, …}) and on a when_subject guard; one command reads one …
1161ESS gapthe config answered is not bound to the matched row; a typed response is opaque to ESS 0.67.0, as on ListTaskPushNotificationConfigs.
1200ESS gapwhich rows configs holds. Section 3.1.9: "The operation MUST return all active push notification configurations for the specified task and MAY support pagination".
1275ESS gapa task of another tenant, or of one when the request has none (and the reverse), answers TaskNotFound, as GetTask other-tenant says.
1283ESS gapa no-op delete emits PushNotificationConfigDeleted; a separate no-op branch (when_related exists: false) is refused, ESS-SYNTH-001 "a step of the scenario changes rows of the selector's entity in a way synthesis does not follow".
1374ESS gapsection 7.6.1, the agent "MUST include a TaskStatus message explaining the required authorization, unless the details of the authorization have been negotiated out-of-band or via an extension".
1525ESS gapthe task's stored artifacts should gain input.artifact, or, with append, the parts of the artifact with the same artifact_id should grow (a2a.proto, TaskArtifactUpdateEvent.append: "the content of this artifact should be appended to a previously sent artifact with the same ID").
1596ESS gapthe exactly-one rule of the oneof. ESS 0.67.0 has no externally tagged union (a union without tag: is refused: "missing field tag"), and an emitting outcome must source every member, the absent ones included: leaving message out of the payload is refused, "ESS-COMMAND-005: emitted payload …
1605ESS gapthe elements after the first. Section 3.1.2 follows the first Task with "zero or more TaskStatusUpdateEvent or TaskArtifactUpdateEvent objects", and section 3.5.2: "Events MUST be broadcast to all active streams for that task" and "Each stream MUST receive the same events in the same order".
1663ESS gaprow has no A2A source; dropping it is refused, ESS-COMMAND-001 "acts on the instance named by row, which is no field of an emitted event of it".
1683ESS gap"Implementations MUST return tasks sorted by their status timestamp time in descending order".
1689ESS gapthe cursor paging (page_size, page_token, next_page_token, "MUST use cursor-based pagination").
1698ESS gapa view answers no error, so the protocol-negotiation refusals (VersionNotSupportedError -32009, ExtensionSupportRequiredError -32008; section 3.6.2 "agents MUST return a VersionNotSupportedError") are not declared for ListTasks.
1711ESS gapwire type is TaskState (TASK_STATE_*); ESS 0.67.0 has no map from it to the lifecycle states the filter compares.
1742ESS gapthe wire spells the state TASK_STATE_*. ESS 0.67.0 gives a lifecycle state no wire spelling: states: [{name: Submitted, wire: TASK_STATE_SUBMITTED}, …] is refused "invalid type: map, expected a string", so the row carries the lifecycle name.
1766ESS gapthe per-row boundary within the Agent's reads (which tasks one authenticated caller may see); ESS 0.67.0 grants a whole view to an actor, no subset of rows.
1840ESS gaprow has no A2A source; dropping it is refused, ESS-SYNTH-001 on DeleteTaskPushNotificationConfig/deleted "published by no immediate, unfiltered, unparameterised, unpaged view carrying its identity".

ess/http.yaml​

LineKindMarker
8ESS gapthe /{tenant}/... additional binding of every operation, for example post: "/{tenant}/message:send" beside post: "/message:send".
31ESS gapDELETE carries its inputs outside the path in a JSON body, where section 11.5 says "HTTP methods that do not support request bodies (GET, DELETE) MUST transmit operation request parameters as path parameters or query parameters": query encoding is admitted on get only (ESS-HTTP-020).
56ESS gapa2a.proto CancelTask, post "/tasks/{id=*}:cancel", body "*", and SubscribeToTask, get "/tasks/{id=*}:subscribe" (section 11.3.2 writes POST /tasks/{id}:subscribe), keep their derived routes, post /tasks/commands/tasks:cancel and post /tasks/commands/tasks:subscribe.