Byte-level integrity witness. Four independent implementations, one verdict lattice.
EMET checks whether the bytes reaching a model, a reviewer, or a pipeline still
match the source they claim to represent, then emits one of three closed
verdicts: MATCH, DRIFT, or UNVERIFIABLE. Four clean-room implementations,
in stdlib-only Python, Rust, Node.js, and Go, load the same marker corpus and
re-derive it identically against a shared conformance suite. Zero dependencies:
run it straight from a checkout or pip install emet.
emet is Hebrew for "truth."
Features
- Portable witness receipts (SPEC s.17). Seal any verdict into a
self-contained, content-addressed JSON receipt; a different party re-verifies
it offline with
emet check, zero shared state, zero trust in the producer. The same subject and verdict yield a byte-identicalreceipt_idacross Python, Rust, and Node.js, and each implementation verifies the others' HMAC signatures. Cross-language parity, including the tampered-receipt negatives, is gated in CI. - Stripped-credential rebind (SPEC s.18, experimental). When a re-encode,
screenshot, or copy strips a C2PA-style embedded credential, the artifact is
orphaned to embedded-metadata verifiers. EMET anchored the raw bytes out of
band, so
emet rebindre-derives the naked bytes' content hash and rebinds them to a known anchor:MATCH(rebound),DRIFT(a claimed identity over substituted bytes), orUNVERIFIABLE(no known anchor, the honest default). - Byte-hash core.
anchorpins raw-byte SHA-256 hashes,verifyrecomputes them,coherencecompares a presented view against its source,corroboratehashes the same file through disjoint read paths to catch a tampered read path, not just a broken hash. - In-band authority stripping.
refusescans bytes against a versioned marker corpus, reports every embedded authority claim by offset, and writes a neutralized copy. It reports the claims; it never obeys them. - Tamper-evident audit chain. Every command appends to a hash-chained log;
emet auditrecomputes the chain and reportsINTACTorBROKEN. - Four implementations, one contract. A frozen v1.0 spec, a language-agnostic conformance suite (44 vectors: 35 core, 5 receipt, 4 rebind), and clean-room ports in Rust, Node.js, and Go, all scored in CI on every push against exactly the capabilities each claims.
- Machine-readable everywhere.
--jsonon any command emits one canonical-JSON envelope; the governed fields are byte-identical across all four implementations and the exit code is unchanged. - Zero dependencies, by construction. Stdlib-only Python, no crates, no npm packages, no Go modules.
Usage
pip install emet
emet selftest # re-derives the tool's own hash: emet_self_sha256=...
Or run it straight from a checkout, no install step at all:
git clone https://github.com/HarperZ9/emet && cd emet
python membrane.py selftest
emet <cmd> and python membrane.py <cmd> are equivalent. The full command
surface:
emet anchor <path>... # pin raw-byte hashes
emet verify <path>... # MATCH / DRIFT / UNVERIFIABLE
emet coherence <source> <view> # is a presented view faithful to source?
emet refuse <file> # detect + strip in-band authority claims
emet corroborate <path> # read-path-diverse agreement
emet audit # recompute the tamper-evident log chain
emet receipt --from-json <file|-> # portable, content-addressed witness receipt
emet check <receipt.json> # stateless offline re-verify
emet rebind <naked> --manifest <m> # rebind stripped bytes (experimental)
emet <any> --json # machine-readable canonical envelope
Exit codes (SPEC section 5): 0 held · 1 a difference found (DRIFT /
VIEW_DIFFERS_FROM_SOURCE / QUARANTINE / BROKEN) · 2 UNVERIFIABLE · 3
markers found · 64 usage.
Note: the marker corpus ships separately from the wheel (SPEC s.8), so an
installed refuse needs EMET_CORPUS set or a source checkout; without it,
the answer is UNVERIFIABLE reason=E_NO_CORPUS, never a silent pass.
Worked example: anchor, verify, let the verdict travel
$ printf 'hello world\n' > report.md
$ emet anchor report.md
anchored report.md sha256=a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447
$ emet verify report.md
MATCH report.md want=a948904f2f0f479b got=a948904f2f0f479b # exit 0
$ printf 'hello world CHANGED\n' > report.md
$ emet verify report.md
DRIFT report.md want=a948904f2f0f479b got=9fc0ea6515ceadd9 # exit 1
Seal the verdict into a receipt and hand it to someone else:
emet verify report.md --json | emet receipt --from-json - > receipt.json
emet check receipt.json # on ANY machine: RECEIPT_VALID / TAMPERED / UNVERIFIABLE
Add --recompute-from-paths to emet check to also re-hash the subject bytes
on disk against the recorded digests. For every command with captured real
output, the companion tools (monitor.py, organs.py), and a runnable demo,
see USAGE.md and examples/.
For developers
The repo ships its own delivery contract; re-check it any time with
python test_forward_delivery_contract.py.
Each implementation declares the optional capabilities it does not yet claim
(EMET_SKIP_CAPABILITIES), and the runner scores it only on what it does
claim, exactly as CI does:
git clone https://github.com/HarperZ9/emet && cd emet
python conformance/run.py membrane.py # Python reference: 44/44
( cd impl/rust && rustc -O emet.rs -o emet )
EMET_SKIP_CAPABILITIES=rebind \
python conformance/run.py impl/rust/emet # Rust: 40/40
EMET_SKIP_CAPABILITIES=rebind \
python conformance/run.py impl/js/emet.js # Node.js: 40/40
( cd impl/go && go build -o emet emet.go )
EMET_SKIP_CAPABILITIES=receipt,rebind \
python conformance/run.py impl/go/emet # Go: 35/35 (core)
Per-implementation capability matrix
| Implementation | Core (35 vectors) | Receipt (5, SPEC s.17) | Rebind (4, SPEC s.18) |
|---|---|---|---|
| Python (reference) | yes | yes | yes |
Rust (impl/rust) |
yes | yes (HMAC hand-composed over its own SHA-256, verified against RFC 4231) | not yet |
Node.js (impl/js) |
yes | yes (native crypto) |
not yet |
Go (impl/go) |
yes | not yet ported | not yet |
An unsigned receipt verifies on the content address alone; the HMAC-SHA256
signature is optional and only strengthens integrity when producer and
verifier share a key channel (EMET_RECEIPT_SIGNING_KEY). The rebind
cross-language port contract is docs/REBIND-SPEC.md.
What it won't do
EMET is an advisory integrity witness: it only reports facts. It can't say TRUSTED, doesn't decide whether a model
is safe, runs outside whatever it audits, and never edits, signs, or blocks
anything. Those constraints are the point, not limitations: see
SPEC.md section 6.
Status
v1.1.0. The spec is frozen and stable at 1.0.0. The byte-hash core, the
exit-code split, the --json envelope, the marker path, and the audit chain
re-derive across four languages and are checked in CI on every push. What the
1.x line asserts is exactly two things: the contract is frozen, and the
reference implementations are production-grade. It deliberately does not claim
re-derivability is proven: all four implementations share an author, and
SPEC section 12's bar, an independent different-author implementation passing
the vectors, is not yet met. For a tool whose only credential is reproduction,
an inflated claim would refute itself, so the claim is scoped to exactly what
CI reproduces today.
Call for an independent implementation
The highest-leverage contribution is not another language but a different-author implementation, written from SPEC.md alone (not by reading the existing code), in any language, that passes the core vectors:
EMET_SKIP_CAPABILITIES=receipt,rebind \
python conformance/run.py ./your-emet # expected: CONFORMANCE 35/35
Where your implementation and the spec disagree, the spec is wrong: open an issue; those divergences are the point. Both clean-room ports already did exactly this. The Node.js port surfaced that the marker occurrence count was unpinned (now pinned in SPEC section 16 and a dedicated vector), and the Go port surfaced the reason-code enum and default-JSON-encoder gaps, now pinned; see docs/spec-findings-from-go-impl.md. Claim a language in Discussions so effort isn't duplicated.
Why it matters
A model-facing view can drift from its source, a monitor can observe the wrong artifact, and a generated report can overstate what was checked. EMET is the small external witness for those seams: it re-derives the bytes and reports what matched, what drifted, and what could not be verified, without ever becoming an authority. The public value is exactly that: every verdict is a fact anyone can re-check, same bytes, same answer. It composes with its peer tools forum (accountable multi-agent orchestration) and accountable-surface (live perceive/gate/actuate surface), and stands alone just as well.
Docs
docs/INTRODUCTION.md (start here) · USAGE.md (every command, captured output) · SPEC.md (the frozen normative contract) · RATIONALE.md (why EMET is shaped this way) · conformance/ · THREAT-MODEL.md · COVERAGE.json · SECURITY.md · CONTRIBUTING.md
MPL-2.0.
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 emet-1.1.0.tar.gz.
File metadata
- Download URL: emet-1.1.0.tar.gz
- Upload date:
- Size: 39.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1888adf393cb85ed5ee49d94166f8f11c66e0de35d14129d40d95d518d52cdb7
|
|
| MD5 |
62dd31e5ac313d811225a319964f0f95
|
|
| BLAKE2b-256 |
6192cef2f2cb9afcdfcc5a1ec35f2c03d591f0c557de5a72a26dfa3e61cee114
|
Provenance
The following attestation bundles were made for emet-1.1.0.tar.gz:
Publisher:
release.yml on HarperZ9/emet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
emet-1.1.0.tar.gz -
Subject digest:
1888adf393cb85ed5ee49d94166f8f11c66e0de35d14129d40d95d518d52cdb7 - Sigstore transparency entry: 2103898230
- Sigstore integration time:
-
Permalink:
HarperZ9/emet@9385ae8a891361572faf6efb7d48aa88c531a4bb -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/HarperZ9
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9385ae8a891361572faf6efb7d48aa88c531a4bb -
Trigger Event:
release
-
Statement type:
File details
Details for the file emet-1.1.0-py3-none-any.whl.
File metadata
- Download URL: emet-1.1.0-py3-none-any.whl
- Upload date:
- Size: 42.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f207aebb45bc3eacd1aa2220e2ba1b90feb3cc5a3edeb1d6d9a3468a2f07921
|
|
| MD5 |
d2738e86aefcb7c7bb7519f095dac9af
|
|
| BLAKE2b-256 |
2612973b091829430505f2e8921dec0587c00fd0cfb76175096522b31546cbd8
|
Provenance
The following attestation bundles were made for emet-1.1.0-py3-none-any.whl:
Publisher:
release.yml on HarperZ9/emet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
emet-1.1.0-py3-none-any.whl -
Subject digest:
8f207aebb45bc3eacd1aa2220e2ba1b90feb3cc5a3edeb1d6d9a3468a2f07921 - Sigstore transparency entry: 2103898861
- Sigstore integration time:
-
Permalink:
HarperZ9/emet@9385ae8a891361572faf6efb7d48aa88c531a4bb -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/HarperZ9
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9385ae8a891361572faf6efb7d48aa88c531a4bb -
Trigger Event:
release
-
Statement type: