Skip to main content

ER1 — Epistemic Receipt v1

An open, offline-verifiable format for proving the constraint state an autonomous AI agent's action was checked against — portable, recomputable in any language. The verdict is recomputed, never trusted.

Two independent verifiers re-deriving the same verdict from the frozen golden vectors, offline

Agents act. Today you can attest who an agent is, whether it was allowed to act, where it ran, and what it did — but nothing attests the constraint state (the active, deterministic "context lineage") the action was actually taken under. ER1 is that missing record: a signed, chained receipt that a stranger can recompute offline, in any language, with no network and no access to the producer — and get the same verdict, or catch the receipt in a lie. What that proves is coherence and integrity, not the empirical truth of the recorded constraints; the boundary is stated precisely in SCOPE_OF_CERTIFICATION.md.

$ pip install er1-verify
$ curl -sO https://raw.githubusercontent.com/Cruxia-Labs/er1-spec/v1.0.0/golden_vectors.json
$ er1-verify golden_vectors.json    # self-test the 6 frozen vectors, offline
VERIFIED ✓  golden_vectors.json:entry[0] name="equals_mismatch_halt"  verdict=HALT (recomputed HALT)  hash=sha256:3c2034ac1c3…  signer=A6EHv_POEL4d… (unpinned)
VERIFIED ✓  golden_vectors.json:entry[1] name="banned_entity_halt"  verdict=HALT (recomputed HALT)  hash=sha256:94196b8debc…  signer=A6EHv_POEL4d… (unpinned)
…and four more; the exit code is 0 only when every receipt verifies.

(unpinned) is the verifier being precise: without --pubkey it proves a receipt is internally consistent and signed by the key it names — pin a key to also assert whose key that is. Tamper a single byte and it says FAILED ✗. The same vectors verify identically in JavaScript (node er1_verify.mjs golden_vectors.json, no dependencies) and in the browser with the network off (verify/er1_verify.browser.mjs, WebCrypto only) — three implementations on disjoint stacks, showing the format is reproducible, not one tool's output. The Ed25519 key pinned in the vectors is test-only — never sign a production receipt with it.

The sdist is self-proving: pip download er1-verify --no-binary :all: unpacks to the verifier, the frozen vectors, and a conformance suite that needs nothing else — python -m pytest test_conformance.py.

What's in the spec repo

The format lives at github.com/Cruxia-Labs/er1-spec; links below are pinned to the v1.0.0 release.

File What it is
er1.schema.json The receipt wire format (JSON Schema 2020-12).
er1_verify.py The reference verifier — one self-contained file, stdlib + cryptography, zero project imports. This package.
er1_verify.mjs A second verifier in JavaScript — node:crypto only, no npm install. A third runs in the browser: verify/er1_verify.browser.mjs (WebCrypto only).
golden_vectors.json Frozen cross-language conformance vectors (a fixed test key + 6 fully-signed receipts). Also ships in this package's sdist.
CONFORMANCE.md How any implementation (Rust/WASM/Go/TS) proves itself conformant.
SCOPE_OF_CERTIFICATION.md Plain-English statement of exactly what a receipt does and does not certify, and the breach definition.
test_conformance.py · test_cross_language.py The Python verifier accepts every golden receipt and catches tampering; the JS verifier computes byte-identical hashes and the same verdicts.
IMPLEMENTATIONS.md The conformance roster — three verifiers on disjoint stacks (Python, Node, browser WebCrypto), and an open invitation to add an independent one in your language.
KEYS.md Announced signing keys and key tiers. A key adds continuity, never the integrity claim — that stays recomputation.

The constraint set

A receipt records the constraint set an action was checked against — each entry a typed rule on an entity (equals / excludes / satisfies), e.g. env:DEPLOY_TARGET equals staging, lib:boto3 excludes, dep:numpy satisfies >=2.0. The conflict predicate (~30 lines, in CONFORMANCE.md) computes ALLOW or HALT deterministically over that set. Only active, deterministic constraints can gate a HALT; advisory (NL-extracted) constraints are carried but never gate.

The on-wire array is named beliefs[] in the frozen v1 schema for signature compatibility; conceptually it is the constraint / context-lineage set. A future schema revision may rename the field.

What it certifies (and what it does not)

ER1 certifies coherence with the recorded constraints (the verdict follows from them by a fixed, public predicate) and integrity (any tampering breaks the signature). It does not certify the empirical truth of the constraints, anything outside the recorded set, or safety/correctness of the action. Garbage in, certified garbage out. The verified claim is the verdict + the chain hash; receipt_id and created_at are opaque signed metadata. See SCOPE_OF_CERTIFICATION.md.

Conformance

An implementation is conformant iff it reproduces every entry in golden_vectors.json from the same pinned inputs — the canonical-JSON serialization (RFC 8785-inspired; see CONFORMANCE.md), the primitive hashes, the conflict-predicate verdict, and the Ed25519 signatures. The spec repo ships three conformant implementations (Python, Node, browser WebCrypto) that produce byte-identical hashes on the golden vectors; that mutual acceptance across disjoint stacks makes ER1 reproducible — not just one vendor's log. (We reserve the word "standard" for when a party other than us recomputes these vectors; see IMPLEMENTATIONS.md.)

Prior art

The closest related work is Context Lineage Assurance for Non-Human Identities in Critical Multi-Agent Systems (arXiv:2509.18415), which describes signed, hash-chained provenance for agent context verifiable without replaying the full history. ER1 differs by being a productized, open format with an explicit, public decision procedure and a frozen cross-language conformance suite.

License

Released under the Apache License 2.0 (see LICENSE) — chosen for its explicit patent grant, the license an open format's adopters can build on. © 2026 Cruxia.


ER1 is small on purpose: a way to prove the constraint state an action was checked against, recomputable by someone who doesn't trust the producer's tooling. sagrada-linter is the first tool that emits one — and we'd rather the format outlive any one tool, including ours. → Cruxia-Labs

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

er1_verify-1.0.0.tar.gz (33.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

er1_verify-1.0.0-py3-none-any.whl (23.4 kB view details)

Uploaded Python 3

File details

Details for the file er1_verify-1.0.0.tar.gz.

File metadata

  • Download URL: er1_verify-1.0.0.tar.gz
  • Upload date:
  • Size: 33.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.4

File hashes

Hashes for er1_verify-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0214e71c64ddf456d55174d3fc7c47fb23e1f55c29d988ee5789258b6f9df0b3
MD5 e64a76bd9d2f6fa8514499d78b11454a
BLAKE2b-256 ec07cd1cbe6b665983fe6bdadd86a6c497d114fc1c578c46dfe928639f4a6e1b

See more details on using hashes here.

File details

Details for the file er1_verify-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: er1_verify-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 23.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.4

File hashes

Hashes for er1_verify-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 26b55647907eece157ea5903d1f3242b0ecd57196eba40ebc0a746f2e6cbaf0c
MD5 51c7b9af481b4e7f03ef80f71ffbe340
BLAKE2b-256 019cae6248798ed1600b48d0ef78b5a63da03ef283dd175f46297b1919783588

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page