Contents

Bundle version: b1. Profiles: record (defined here) and chain (reserved, §11).

A proof bundle is one JSON document that carries one DEO record, the subject, together with the material a verifier needs to check that record on its own: the record's envelope, its place in its chain, and the checkpoints, proofs and publications that tie its digest to a public ledger or a timestamp. A verifier reads a bundle without contacting whoever produced it. Nothing in a bundle is believed because the bundle says it: every fact is recomputed, and trust comes only from the auditor's own inputs (a publisher manifest, header sources, RFC 3161 roots).

The conventions of Specs §3 apply throughout.

1. Scope

This document defines:

  • the members of a b1 bundle and what each one carries (§3, §5 to §10);
  • how a verifier reads a bundle before checking anything, which decides the bundle row (§4);
  • how a verifier takes the anchoring material out of a bundle and hands it to the anchor verification of Anchor §10 (§7);
  • the order of the rows a verifier reports for a record bundle (§12);
  • the layout of the b1 conformance corpus (§13).

It relies on:

  • Record for the envelope, the payload, the record digest, the chain link and the record's own RFC 3161 token;
  • Anchor for checkpoint bodies, origins, the published value P, publication entries, the record artifact nonRepudiation.anchor and its verification;
  • Tree for inclusion paths, consistency proofs and the hash encoding;
  • Verification for the four outcomes, the check catalogue (row ids and reasons), the report and the exit codes.

2. Terms

  • Subject: the one record a record bundle is about.
  • Exporter: whatever writes a bundle. Verifier: whatever reads one and reports on it.
  • Slot: a top-level member with a fixed name that every b1 bundle carries (§3.2).
  • Reserved slot: a slot this version reserves without defining its content (§8). A later specification may define it without a new bundle version.
  • Log, origin: an append-only Merkle log and the name its checkpoint bodies carry (Anchor §3, §4.3). The subject's evidence log is the log of its chain; the anchor log is its domain's log of checkpoint digests (Anchor §5). A Tzun origin whose rest is anchors (Anchor §4.3.1) is an anchor-log origin; every other key of the anchoring slot is read as an evidence-log origin.
  • Final publication: a publication of an anchor checkpoint's P (Anchor §6, §7) that the exporter holds as final.
  • Heavy material: the members an evm-calldata/1 entry needs for an offline check and the envelope leaves out: rawTransaction, blockHeader, txIndex and txProof (Anchor §7.2, §8.2).

3. The bundle object

3.1 Members

A b1 record bundle is a JSON object with these members:

MemberTypeContent
bundleVersionstring"b1" (§4)
profilestring"record"; "chain" is reserved (§11)
subjectobjectNames the subject (§5.1)
envelopeobjectThe subject's envelope, as stored (§5.2)
chainobject or nullThe subject's chain id and predecessor (§5.3)
custodyobject or nullCustody material (§6)
credentialsnullReserved slot (§8)
relatedRecordsnullReserved slot (§8)
anchoringobject or nullCheckpoints, publications and proofs, by origin (§7)
anchorPendingobject or nullThe pending state of an unanchored subject (§7.7)
policynullReserved slot (§8)
extensionsobject or nullExtensions, by name (§9)
exporterobject or nullInformation about the export; never an input (§10)

3.2 Every slot is present

Every member of §3.1 other than bundleVersion and profile is a slot. A b1 bundle MUST carry every slot. A slot with nothing to carry holds null. A slot that is missing, as opposed to null, makes the document something other than a b1 bundle, and a verifier reads it as unreadable (§4). Because every slot is always present, material can be added to a reserved slot later without a new bundle version, and a reader never has to guess whether a missing member held nothing or has been removed.

Inside a slot, a member whose value is null reads as absent unless a rule of this document says otherwise.

3.3 Other members

A record bundle MUST NOT carry any other top-level member. A verifier reports each top-level member that §3.1 does not list as a row member[<key>] that abstains, reason unsupported_member (Verification §4.7), because it has not examined what the member carries. An abstention is never a pass.

3.4 Example (informative)

{
  "bundleVersion": "b1",
  "profile": "record",
  "subject": { "evidenceId": "7d0c…", "canonicalDigest": "<hex64>" },
  "envelope": { "envelopeVersion": "e1", "payload": { … }, "integrity": { … },
                "nonRepudiation": { "rfc3161Token": "…", "anchor": { … } } },
  "chain": { "chainId": "default", "predecessor": { "evidenceId": "…", "sequenceNumber": 41,
                                                    "canonicalDigest": "<hex64>" } },
  "custody": null,
  "credentials": null,
  "relatedRecords": null,
  "anchoring": {
    "<evidence-log origin>": {
      "checkpoints": [
        { "body": "<the subject's own evidence-log checkpoint>", "signatures": [] },
        { "body": "<the newest anchored one>", "signatures": [],
          "logPath": ["<hex64>"], "anchorLeafIndex": 409, "anchorSize": 412,
          "anchorPath": ["<hex64>"] } ],
      "consistency": [ { "fromSize": 1024, "toSize": 1100, "path": ["<hex64>"] } ] },
    "<anchor-log origin>": {
      "checkpoints": [
        { "body": "<the subject's own anchor checkpoint>", "signatures": [],
          "publications": [ { "kind": "evm-calldata/1", "chain": "eip155:11155111",
                              "transactionId": "0x…", "blockNumber": 7123456, "blockHash": "0x…",
                              "publisher": "0x…", "rawTransaction": "0x…", "blockHeader": "0x…",
                              "txIndex": 3, "txProof": ["0x…"] } ] },
        { "body": "<the newest anchor checkpoint>", "signatures": [], "publications": [ … ] } ],
      "consistency": [ { "fromSize": 380, "toSize": 412, "path": ["<hex64>"] } ] } },
  "anchorPending": null,
  "policy": null,
  "extensions": { "witness/1": null },
  "exporter": { "exportedAt": "2026-01-01T00:00:00.000Z", "exportedBy": "…" }
}

4. Reading a bundle: the bundle row

A verifier reads a bundle in the order below before any other check. The outcome is the bundle row of Verification §4.2.

  1. The document MUST be a JSON text (Record §3.1) whose top-level value is an object. Otherwise the row is checked-wrong, malformed_bundle.
  2. bundleVersion MUST be the string "b1". A value that is absent, null, not a string, or another string makes the verifier abstain on the whole bundle: abstain, unsupported_bundle_version. The version is read before anything else in the object, so a bundle of an unknown version is never judged by this version's rules.
  3. profile MUST be the string "record". Any other value, "chain" and absence included, makes the verifier abstain on the whole bundle: abstain, unsupported_bundle_profile.
  4. Every slot of §3.1 MUST be present (§3.2).
  5. envelope MUST be an object; envelope.payload and envelope.integrity MUST be objects; and envelope.nonRepudiation, when present and not null, MUST be an object.
  6. Every slot MUST be null or an object.
  7. In chain: chainId, when present and not null, MUST be a string, and predecessor, when present and not null, MUST be an object.
  8. anchoring MUST have the shape of §7.1.
  9. No member name of the bundle object, of extensions, of envelope.payload, of envelope.nonRepudiation or of anchoring holds a lone surrogate (Record §3.1). These are the names a report carries as part of a row id (Verification §4.7), and a report that holds a lone surrogate cannot be written (Verification §6.5).

A failure at steps 4 to 9 makes the row checked-wrong, malformed_bundle. When every step holds, the row is checked-correct.

When the bundle row is not checked-correct, it is the only row of the report, and the exit code is 2 (Verification §6.6). A verifier that fails for a reason of its own while checking a bundle, rather than because of the bundle, reports the one row bundle, not-checked, bundle_verifier_error.

Whatever the bundle row's outcome, a report restates the bundle's bundleVersion and subject exactly as the bundle gives them, and null for either one the bundle does not carry or a document that is not JSON (Verification §6.1).

5. The record

5.1 subject

subject is { "evidenceId": <string>, "canonicalDigest": <hash> }. It MUST name the envelope's record: evidenceId equal to envelope.payload.evidenceId, and canonicalDigest equal, as a hash (Tree §4), to the digest the envelope stores in envelope.integrity.canonicalDigest.

The comparison uses the stored digest, never a recomputed one. A payload edited after capture is therefore reported once, by record.digest, and not a second time here. Any other outcome of the comparison, including a subject that is null or a member that is missing or unreadable, makes the row subject checked-wrong, subject_mismatch.

5.2 envelope

envelope is the subject's envelope exactly as stored (Record §2). An exporter MUST NOT alter it. A verifier:

  • recomputes the record digest from envelope.payload (Record §4), which decides the row record.digest. Every row that takes the digest as its input reads the recomputed digest, and is not-checked, blocked_by:record.digest, unless that row is checked-correct. A row whose artifact the envelope does not carry reports it absent instead, whatever the digest;
  • reads under envelope.nonRepudiation: rfc3161Token, the record's own timestamp (Record §10); anchor, the record artifact (Anchor §8); the sign-off material signoff and webauthnAssertion, which the rows signoff.expectation and signoff.key read (Verification §4.5, §5); the mandate material mandate and mandateIssuance, which signoff.expectation and the mandate rows read (Verification §4.12, §5); and confirmation, which signoff.expectation reads when the record owes one (Verification §5), and which is otherwise reported as material this version does not read (Verification §4.7);
  • never takes a stored summary as an input. nonRepudiation.rfc3161Metadata is a display copy of fields of the token, and envelope.attestationStatus is the writer's own summary; neither is read;
  • reports a row for each payload member that Record §2.2 does not name, which the digest does not cover, and for any other material present under nonRepudiation that it does not verify, so that nothing present is passed over (Verification §4.7).

5.3 chain

chain is { "chainId": <string>, "predecessor": <object or null> }.

  • chainId is the id of the chain the subject belongs to. The verifier passes it as the chain id of step 2b of Anchor §10.3, for the subject's anchor (§7.4) and for anchor.newer (§7.5). When chain or chainId is null or absent, no chain id is supplied, and step 2b reports the chain unchecked. A chainId that holds a lone surrogate is supplied, and no origin spells it.
  • predecessor is the record numbered one below the subject in the same chain: { "evidenceId", "sequenceNumber", "canonicalDigest" }, with the digest that record stores. It is null for the first record of a chain, whose payload.sequenceNumber is 1. An exporter SHOULD carry it for every other record: without it the chain link cannot be checked.

The row record.chainLink (Verification §4.3) checks envelope.integrity.chainLink (Record §5) against predecessor, using the digests as stored, so that an edited payload is record.digest's finding alone. A subject numbered above 1 whose bundle carries no predecessor reads not-checked, not_in_bundle:predecessor; a predecessor that is present must be numbered exactly one below the subject.

6. custody

custody is null or an object that carries custody material for the subject. This version of the specification does not define that material and does not verify it. The row custody.ledger (Verification §4.3) reports what a verifier of this version decides about it; custody material it cannot verify is never passed over.

7. Anchoring

7.1 The anchoring slot

anchoring maps origins to logs:

"anchoring": { "<origin>": { "checkpoints": [ <checkpoint entry>, … ],
                             "consistency": [ <consistency entry>, … ] } }

It is {} or null when the bundle carries no anchoring material. Its shape, which step 8 of §4 requires:

  • each key is a string with no lone surrogate, and each value is an object;
  • checkpoints is present and is an array of at most two checkpoint entries (§7.3), each an object whose body parses as a checkpoint body (Anchor §4.2) naming exactly the origin it is keyed under;
  • consistency, when present and not null, is an array of objects (§7.6).

Keying every body under its own origin means two logs are never compared as one: a bundle that places a body of one log under the key of another is unreadable.

7.2 Checkpoint entries

MemberTypeCarried byRule
bodystringevery entryA checkpoint body (Anchor §4.1)
signaturesarray of signature entriesevery entrySignatures on the body (Anchor §4.5), each a signature entry (below). This version defines no check over them: a verifier does not read them, and they have no row in the report (Verification §4.7). Anchor §4.5 defines no log key in this version, and until a log key exists an exporter writes [].
publicationsarrayanchor-log entriesEvery final publication of this checkpoint's P, each a publication entry with its heavy material (§7.4)
logPatharray of hashesone evidence-log entryThe subject's inclusion path in this body: PATH(leafIndex, D[n]), leaf first (Tree §3.3), where n is the body's size
anchorLeafIndexintegerthe same entryThe index of this body's checkpoint digest (Anchor §4.4) in the anchor log
anchorSizeintegerthe same entryThe size of the carried anchor checkpoint that includes this body
anchorPatharray of hashesthe same entryPATH(anchorLeafIndex, A[anchorSize]), leaf first

The last four members compose the subject's anchor into a newer anchor checkpoint (§7.5). An exporter writes them on at most one evidence-log entry.

Signature entries. Each element of signatures is an object with two members, line and proofs:

{ "line": "— <key name> <base64(key ID ‖ signature)>",
  "proofs": [ { "kind": "rfc3161", "token": "<base64 TimeStampResp>" } ] }
  • line is one signature line of the signed note on body, in the form of Anchor §4.5, without its final LF.
  • proofs is an array of proofs over line, [] when the exporter holds none. A proof is an object whose member kind, a string, names its form and the members it carries beside kind.
kindMembers beside kindThe proof
rfc3161token, a stringAn RFC 3161 timestamp over line: the DER TimeStampResp, in base64, to a TimeStampReq that is that of Anchor §7.3 with the SHA-256 of the UTF-8 bytes of line as hashedMessage in place of P

Proof kinds are additive. A verifier that reads signatures abstains on a proof whose kind it does not know, and never fails it, so that a kind defined later makes no bundle fail. A verifier of this version reads none of them (above).

7.3 Which checkpoints a record bundle carries

For a subject that a final publication covers, the exporter carries its evidence log and its domain's anchor log. For each of the two logs it carries at most two checkpoints:

  1. the subject's own: the evidence-log body its artifact names as logCheckpoint, and the anchor checkpoint it names as anchorCheckpoint. Nothing but the artifact authenticates these bodies, so an exporter carries them only when the envelope holds the artifact;
  2. the newest: the newest anchor checkpoint that has a final publication when the bundle is written, and the newest evidence-log checkpoint that anchor checkpoint includes.

When both name the same body, the log has one checkpoint. When the envelope holds no artifact yet, the exporter carries the newest checkpoint of each log alone, with the subject's anchor into it (§7.5).

A record bundle MUST NOT carry intermediate checkpoints. A verifier reads more than two checkpoints under one origin as an unreadable bundle (§4 step 8). One direct consistency proof per log (§7.6) joins the two checkpoints, so the size of a record bundle's anchoring does not grow with the age of the record. A run of consecutive checkpoints belongs to the chain profile (§11).

7.4 Publications, and the join with the envelope

Each anchor-log checkpoint entry carries, in publications, every final publication of that checkpoint's P as a publication entry of Anchor §8.2. An evm-calldata/1 entry carries its heavy material. A bundle's evm-calldata/1 entry MAY omit transactionId (Anchor §8.2).

The envelope's artifact lists its publications without the heavy material. Before verifying the subject's anchor, a verifier joins each of its entries with the heavy material the bundle carries:

  1. The bundle's entries are every publication entry of every anchor-log checkpoint entry in the bundle, taken with origins in byte order of their keys, then checkpoint entries in array order, then publications in array order.
  2. An envelope entry of kind evm-calldata/1 with a string transactionId joins the first bundle entry that is also of kind evm-calldata/1, whose rawTransaction hashes under keccak256 to that transactionId (compared without regard to case), and whose blockHash, if both entries state one, is the same (compared without regard to case). Two transactions mined in one block are therefore never confused.
  3. The joined entry keeps every member of the envelope's entry and gains each heavy member it does not already have; a member whose value is null is one it does not have (§3.2), and a bundle member whose value is null gives nothing. No other member of the bundle entry is taken: the chain, block number, block hash and publisher checked are the envelope's.
  4. An envelope entry that joins no bundle entry, and every entry of another kind, is verified as the envelope writes it.

The verifier then runs Anchor §10.3 to §10.6 over the artifact with the joined entries, the recomputed digest, payload.sequenceNumber, and chain.chainId. Its rows are the anchor row and its step and publication rows of Anchor §10.7, in that order. When the envelope holds neither nonRepudiation.anchor nor nonRepudiation.blockchainAnchor, the anchor rows report the artifact absent (Anchor §10.9). Otherwise, when record.digest is not checked-correct, anchor and each of its six step rows are not-checked, blocked_by:record.digest.

7.5 The subject's anchor into a newer checkpoint: anchor.newer

When a bundle carries a checkpoint that the envelope's artifact does not name, or the envelope has no artifact yet, the exporter writes logPath, anchorLeafIndex, anchorSize and anchorPath on the largest evidence-log checkpoint it carries (§7.2), so that the subject's anchor into the newest anchor checkpoint can be checked. That checkpoint can be the artifact's own logCheckpoint, when the evidence log did not grow while the anchor log did.

A verifier checks that anchor as follows.

  1. The target. Among the evidence-log checkpoint entries that carry any of the four members (a member whose value is null is not carried, §3.2), the target is the one whose body has the largest size, searched first under the origin of the artifact's logCheckpoint (when the artifact is present and that body parses) and, if no entry there carries the members, under every evidence-log origin. On equal sizes, the first in the order of §7.4 step 1 is taken. With no target there is no anchor.newer row.
  2. The composed artifact. The verifier builds a record artifact (Anchor §8.1) from: anchorSpec "tzun-anchor/1", merkleSpec "rfc6962", leafIndex equal to payload.sequenceNumber − 1 (when the sequence number is an integer of at least 1), the target's body as logCheckpoint, and its logPath and anchorLeafIndex; then, from the first anchor-log checkpoint entry (same order) whose origin has the same domain prefix as the target's (Anchor §4.3.1; any anchor-log origin when the target's origin is not a Tzun origin) and whose body's size equals the target's anchorSize, that body as anchorCheckpoint, the target's anchorPath, and that entry's publications. A member the bundle cannot supply is left out, and the composed artifact then fails the shape of step 2 of Anchor §10.3 (malformed_anchor).
  3. The verification. The verifier runs Anchor §10.3 to §10.6 over the composed artifact, with the recomputed digest, payload.sequenceNumber and chain.chainId. Its publications are the bundle's own entries, which carry their heavy material and need no join. Because logPath is the subject's own path, every step applies, the inclusion of the subject in the newer body included: this is a stronger check than the minimum of Anchor §10.8, and it authenticates the two bodies it names in the same way.
  4. The row. The verifier reports one row, anchor.newer, with the outcome and reason that the anchor row of Anchor §10.7 would give the composed artifact. When it is checked-correct its facts are treeSize and anchorSize, the sizes of the two bodies it authenticated. The step and publication rows of the composed artifact are not reported. When record.digest is not checked-correct, the row is not-checked, blocked_by:record.digest.

7.6 Consistency proofs

A consistency entry is { "fromSize": <integer>, "toSize": <integer>, "path": [<hash>, …] }: the proof PROOF(fromSize, D[toSize]) of Tree §3.5 between two checkpoints of the log it is keyed under. An exporter writes one direct proof between the two checkpoints it carries for a log, with fromSize the smaller size and toSize the larger.

A verifier reports the rows anchor.consistency[<origin>] of Anchor §10.8, in byte order of the origin:

  • the origins are every key of anchoring, and the origin of every body that anchor or anchor.newer authenticated;
  • a body is authenticated by anchor when the subject's anchor is checked-correct (its logCheckpoint and anchorCheckpoint), and by anchor.newer when that row is checked-correct (the two bodies of the composed artifact);
  • a carried body of the origin that neither row authenticated makes the row not-checked, blocked_by:anchor while anchor is not checked-correct, and blocked_by:anchor.newer once it is, whether or not the report has an anchor.newer row;
  • otherwise, with two authenticated bodies of the origin, the proof used is the path of the first carried entry whose fromSize and toSize equal the smaller and the larger of their sizes; the sizes and roots compared are the parsed bodies' own, never the entry's (Anchor §10.8). A path that is missing or null is not an array of hashes. With no such entry the row is not-checked, not_in_bundle:consistency_proof;
  • an origin with fewer than two authenticated bodies and no unauthenticated carried body reports no row.

7.7 An unanchored subject: anchorPending

anchorPending is { "origin": <string>, "leafIndex": <integer>, "since": <date-time> } or null.

  • An exporter that anchors, holding a subject that no final publication covers yet, writes the subject's evidence-log origin, its leafIndex (payload.sequenceNumber − 1), and in since the time the subject's leaf entered its evidence log. It carries no anchoring for that subject (anchoring is {}).
  • The pending state lives only in this slot. It is never written under nonRepudiation (Anchor §8.4).
  • A verifier reports a non-null anchorPending, whatever it holds, as the row anchor.pending, not-checked, not_yet_published. That row never abstains and is never absent, so a bundle that reports it exits 4 unless the auditor allows unchecked rows (Verification §6.6). No check reads the slot's members.

7.8 A subject with no anchoring material

A bundle whose envelope has no artifact, whose anchoring is {} or null, and whose anchorPending is null is what an exporter that does not anchor writes. Its anchor rows report the artifact absent, and absence is not an unchecked artifact (Verification §6.6), so the exit code alone does not show that the subject is anchored. An auditor who needs an anchor requires anchor, or anchor.newer for a subject whose envelope has no artifact yet (Verification §3.2, §6.6).

8. Reserved slots: credentials, relatedRecords, policy

These slots are reserved for sign-off verification material. This version of the specification does not define their content and does not verify it. An exporter of this version writes null in each.

A verifier of this version never treats a filled reserved slot as a pass:

  • a credentials slot that is not null makes signoff.key abstain, unsupported_signoff, unless an earlier rule of that row decides it (Verification §4.5);
  • a relatedRecords or policy slot that is not null is reported as a row with the slot's name as its id, abstain, unsupported_slot.

9. extensions

extensions is null or an object whose keys name extensions. A key whose value is null is an extension that is not present. The key witness/1 is reserved for independent witness attestation, which this version of the specification does not define.

A verifier reports each key with a non-null value that it does not implement as the row extension[<key>], abstain, unsupported_extension, in byte order of the key. The abstention covers that key only; the rest of the bundle is checked as usual. A verifier of this version implements no extension.

10. exporter

exporter is null or an object that describes the export, for example exportedAt (a date-time), exportedBy (a string naming the software) and the exporting store's own verdict on the subject. Exporters MAY add members. A verifier MUST NOT use any of it as an input to any check: a bundle's account of itself proves nothing.

11. The chain profile (reserved)

The profile "chain" is reserved for a bundle that carries a whole range of a log: its records and their leaves, in members that a record bundle does not have. Checks that need a whole leaf range, such as recomputing a log's roots from its leaves (log.recompute) and confirming that every record of the range is exactly one leaf (log.membership), belong to that profile. This version of the specification does not define it, and a verifier of this version abstains on a chain-profile bundle as a whole (§4 step 3).

12. The rows of a record bundle, in report order

Verification §4.1 fixes the order of the rows of a record bundle whose bundle row is checked-correct. This table lists them in that order, with the bundle material each one reads. Their outcomes, reasons and facts are those of Verification §4 and Anchor §10.7.

RowsReadsSection
bundlethe whole document§4
subjectsubject, the envelope§5.1
record.digestenvelope.payload, envelope.integrity§5.2
record.chainLinkenvelope.integrity.chainLink, chain.predecessor§5.3
custody.ledgercustody§6
ts.record.token, ts.record.trustnonRepudiation.rfc3161Token§5.2
signoff.expectation, signoff.keypayload.signoffExpectation, nonRepudiation.signoff, nonRepudiation.webauthnAssertion, nonRepudiation.mandate, nonRepudiation.confirmation, credentials§5.2, §8
decider, decider.freshnesspayload.decider, payload.signoffExpectation, the sign-off material§5.2
contributions, contributions.binding, contributions.pipelinepayload.contributions, and the payload members it is checked against§5.2
links, then links[<i>] and links[<i>].edge by indexpayload.links, payload.aiSystemId, payload.action, payload.contributions, payload.signoffExpectation, and the payload members a relation's record-local rule reads§5.2
mandate.issuance, mandate.scope, mandate.limits, mandate.key, mandate.assertionTimestamppayload.signoffExpectation, payload.schemaVersion, payload.decider, payload.aiSystemId, payload.action, payload.aiOutput, payload.contributions, the payload members that the mandate document's predicates and caps name, nonRepudiation.mandate, nonRepudiation.mandateIssuance, credentials§5.2, §8
anchor, its step rows, then its publication rowsnonRepudiation.anchor, joined with anchoring§7.4
anchor.neweranchoring§7.5
anchor.consistency[<origin>], by originanchoring§7.6
anchor.pendinganchorPending§7.7
extension[<key>], by keyextensions§9
relatedRecords, then policythe reserved slots§8
payload.<name>, by namepayload members that Record §2.2 does not name§5.2
member[<key>], by keyother top-level members§3.3
rows for other material under nonRepudiationthe envelope§5.2

A row whose section says it is reported only in some cases (contributions.pipeline, links[<i>] and links[<i>].edge, the mandate rows, anchor.newer, anchor.consistency[<origin>], anchor.pending, the reserved slots, extensions, other payload members, other members) is left out in the others.

13. The b1 conformance corpus

13.1 Layout

The corpus is the bundle-b1/ directory of the conformance vectors (Vectors). index.json lists every case by name, with its expected exit code and a description of what it pins. Each case is a directory:

FileContent
bundle.jsonThe bundle an exporter wrote, or that bundle altered as the case states
inputs.jsonThe auditor's inputs (§13.2)
expected-report.jsonThe report of Verification §6, without checkedAt
expected-exitThe exit code, as decimal digits followed by a newline

The expected reports are stated from this specification; every value inside them (a digest, an origin, a transaction id, a block time, a token's time) comes from the run that produced the case.

13.2 inputs.json

{
  "publisherManifest": { "publishers": { … } } | null,   // Anchor §9; null: none supplied
  "headerSources": {                                     // keyed by CAIP-2 chain; {} for none
    "eip155:31337": {
      "chainId": 31337,
      "finality": "finalized",                           // the finality it declares (Anchor §10.4)
      "finalizedBlockNumber": 13,
      "blocks": [ { "number": 1, "hash": "0x…", "timestamp": 1790514581 } ]
    }
  },
  "trustAnchorsPem": [ "-----BEGIN CERTIFICATE-----…" ], // RFC 3161 roots; [] for none
  "regime": { "require": [], "requireRung": [], "allowUnchecked": false }
}
  • A header source here is static. It has the stated chain id and finality, reports finalizedBlockNumber as its finalized height, and knows exactly the canonical blocks it lists, each by number, hash and unix time in seconds. It has no block at any height it does not list, and it looks up no transaction, so only a trie proof in the bundle places a transaction in its block.
  • No other input exists for a case: no trust store of the environment, and no chain registry beyond the verifier's own (Anchor §9).
  • regime is the auditor's policy for the exit code: the rows that must be checked-correct, the rungs required, and whether unchecked rows are allowed (Verification §3.2).

13.3 Replaying a case

A verifier replays a case by verifying bundle.json with the inputs of inputs.json, the publisher manifest supplied as the bytes of its canonical form (Record §3). The case holds when the report, without checkedAt and in canonical form, equals expected-report.json, and the exit code equals expected-exit. Specs §6 states what conformance requires across the corpus.