A2A (Agent-to-Agent)
The @peac/mappings-a2a package provides two capabilities: (1) carrying verifiable evidence through A2A metadata in TaskStatus, Message, and Artifact objects using the Evidence Carrier Contract, and (2) issuing signed handoff observation records for agent-to-agent task delegation events (v0.14.1+).
A2A v1.0.0 compatible. The A2A adapter supports Agent Card, TaskState, and Parts for A2A v1.0.0. Microsoft AGT and AAIF (Agent AI Interoperability Framework) compatible.
Install
pnpm add @peac/mappings-a2a
Quick start
import { attachA2aCarrier, extractA2aCarrier } from '@peac/mappings-a2a';
// Attach evidence to an A2A artifact
const artifact = attachA2aCarrier(originalArtifact, {
receipt_ref: 'sha256:abc123...',
receipt_jws: 'eyJhbGciOiJFZERTQSIs...',
});
// Extract evidence from an A2A message
const carrier = extractA2aCarrier(incomingMessage);
if (carrier) {
console.log(carrier.receipt_ref); // 'sha256:abc123...'
console.log(carrier.receipt_jws); // 'eyJhbGciOiJFZERTQSIs...'
}
Carrier placement
A2A evidence is placed in the metadata object using a reverse-DNS extension URI:
{
"metadata": {
"https://www.peacprotocol.org/ext/traceability/v1": {
"carriers": [
{
"receipt_ref": "sha256:abc123...",
"receipt_jws": "eyJhbGciOiJFZERTQSIs..."
}
]
}
}
}
The carrier array supports multiple receipts per A2A object. Each carrier includes at minimum receipt_ref (SHA-256 integrity anchor) and receipt_jws (signed compact JWS).
Agent Card discovery
A2A agents advertise PEAC support via the Agent Card capabilities.extensions array:
{
"name": "Evidence Agent",
"capabilities": {
"extensions": [
"https://www.peacprotocol.org/ext/traceability/v1"
]
}
}
3-step discovery flow
- Agent Card -- check
capabilities.extensions[]for the PEAC traceability extension URI - Well-known -- fetch
/.well-known/peac-issuer.jsonfrom the agent's host for issuer configuration and JWKS URI - Header probe -- check for
PEAC-Receiptheader in HTTP responses from the agent
Transport limits
| Constraint | Value |
|---|---|
| Maximum embed size | 64 KB |
| Carrier format | PeacEvidenceCarrier |
| Integrity check | sha256(receipt_jws) === receipt_ref |
When extracting a carrier from A2A metadata, always verify that sha256(receipt_jws) matches receipt_ref. This prevents tampering during transport.
Supported A2A objects
| Object | Carrier placement |
|---|---|
TaskStatus | status.metadata[extensionURI].carriers[] |
Message | message.metadata[extensionURI].carriers[] |
Artifact | artifact.metadata[extensionURI].carriers[] |
Handoff Observation Records (v0.14.1+)
Beyond evidence carriage, @peac/mappings-a2a can issue signed handoff observation records that describe agent-to-agent task delegation events. These records use the org.peacprotocol/a2a-handoff extension namespace and are compatible with Microsoft AGT (Agent Governance Toolkit) and AAIF (Agent AI Interoperability Framework).
Type URIs
| Type URI | Description |
|---|---|
org.peacprotocol/a2a-task-submitted | Task was submitted to an agent |
org.peacprotocol/a2a-task-accepted | Agent accepted the task |
org.peacprotocol/a2a-task-rejected | Agent rejected the task |
org.peacprotocol/a2a-task-completed | Agent reported task completion |
org.peacprotocol/a2a-task-failed | Agent reported task failure |
org.peacprotocol/a2a-task-cancelled | Task was cancelled |
org.peacprotocol/a2a-handoff-initiated | Handoff from one agent to another was initiated |
org.peacprotocol/a2a-handoff-accepted | Receiving agent accepted the handoff |
org.peacprotocol/a2a-handoff-completed | Handoff completed successfully |
org.peacprotocol/a2a-handoff-failed | Handoff failed |
Issuing a handoff observation record
import { issueA2AHandoffRecord } from '@peac/mappings-a2a';
import { issue } from '@peac/protocol';
// Build the handoff observation extension object
const handoffExtension = issueA2AHandoffRecord({
type: 'org.peacprotocol/a2a-task-submitted',
task_ref: 'urn:task:abc-123',
upstream_event_ref: 'ref:event/submit-001',
caller_agent_ref: 'did:web:orchestrator.example.com',
target_agent_ref: 'did:web:worker.example.com',
method_ref: 'ref:method/process-document',
observed_at: new Date().toISOString(),
});
// Issue a signed record
const jws = await issue({
sub: 'urn:task:abc-123',
iss: 'https://orchestrator.example.com',
type: 'org.peacprotocol/a2a-task-submitted',
extensions: handoffExtension,
}, signingKey);
Key fields
| Field | Required | Description |
|---|---|---|
task_ref | Yes | Opaque reference to the A2A task (urn:, ref:, did:, sha256:) |
upstream_event_ref | No | Reference to the upstream A2A event that triggered this observation |
caller_agent_ref | No | Reference to the delegating agent |
target_agent_ref | No | Reference to the receiving agent |
method_ref | No | Reference to the method or capability being invoked |
card_ref | No | SHA-256 digest of the target Agent Card (sha256:<64 hex>) |
observed_at | Yes | ISO 8601 timestamp of the observed event |
Handoff observation records describe what your system observed during agent coordination. PEAC does not route tasks, authorize agents, or enforce handoff policies. The upstream A2A infrastructure owns those decisions.
AGT and AAIF Compatibility
Handoff observation records are compatible with Microsoft AGT (Agent Governance Toolkit) and AAIF (Agent AI Interoperability Framework). PEAC records complement AGT governance by providing portable, offline-verifiable signed evidence of agent coordination events that can be verified outside the system that produced them.
Integration pattern:
- Your AGT-governed agent handles a task submission or handoff
- Issue a PEAC handoff observation record at the coordination boundary
- Attach the
receipt_refandreceipt_jwsto the A2A metadata usingattachA2aCarrier - The receiving agent or auditor can verify the record offline using only the issuer's public key
import { issueA2AHandoffRecord, attachA2aCarrier } from '@peac/mappings-a2a';
import { issue } from '@peac/protocol';
// Issue a signed record at the AGT governance boundary
const handoffExt = issueA2AHandoffRecord({
type: 'org.peacprotocol/a2a-handoff-initiated',
task_ref: 'urn:task:agt-governed-001',
caller_agent_ref: 'did:web:gateway.corp.example.com',
target_agent_ref: 'did:web:worker.corp.example.com',
observed_at: new Date().toISOString(),
});
const jws = await issue({
sub: 'urn:task:agt-governed-001',
iss: 'https://gateway.corp.example.com',
type: 'org.peacprotocol/a2a-handoff-initiated',
extensions: handoffExt,
}, signingKey);
// Attach to the outgoing A2A artifact
const artifact = attachA2aCarrier(originalArtifact, {
receipt_ref: computeReceiptRef(jws),
receipt_jws: jws,
});