Version: 0.3
Status: Normative
Package: @peac/mappings-a2a
A2A Spec Version: v1.0.0 (stable). v0.3.0 compatibility was deprecated in v0.12.3 and removed in v0.13.0 (DD-186).
Extension URI: https://www.peacprotocol.org/ext/traceability/v1
Depends on: Evidence Carrier Contract (DD-124)
This document specifies how PEAC evidence carriers are placed within A2A (Agent-to-Agent Protocol) messages and metadata. It covers Agent Card declaration, metadata layout, header conventions, and security considerations. A2A v1.0.0 is the only accepted wire format; the v0.3.0 compatibility path (top-level url, kebab-case TaskState normalization, /.well-known/agent.json legacy discovery) was removed in v0.13.0.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174) when, and only when, they appear in all capitals, as shown here.
A2A (Linux Foundation) defines a protocol for agent-to-agent communication. PEAC provides an evidence layer that agents can use to carry signed interaction receipts, consent records, and other traceability data alongside A2A messages.
PEAC evidence is carried as an A2A extension, registered via the Agent Card and transmitted in metadata maps on TaskStatus, Message, and Artifact objects. This profile supports both HTTP/SSE and gRPC transports as defined in A2A v1.0.
Agents that support PEAC evidence MUST declare the extension in their Agent Card's extensions array (A2A v1.0.0):
{
"name": "ExampleAgent",
"url": "https://agent.example.com",
"extensions": [
{
"uri": "https://www.peacprotocol.org/ext/traceability/v1",
"description": "PEAC signed interaction receipt evidence",
"required": false,
"params": {
"supported_kinds": ["interaction-record+jwt", "peac-receipt/0.1"],
"carrier_formats": ["embed", "reference"],
"issuer_config_url": "https://agent.example.com/.well-known/peac-issuer.json"
}
}
]
}Fields:
| Field | Type | Required | Description |
|---|---|---|---|
uri |
string |
MUST | Extension URI (exactly as shown above) |
description |
string |
SHOULD | Human-readable description |
required |
boolean |
MUST | Whether counterparty MUST support this extension |
params |
object |
MAY | Extension parameters (schema below) |
Params schema:
| Field | Type | Description |
|---|---|---|
supported_kinds |
string[] |
Wire format versions: interaction-record+jwt (Wire 0.2, preferred), peac-receipt/0.1 (Wire 0.1, legacy) |
carrier_formats |
string[] |
Supported carrier formats: embed, reference |
issuer_config_url |
string |
URI for issuer configuration (peac-issuer.json) |
The Agent Card is discoverable at /.well-known/agent-card.json, the A2A v1.0.0 canonical path. The v0.3.0 legacy path /.well-known/agent.json was deprecated in v0.12.3 and removed in v0.13.0 (DD-186); implementations MUST NOT probe it. Implementations MAY additionally probe /.well-known/peac.json as a PEAC-specific discovery extension and MAY use a HEAD-request header probe as a secondary fallback (see packages/mappings/a2a/src/discovery.ts).
Per A2A spec v1.0.0, extension data is placed as a value under the extension URI key in a metadata map:
metadata[EXTENSION_URI] = { ...extension_payload }
For PEAC, the extension URI key is:
https://www.peacprotocol.org/ext/traceability/v1
The value under the extension URI key MUST be an object with the following structure:
{
"https://www.peacprotocol.org/ext/traceability/v1": {
"carriers": [
{
"receipt_ref": "sha256:abc123...",
"receipt_jws": "eyJhbGciOi..."
}
],
"meta": {
"transport": "a2a",
"format": "embed",
"max_size": 65536
}
}
}| Field | Type | Required | Description |
|---|---|---|---|
carriers |
PeacEvidenceCarrier[] |
MUST | Array of evidence carriers |
meta |
CarrierMeta |
MAY | Transport metadata |
The carriers array uses the PeacEvidenceCarrier schema defined in the Evidence Carrier Contract. The meta object follows the CarrierMeta schema.
PEAC evidence MAY be attached to:
| A2A Object | Metadata Field | Typical Use Case |
|---|---|---|
| TaskStatus | status.metadata[URI] |
Payment for task execution |
| Message | message.metadata[URI] |
Per-message evidence |
| Artifact | artifact.metadata[URI] |
Evidence attached to output artifacts |
Implementers SHOULD prefer TaskStatus.metadata for receipts that apply to the entire task lifecycle.
When evidence is present, the A2A-Extensions header SHOULD be set to indicate which extensions are active:
A2A-Extensions: https://www.peacprotocol.org/ext/traceability/v1
Multiple extensions are comma-separated:
A2A-Extensions: https://www.peacprotocol.org/ext/traceability/v1, https://example.com/ext/audit
This header is informational; the authoritative source of extension data is always the metadata map. No X- prefixed headers are used (DD-86).
| Transport | Max Carrier Size | Format | Rationale |
|---|---|---|---|
| A2A | 64 KB (65,536 B) | embed | Metadata map in JSON body |
Carriers exceeding 64 KB MUST be rejected at attachment time. For larger evidence payloads, use reference format with receipt_ref only.
Receipts SHOULD be attached at the following TaskStatus transitions:
| State | Action |
|---|---|
working |
Attach receipt after payment is confirmed, before processing |
completed |
Attach final receipt with full evidence |
failed |
Attach receipt if payment was captured before failure |
Consumers extract evidence using:
- Sync extraction: Validates carrier structure (schema + size limits)
- Async extraction (DD-129): Additionally verifies
receipt_refconsistency whenreceipt_jwsis present
Async extraction is the RECOMMENDED path. Sync extraction is suitable for read-only display of carrier metadata.
All PEAC data MUST be placed under the https://www.peacprotocol.org/ext/traceability/v1 URI key. This prevents collision with other extensions.
Every extract() call validates carrier structure before returning data to the consumer. Invalid carriers (malformed receipt_ref, invalid JWS format, oversized payloads) are silently dropped and return null.
PEAC evidence carriers MUST NOT include raw user prompts, conversation content, or PII. Carriers contain only cryptographic references (receipt_ref), signed receipts (receipt_jws), and structural metadata.
Discovery functions that fetch Agent Cards from remote URLs MUST implement SSRF protections: DNS rebinding defense, private IP rejection, scheme allowlist (https: only), redirect rejection, response size cap (256 KB), and Content-Type validation.
An implementation is conformant with this profile if it:
- Places PEAC carriers under the correct extension URI key in metadata
- Uses
PeacEvidenceCarrierschema for all carrier objects - Enforces the 64 KB size limit
- Validates carrier structure at extraction time
- Declares the extension in Agent Card when advertising support
Profile version 0.3 (introduced in v0.14.1):
- §2.2 corrected:
/.well-known/agent-card.jsonis the A2A v1.0.0 canonical Agent Card discovery path. The v0.3.0 legacy path/.well-known/agent.jsonwas removed in v0.13.0 (DD-186) and MUST NOT be probed. Earlier wording in profile 0.2 inverted these labels; the implementation inpackages/mappings/a2a/src/discovery.tsalways behaved per the corrected version. - Companion observational profile
docs/specs/A2A-HANDOFF-RECORDS.md(profile 0.1) introduced in v0.14.1 defines theorg.peacprotocol/a2a-handoffextension namespace and 10 type URIs (Agent Card observation + 9 task-lifecycle event observations).