AER-1 Implementer's Guide

Canonical definition

An AI agent execution receipt is a verifiable record of one AI agent tool call. It identifies the execution, preserves the exact bytes used for its output commitment, records the tool and time, and gives a reviewer a public path to inspect what the execution system observed.

AER-1 is an open draft spec for AI work receipts, authored by Brennan Zambo.

This guide follows the current open draft spec draft -12. The schema version remains 0.3; schema version and draft revision are different identifiers.

Start with the required fields

The required identity is id, a UUID. receipt_schema_version identifies the receipt schema and is 0.3 in this draft. created_at is a timezone-bearing RFC 3339 timestamp. The published tool object names the capability, version, and caller scope.

provenance_class states whether the record was executed by the recording system, observed via a gateway, or logged from an agent report. Do not collapse those statements. canonical_bytes is Base64 of the exact UTF-8 bytes. Hash those bytes with SHA-256 and put the lowercase digest after sha256: in output_hash. A passing record uses verification_status equal to verified.

Raw live MCP _receipt schema mapping

The JSON Schema validates the result._receipt object exactly as returned by the MCP JSON-RPC response. It does not validate the outer JSON-RPC envelope. Do not rename fields, normalize values, or convert this transport receipt into a separate projection.

Live MCP _receipt fieldPublished schema fieldProjection rule
ididCopy the receipt identifier unchanged.
tooltoolPreserve the tool name as the transport's string value.
timestamptimestampPreserve the RFC 3339 timestamp; do not rename it to created_at.
tool_contexttool_contextPreserve the object, including its name, version, and scope, when present.
receipt_schema_versionreceipt_schema_versionPreserve the transport value when present.
provenance_classprovenance_classCopy the declared provenance class unchanged.
canonical_bytes, canonical_byte_length, hash_algorithm, and output_hashSame namesPreserve the committed bytes and integrity metadata without parsing or reserializing.
verification_statusverification_statusPreserve the transport status such as execution_observed or not_verified; do not rewrite it to verified.
statusstatusPreserve the execution result status unchanged, including errors.

receipt_schema_version and tool_context may be absent when the receipt builder is called without context. If present, they must retain the raw transport form. Other transport fields remain available as additional properties and must not be silently discarded.

The schema accepts both successful and failed transport receipts. A provider failure such as provider_unavailable remains a failed receipt; do not convert it to an execution success or to verified.

When your implementation is ready to be listed, use the public implementation registry. The source manifest is the root registry.json; listings are not certification.

Canonical bytes and the verify loop

  1. Preserve the exact bytes before parsing or reserializing.
  2. Decode Base64 strictly and reject invalid UTF-8.
  3. Compute SHA-256 over those bytes and compare the lowercase digest.
  4. Validate identity, time, tool, provenance, and status separately.
  5. Report only the observation supported by the record.

Use the stdlib-only Python verifier as a worked example, then run the versioned vectors. Advertising RFC 8615 discovery is optional and must point to the exact version and endpoints you support.

Extensions and limits

Additional fields may add context without changing the meaning of the core fields. A verifier must fail clearly when it cannot interpret a required version. A receipt proves what the execution system recorded, not correctness or an unobserved outside result.

Reader-produced receipt

After your implementation emits a receipt, save its exact canonical bytes, calculate the hash, and run both your verifier and the published vectors. Keep the output showing the UUID, expected verdict, and matching digest as your reproducible result.

Operational implementation details

Start at the boundary where a tool call becomes durable. Capture the request context needed to identify the call, then freeze the bytes that the receipt will commit. Do not build those bytes from a later display object. A display object may omit fields, normalize whitespace, or reorder keys for readability. The committed representation must remain available to the verifier in the same encoding used when the digest was calculated.

Validate in layers so a failure tells the operator what to repair. First check that the document is valid JSON and that Base64 decoding succeeds. Next check UTF-8 decoding, required field presence, UUID syntax, timestamp grammar, and the allowed provenance values. Finally calculate the digest and compare it with the declared output hash. A digest mismatch is different from an unsupported schema version, and both are different from an unavailable network resource.

Keep the original input and the public projection separate. A safe public page can show the identifier, tool metadata, status, and a shortened result while keeping sensitive arguments under the owning system's access controls. Redaction must happen before publication, not after a public URL has been shared. If a redacted projection has its own commitment, label that commitment so a reviewer does not confuse it with the original bytes.

When a call fails, record the failure at the same execution boundary as a successful call. Timeouts, rejected permissions, malformed arguments, and provider errors are useful evidence about what the system attempted and what it did not observe. Do not convert a pending or blocked state into verified merely because a later summary sounds confident. A later read-back may establish a new observation, but it should not rewrite the earlier record.

Testing and maintenance

Build tests around both valid and invalid cases. Change one byte and confirm that the verifier rejects the digest. Change the timestamp to an impossible calendar date and confirm that syntax checking does not accept it. Remove each required field in turn, use invalid Base64, and try an unknown provenance value. These tests make error handling visible and protect the boundary when a serializer or framework is upgraded.

Run the published vector index in a clean environment without relying on a local database or an active session. Record the schema version, draft revision, interpreter version, and command used for the run. If a result differs, preserve the failing input and compare bytes before changing code. A reproducible failure is more useful than a green result produced by silently changing fixtures.

For a service deployment, monitor the availability of the public receipt path and verifier separately. A page can be reachable while its API is unavailable, or an API can return a record while a proxy strips important headers. Check content type, status, identifier consistency, and the digest response from an independent network location. Treat an unavailable check as unavailable evidence, not as a passing or failing receipt.

Document retention and correction rules before launch. Append a correction or superseding observation instead of editing canonical bytes in place. Preserve the original creation time and identify the event that caused the correction. This lets reviewers distinguish an original execution from a later administrative update.

Finally, describe compatibility honestly. Optional fields can carry tracing data, evidence references, or local diagnostics, but required extensions need a version and a clear failure mode. A verifier that understands only this draft can still report the core fields while declining an extension it cannot evaluate. That behavior keeps partial understanding visible and prevents accidental overclaiming.

Practical review checklist

Before releasing a receipt, compare the identifier in the response, public URL, and verifier request. A mismatch usually indicates that a caller followed the wrong redirect or mixed records from separate attempts. Check the creation time against the workflow clock, but do not use time alone as proof that an external action occurred. The timestamp locates an observation; it does not replace a read-back from the system that owns the result.

Review provenance with the same care as the hash. An execution record and a received report may have identical bytes and still support different conclusions. Preserve the actor, gateway, or reporting boundary in the provenance value. If several systems contribute evidence, create separate records or clearly named evidence references instead of merging their statements into one ambiguous sentence.

For long-running work, decide how retries are represented. A retry should have its own identity and creation time, while the workflow can link related attempts through an optional correlation field. Do not overwrite the first attempt when a later retry succeeds. Keeping both records lets an operator explain delay, duplicate requests, and partial completion without guessing from a final summary.

Make the verifier output useful to both machines and people. A machine-readable result should include a stable status and an actionable error class. A human-facing page should show the same identity, version, provenance, and digest result without changing their values. Avoid displaying a green status when the bytes were not available for comparison, even if the record has a valid shape.

Plan upgrades as compatibility work. When a new schema adds a required field, publish the version boundary and retain a verifier for older records during the transition. When an optional field is removed, document the loss of context. Never silently reinterpret a field because a new release happens to use the same spelling. Clear migration notes help independent implementers reproduce historical checks and make disagreements diagnosable.

These practices keep the receipt narrow and durable. The format is most useful when another reviewer can retrieve the same record, inspect the same bytes, repeat the same digest calculation, and reach the same limited conclusion. It should make uncertainty easier to describe, not hide uncertainty behind a polished page.

For developers and agents

Zambo gives AI work a receipt you can check. For people: add Zambo to your AI app and ask for a job. These technical links are for developers and AI agents. One hosted MCP at https://zambo.dev/mcp. Check the proof for recorded tool calls (verify a receipt). Agents: 24-hour Day Pass, $0.99 USDC on Base via x402, not per call. People: Zambo Pass $29/mo or $290/yr; holder pass $19/mo for verified $ZAMBO holders.

Start here: For AI agents · Add Zambo · Check a receipt · Answers · Guides · What a receipt is · Open receipt format (draft) · All tools · Pricing · Day Pass: $0.99 · Agent Day Pass · Switch AIs without losing your work · Connect your AI · Founder · Source code
Brennan on X · Zambo on X