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.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0214e71c64ddf456d55174d3fc7c47fb23e1f55c29d988ee5789258b6f9df0b3
|
|
| MD5 |
e64a76bd9d2f6fa8514499d78b11454a
|
|
| BLAKE2b-256 |
ec07cd1cbe6b665983fe6bdadd86a6c497d114fc1c578c46dfe928639f4a6e1b
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26b55647907eece157ea5903d1f3242b0ecd57196eba40ebc0a746f2e6cbaf0c
|
|
| MD5 |
51c7b9af481b4e7f03ef80f71ffbe340
|
|
| BLAKE2b-256 |
019cae6248798ed1600b48d0ef78b5a63da03ef283dd175f46297b1919783588
|