These documents specify what a verifier of DEO proof bundles checks and how it reports: the Decision Evidence Object (DEO) record, the proof bundle that carries one record to a verifier, the anchoring format that ties a record's digest to a public ledger or a timestamp, the Merkle tree profile under it, and the verification contract that turns all of it into a report and an exit code. An implementation can be written from these documents and the vectors of §5 alone.
1. Documents
| Name | Document | Scope |
|---|---|---|
| Specs | This index | The documents, their versions, the shared conventions, the conformance vectors, what conformance means, and how these pages are addressed and cited |
| Record | DEO Record Format 1.0 | The DEO v1.0 record: envelope and payload, the hashed field set, canonical serialization, canonicalDigest, the chain link, the decider and agent descriptors, contributions, links to other records, the signature expectation and the mandate form, the profile of the record's own RFC 3161 token, and size limits |
| Verification | DEO Verification 1.0 | The verification contract: the four row outcomes, the check catalogue (row ids and reasons), the report JSON and the exit codes |
| Bundle | DEO Proof Bundle b1 | The b1 proof bundle: its members, how a verifier reads it, how its anchoring material reaches the anchor checks, the order of its rows, and the layout of its conformance corpus |
| Anchor | tzun-anchor/1 | tzun-anchor/1: checkpoint bodies and origins, the published value P, the publication kinds (evm-calldata/1, rfc3161/1), the record artifact nonRepudiation.anchor, the publisher manifest, and verification, the RFC 3161 token checks included |
| Tree | RFC 6962 tree profile, revision 2 | The RFC 6962 tree profile, revision 2: tree math, inclusion and consistency proofs, and the hash encoding |
| Vectors | Conformance vectors 1.0 | The conformance vectors of §5, as one archive with its SHA-256 |
A citation names a document by the name in the first column (§3.7).
A verifier meets them in this order: it reads a bundle (Bundle), recomputes the record's digest and chain link (Record), checks the record's timestamp and anchor (Anchor, over the proofs of Tree), and reports every check as a row (Verification).
2. Versions
| Construct | Where the tag sits | Tag | Defined in | Frozen |
|---|---|---|---|---|
| Record payload | payload.schemaVersion | "v1.0" | Record | no |
| Record envelope | envelopeVersion | "e1" | Record | no |
| Canonical serialization | (follows the payload's schema) | v1.0 | Record §3 | no |
| Agent descriptor | the descriptor's v | "tzun-agent/1" | Record §6.9 | no |
| Mandate document | nonRepudiation.mandate.document.v | "tzun-mandate/1" | Record §9.7 | no |
| Mandate statement | nonRepudiation.mandate.statement.v | "tzun-signoff-mandate/1" | Record §9.6 | no |
| Proof bundle | bundleVersion | "b1" | Bundle | no |
| Anchor format | nonRepudiation.anchor.anchorSpec | "tzun-anchor/1" | Anchor | no |
| Tree profile | nonRepudiation.anchor.merkleSpec | "rfc6962", profile revision 2 | Tree | no |
| Publication kinds | publications[i].kind | "evm-calldata/1", "rfc3161/1" | Anchor §7 | no |
| Report | reportVersion | "tzun-verify-report/1" | Verification | no |
| Extension | a key of the bundle's extensions | "witness/1", reserved | Bundle §9 | no |
Freezing. A version that is not frozen can change under the same tag, and no compatibility is
owed across such a change. The versions an anchor commits to (the envelope and payload versions,
the canonical serialization, tzun-anchor/1, the tree profile and the publication kinds in use)
freeze at the first publication of an anchor whose anchor origin is not a test origin
(Anchor §4.3.4); anchors under test origins freeze nothing. The bundle and report versions
freeze when this table marks them frozen. A frozen version is never edited: a change to the bytes it
defines, or to the outcome a verifier reaches under it, takes a new tag (Anchor §2,
Tree §0).
A verifier that meets a tag it does not implement never reads the tagged material by the rules of
another tag. It abstains on that material, and on the whole bundle when the tag is
bundleVersion (Verification §2.2).
3. Conventions
These conventions hold in every document of this specification unless a document states otherwise for a particular member.
3.1 Requirement keywords
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in these documents are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174) when, and only when, they appear in all capitals, as shown here.
3.2 Notation
SHA-256is the hash of FIPS 180-4;keccak256is the Keccak-256 hash Ethereum uses (not FIPS 202 SHA3-256).‖joins byte strings end to end.LFis the byte 0x0A.MTH,PATHandPROOFare the tree hash, the inclusion path and the consistency proof of Tree §3.- A row is one check of a report, named by its id (Verification §4). Ids in running
text are written in code font:
record.digest,anchor.evm.tx[0]. <x>in an id or a reason stands for a value filled in per row, as inanchor.consistency[<origin>]orblocked_by:<id>.
3.3 JSON
- Every JSON document these documents define (a record, a bundle, a report, a publisher manifest, a vector file) is read by the rules of Record §3.1: UTF-8 with no byte-order mark and nothing but whitespace after the value, the last value of a repeated member name, lone surrogates kept as written, and a bound on nesting.
- An integer is a JSON number whose value is a whole number in
[0, 2^53 − 1]. A writer writes it without a fraction or an exponent; a reader takes the value, so3.0reads as 3, and never takestrueorfalseas a number (Tree §4). - Whether
nulland absence mean the same thing is stated per document: Record §1.2 for a record, Bundle §3.2 for the slots of a bundle. Where a document lists the exact members of an object (Anchor §8.1), a member it does not list is not allowed even when its value isnull.
3.4 Hex
- A hash (a record digest, a tree root, an element of a path or a proof) is a JSON string of
exactly 64 hexadecimal digits with no prefix. Writers write lowercase; readers accept any case and
compare the decoded bytes; anything else is refused, never repaired (Tree §4). The
shorthand
<hex64>in examples stands for one. - A value with a
0xprefix (a transaction id, an address, a block hash, RLP-encoded bytes) is an Ethereum value. Anchor §7.2, §8.2 and §9 give its exact form and how it is compared. - The chain segment of an origin is the lowercase hex of the chain id's UTF-8 bytes, and only lowercase is accepted (Anchor §4.3).
3.5 base64
base64 is the standard alphabet with = padding (RFC 4648 §4). A member that uses the URL-safe
alphabet or leaves out padding says so where it is defined.
3.6 Times
A date-time is an RFC 3339 date-time in UTC, written with Z. A member with a different grammar
states it (Anchor §9 admits numeric offsets in the publisher manifest; Verification
§6.5 fixes three fractional digits in the report).
A block time is an Ethereum block's timestamp, in seconds since the Unix epoch.
3.7 Citations, and normative text
- A citation names a document by its name (§1) and a section: Record §3. Within one document, §3.2 alone means that document's own section. A list that follows a named citation stays in the named document: Anchor §7.2, §8.2 and §9 are three sections of Anchor.
- A section's anchor on its page is its number, prefixed with
sand with each dot replaced by a hyphen (§8.2): Record §3.2 is/record/1.0/#s3-2. - RFCs are cited by number and section:
RFC 6962 §2.1. - Sections, rules and tables are normative. Examples, and passages marked informative, are not.
4. Scope of this version
This version of the specification does not verify the following. None of them counts as a pass.
When a bundle carries one of the first seven, Verification gives the row that reports it.
Whether a mandate was in force has no row, but a record decided under a mandate never exits 0,
since its mandate.key row is never decided (Verification §4.12, §6.6).
- who a decider is beyond what the record states, agent descriptors, pipeline definitions, signatures over contribution steps, the target rules of links and their edges, and the rules of relations a verifier does not know (Verification §4.8 to §4.11);
- who signed a mandate, and whether it was in force when a record was captured (Verification §4.8, §4.12);
- custody material (Bundle §6);
- WebAuthn signatures, and so every sign-off row other than
signoff.expectationandsignoff.key(Verification §4.5, §4.8); - the reserved slots
credentials,relatedRecordsandpolicy(Bundle §8); - extensions,
witness/1included (Bundle §9); - chain-profile bundles (Bundle §11);
- signatures on checkpoint bodies (Bundle §7.2, Anchor §4.5), which a verifier of this version does not read.
5. Conformance vectors
The vectors are published as one archive (Vectors); its page gives the archive's SHA-256 and
describes each file. Each file states, for every entry, the result this specification requires. The
archive now published predates the revision of Record 1.0 of 1 October 2026, which changed the
hashed field set of v1.0 in place (Record §4.1). Its records were hashed under the earlier set
0.7, apart from one case hashed under before-0.7 on purpose and the cases tampered on purpose,
and under the revised text none of their digests recomputes. These parts of it are therefore
superseded: the records of signoff-expectation-vectors.json and anchor-e2e-vectors.json, the
entries of v1.0-integrity-vectors.json whose hashedFields is the earlier set, and the
bundle-b1/ corpus, whose expected reports also lack the rows of Verification §4.9 to §4.11 and
the payload rows of Verification §4.7. The archive has no vectors for the members Record §6 to §9
add. The other vectors still hold: those of Tree, the canonical serialization vectors, which
serialize each input whole, and the checkpoint and origin vectors. The archive also predates the
kind rule of Anchor §10.3 step 2b, so one of its entries is superseded: the
checkpoint-vectors.json artifact case "a leaf of a store log of another kind, with no chain id:
the chain is unchecked", for which the text gives anchor.origin checked-wrong,
chain_id_mismatch. And a note in v1.0-integrity-vectors.json cites the session form by its
former section number; it is now Record §9.1. The archive is rebuilt from vectors written under the
revised text, and until then the text governs (§7).
| File | What it pins | Sections |
|---|---|---|
merkle-rfc6962-vectors.json | Leaf hashes, tree hashes and inclusion paths for trees of several sizes; the root of the empty tree; two leaf lists whose roots MUST differ | Tree §3.1 to §3.4, §9 |
merkle-consistency-vectors.json | Valid consistency proofs, their refused mutations, the edge rules, and the hash encoding rule | Tree §3.5, §4, §9 |
v1.0-canonical-vectors.json | Canonical bytes for payloads of v1.0, and inputs a serializer MUST refuse | Record §3 |
v1.0-integrity-vectors.json | The form of canonicalDigest and of the chain link | Record §4, §5 |
signoff-expectation-vectors.json | The grammar of payload.signoffExpectation, sign-off statement digests and challenges, the comparison a verifier makes between the expectation and the sign-off material a record carries, and the verdicts on whole records | Record §9, Verification §5 |
checkpoint-vectors.json | Checkpoint bodies and their digests, origins and origin binding, anchor-log leaves and P, and record artifacts with the rows each one yields | Anchor §4 to §6, §10.3, §10.6, §10.7 |
evidence-log-origin-vectors.json | The evidence-log origin for a range of chain ids | Anchor §4.3 |
anchor-e2e-vectors.json | Records anchored end to end on a local development chain: their artifacts, the epochs' anchor checkpoints, P and consistency proofs, and each publication with its heavy material | Anchor §6 to §10 |
bundle-b1/ | b1 bundles with the auditor's inputs, the expected report and the expected exit code, one directory per case | Bundle §13, Verification |
6. Conformance
An implementation conforms to this specification when:
- for every entry of every vector file of §5 other than
bundle-b1/, it gives the result the entry states (Tree §9 and Anchor §13 detail this for their files); and - for every case of
bundle-b1/, replayed as Bundle §13.3 describes, its report is identical toexpected-report.json(compared as Verification §6.5 states) and its exit code is identical toexpected-exit.
These parts of the vector files are informative, and item 1 does not cover them:
- in
signoff-expectation-vectors.json, the name ashapesentry gives itsviolation: only whetherviolationisnull(the value is well formed) or not (it is malformed, Record §9.2) is normative; - members that describe other software, or that a file marks as documentation rather than
conformance:
c2spConformingandstockParserAcceptsincheckpoint-vectors.json, andsizeMalleabilityinmerkle-consistency-vectors.json; - descriptive text:
description,source,note,case,why,generator, and theformatandnotesmembers.
A report that differs from the expected one in any row, reason, fact, input fingerprint or summary member, or in the order of its rows, does not conform, whatever its exit code.
7. The specification governs
- Where the code, the comments or the documentation of an implementation,
tzun-verifyincluded, differ from these documents, these documents govern, and the difference is a defect in the code or its documentation. - Where a vector and the text differ, the text governs. A corrected vector cites the section it follows, and every implementation that replays the vectors moves with it.
- Where two documents of this specification overlap, the document that defines the construct governs: Record for the record's bytes and digest; Tree for tree math and hash encoding; Anchor for the anchoring wire format and the anchor checks; Bundle for the bundle's members and how they are read; Verification for outcomes, rows, reasons, the report and the exit codes.
8. Addresses, anchors and versions
8.1 Addresses
Each version of a document has its own address: https://spec.tzun.ai/, the document's path, and
the version, as in https://spec.tzun.ai/record/1.0/ for Record 1.0. The document of §1 whose name
is Specs, this index, is the one page without a version; it is https://spec.tzun.ai/. The address
of a document without a version, as in https://spec.tzun.ai/record/, leads to its latest version
and changes when a new one is published; a citation that must keep its meaning uses the versioned
address.
8.2 Section anchors
Every numbered section of a document has an anchor on its page made from its number: s, then
the number with each dot replaced by a hyphen. Section 3 has the anchor #s3, section 3.2 #s3-2
and section 4.3.1 #s4-3-1, so Anchor §10.5 is https://spec.tzun.ai/anchor/1/#s10-5. A section
keeps its number, and so its anchor, for the life of the version.
8.3 Citations outside these pages
Text outside these pages cites a document the way these documents cite each other (§3.7): Record §3.2, Anchor §10.5, Verification §6.2, with the table of §1 or the addresses of §8.1 at hand for a reader who needs them. On these pages, every such citation is a link to the section in the version the citing document was written against.
8.4 Status, immutability and errata
The banner of each page states the document's name, its version and its status.
- Draft: the text can still change at the same address.
- Frozen: the text at the address never changes. A correction is published as a new version at a new address, or as a dated errata note shown with the page, apart from the text it corrects.
The tags a document defines freeze by the rules of §2, and the page of that version is marked Frozen when they do. An address, once published, stays: it is never removed and never given other text. This index is not versioned: its numbered sections keep their numbers, and a change that would alter what a frozen version means is made as a new version of that document instead.