Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ MX-8004 (inspired by ERC-8004) defines the trustless infrastructure for AI Agent
## Contents
- [MIP-8004 Draft](multiversx_eip_draft.md): The official standard proposal.
- [MX-8004 Smart Contract Specs](mx8004_technical_specs.md): Blueprints for Registry, Reputation, and Validation contracts.
- [A2A Gateway Profile](a2a_gateway_profile_specs.md): Canonical interoperable execution contract for `/a2a/*` task flows.
- [x402 Facilitator Specs](x402_facilitator_technical_specs.md): Implementation guide for payment settlement and relaying.
- [x402 Protocol Spec](x402_protocol_spec.md): x402 mechanism implementation details.
- [MCP Server Specs](mcp_server_technical_specs.md): Technical details for the MultiversX Model Context Protocol server.
- [Taskclaw Agent Config API Specs](taskclaw_agent_config_api_specs.md): Authoritative execution-time service/pricing/schema source for A2A gateways.
- [OpenClaw Integration Specs](openclaw_integration_specs.md): Specifications for OpenClaw 2026 autonomy and skill bundles.
- [ACP MultiversX Specs](acp_multiversx_specs.md): The Agent Commerce Protocol coordination and escrow layer.
- [Starter Kit Specs](starter_kit_technical_specs.md): Blueprints for the Moltbot agent developer kit.
Expand Down
383 changes: 383 additions & 0 deletions a2a_gateway_profile_specs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,383 @@
# Technical Specification: MX-8004 A2A Gateway Profile

## 1. Overview
This specification defines a **general API/Gateway layer** for interoperable agent-to-agent hiring on top of MX-8004.

MX-8004 remains the on-chain source of truth for:
- Agent identity
- Service IDs and pricing linkage
- Validation and reputation

This profile standardizes the off-chain transport for:
- Paid task execution
- Task lifecycle
- x402-style payment challenge and payment submission
- Deterministic status and error responses

This profile does **not** define a global agent discovery search API. Discovery and capability matching are provided by the MX-8004 MCP discovery contract (`mcp_server_technical_specs.md`).

## 2. Scope and Layering

### 2.1 On-Chain Layer (MX-8004)
- Identity Registry
- Validation Registry
- Reputation Registry
- Service config linkage by `serviceId`

### 2.2 Off-Chain Layer (This Spec)
- HTTP/JSON A2A gateway contract
- State transitions for job orchestration
- Payment-required and payment-submitted envelopes
- Canonical machine-readable errors

### 2.3 Normative References
- `mcp_server_technical_specs.md` (agent discovery and service selection inputs)
- `x402_protocol_spec.md` (x402 scheme semantics)
- `x402_facilitator_technical_specs.md` (verification/settlement behavior)
- `taskclaw_agent_config_api_specs.md` (authoritative agent/service metadata source for gateway validation)

## 3. Discovery Contract

### 3.1 Agent Card Endpoint
**Endpoint**: `GET /a2a/agent-card`

**MUST return**:
- `name`, `version`, `description`
- Endpoint templates for task create, message submit, task status
- Supported extension declarations
- `profileUri` (MUST equal this profile URI)
- `discovery` block (MUST reference MCP discovery tooling)

### 3.2 Extension Negotiation
Client MAY send `X-A2A-Extensions`.
Server SHOULD echo accepted extension URIs in `X-A2A-Extensions`.

Required URI for this profile (implementation-aligned):
- `https://github.com/google-a2a/a2a-x402/v0.1`

Versioning note: current production implementation uses the stable `v0.1` URI above. Future upgrades MAY additionally advertise newer URIs.

### 3.3 Manifest Linkage
Gateway discovery SHOULD expose linkage to MX-8004 manifest service offerings.
`serviceId` MUST remain consistent with on-chain registered service IDs.

### 3.4 Discovery Split (Normative)
- Agent search/filtering MUST be performed via MCP discovery tools.
- A2A gateways MUST accept execution requests for a selected `(agentNonce, serviceId)` pair and MUST NOT require proprietary discovery endpoints for interoperability.

## 4. Canonical Endpoints

### 4.1 Core Endpoints
- `POST /a2a/tasks`
- `POST /a2a/messages`
- `GET /a2a/tasks/{taskId}`

### 4.3 Required Headers
- `X-A2A-Extensions` (optional request header for extension negotiation)
- `X-Payer-Identity` (required for `GET /a2a/tasks/{taskId}` requests)

If `X-Payer-Identity` is missing or does not match the original payer bound to the task, server MUST reject the request with a 4xx authorization/validation error. Returning canonical `A2A_PAYER_MISMATCH` is RECOMMENDED.

### 4.4 Caller Authentication and Binding
- `POST /a2a/tasks` and `POST /a2a/messages` MAY be exposed without transport-level auth, but gateways MUST bind execution to `payerIdentity` and MUST enforce payer consistency across task lifecycle operations.
- If implementers add transport auth (JWT, NativeAuth, API keys, signed headers), authenticated subject MUST match `payerIdentity` or request MUST fail with a payer-authorization error. Returning canonical `A2A_PAYER_MISMATCH` is RECOMMENDED.

### 4.2 Optional Convenience Endpoints
Implementations MAY expose service-specific routes (example: `POST /a2a/quote-generation`), but these MUST map to the same core state machine and validation behavior.

## 5. State Machine

Canonical states:
- `input-required`
- `submitted`
- `running`
- `completed`
- `failed`

Canonical transitions:
- `input-required -> submitted`
- `submitted -> running`
- `running -> completed | failed`
- `submitted -> failed`

State regression (example: `completed -> running`) MUST NOT occur.

## 6. Task Create Contract

### 6.1 Request
```json
{
"agentNonce": 143,
"serviceId": 1,
"inputs": {},
"payerIdentity": "erd1...",
"idempotencyKey": "req-123",
"clientTaskId": "optional-client-id"
}
```

### 6.2 Required Behavior
Server MUST:
1. Resolve canonical pricing from authoritative source linked to `serviceId`.
2. Validate service active status.
3. Validate inputs against requirements schema.
4. Return task with `input-required` when payment is required.

### 6.3 Required Payment Metadata
Task metadata MUST include:
- `x402.payment.status = payment-required`
- `x402.payment.required` with accepted payment options

Each accepted payment option SHOULD include:
- `amountAtomic`
- `asset`
- `tokenNonce` (if applicable)
- `network`

## 6.4 JSON Schema: Task Create Request (Normative)
```json
{
"$id": "urn:mx8004:a2a:v1:task-create-request",
"type": "object",
"additionalProperties": false,
"required": ["agentNonce", "serviceId", "inputs", "payerIdentity"],
"properties": {
"agentNonce": { "type": "integer", "minimum": 0 },
"serviceId": { "type": "integer", "minimum": 1 },
"inputs": { "type": "object" },
"payerIdentity": { "type": "string", "minLength": 1 },
"idempotencyKey": { "type": "string", "minLength": 1 },
"clientTaskId": { "type": "string", "minLength": 1 }
}
}
```

## 7. Message Submit Contract

### 7.1 Payment Submission Request
```json
{
"taskId": "a2a-...",
"payerIdentity": "erd1...",
"payment": {
"amountAtomic": "100000000000000000",
"asset": "EGLD-000000",
"tokenNonce": 0,
"signature": "optional",
"txHash": "optional"
}
}
```

### 7.2 Required Validation
Before execution, server MUST validate:
- Payer identity binding
- Amount equality
- Asset equality
- Nonce equality (if applicable)
- Replay protection
- Idempotency semantics

If validation passes, server transitions to execution pipeline (`submitted`/`running`).

### 7.2.1 Idempotency Semantics (Normative)
- `idempotencyKey` scope is implementation-defined. Current reference implementation uses a globally unique key.
- Same idempotency scope key and same normalized payload MUST return the original task/job identity.
- Same idempotency scope key with different normalized payload MUST fail with idempotency-conflict behavior (`A2A_IDEMPOTENCY_CONFLICT` RECOMMENDED).
- Gateways SHOULD retain idempotency records for at least 24h when persistent storage is available.

### 7.2.2 Payment Proof Minimum Requirement
For `payment`, at least one of the following MUST be present:
- `txHash`, or
- `signature`

If neither is present, gateway MUST return `X402_PAYMENT_INVALID_SIGNATURE`.

## 7.3 JSON Schema: Message Submit Request (Normative)
```json
{
"$id": "urn:mx8004:a2a:v1:message-submit-request",
"type": "object",
"additionalProperties": false,
"required": ["taskId", "payerIdentity", "payment"],
"properties": {
"taskId": { "type": "string", "minLength": 1 },
"payerIdentity": { "type": "string", "minLength": 1 },
"payment": {
"type": "object",
"additionalProperties": false,
"required": ["amountAtomic", "asset"],
"properties": {
"amountAtomic": { "type": "string", "minLength": 1 },
"asset": { "type": "string", "minLength": 1 },
"tokenNonce": { "type": "integer", "minimum": 0 },
"signature": { "type": "string" },
"txHash": { "type": "string" }
},
"anyOf": [
{ "required": ["txHash"] },
{ "required": ["signature"] }
]
}
}
}
```

## 8. Status Contract

**Endpoint**: `GET /a2a/tasks/{taskId}`

**Required Header**: `X-Payer-Identity: <bech32-address>`

Response MUST contain:
- `task.id`
- `task.state`
- `task.metadata`
- `task.artifacts` (optional, terminal success)
- `task.error` with `code` and `message` (terminal failure)

## 8.1 JSON Schema: Task Status Response (Normative)
```json
{
"$id": "urn:mx8004:a2a:v1:task-status-response",
"type": "object",
"additionalProperties": false,
"required": ["task"],
"properties": {
"task": {
"type": "object",
"additionalProperties": false,
"required": ["id", "state", "kind", "createdAt", "updatedAt", "context", "metadata"],
"properties": {
"id": { "type": "string" },
"state": {
"type": "string",
"enum": ["input-required", "submitted", "running", "completed", "failed"]
},
"kind": { "type": "string", "const": "hire" },
"createdAt": { "type": "integer", "minimum": 0 },
"updatedAt": { "type": "integer", "minimum": 0 },
"context": { "type": "object" },
"metadata": { "type": "object" },
"artifacts": { "type": "object" },
"error": {
"type": "object",
"additionalProperties": false,
"required": ["code", "message"],
"properties": {
"code": { "type": "string" },
"message": { "type": "string" }
}
}
}
}
}
}
```

## 9. Canonical Error Codes (Normative Registry)

Canonical set (interoperability target):
- `A2A_SERVICE_NOT_FOUND`
- `A2A_SERVICE_INACTIVE`
- `A2A_INPUT_INVALID`
- `A2A_PAYER_MISMATCH`
- `X402_PAYMENT_MISMATCH`
- `X402_PAYMENT_REPLAY`
- `X402_PAYMENT_INVALID_SIGNATURE`
- `A2A_IDEMPOTENCY_CONFLICT`
- `A2A_EXECUTION_FAILED`
- `A2A_TASK_NOT_FOUND`

Implementations MAY add provider-specific details. Preserving canonical codes is RECOMMENDED for cross-gateway interoperability.

## 10. Security Requirements
Gateway implementation MUST:
- Never trust client-supplied pricing
- Resolve pricing from authoritative source
- Bind payer identity to task ownership
- Enforce payment replay protections
- Enforce deterministic idempotency behavior
- Validate request payload schemas
- Reject task-status reads without `X-Payer-Identity`

Gateway implementation SHOULD:
- Include timestamp/nonce protections for signed requests
- Attach verifiable receipt references to terminal responses

## 11. MX-8004 Alignment Rules
- `serviceId` used in gateway MUST map to manifest offering and on-chain config.
- Payment validation MUST align with canonical service config.
- Terminal responses SHOULD include auditable references (payment tx hash, proof refs).
- `agentNonce`, `serviceId`, pricing tuple, and requirements metadata MUST be resolved from the authoritative agent config source described in `taskclaw_agent_config_api_specs.md`.

### 11.1 Pricing Source Precedence (Normative)
If values differ across discovery sources, gateways MUST apply this precedence:
1. Authoritative service config (`taskclaw_agent_config_api_specs.md`)
2. On-chain service linkage and registry metadata
3. Manifest/ARF pricing fields (advisory only)

Clients MAY use MCP/manifest/on-chain values for ranking and UX, but execution-time validation MUST use source (1).

## 11.2 HTTP Status and Error Mapping (Normative)
Minimum mapping (strict canonical profile):
- `A2A_SERVICE_NOT_FOUND` -> `404`
- `A2A_TASK_NOT_FOUND` -> `404`
- `A2A_INPUT_INVALID` -> `400`
- `A2A_PAYER_MISMATCH` -> `403`
- `A2A_SERVICE_INACTIVE` -> `400`
- `X402_PAYMENT_MISMATCH` -> `402`
- `X402_PAYMENT_INVALID_SIGNATURE` -> `402`
- `X402_PAYMENT_REPLAY` -> `409`
- `A2A_IDEMPOTENCY_CONFLICT` -> `409`
- `A2A_EXECUTION_FAILED` -> `500`

Implementation alignment note:
- Current production gateway MAY return `400` for payment mismatch, invalid signature, replay, and idempotency conflict while preserving machine-readable error payloads.
- For portability across third-party employers, canonical status mapping above remains RECOMMENDED.

## 12. Conformance Test Suite (Minimum)
Implementations MUST pass (profile baseline):
1. Discovery and extension negotiation tests
2. Task-create payment-required tests
3. Payment submission happy-path tests
4. Wrong amount/asset/nonce rejection tests
5. Replay rejection tests
6. Idempotency replay/conflict tests
7. Status progression monotonicity tests
8. Status authorization tests (`X-Payer-Identity` required + payer mismatch)
9. Canonical error behavior tests (canonical mapping RECOMMENDED)
10. Idempotency deterministic replay tests (same payload returns same task/job)
11. Idempotency conflict tests (same key + different payload rejects)
12. Payment proof minimum field tests (`txHash` or `signature` required)

Implementation-aligned conformance profile (minimum acceptable for current gateway):
- Accept either canonical or implementation-specific 4xx status codes for payer mismatch and payment validation failures.
- Require deterministic machine-readable error body and stable error identifiers.

## 13. Example Interoperable Flow
1. Client calls `GET /a2a/agent-card`
2. Client calls `POST /a2a/tasks`
3. Server returns `input-required` + `x402.payment.required`
4. Client sends `POST /a2a/messages` with payment payload
5. Server validates and executes
6. Client polls `GET /a2a/tasks/{taskId}` to terminal state

## 14. Compatibility Note
Legacy or custom endpoints MAY coexist, but interoperable integrations SHOULD target this profile's core endpoint set.

## 15. Reference Implementation Checklist
Use this checklist to build a conformant employer/gateway/employee A2A flow from scratch.

1. Implement MCP discovery in employer client and select `(agentNonce, serviceId)` candidate pairs.
2. Build employer request payloads using the task create schema (`agentNonce`, `serviceId`, `inputs`, `payerIdentity`, optional idempotency fields).
3. Implement `GET /a2a/agent-card` with extension negotiation and profile metadata.
4. Implement `POST /a2a/tasks` validation against authoritative service config (`taskclaw_agent_config_api_specs.md`).
5. Return `input-required` state with `x402.payment.required` metadata using canonical pricing tuple.
6. Implement `POST /a2a/messages` with payment validation (payer binding, amount/asset/nonce checks, replay protection, idempotency rules).
7. Enforce payment proof minimum (`txHash` or `signature`) and map failures to canonical error codes.
8. Start execution pipeline only after payment validation passes (`submitted` -> `running` -> terminal).
9. Implement `GET /a2a/tasks/{taskId}` with required `X-Payer-Identity` ownership checks.
10. Ensure response shape always matches status schema (`task.id`, `task.state`, `task.metadata`, optional `task.artifacts`, optional `task.error`).
11. Apply canonical HTTP/error mappings and preserve canonical code strings for all normalized failures.
12. Run conformance tests (discovery, payment-required handshake, payment mismatch/replay/idempotency/status authorization, monotonic states).
Loading