Skip to content
v0.11.2Since v0.11.1

Evidence Carrier Contract

Universal interface for carrying verifiable evidence across transports. The PeacEvidenceCarrier type (Layer 0, zero runtime) and CarrierAdapter<TInput, TOutput> pattern decouple receipt production from transport-specific encoding.

Types in @peac/kernel. Validation schemas in @peac/schema. Normative spec: EVIDENCE-CARRIER-CONTRACT.md.

PeacEvidenceCarrier Type

The carrier type defines the fields that travel with evidence across any transport:

PeacEvidenceCarrierTypeScript
interface PeacEvidenceCarrier {
  /** SHA-256 of receipt_jws: "sha256:<64 hex chars>". MUST. */
  receipt_ref: string;

  /** JWS Compact Serialization. SHOULD for embed carriers. */
  receipt_jws?: string;

  /** HTTPS URL locator hint. MAY. v0.11.2+. */
  receipt_url?: string;

  /** Policy binding status. MAY. */
  policy_binding?: PolicyBindingStatus;

  /** Actor binding reference. MAY. */
  actor_binding?: string;

  /** Request nonce for replay prevention. MAY. */
  request_nonce?: string;
}

Field Reference

FieldRequirementDescription
receipt_refMUSTSHA-256 of the receipt_jws value: sha256:<64 hex chars>
receipt_jwsSHOULDJWS Compact Serialization of the signed receipt. Required for embed-mode transports.
receipt_urlMAYHTTPS-only URL (max 2048 chars). Locator hint only: no credentials, no implicit fetch (DD-55). v0.11.2+.
policy_bindingMAYThree-state policy binding status: verified, failed, or unavailable
actor_bindingMAYReference binding the carrier to a specific actor identity
request_nonceMAYNonce for replay prevention across transports

CarrierAdapter Interface

Each transport implements a CarrierAdapter<TInput, TOutput> with three methods:

CarrierAdapterTypeScript
interface CarrierAdapter<TInput, TOutput> {
  /** Extract carriers from transport-specific input. */
  extract(input: TInput): PeacEvidenceCarrier[];

  /** Attach carriers to transport-specific output. */
  attach(output: TOutput, ...carriers: PeacEvidenceCarrier[]): TOutput;

  /** Validate transport constraints (size limits, format). */
  validateConstraints(carriers: PeacEvidenceCarrier[]): ValidationResult;
}

Transport Size Limits

Each transport enforces a maximum carrier size. Embed transports carry the full JWS inline. Header transports use the PEAC-Receipt header with compact JWS.

TransportPlacementMax SizeMode
MCP_meta64 KBEmbed
A2Ametadata64 KBEmbed
ACPPEAC-Receipt header8 KBHeader
UCPpeac_evidence field64 KBEmbed
x402PEAC-Receipt header8 KBHeader
HTTPPEAC-Receipt header8 KBHeader

Protocol-Specific Placement

MCP

Evidence is carried in the _meta object of MCP tool responses using reverse-DNS keys:

MCP _metaJSON
{
  "_meta": {
    "org.peacprotocol/receipt_ref": "sha256:abc123...",
    "org.peacprotocol/receipt_jws": "eyJhbGciOi..."
  }
}

A2A

Evidence is carried in A2A metadata keyed by extension URI:

A2A metadataJSON
{
  "metadata": {
    "https://www.peacprotocol.org/ext/traceability/v1": {
      "carriers": [{
        "receipt_ref": "sha256:abc123...",
        "receipt_jws": "eyJhbGciOi..."
      }]
    }
  }
}

ACP, x402, HTTP

Evidence is carried in the PEAC-Receipt HTTP header as compact JWS:

HTTP header
PEAC-Receipt: eyJhbGciOiJFZERTQSIsInR5cCI6InBlYWMtcmVjZWlwdC8wLjEiLC...

UCP

Evidence is carried in the peac_evidence field of UCP webhook payloads:

UCP webhookJSON
{
  "peac_evidence": {
    "receipt_ref": "sha256:abc123...",
    "receipt_jws": "eyJhbGciOi..."
  }
}

receipt_ref Integrity (DD-129)

The receipt_ref field is a content-addressable identifier computed as sha256(receipt_jws). Extractors MUST verify this relationship before processing:

verification.tsTypeScript
import { computeReceiptRef } from '@peac/schema';

const carrier = adapter.extract(input)[0];

// Verify receipt_ref matches the JWS content
const computedRef = computeReceiptRef(carrier.receipt_jws);
if (computedRef !== carrier.receipt_ref) {
  throw new Error('receipt_ref integrity check failed');
}

// Proceed with JWS signature verification...

This check runs before signature verification to detect transport-level tampering.

receipt_url Constraints (DD-135)

The optional receipt_url field is a locator hint for retrieving receipts that exceed embed size limits. It is subject to strict constraints:

ConstraintValue
SchemeHTTPS only
Max length2048 characters
CredentialsMUST NOT contain credentials in URL
Implicit fetchMUST NOT trigger implicit fetch (SSRF prevention, DD-55)
Post-fetch verificationsha256(receipt_jws) == receipt_ref

Callers that fetch from receipt_url MUST verify the receipt_ref integrity check after retrieval.

Packages

PackageLayerProvides
@peac/kernelLayer 0PeacEvidenceCarrier, CarrierAdapter types (zero runtime)
@peac/schemaLayer 1Zod schemas, computeReceiptRef(), validation-only (no I/O)
@peac/mappings-mcpLayer 4MCP _meta carrier adapter
@peac/mappings-a2aLayer 4A2A metadata carrier adapter
@peac/mappings-acpLayer 4ACP header carrier adapter
@peac/mappings-ucpLayer 4UCP webhook carrier adapter
@peac/adapter-x402Layer 4x402 header carrier adapter

Links

Transport Integrations

Each transport has a dedicated mapping or adapter package that implements the CarrierAdapter interface. See the integrations page for transport-specific documentation.