Skip to main content

aer1-verify

Verify an AER-1 verifiable execution receipt completely offline. No network, no API key, no trust in any server, including ours. Free forever. It also verifies receipt chain-head anchors on Nostr and Bitcoin, so a receipt recorded long ago can be rechecked against a public anchor.

Try it live: interactive demo ��� mint a real verifiable receipt in your browser, no install, no signup.

Why this exists

A verifiable receipt says: this AI did this work, and the record was not changed afterward. That claim should not require you to trust the company that issued it. aer1-verify rechecks the cryptography locally, from the receipt data alone. If the math holds, the receipt is intact. If it does not, the receipt is forged or corrupt.

The honest boundary, stated plainly: this tool proves the recorded result was not changed. It does not prove the recorded result is correct. Integrity, not truth. That is what AER-1 receipts claim, and it is all this tool checks.

Install

Single file, standard library only. No dependencies.

# Option 1: copy the file, nothing else needed
curl -O https://gitlab.com/rambozambodotdev/zambo/-/raw/main/aer1-verifier/aer1_verify.py

# Option 2: pip install
pip install .

Use

Get a receipt as JSON. From zambo.dev, the verify endpoint returns one:

curl -s "https://zambo.dev/api/v2/receipt/<receipt-id>/verify" -o receipt.json

Then verify it offline (unplug your network if you want to prove the point):

python3 aer1_verify.py receipt.json

Output:

aer1-verify 0.1.0
receipt: c5dadb0a-8f99-40f6-b30a-40852435b752
  [PASS] input shape recognized (envelope.receipt)
  [PASS] required fields present (id, canonical_bytes, output_hash)
  [PASS] canonical_bytes is strict base64 -- 740 bytes
  [PASS] decoded bytes are strict UTF-8 (fail closed)
  [PASS] canonical_byte_length matches decoded length -- field=740 actual=740
  [PASS] canonical JSON parses
  [PASS] canonical form re-encodes byte-exactly
  [PASS] output_hash is sha256: + 64 lowercase hex chars
  [PASS] hash_algorithm agrees with sha256 -- got: 'sha256'
  [PASS] sha256(canonical_bytes) equals output_hash
  [PASS] created_at/timestamp is a real calendar date
  [PASS] timestamp is not in the future
  [PASS] verification_status (server claim, informational only) -- server said: 'verified'; offline verdict rests on the math above
VERDICT: PASS: fingerprint matches, receipt intact

Machine-readable output for CI:

python3 aer1_verify.py receipt.json --json

Exit codes: 0 = PASS, 1 = FAIL, 2 = usage or input error.

What it checks

  1. Required fields: the receipt carries id, canonical_bytes, output_hash.
  2. Strict base64: the committed bytes decode cleanly, no leniency.
  3. Strict UTF-8: the bytes are valid UTF-8. Anything else fails closed.
  4. Byte length agreement: the declared length matches the decoded bytes.
  5. Canonical round-trip: the JSON re-encodes to byte-identical bytes (sorted keys, compact separators, UTF-8). The fingerprint covers exactly what you see; nothing hides outside it.
  6. Fingerprint shape: output_hash is sha256: plus 64 lowercase hex chars.
  7. Algorithm agreement: the declared hash algorithm is sha256.
  8. The core check: SHA-256(canonical_bytes) equals the committed output_hash. This is the whole proof.
  9. Timestamp sanity: the issue time is a real calendar date and not in the future.

The server's verification_status field is reported, never trusted. An offline verifier checks math, not the issuer's word. That is the point.

Try breaking it

# Take a real receipt, change one character in the recorded result,
# keep the old fingerprint, and watch verification fail:
python3 - <<'EOF'
import json, base64
r = json.load(open('receipt.json'))['receipt']
raw = base64.b64decode(r['canonical_bytes']).decode('utf-8')
raw = raw.replace('164.00', '164.01', 1)  # one character
r['canonical_bytes'] = base64.b64encode(raw.encode()).decode()
r['canonical_byte_length'] = len(raw.encode())
json.dump({'receipt': r}, open('forged.json', 'w'))
EOF
python3 aer1_verify.py forged.json   # -> VERDICT: FAIL

One character. The fingerprint no longer matches. That is the security property, demonstrated negatively.

Input shapes

Liberal on input, strict on math. Accepts:

  • the bare receipt object (canonical_bytes / output_hash present),
  • the {"receipt": {...}} envelope from the zambo.dev verify endpoint,
  • the MCP _receipt shape returned with tool calls.

Tests

python3 tests/test_verifier.py

Fixtures include real receipts issued by zambo.dev plus adversarial mutations (tampered bytes, bad base64, wrong digest, non-UTF-8 bytes). The real-receipt fixtures must keep passing: they pin this tool to production.

Relation to AER-1

AER-1 is the AI Agent Execution Receipt specification (IETF Internet-Draft draft-zambo-aer1). This verifier implements the receipt-integrity checks from the draft's canonicalization and fingerprint rules. It is a verifier, not an issuer: it cannot create receipts, only judge them.

License

Same as the parent repository.

Metadata

Release files for aer1-verify 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for aer1-verify 0.2.0
File Interpreter ABI Platform
aer1_verify-0.2.0-py3-none-any.whl Python 3 none any Details

Release files / aer1_verify-0.2.0-py3-none-any.whl

Download URL aer1_verify-0.2.0-py3-none-any.whl
Size 7.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b6f096b41558aa67d62af3c08ad5c1e3ed2cb03478372eaa8d2c5b53b0bfafe1
BLAKE2b-256 checksum
How to use checksums
aac56ef10639d7e41e936fc3493285832155c37b9c2ac828dc21922c0c885af0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via rambo-pypi-grab/0.1.0

Release history Release notifications | RSS feed

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

1 release file

This release

0.2.0 This release

1 release file

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page