Provenance Data Record (PDR) — the cryptographically signed artifact issued by AOTrust.
A PDR is a fixed-size binary record that proves an AI agent produced specific work at a specific time. Two formats exist:
| Format | Size | Use |
|---|---|---|
| Internal | 193 bytes | Notary-internal storage, never exposed to clients |
| External | 239 bytes | Client-facing, self-verifying artifact |
All client-facing PDRs are External (239 bytes). Internal PDRs are an implementation detail of the notary service.
Format: <BBBQ36s32s32s32s32s64s
Total: 1 + 1 + 1 + 8 + 36 + 32 + 32 + 32 + 32 + 64 = 239 bytes
| Offset | Size | Field | Type | Description |
|---|---|---|---|---|
| 0 | 1 | version |
U8 | PDR version: 0x03 (ordinary) or 0x04 (bilateral) |
| 1 | 1 | sig_scheme |
U8 | Signature scheme: 0x01 = Ed25519 |
| 2 | 1 | payment_anchor_type |
U8 | Payment rail enum (see below) |
| 3 | 8 | timestamp_utc |
U64 | Unix timestamp in seconds |
| 11 | 36 | issuer_id |
bytes(36) | Notary NEAR account, NUL-padded (e.g. notary-node.near) |
| 47 | 32 | subject_hash |
bytes(32) | SHA-256 of agent account |
| 79 | 32 | payload_hash |
bytes(32) | v0x03: SHA-256 of work result. v0x04: Binding Hash = sha256(work_hash + sig_A + agent_pubkey) |
| 111 | 32 | merkle_root |
bytes(32) | Merkle root from daily on-chain anchor |
| 143 | 32 | payment_hash |
bytes(32) | Payment transaction hash (multi-chain) |
| 175 | 64 | signature |
bytes(64) | Ed25519 signature (NEP-413) |
Payload = bytes 0–174 (175 bytes). Signature = bytes 175–238 (64 bytes).
The Ed25519 signature follows NEP-413:
NEP413_buffer = pack("<II175s", 2147484061, 175, payload_bytes)
signature = Ed25519.sign(NEP413_buffer)
CRITICAL: The signature covers the dynamic payload pdr_bytes[:-64], not a hardcoded offset. This ensures forward compatibility if field sizes change in future versions.
payment_anchor_type is inside the signed payload, making PDRs self-verifying — no external metadata channel required.
Format: <BB16s32s32sQQQ4s8sBH3sB4s
Total: 1 + 1 + 16 + 32 + 32 + 8 + 8 + 8 + 4 + 8 + 1 + 2 + 3 + 1 + 4 + 64 = 193 bytes
| Offset | Size | Field | Type | Description |
|---|---|---|---|---|
| 0 | 1 | version |
U8 | 0x03 (both ordinary and bilateral use same internal version; bilateral marked by signing_mode=0x02) |
| 1 | 1 | composite |
U8 | Composite nibble byte (see below) |
| 2 | 16 | task_id |
bytes(16) | Task UUID |
| 18 | 32 | agent_account_hash |
bytes(32) | SHA-256 of agent account |
| 50 | 32 | work_hash |
bytes(32) | SHA-256 of work result |
| 82 | 8 | timestamp_ns |
U64 | Timestamp in nanoseconds |
| 90 | 8 | global_seq |
U64 | Global sequence number |
| 98 | 8 | parent_seq |
U64 | Parent sequence (0 for standard; escrow PROVISIONAL PDR ref for SETTLED) |
| 106 | 4 | payment_ref |
bytes(4) | First 4 bytes of payment hash (indexing) |
| 110 | 8 | semantic_anchor |
bytes(8) | Semantic anchor |
| 118 | 1 | signing_mode |
U8 | 0x01 = VPS |
| 119 | 2 | reputation_count |
U16 | Reputation counter |
| 121 | 3 | reserved |
bytes(3) | Reserved |
| 124 | 1 | sig_scheme |
U8 | 0x01 = Ed25519 |
| 125 | 4 | expansion_reserved |
bytes(4) | PQ-signature pointer buffer (quantum migration path) |
| 129 | 64 | signature |
bytes(64) | Ed25519 signature (NEP-413) |
Payload = bytes 0–128 (129 bytes). Signature = bytes 129–192 (64 bytes).
Byte 1 (composite) packs two 4-bit fields:
[aaaa bbbb]
││││ │││└── pdr_type (bits 3–0)
└└└┘────── payment_anchor_type (bits 7–4)
composite = (payment_anchor_type << 4) | (pdr_type & 0x0F)
pdr_type = composite & 0x0F
payment_anchor_type = (composite >> 4) & 0x0FBackward compatibility: Old PDRs with composite = 0x00 → UNPAID (0x0) + standard (0x0). Existing Merkle tree proofs remain valid.
NEP413_buffer = pack("<II129s", 2147484061, 129, internal_payload)
signature = Ed25519.sign(NEP413_buffer)
| Value | Name | Description |
|---|---|---|
0x00 |
UNPAID | No payment. Blocked on mainnet. Available on testnet. |
0x01 |
NEAR_DIRECT | Direct NEAR payment |
0x02 |
AGENT_MARKET_SUBMIT | Reserved |
0x03 |
AGENT_MARKET_RELEASE | Reserved |
0x04 |
NEAR_ESCROW_LOCK | Escrow locked (PROVISIONAL PDR) |
0x05 |
X402_BASE | x402 payment on Base |
0x06 |
X402_POLYGON | x402 payment on Polygon |
0x07 |
X402_NEAR | x402 payment on NEAR (future) |
0x08 |
CHAIN_SIG_PAYMENT | NEAR Chain Signatures payment |
0x09 |
NEAR_ESCROW_SETTLED | Escrow released (SETTLED PDR) |
0x0A–0xFE |
— | Reserved |
0xFF |
UNKNOWN | Unrecognized, treat as UNPAID |
All types are flat $0.01 per PDR. The anchor type is a technical attribute, not a pricing tier.
- Standard PDRs (NEAR_DIRECT, X402_*):
parent_seq = 0 NEAR_ESCROW_LOCK(0x04, PROVISIONAL):parent_seq = 0NEAR_ESCROW_SETTLED(0x09, SETTLED):parent_seq = global_seqof the original PROVISIONAL PDR, binding SETTLED to PROVISIONAL cryptographically
- Same 239-byte external format as v2.3 — no size change
payload_hashsemantics: Binding Hash =sha256(work_hash + sig_A_bytes + agent_pubkey_bytes)- Produced when
agent_sig+agent_pubkeyare provided in notarize request agent_sigstored innotary_ledger.agent_sigcolumn (TEXT)- Internal PDR
signing_mode=0x02(bilateral marker) - Price: $0.01 (same as ordinary)
- Parser:
format_version="v2.4", same struct unpack as v2.3
- Added
payment_anchor_typefield (1 byte) to External PDR at offset 2 - External PDR grew from 238 → 239 bytes
- External payload grew from 174 → 175 bytes
- All subsequent field offsets shifted +1 byte
payment_anchor_typeis inside the signed payload (prevents forgery)- Internal PDR:
compositebyte at offset 1 now explicitly encodespayment_anchor_typein high nibble expansion_reserved(4 bytes) added at Internal offset 125 for quantum migration path
- External PDR: 238 bytes, no
payment_anchor_typefield - All PDRs implicitly treated as
NEAR_DIRECT(0x01) when parsed by v2.3 code - Internal PDR:
compositebyte existed butpayment_anchor_typewas not explicitly defined in high nibble
| Field | v2.2 Offset | v2.3 Offset | Change |
|---|---|---|---|
version |
0 | 0 | 0x02 → 0x03 |
sig_scheme |
1 | 1 | Unchanged |
payment_anchor_type |
— | 2 | NEW |
timestamp_utc |
2 | 3 | +1 shift |
issuer_id |
10 | 11 | +1 shift |
subject_hash |
46 | 47 | +1 shift |
payload_hash |
78 | 79 | +1 shift |
merkle_root |
110 | 111 | +1 shift |
payment_hash |
142 | 143 | +1 shift |
signature |
174 | 175 | +1 shift |
| Total | 238 | 239 | +1 byte |
Given a 239-byte external PDR and the notary's Ed25519 public key:
- Split:
payload = pdr[:-64],sig = pdr[-64:] - Build NEP-413 envelope:
pack("<II", 2147484061, len(payload)) + payload - Verify:
Ed25519.verify(envelope, sig, pubkey)
See pdr_parser.py for a standalone implementation.