Contents

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

NameDocumentScope
SpecsThis indexThe documents, their versions, the shared conventions, the conformance vectors, what conformance means, and how these pages are addressed and cited
RecordDEO Record Format 1.0The 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
VerificationDEO Verification 1.0The verification contract: the four row outcomes, the check catalogue (row ids and reasons), the report JSON and the exit codes
BundleDEO Proof Bundle b1The 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
Anchortzun-anchor/1tzun-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
TreeRFC 6962 tree profile, revision 2The RFC 6962 tree profile, revision 2: tree math, inclusion and consistency proofs, and the hash encoding
VectorsConformance vectors 1.0The 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

ConstructWhere the tag sitsTagDefined inFrozen
Record payloadpayload.schemaVersion"v1.0"Recordno
Record envelopeenvelopeVersion"e1"Recordno
Canonical serialization(follows the payload's schema)v1.0Record §3no
Agent descriptorthe descriptor's v"tzun-agent/1"Record §6.9no
Mandate documentnonRepudiation.mandate.document.v"tzun-mandate/1"Record §9.7no
Mandate statementnonRepudiation.mandate.statement.v"tzun-signoff-mandate/1"Record §9.6no
Proof bundlebundleVersion"b1"Bundleno
Anchor formatnonRepudiation.anchor.anchorSpec"tzun-anchor/1"Anchorno
Tree profilenonRepudiation.anchor.merkleSpec"rfc6962", profile revision 2Treeno
Publication kindspublications[i].kind"evm-calldata/1", "rfc3161/1"Anchor §7no
ReportreportVersion"tzun-verify-report/1"Verificationno
Extensiona key of the bundle's extensions"witness/1", reservedBundle §9no

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-256 is the hash of FIPS 180-4; keccak256 is the Keccak-256 hash Ethereum uses (not FIPS 202 SHA3-256).
  • ‖ joins byte strings end to end. LF is the byte 0x0A.
  • MTH, PATH and PROOF are 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 in anchor.consistency[<origin>] or blocked_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, so 3.0 reads as 3, and never takes true or false as a number (Tree §4).
  • Whether null and 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 is null.

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 0x prefix (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 s and 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.expectation and signoff.key (Verification §4.5, §4.8);
  • the reserved slots credentials, relatedRecords and policy (Bundle §8);
  • extensions, witness/1 included (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).

FileWhat it pinsSections
merkle-rfc6962-vectors.jsonLeaf hashes, tree hashes and inclusion paths for trees of several sizes; the root of the empty tree; two leaf lists whose roots MUST differTree §3.1 to §3.4, §9
merkle-consistency-vectors.jsonValid consistency proofs, their refused mutations, the edge rules, and the hash encoding ruleTree §3.5, §4, §9
v1.0-canonical-vectors.jsonCanonical bytes for payloads of v1.0, and inputs a serializer MUST refuseRecord §3
v1.0-integrity-vectors.jsonThe form of canonicalDigest and of the chain linkRecord §4, §5
signoff-expectation-vectors.jsonThe 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 recordsRecord §9, Verification §5
checkpoint-vectors.jsonCheckpoint bodies and their digests, origins and origin binding, anchor-log leaves and P, and record artifacts with the rows each one yieldsAnchor §4 to §6, §10.3, §10.6, §10.7
evidence-log-origin-vectors.jsonThe evidence-log origin for a range of chain idsAnchor §4.3
anchor-e2e-vectors.jsonRecords 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 materialAnchor §6 to §10
bundle-b1/b1 bundles with the auditor's inputs, the expected report and the expected exit code, one directory per caseBundle §13, Verification

6. Conformance

An implementation conforms to this specification when:

  1. 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
  2. for every case of bundle-b1/, replayed as Bundle §13.3 describes, its report is identical to expected-report.json (compared as Verification §6.5 states) and its exit code is identical to expected-exit.

These parts of the vector files are informative, and item 1 does not cover them:

  • in signoff-expectation-vectors.json, the name a shapes entry gives its violation: only whether violation is null (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: c2spConforming and stockParserAccepts in checkpoint-vectors.json, and sizeMalleability in merkle-consistency-vectors.json;
  • descriptive text: description, source, note, case, why, generator, and the format and notes members.

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-verify included, 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.

Licence and attribution

The text of these documents is licensed under the Creative Commons Attribution 4.0 International licence (CC BY 4.0; legal code in LICENSE). To reuse a document, credit it with its title, status, copyright, licence and address, for example:

DEO Record Format 1.0 (Draft), © 2026 Tzun, Inc., CC BY 4.0, https://spec.tzun.ai/record/1.0/

For a Draft, add the date you copied it, since its text can still change at its address. If you change the text, say so.

The code blocks in these documents and the conformance vectors archive are dedicated to the public domain under CC0 1.0 Universal (CC0 1.0; legal code in LICENSE-CC0). No credit is required to use them.