It works out the fingerprint itself.
An AI model is always handling files: one it edits, a prompt it’s given, a view it shows you and calls a true copy of the original. EMET opens those files directly and works out the fingerprint again from scratch, using SHA-256 (a standard, widely trusted recipe for turning any file into one short, unique fingerprint). Then it compares that to the fingerprint it saved before. The answer comes only from running the same recipe over the same file, never from the system telling you it’s fine. It stands outside the thing it’s checking.
Knowing where a file came from is one thing. It still doesn’t tell you whether the copy the model is looking at right now is unchanged. That’s the gap this closes.Three answers. None of them trusted.
There are exactly three answers it can give (MATCH, DRIFT, UNVERIFIABLE), and there will only ever be three. That’s not a promise written in a comment somewhere; the code is shaped so a fourth answer simply has nowhere to come from. It can never tell you to trust something, because it was never given any trust to hand out.
Don’t take the answer on my word. Watch it flip.
A single character is enough to change everything. Check a file, add one character to it, then ask again. The same rules, written out in three different programming languages, all land on the same answer.
$ python membrane.py verify demo_sample.txt MATCH demo_sample.txt want=d02206abca2a… got=d02206abca2a… (exit 0) # append one byte to the file, ask the same question $ python membrane.py verify demo_sample.txt DRIFT demo_sample.txt want=d02206abca2a… got=b072d611645e… (exit 1) # one spec, four separate language implementations, CI on every push membrane.py → CONFORMANCE 35/35 vectors pass impl/rust/emet → CONFORMANCE 35/35 vectors pass impl/js/emet.js → CONFORMANCE 35/35 vectors pass impl/go/emet → CONFORMANCE 35/35 vectors pass
Change a single character in the file and the answer drops from MATCH to DRIFT. It reads the file itself, not anyone who promises it’s fine.
Captured live from the emet run · receipt format from adapters/proof_surface_receipt.py · 35/35 conformance vectors, four language implementations, CI each push. Honest limit: I wrote all four versions myself, so they can only earn one honest claim: that the written rules are clear enough to build from. What they still can’t claim is that someone with no connection to me rebuilt the tool from the spec and got the same answers, and that different-author version is something I still owe. See a sample proof-surface report →
One set of rules, four languages.
I wrote the same rules out four separate times, each in a different programming language (Python, Rust, Node.js, Go), and each built only from what comes with that language, nothing borrowed from the outside. All four pass the very same thirty-five test cases on every change.
Four versions agreeing is not the same as four people agreeing.
They all came from one person: me. So they earn one honest claim and not a single one more: the rules are clear enough that someone can build a working tool from them. What I still owe is the real test, a version built by someone with no tie to me, a different author and not just a fifth language. I say that here in plain words, instead of letting the number quietly imply more than it should.
One file, or a whole packet.
Checking a single file is the core. But an agent rarely produces just one file, it produces a packet: a report, the things it references, the record of what it did. So EMET can now witness the whole packet at once. You hand it a small manifest (a list that names every file in the packet next to the fingerprint recorded for it), and it re-derives each one, opening every file and working out its fingerprint again from scratch, then comparing that to the fingerprint written down. It is the same recipe as before, run over a list instead of a single name.
The answer stays the same three, and only these three. MATCH means every file in the packet re-derived to the fingerprint recorded for it. DRIFT means at least one recorded fingerprint no longer matches the file on disk. UNVERIFIABLE means a listed file is missing or unreadable, or the manifest itself is malformed, so the comparison can’t be made. A difference always wins over a can’t-check: if anything drifted, the packet reports DRIFT. There is still no fourth answer, and no way for the manifest to smuggle one in. If a word that sounds like permission shows up anywhere in the list, even in a filename, it is refused before any verdict is formed. The witness runs entirely inside EMET, and it never becomes an authority.
$ python adapters/proof_surface_receipt.py bundle bundle.json # re-derives every file the manifest lists, against its recorded sha256 MATCH files_total=7 files_rederived=7 # every file re-derived DRIFT one recorded digest no longer matches the file on disk UNVERIFIABLE a listed file is missing, or the manifest is malformed
This is the external check for a generated proof-packet: not “the tool that made it says it’s fine,” but every file re-derived from scratch against the fingerprint written down for it.
Bundle witness from adapters/proof_surface_receipt.py · manifest schema proof-surface-bundle/v0 · same closed lattice, same no-authority contract as the single-file core. It reads the manifest and the files, and speaks for neither.
Copy it. Run the tests. Try it on real work.
It’s small, it’s open for anyone to read, and it leans on almost nothing else. Copy it onto your own machine, run the tests, point it at something you actually care about. And the moment it lets you down, tell me. I would honestly rather hear where it breaks than be told it’s fine. That’s what shows me what to build next.
$ pip install emet # the tool, zero dependencies $ emet selftest # re-derives its own hash; never says “trusted” $ git clone https://github.com/HarperZ9/emet && cd emet $ python conformance/run.py membrane.py CONFORMANCE 35/35 vectors pass