Internet-Draft VTL July 2026
El Khatabi Expires 16 January 2027 [Page]
Workgroup:
Independent Submission
Internet-Draft:
draft-elkhatabi-verifiable-telemetry-ledgers-08
Published:
Intended Status:
Informational
Expires:
Author:
B. El Khatabi
Independent

Verifiable Telemetry Ledgers for Resource-Constrained Environments

Abstract

This document profiles a verifiable-telemetry ledger for resource-constrained deployments. Its interoperability boundary begins with exact canonical-record byte strings that an upstream system has already produced. The profile fixes admission and assignment of those byte strings to serial-numbered segments, deterministic commitment-tree calculation, a Concise Binary Object Representation (CBOR) segment artifact, a verification manifest, three disclosure classes, and binding of the segment-artifact digest to external timestamp channels. Transport framing, decryption, anti-replay processing, payload interpretation, and source-telemetry-to-record mapping are outside this profile. Segment closure uses a deployment-configured elapsed-time interval and does not depend on source or gateway calendar dates. RFC 3161 timestamp responses are the mandatory-to-implement interoperable timestamp channel. OpenTimestamps (OTS) and peer signatures are optional parallel channels.

The profile enables independent recomputation and audit of disclosed evidence from the admitted canonical-record bytes onward. It does not verify how source telemetry was authenticated, interpreted, or mapped to those bytes, and it does not cover device onboarding, end-to-end security of sensor values, or safety decisions.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 16 January 2027.

Table of Contents

1. Introduction

Long-lived telemetry deployments need evidence that record bytes disclosed later are the same bytes a ledger producer committed when they were admitted, even when upstream delivery is intermittent and verification happens later.

Two trust questions must be distinguished. The first is whether a source was genuine, authorized, and mapped correctly. The second is whether, after exact record bytes were selected for commitment, a later verifier can determine that those bytes, the ledger artifact, and external evidence still agree. This profile standardizes the second question.

This memo is an Independent Submission. It is not an Internet Standard and has not been evaluated as having IETF community consensus.

The profile begins at an explicit byte-level handoff. An upstream admission system constructs one deterministic-CBOR canonical-record byte string and presents it to the ledger producer. Source eligibility, transport security, anti-replay processing, payload interpretation, and source-to-record mapping occur before that handoff and are outside this profile. The interoperability contract begins with the exact byte string presented for admission.

Protocol at a Glance

The following informative summary provides a reading path through the normative requirements that follow:

  1. Admission. The ledger producer validates the byte-level profile and admits the unchanged canonical-record bytes into the logical interval open at the admission linearization point. Each admission is one record occurrence, including when two admitted occurrences have identical bytes.
  2. Commitment. The producer computes each leaf as SHA-256(0x00 || record), sorts the leaf hashes, and calculates segment_root over the complete sorted list using the domain-separated tree construction in Section 4.3. It partitions the same list deterministically into the batch objects embedded in the segment artifact. Batch roots describe their respective batches; they are not combined to calculate segment_root.
  3. Sealing. The producer encodes the authoritative segment artifact using deterministic CBOR. The artifact carries the commitment profile identifier, ledger and segment identity, closure claim, predecessor-artifact digest, batch objects, and segment root.
  4. External evidence. The producer computes SHA-256 over the exact segment-artifact bytes and submits that digest to at least one timestamping channel. Producers and verifiers implement [RFC3161]; a deployment can use OTS instead for a particular segment. Peer signatures are optional attestations over the same digest and do not by themselves satisfy the timestamping requirement.
  5. Verification. A verifier starts from the authoritative segment artifact and performs the checks supported by the disclosed bundle. Class A supports public record-level recomputation. Class B supports controlled audit when some record material is withheld. Class C is anchor-only and does not support record-level or batch recomputation. The verifier reports executed and skipped checks and validates chain adjacency only when the predecessor artifact is disclosed.
Table 1: Principal Object Authority
Object Status Principal role
Canonical-record bytes Authoritative admitted input Exact leaf preimage after admission
Segment CBOR Authoritative segment artifact Hashed, chained, and externally timestamped
Manifest Producer claim; non-authoritative Indexes the bundle and claims disclosure class
Verifier result Verifier-authored scoped output Reports scope, checks, channels, and outcome

Segment intervals are ledger batching rules, not source-reporting periods or civil-time claims. The producer assigns each admitted record to the logical interval open at its admission linearization point and uses a non-decreasing elapsed-time source for interval closure. Source arrival time, upstream processing time, ingest_time, device_time, and UTC do not select segment membership. Segment identity is (ledger_id, segment_number), and a sealed segment is not reopened. Section 4.4 specifies boundary ordering, empty intervals, size-triggered closure, policy changes, and recovery behavior.


Source telemetry
      |
      v
+----------------------------+       OUTSIDE THIS PROFILE
| Upstream admission system  |
| auth / replay / projection |
+----------------------------+
      | exact canonical-record bytes
======|================================================ boundary
      v
+----------------------------+ --> segment CBOR ------> Verifier
| Ledger producer            |
| admit / assign / commit    | --> artifact digest
| seal / chain               |          |
+----------------------------+          +--> timestamp: RFC 3161 / OTS
                                        +--> attestation: peers (optional)
Figure 1: Evidence Path and Interoperability Boundary

Successful verification establishes consistency within the scope reported by the verifier. When the necessary material is disclosed, it can show that exact record bytes produce the claimed commitments, that the authoritative artifact produces the digest bound by the disclosed external evidence, and that disclosed predecessor artifacts form the claimed chain adjacency. It does not establish source authenticity, correct source-to-record mapping, dataset completeness, physical truth, or the absence of selective drops before admission.

1.1. Scope Boundary

This profile covers the ledger evidence path beginning with admission of an already-formed canonical-record byte string:

  • byte-preserving record validation, admission, and segment assignment;
  • deterministic hashing, batching, and chaining into authoritative segment artifacts;
  • binding the segment-artifact digest to external timestamping or attestation evidence;
  • verifier-facing manifests, disclosure, and export behavior; and
  • scoped independent verification and reporting.

It does not specify source transport or framing, authentication, decryption or other transport security, anti-replay processing, manufacturer identity, onboarding, fleet inventory, PKI policy, network admission, source buffering, identifier or message-type mapping, payload schemas, source-to-record projection, or firmware orchestration. Those functions can be colocated with the ledger producer, but they remain outside the interoperability claim made by this document.

1.2. Ledger Producer Trust Boundary

The ledger producer is trusted to validate and admit each accepted byte string, assign it to one segment, preserve its exact octets, maintain durable segment state, and construct the specified artifacts. An upstream system that constructs the record bytes is separately trusted for their source semantics but is outside this profile.

This profile makes post-admission inconsistency detectable. It does not prove that upstream admission was correct, reveal a source event that was never admitted, establish ingestion completeness, validate a source-to-record mapping, or show that a committed measurement was physically true.

1.3. Document Roadmap

Section 2 defines the common terminology, and Section 3 identifies the system roles. Producer implementers should focus on Sections 4 through 6, Section 9, and Section 10. Verifier implementers should focus on Sections 4 through 7, Section 9, and Appendices A through D. Operators should additionally read Sections 10 through 12 and Section 14. Commitment-profile, versioning, and registry designers should read Sections 8, 13, and 15.

2. Conventions and Terminology

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

Terms:

3. System Roles

In this document, optional parallel attestation channels are not required for baseline conformance. A conforming deployment MUST use at least one timestamping channel and MUST implement the [RFC3161] channel. OTS ([OTS]) and peer signatures are optional; when present, they MUST bind to the same authoritative segment-artifact digest and verifiers MUST report their results separately.

4. Data and Commitment Model

The normative input to this section is an exact canonical-record byte string that has already been produced by an upstream admission system. The interoperable core begins at that byte-level handoff and covers record admission, segment assignment, deterministic hashing and tree calculation, segment artifacts, disclosure, and verification. No source transport, decryption, anti-replay, payload interpretation, or source-to-record projection is defined by this document.

4.1. Canonical-Record Input Boundary

The protocol input defined by this document is one exact canonical-record byte string. The byte string MUST encode exactly one CBOR data item using the record shape below and the deterministic encoding constraints in Section 4.2. A ledger producer MUST reject a proposed input that does not satisfy those byte-level constraints.

Once admitted, the exact supplied octets are authoritative. The ledger producer MUST use those octets, without modification, as the leaf preimage under Section 4.3. It MUST NOT decode and re-encode, normalize, enrich, remove, reorder, or otherwise substitute a different byte string for commitment. Each admission event contributes one record occurrence, including when two admitted occurrences have identical byte strings.

Source transport, framing, authentication, decryption, anti-replay processing, duplicate-submission policy, device-identifier mapping, message-type mapping, payload interpretation, and construction of the canonical-record byte string are upstream of this boundary and are not specified or verified here. A physical gateway MAY perform those functions and ledger production in one implementation, but its interoperability claim under this document begins only with the exact byte string passed across this logical boundary.

For verifiable-telemetry-canonical-cbor-v2, each canonical-record byte string encodes the following fixed seven-element CBOR array:

canonical-record-v1 = [
  version: 1,
  device_id: bstr .size 8,
  fc: uint,
  ingest_time: uint,
  device_time: uint / nil,
  kind: uint,
  payload: any
]

The positional labels are conventional names for inspecting disclosed records; they do not move source-to-record mapping into this profile. Their byte-level requirements are:

  • version is the unsigned integer 1.
  • device_id is an opaque 8-octet identifier assigned upstream. This document defines no mapping from a transport or deployment alias to this value.
  • fc is an unsigned upstream-supplied sequence value. This document defines no replay or duplicate-suppression semantics for it.
  • ingest_time is an unsigned count of whole non-leap seconds since 1970-01-01T00:00:00Z. Its assignment and accuracy are upstream responsibilities, and it MUST NOT select segment membership.
  • device_time is an unsigned application timestamp or null. Its epoch and unit are upstream semantics, and it MUST NOT select segment membership.
  • kind is an unsigned application discriminator. This document defines no message-type or payload-family mapping for it.
  • payload is one CBOR data item permitted by Section 4.2. Its schema and meaning are outside this profile.

A different record array shape or different byte-level field type is a different commitment profile and requires a distinct commitment_profile_id. Application schemas MAY separately define the meanings of device_id, fc, device_time, kind, and payload, but successful verification under this document does not validate those external semantics.

Class A recomputation starts with the disclosed canonical-record byte strings. It demonstrates that those exact bytes produce the disclosed leaf digests, roots, and authoritative segment artifact. It does not reconstruct the bytes from source telemetry. Conformance vectors for this profile therefore MUST begin with exact canonical-record byte strings; transport messages and upstream projection fixtures, if supplied, are informative and are not inputs to baseline conformance.

4.2. Deterministic Concise Binary Object Representation (CBOR) Commitment Encoding

This section does not define a new general-purpose CBOR variant. It records the narrow deterministic CBOR encoding used for commitment bytes by this profile. The identifier verifiable-telemetry-canonical-cbor-v2 names this commitment recipe so verifiers can tell which byte-level rules were used; see Section 13.3 for allocation policy.

The authoritative commitment artifacts, namely CBOR canonical-record artifacts and the canonical segment artifact, use a constrained subset of the length-first core deterministic encoding requirements in Section 4.2.3 of [RFC8949]. For commitment bytes in this profile, the following concrete choices apply:

  • All commitment-path items MUST use definite-length encoding.
  • Integers MUST use the shortest encoding width permitted by [RFC8949].
  • Map keys MUST be CBOR text strings.
  • Map keys MUST be sorted by encoded key length ascending, then by lexicographic order of the encoded key bytes.
  • Duplicate map keys and invalid UTF-8 text strings MUST be rejected.
  • Finite floating-point values MUST be encoded using the shortest of float16, float32, or float64 that exactly preserves the value.
  • NaN, positive infinity, and negative infinity MUST be rejected in commitment paths.
  • CBOR tags MUST NOT appear in commitment bytes.
  • Supported values are unsigned integers, negative integers, byte strings, text strings, arrays, maps, booleans, null, and deterministic finite floats.

Implementations MUST NOT accept generic CBOR serializers as authoritative commitment encoders. An encoder is acceptable only if it yields the same bytes as these rules.

JSON projections of canonical-record artifacts and segment artifacts are optional and non-authoritative. They MUST NOT be used as commitment inputs. When produced, such projections SHOULD follow [RFC8785].

Upstream systems MAY use any transport or internal encoding. Only the exact canonical-record byte string admitted at Section 4.1 is an authoritative record commitment input. A different record encoding is not this profile unless it is identified by a distinct commitment_profile_id and verified under its own rules.

4.3. Deterministic Commitment Tree Calculation

For a given segment S, the current commitment profile computes segment_root from canonical-record bytes using the domain-separated tree shape of Section 2.1.1 of [RFC9162], specialized to SHA-256 and to the multiset ordering below. SHA-256 is defined by [RFC6234].

For each exact canonical-record byte string record, compute leaf_hash = SHA-256(0x00 || record). Sort the resulting raw 32-octet leaf hashes in ascending byte order. Lowercase hexadecimal is only their artifact representation; sorting those fixed-width lowercase strings is equivalent to sorting the raw bytes.

Let MTH(L) operate on the sorted list of already-computed leaf hashes. MTH({}) = SHA-256("") and MTH({x}) = x. For a list of n > 1 hashes, let k be the largest power of two strictly less than n, and compute MTH(L) = SHA-256(0x01 || MTH(L[0:k]) || MTH(L[k:n])). Implementations MUST NOT duplicate an unpaired final hash. The prefixes 0x00 and 0x01 provide leaf/parent domain separation, and the recursive split gives every leaf count a unique tree shape.

For an emitted empty segment, batches MUST be an empty array and segment_root MUST equal MTH({}), the SHA-256 digest of zero bytes: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855. Its closure_policy.empty_mode MUST be emit; an empty artifact under suppress mode is invalid. For a non-empty segment, batches MUST contain at least one non-empty batch. The resulting segment_root is deterministic for the multiset of committed canonical records. Because leaf digests are sorted before reduction, the root does not commit to admission order. Admission order selects segment membership at the boundary but is not itself a verifier-visible total-order claim.

Any future change to this calculation that alters commitment bytes MUST use a new commitment_profile_id.

4.4. Segment Formation and Closure

Normal Interval Timing and Admission

Segment formation uses a gateway elapsed-time source that MUST be non-decreasing and MUST progress during normal operation while an interval is open. Its resolution MUST be no greater than the configured interval_ms. The configured interval_ms is a fixed elapsed duration. It is not a civil- time duration and MUST NOT be aligned by local midnight, UTC midnight, time zone, daylight-saving transition, or leap second. The first logical interval of an epoch opens when the ledger is activated. Each normal or early closure immediately opens the next logical interval. Logical intervals continue across idle periods in both empty modes; suppress changes artifact emission and serial consumption, not the elapsed-time schedule.

The gateway MUST serialize the interval-boundary transition with the admission linearization point. For an interval whose elapsed-time deadline is T:

  • A record whose acceptance linearizes before T belongs to the current logical interval.
  • At T or later, the gateway MUST process the boundary before another acceptance can linearize.
  • Upstream processing can begin before T, but if canonical-record admission linearizes at or after T, the record belongs to the next logical interval.
  • Source arrival time, upstream validation or record-construction time, device_time, and ingest_time MUST NOT override this assignment.

The gateway MUST determine deadline expiry by checked elapsed-time subtraction; it MUST NOT add interval_ms to an absolute counter in a way that can wrap. If elapsed time cannot be represented or compared safely, the gateway MUST enter the recovery procedure below before accepting another record.

Policy Changes and Early Closure

The gateway snapshots closure_policy when a logical interval opens. That snapshot MUST remain unchanged through closure. A normal configuration update becomes effective for the next logical interval. An immediate update MUST first close the current logical interval under the old snapshot. It emits an artifact with close_reason equal to reconfigure unless the interval is empty under suppress mode, in which case it emits no artifact and consumes no segment number.

Early closure is permitted only for a condition represented by the committed close_reason. A gateway MUST NOT place a record whose acceptance linearizes after the interval deadline into the expired interval merely because closure processing was late. Late closure is an operational fault and SHOULD generate an alarm.

Limits and Close-Reason Selection

closure_policy.record_limit, when non-null, is the maximum number of admitted records in one logical interval. The interval closes immediately after the acceptance that makes the record count equal to record_limit.

closure_policy.size_limit_bytes, when non-null, is a close threshold for the sum of the lengths of the exact admitted canonical-record byte strings. After an acceptance has linearized, if the resulting byte total is greater than or equal to size_limit_bytes, the producer MUST close that logical interval before another acceptance can linearize. The triggering record remains assigned to the interval because segment assignment is final at the admission linearization point. Consequently, size_limit_bytes is not a hard pre-admission maximum and an emitted segment can exceed the threshold by the contribution of its final admitted record. If a single record admitted to an empty interval exceeds size_limit_bytes, that record forms a one-record interval, which MUST close before another acceptance can linearize. Threshold comparisons and byte-count updates MUST use checked arithmetic; the producer MUST enter recovery or stop acceptance before acknowledging a record if the new total cannot be represented safely.

If multiple close conditions are simultaneously true, the committed close_reason MUST be selected by this precedence, from highest to lowest: recovery, shutdown, reconfigure, size_limit, record_limit, interval, then manual. The selected reason does not change which acceptances already linearized into the interval.

Empty Intervals and Timer Continuity

While elapsed-timer continuity is maintained, in emit mode every logical interval produces an artifact; an empty interval uses the empty construction in Section 4.3. In suppress mode, an empty logical interval produces no artifact and consumes no segment number. The next emitted artifact uses the next contiguous number. A suppressed interval makes no completeness or non-observation claim.

Suspend time counts toward interval_ms when the selected elapsed-time source advances across suspend. If it does not, or if its continuity is uncertain, the gateway MUST apply the recovery procedure before accepting another record.

Recovery and Durable State

After restart or failover, the gateway MUST recover the active ledger_id, next segment number, policy snapshot, and any open interval state before accepting more telemetry. If elapsed-time or open-interval state is uncertain, the gateway MUST NOT infer the boundary from a possibly regressed wall clock. It MUST either stop acceptance or seal recoverable material with close_reason equal to recovery before accepting into a new interval. It MUST NOT synthesize historical empty artifacts and represent them as having been sealed at missed deadlines.

The admission linearization point is a durable transaction boundary. Before acknowledging acceptance, the producer MUST make the exact canonical-record octets, their membership in the open interval, the interval record count and byte count, and the corresponding recovery state atomically durable or recoverable. After a crash, an acceptance MUST be recovered exactly once in the same logical interval, or it MUST be treated as never having completed. Segment sealing MUST atomically persist the authoritative artifact, its digest, the next serial allocation, and the new open-interval state before admission resumes.

Deterministic Batch Partitioning

For a non-empty interval, compute the complete sorted leaf-hash list defined in Section 4.3. Partition that list into consecutive batches of at most closure_policy.batch_record_limit hashes. Batch zero contains the first hashes, batch one the next hashes, and so on; only the last batch can contain fewer than the limit. This rule is the sole baseline batch partitioning rule and is independent of storage flushes, worker scheduling, or input-file layout.

4.5. Segment Artifact Schema

The authoritative segment artifact is a deterministic CBOR-encoded segment record produced under Section 4.2. It is the stable segment-scoped object of commitment verification. It commits to one record multiset, its ledger identity, serial number, closure policy and reason, and predecessor artifact. It is not a transport envelope, publication statement, or complete verification claim.

A segment artifact is interpreted only under its in-band commitment_profile_id. Because that identifier is inside the authoritative bytes, every proof over the segment-artifact digest binds the commitment semantics. A verifier-facing manifest MUST repeat the same value and verifiers MUST reject a mismatch. Verifiers MUST NOT infer the commitment profile from the file name, media type, segment-record version, or proof sidecar alone.

The segment record contains exactly these fields:

  • version (uint): segment-record schema version, exactly 2.
  • commitment_profile_id (tstr): exactly verifiable-telemetry-canonical-cbor-v2.
  • ledger_id (tstr): stable ledger identifier consisting of exactly 32 lowercase hexadecimal characters.
  • site_id (tstr): non-empty site identifier.
  • segment_number (uint): serial number in the range 0..(2^64-1).
  • closure_policy (map): immutable policy snapshot for this logical interval, containing exactly version equal to 1; positive uint64 interval_ms and batch_record_limit; record_limit and size_limit_bytes, each a positive uint64 or null; and empty_mode equal to emit or suppress.
  • close_reason (tstr): exactly one of interval, reconfigure, record_limit, size_limit, shutdown, recovery, or manual.
  • prev_segment_sha256 (tstr): SHA-256 digest of the exact previous authoritative segment-artifact bytes, as 64 lowercase hexadecimal characters, or the epoch predecessor value defined in Section 4.6.
  • batches (array): authoritative batch objects sorted by batch_number; exactly empty for an empty emitted segment.
  • segment_root (tstr): deterministic segment root as 64 lowercase hexadecimal characters.

Each batch object contains exactly these fields:

  • version (uint): batch-record schema version, exactly 2.
  • ledger_id (tstr): the containing segment's ledger_id.
  • site_id (tstr): the containing segment's site_id.
  • segment_number (uint): the containing segment's segment_number.
  • batch_number (uint): batch serial in the range 0..(2^64-1), unique within the segment.
  • merkle_root (tstr): batch Merkle root as 64 lowercase hexadecimal characters.
  • count (uint): positive number of committed canonical records in the batch.
  • leaf_hashes (non-empty array of tstr): leaf hashes sorted as lowercase hexadecimal strings.

The batch objects embedded in the segment artifact are authoritative batch metadata. For a non-empty segment, batch objects MUST be sorted by ascending batch_number, and batch numbers MUST be unique and contiguous starting at zero. Their leaf lists MUST be the consecutive partitions of the complete sorted segment leaf list required by Section 4.4.

  • For each batch, ledger_id, site_id, and segment_number MUST equal the containing segment fields.
  • For each batch, count MUST equal the length of leaf_hashes and MUST be greater than zero.
  • For each batch, merkle_root MUST equal the Merkle reduction of that batch's leaf_hashes under Section 4.3.
  • The multiset union of all batch leaf_hashes MUST equal the segment leaf-digest multiset from which segment_root is computed.

segments/<segment-number>.cbor is authoritative. The corresponding segments/<segment-number>.json file is a projection only. The path label is the 20-digit, zero-padded decimal rendering of the unsigned serial number; it is not a protocol field. A verifier MUST compare the decoded segment_number with the manifest claim rather than trusting the file name.

4.6. Segment Chaining

Segment identity and chaining are defined within one stable ledger_id. They do not depend on UTC dates or elapsed idle time.

  • The epoch segment MUST have segment_number equal to 0 and prev_segment_sha256 equal to 64 zero characters, representing 32 zero bytes.
  • Every non-epoch segment MUST have a serial number exactly one greater than its predecessor, MUST retain the same ledger_id and site_id, and MUST set prev_segment_sha256 to SHA-256 over the predecessor's exact authoritative CBOR bytes.
  • A producer MUST NOT reuse, skip, or wrap segment_number. Before serial exhaustion, it MUST stop the ledger and start a new ledger with a new ledger_id.
  • A closure-policy change MUST take effect only in a newly opened logical interval. It does not reset segment_number or ledger_id.

When a new epoch begins, the producer MUST generate ledger_id from a cryptographically strong random source. If durable sequence state cannot be recovered unambiguously, a producer MUST stop acceptance or begin a new ledger with a fresh identifier; it MUST NOT reset the serial under the old identifier. Redundant gateways MUST use single- writer fencing or an atomic shared allocator so that they cannot emit different artifacts for the same (ledger_id, segment_number).

A verifier given adjacent segment artifacts MUST validate serial continuity and predecessor-digest linkage. A partial disclosure that omits the predecessor can still support validation of the disclosed artifact and its external proof, but the verifier MUST report segment chain validation as skipped because the predecessor is unavailable.

5. Artifacts and Verification Bundles

Illustrative artifact layout:

Each disclosed records/<record-id>.cbor file contains the exact canonical-record octets admitted at the boundary in Section 4.1. A storage or bundle layer MUST NOT add a wrapper to those file octets or replace them with a re-encoding. File names are non-authoritative and are not leaf inputs.

Deployments MAY store artifacts differently and MAY export them as bundles. The path shapes above are illustrative. In those shapes, <segment-number> and <batch-number> are 20-digit, zero-padded decimal renderings of their uint64 values.

Standalone batch metadata files are convenience projections of batch objects already carried in the authoritative segment artifact. They are not additional commitment inputs. Verifiers that process disclosed standalone batch-metadata projections MUST compare them with the corresponding batch object in the authoritative segment artifact and reject mismatches.

Every verification bundle that claims a disclosure class under this document MUST disclose the authoritative segment artifact and the producer-supplied manifest segments/<segment-number>.verify.json. The artifact's in-band commitment_profile_id is the cryptographically bound profile identifier. The manifest repeats the ledger identity, segment number, commitment profile, claimed disclosure class, artifact digests, and claimed channel state. It MUST NOT contain checks_executed, checks_skipped, or an overall verification outcome.

Each entry in artifacts.records represents one admitted record occurrence. Duplicate entries are permitted and MUST be counted separately. When two or more occurrences have identical canonical- record bytes, their entries MAY reference the same disclosed artifact; a Class A verifier MUST hash its exact octets once for each listed occurrence. Artifact-reference order does not assert admission order.

A verifier MAY emit a separate segments/<segment-number>.result.json. Only that verifier-produced result states the checks actually executed or skipped, the per-channel validation status, policy, and overall outcome. A producer manifest and a verifier result MUST NOT be represented as the same object.

Verifier-facing manifests MUST be portable. Artifact paths in the manifest are UTF-8 strings interpreted relative to the disclosed evidence bundle root, using / as the only separator. A path MUST be non-empty; MUST NOT begin with /, \, or a drive-letter prefix; MUST NOT contain \, a colon, a control character in the ranges U+0000 through U+001F or U+007F, an empty path component, or a component equal to . or ..; and after resolution MUST remain below the bundle root. Verifiers MUST reject a symbolic link, reparse point, or equivalent filesystem indirection, or MUST use a containment-enforcing open operation that prevents such indirection from changing the target between validation and access. Path validation and file opening MUST be one race-resistant operation; a check-then-open sequence that permits target substitution is non-conformant. These checks are semantic requirements and do not depend on a regular-expression dialect. Every artifact listed in the manifest MUST carry a lowercase hexadecimal SHA-256 digest entry.

The verifier-facing metadata binds claim semantics to the stable segment artifact. A bundle that discloses segments/<segment-number>.cbor and a timestamp proof can obtain the applicable commitment_profile_id from the artifact itself. If a manifest is also disclosed, its repeated identifier MUST match the in-band value.

The verification manifest is the primary disclosure surface for verifier-visible producer claims. Its schema is defined in Appendix C. Deployment-specific data can be carried only in the explicit operational-summary or extension containers and MUST preserve the semantics defined here.

At minimum, an OTS sidecar MUST bind:

Verifiers MUST recompute the segment artifact digest and compare it with the sidecar before accepting any proof validation result.

6. Anchoring and Verification

6.1. Anchoring Contract

The generic anchoring contract is simple: a gateway computes the SHA-256 digest of the authoritative segment artifact and submits that digest to one or more external timestamping channels. Verifiers MUST first recompute the segment artifact digest locally; proof validation occurs only after digest binding validation succeeds.

A timestamp or attestation over the segment-artifact digest binds the complete artifact bytes, including the in-band commitment_profile_id. It does not bind a disclosure class, producer manifest, verifier policy, or checks exercised unless the timestamped object separately includes those items.

A deployment conforming to this profile MUST use at least one timestamping channel for each emitted segment. Conforming producers and verifiers MUST implement the [RFC3161] channel defined below. Implementation support is mandatory, but a deployment MAY use OTS ([OTS]) instead of RFC 3161 for a particular emitted segment. Peer signatures are optional attestations and do not by themselves satisfy the timestamping-channel requirement. OTS and peer signatures are not baseline interoperable timestamp profiles.

time ------------------------------------------------------------>

Upstream |--record bytes-->|      |--record bytes-->|              |
Ledger   | admit exact bytes      | admit exact bytes              |
         |----- segment N open for configured elapsed interval ----|
         |          write segments/SEGMENT-N.cbor                  |
         |---------- submit digest to OTS / RFC 3161 ------------->|
Channel  |                pending / delayed proof        | upgrade |
Verifier |                                      verify later from  |
         |<---------------- disclosed bundle --------------------->|
Figure 2: Illustrative Commitment and Proof Lifecycle

Figure 2 illustrates the current lifecycle. The upstream path can be intermittent, although it lies outside this profile. Proof completion or later publication can lag behind the authoritative segment-artifact write.

6.2. RFC 3161 Interoperable Timestamp Channel

Conforming producers and verifiers MUST implement this channel. As specified in Section 6.1, a deployment is not required to use it for every segment.

When this channel is used, the producer MUST set TimeStampReq.messageImprint.hashAlgorithm to SHA-256 and its hashedMessage to the exact 32-octet result of SHA-256 over the authoritative segment-artifact bytes. The producer MUST NOT hash that 32-octet result again.

A deployment using this channel MUST define the accepted TSA trust anchors and any required TSA policy OIDs or other validation constraints.

A verifier evaluating disclosed RFC 3161 evidence MUST recompute the segment-artifact digest and validate the TimeStampResp and time-stamp token under [RFC3161]. Validation MUST include response status, confirmation that TSTInfo.messageImprint uses SHA-256 and contains the recomputed digest, the token signature, and the TSA signer certificate and certification path under the configured trust anchors and policy constraints. Successful validation MUST be reported as tsa_verification.

6.3. Optional OTS Channel

When [OTS] is used, the gateway stamps SHA-256(segments/<segment-number>.cbor) and stores an OTS proof plus an OTS sidecar.

OpenTimestamps is referenced here as a deployed public timestamping ecosystem rather than an IETF-standardized proof format. Implementations claiming OTS support depend on the interoperable behavior of the public OTS project, its calendar servers, and compatible client tooling. OTS proof-format interoperability is therefore defined operationally by that ecosystem and its reference implementations. A verifier reports this deployment-specific check using an extension identifier beginning with x-, for example x-ots-verification; it MUST NOT report tsa_verification for an OTS proof.

6.3.1. OTS Anchoring Lifecycle

  1. Submission: the gateway submits the segment artifact digest to one or more OTS calendars.
  2. Pending: a calendar can return an incomplete proof while awaiting Bitcoin commitment.
  3. Upgrade: the gateway or a background process can later upgrade the proof to include completed attestations.
  4. Verification: a verifier recomputes the artifact digest and validates the proof.

Calendar selection and multi-calendar availability guidance are described in Section 10.4.

6.3.2. Handling Delayed or Failed Anchoring

If OTS submission fails, times out, or yields only an incomplete proof, the gateway MUST still write the authoritative segment artifact and MUST treat OTS as a separate channel whose state is not yet complete. Any later replacement or upgrade of the OTS proof MUST continue to bind to the same authoritative segment-artifact digest. Operator handling and verifier reporting for pending or absent proofs are described in Section 10.3, Section 10.4, and Section 10.5.

6.3.3. Proof Status Vocabulary

Verifier results SHOULD use the following status vocabulary for timestamp and optional parallel attestation channels:

  • verified: proof validation succeeded for the disclosed artifact binding.
  • pending: a proof exists but is incomplete or awaiting upgrade; this is not equivalent to invalid.
  • missing: the expected proof or channel artifact is absent.
  • failed: validation was attempted and did not succeed.
  • skipped: validation was not attempted because of disclosure class, verifier configuration, or local policy.

Whether missing, pending, or skipped is verifier-fatal depends on the disclosure class, local verifier policy, and whether the relevant channel is required.

6.4. Optional Parallel Attestation

Deployments MAY also produce:

  • An OTS proof over the same segment-artifact digest.
  • A deployment-specific peer signature quorum over the same segment-artifact digest.

This document does not define an interoperable peer-signature validation profile. Peer-signature validation MUST be reported under an extension identifier beginning with x-, for example x-peer-quorum-verification. A future specification can register interoperable peer-signature semantics.

When multiple channels are present, verifiers SHOULD validate all available channels independently and report per-channel results.

If a verifier is configured in strict mode for optional channels, failure of those channels MUST cause overall verification failure.

6.5. Verification

Verifiers MUST first decode the authoritative segment artifact and determine the applicable commitment_profile_id from its in-band field. The verifier MUST reject an absent or unsupported value. When a verifier-facing manifest is disclosed, its repeated value MUST exactly match the artifact field.

The verifier MUST treat commitment_profile_id as the semantic key for interpreting the authoritative segment artifact. A structurally well-formed segment artifact and a valid timestamp proof are insufficient for semantic verification if the applicable commitment_profile_id is absent or unsupported. A manifest mismatch is a verification failure even when the artifact and timestamp are otherwise valid.

Verifiers MUST determine the applicable verification scope from the disclosed artifacts, the claimed disclosure class, and local verifier policy. Reported outcomes MUST NOT claim checks or assurances outside that scope.

Producer manifests do not report executed or skipped checks. A verifier produces those lists only in its separate result after validating the disclosed artifacts.

Verifiers SHOULD apply checks in the following fail-fast order, subject to the claimed disclosure class:

  1. Validate that disclosed artifacts are sufficient for the claimed disclosure class, and report bundle_disclosure_validation.
  2. Validate the authoritative segment artifact and, when disclosed or consumed, the verifier-facing manifest, and report segment_artifact_validation and verification_manifest_validation as applicable.
  3. For an epoch segment, validate serial zero and the zero predecessor value. For a non-epoch segment whose predecessor is disclosed, validate ledger and site identity, contiguous serials, and prev_segment_sha256. Report segment_chain_validation as executed or, when the predecessor is unavailable, as skipped with reason predecessor_not_disclosed.
  4. For Class A bundles, validate each disclosed canonical-record CBOR artifact, hash its exact disclosed octets without re-encoding, validate the batch metadata contract, and recompute segment_root. Compare the recomputed result to the authoritative segment_root, and report record_level_recompute and batch_metadata_validation. Do not attempt to reconstruct a record from source telemetry.
  5. For Class B bundles, validate the authoritative segment artifact and any disclosed batch metadata. If withheld material prevents public recomputation, report record_level_recompute in checks_skipped. Deployment-specific withheld-material checks MAY be reported only through extension names beginning with x-.
  6. For Class C bundles, report record_level_recompute and batch_metadata_validation in checks_skipped as out of scope, and treat the result as anchor-only evidence.
  7. Recompute SHA-256(segments/<segment-number>.cbor) and compare it with every applicable disclosed binding value: the manifest's artifacts.segment_cbor.sha256 value, an RFC 3161 messageImprint.hashedMessage, an OTS sidecar artifact_sha256, or deployment-specific peer-attestation binding metadata. A mismatch in any consumed binding is a verification failure. Report segment_digest_binding. If no binding value is disclosed, report the check as skipped with reason missing_binding_metadata; the bundle is then insufficient for any disclosure class defined here.
  8. Validate an [RFC3161] timestamp response when present or required by verifier policy, and report tsa_verification.
  9. Validate OTS proofs or peer attestations as configured and report them only through distinct x- extension check identifiers.

When batch metadata is within the exercised verification scope, verifiers MUST apply the following checks before accepting a result:

  • each batch count equals the length of its leaf_hashes;
  • each batch repeats the containing ledger_id, site_id, and segment_number exactly;
  • batch numbers are unique, contiguous from zero, and ordered numerically;
  • batch leaf lists are the consecutive partitions of the sorted segment leaf list under the committed batch_record_limit;
  • each batch merkle_root equals the Merkle reduction of its leaf_hashes;
  • the union multiset of batch leaf_hashes equals the leaf digest multiset derived from disclosed canonical records when canonical-record artifacts are available; and
  • any standalone batch-metadata projection matches the corresponding batch object in the authoritative segment artifact.

Verifier implementations SHOULD expose machine-usable failure categories:

  • malformed or missing artifacts,
  • missing or unsupported commitment_profile_id,
  • Merkle mismatch,
  • batch metadata mismatch,
  • segment serial, ledger identity, site identity, or predecessor-digest mismatch,
  • missing or invalid required timestamp proof,
  • sidecar mismatch or digest mismatch,
  • insufficient disclosure for the claimed verification level, and
  • optional-channel failure.

Verifier output SHOULD state the claimed disclosure class, the verification scope actually exercised, the per-channel proof status, which checks were executed, which checks were skipped, and whether the resulting claim is public recompute, partial verification, or anchor-only evidence.

Standardized Check Identifiers

When verifier results report checks_executed or checks_skipped, this profile defines the following interoperable check identifiers:

  • bundle_disclosure_validation: disclosure-class sufficiency was validated.
  • verification_manifest_validation: the verifier-facing manifest was validated.
  • segment_artifact_validation: the authoritative segment artifact was validated structurally and semantically under the claimed profile.
  • segment_chain_validation: epoch-segment state or adjacent segment serial, identity, and predecessor-artifact digest linkage were validated.
  • record_level_recompute: record-level recomputation from disclosed canonical-record artifacts was performed.
  • batch_metadata_validation: authoritative or disclosed batch metadata was validated against the segment artifact and disclosed record material within scope.
  • segment_digest_binding: the recomputed SHA-256(segments/<segment-number>.cbor) digest was compared with disclosed binding metadata.
  • tsa_verification: the [RFC3161] timestamp channel was validated.

A verifier result that reports one of these standardized checks MUST use the exact identifier listed here. For any standardized check whose applicability conditions are met within the exercised verification scope, the verifier result MUST report that check exactly once in either checks_executed or checks_skipped. The same standardized identifier MUST NOT appear in both lists and MUST NOT appear more than once. Silent omission of an applicable standardized check is non-conformant.

Applicability is determined as follows:

  • bundle_disclosure_validation and segment_artifact_validation apply whenever verification proceeds on a disclosed bundle.
  • verification_manifest_validation applies when a verifier-facing manifest is disclosed or consumed to obtain verifier-visible metadata.
  • segment_chain_validation applies to every disclosed segment. For an epoch segment it validates the zero predecessor and serial zero. For a non-epoch segment, it MUST be executed when the predecessor is disclosed and otherwise MUST be reported as skipped.
  • For Class A bundles, record_level_recompute, batch_metadata_validation, and segment_digest_binding apply. If required artifacts for one of these checks are absent, that check MUST appear in checks_skipped with a reason indicating insufficient disclosure or missing artifacts.
  • For Class B bundles, batch_metadata_validation and segment_digest_binding apply when the corresponding artifacts are disclosed. If withheld material prevents public recomputation, record_level_recompute MUST appear in checks_skipped.
  • For Class C bundles, record_level_recompute and batch_metadata_validation MUST appear in checks_skipped as out of scope, while segment_digest_binding applies when the segment artifact and binding metadata are disclosed.
  • tsa_verification applies when the RFC 3161 channel is disclosed or required by verifier policy. Other channels use x- extension identifiers.

Additional deployment-specific checks MAY be reported, but they MUST NOT redefine these identifiers and MUST use a distinct extension name beginning with x-.

Verifier output MUST NOT be represented as proving more than the exercised verification scope. In particular, a successful result does not by itself establish dataset completeness, physical truth of measurements, or suitability for autonomous actuation or sanctions.

7. Disclosure Classes

Verification claims depend on what artifacts are disclosed. This profile defines three disclosure classes.

Disclosure classes are verifier behavior, not prose intent. A verifier MUST decide each class from the artifacts it can recompute, the artifacts it cannot recompute, and the checks it reports as executed or skipped. A verifier claim for any disclosure class MUST be limited to the verification scope supported by the disclosed artifacts and MUST NOT be represented as proving dataset completeness, physical truth of measurements, omitted device lifecycle state, omitted external channels, or suitability for autonomous actuation or sanctions.

Class A (Public Recompute)

Class A is appropriate when public recomputation from disclosed canonical records and authoritative artifacts is required. A Class A bundle MUST include all canonical-record artifacts required to recompute the claimed segment root, the canonical segment artifact including its authoritative batch objects, any disclosed standalone batch-metadata projections, the verifier-facing segment manifest, and at least one proof artifact plus its binding metadata. The segment artifact itself records the commitment_profile_id.

A Class A verifier can perform record-level recomputation, batch-metadata validation, segment-root recomputation, segment-artifact digest validation, manifest artifact-digest validation, and enabled anchor or publication-proof validation when the corresponding artifacts are disclosed. It MUST report recomputation, profile, and manifest status. A public-recompute claim is invalid if required record artifacts are missing, root recomputation was skipped, the in-band profile is absent or unsupported, or digest checks fail.

Class B (Partner Audit)

Class B is appropriate for controlled disclosure where some record material is withheld while commitment and anchor evidence remain auditable. Class B outputs MUST NOT be represented as publicly recomputable. A Class B bundle MUST include the canonical segment artifact, the verifier-facing segment manifest, and at least one timestamp proof plus binding metadata. It MAY include standalone batch-metadata projections, commitments covering withheld material, and a policy artifact describing withheld or partitioned material.

Class B validation is limited to the authoritative segment artifact, disclosed batch metadata, any disclosed withheld-material commitments, any auditor-supplied material, and any anchor channels present in the bundle. Verifier output SHOULD explicitly state when record-level recomputation was partial or was not attempted for withheld material. It MUST report record_level_recompute as skipped when public record-level recomputation is impossible and MUST report that the result is not publicly recomputable. Deployment-specific checks for withheld-material commitments or policy artifacts MUST use extension names beginning with x-.

Class C (Anchor-Only)

Class C is appropriate when only existence and timestamp evidence is disclosed. A Class C disclosure MUST be labeled as existence and timestamp evidence only and MUST NOT claim record-level reproducibility. A Class C bundle MUST include the canonical segment artifact, the verifier-facing segment manifest, and at least one timestamp proof artifact plus the metadata needed to bind it to the segment artifact digest. The in-band commitment_profile_id supplies the profile identity.

A Class C verifier can validate segment-artifact digest binding, manifest digests, chain or anchor existence, and timestamp or publication status when the relevant artifacts are present. Class C verifier output SHOULD be reported as anchor-only evidence. It MUST report record-level and batch recomputation as skipped. It MUST NOT report segment_chain_validation as executed for a non-epoch segment unless the predecessor artifact is disclosed.

The verifier-facing manifest MUST include:

A separate verifier result MUST identify the artifact digest and commitment profile it evaluated, the claimed disclosure class, checks executed, checks skipped with reasons, per-channel validation results, verifier policy, and overall outcome.

8. Versioning

This profile has several independent version surfaces:

The commitment profile defined in this document is verifiable-telemetry-canonical-cbor-v2. If a verifier encounters an unsupported commitment_profile_id, it MUST reject the verification claim rather than silently using a fallback interpretation.

This revision defines exactly one non-private commitment_profile_id. Additional non-private profile identifiers are allocated as described in Section 13.3 and require a stable public specification before they are used for interoperability claims.

The move from calendar-day artifacts to serial-numbered segments is a commitment-format migration, not an editorial alias. It changes the authoritative artifact family, schema bytes, paths, chain input, and verifier semantics. Therefore this revision uses segment and batch schema version 2, verification-manifest version 2, the new media type in Section 13.1, and verifiable-telemetry-canonical-cbor-v2. A producer MUST NOT label v2 bytes with the v1 identifier. Migration from a v1 day ledger starts a fresh v2 ledger_id at segment zero; any cross-profile migration statement requires a separately specified artifact and is not a normal prev_segment_sha256 link.

The fixed canonical-record array retains its in-band record discriminator value 1. The v2 profile uses domain-separated leaf and parent hashes, the uniquely determined recursive tree shape in Section 4.3, and deterministic batch partitioning. Its roots are therefore not interchangeable with roots produced by the legacy duplicate-last construction.

The authoritative segment artifact carries the applicable commitment_profile_id in-band. A verifier-facing manifest repeats it and MUST match the artifact. Timestamping the artifact digest therefore binds the profile identifier without relying on an unprotected manifest association.

A segment-record version identifies the schema of the segment artifact under a known commitment profile. It is not a substitute for commitment_profile_id. Likewise, a media type or file extension can identify the artifact family, but it does not authorize a verifier to select canonical CBOR, hash, or Merkle rules without an explicit commitment profile.

The following migration rules apply to the public contract surfaces:

New commitment_profile_id
Required for changes to authoritative fact, batch, or segment commitment bytes; deterministic CBOR encoding rules; accepted integer, float, null, timestamp, or unknown-field behavior for commitment inputs; hash algorithm; Merkle leaf ordering; parent construction; odd-leaf policy; segment-artifact chaining semantics; or disclosure-class recomputation semantics.
New schema version or schema identifier
Required for changes to a public schema's required fields, closed-field policy, field type, enum vocabulary, or field meaning while preserving the same artifact family and commitment profile.
New artifact family
Required for a new primary evidence object, trust domain, publication statement, disclosure package, rejection-audit public contract, sealed-state object, or non-segment commitment unit.
Verifier tolerance only
Appropriate for accepting legacy aliases, optional historical fields, alternate discovery locations, or stricter and looser validation lanes when produced commitments and verifier truth claims do not change. Material tolerance behavior MUST be reported by verifier output.
Projection change only
Appropriate for SensorThings output, JSON presentation, CLI rendering, report formatting, non-authoritative labels, or read-only consumer exports that are not hashed into commitments and do not change verifier claims.

A change can trigger more than one action. For example, a new publication statement that also changes commitment bytes requires both a new artifact family and a new commitment_profile_id.

9. Conformance Vectors

The deterministic rules in this profile can be exercised with machine-readable conformance vectors. Vector suites SHOULD cover the positive and negative cases below.

Positive coverage should include:

Negative coverage should include:

Cross-implementation checks SHOULD verify byte-for-byte parity across at least two independent implementations. Interval tests MUST use a controllable fake elapsed-time source and restart tests MUST inject failures at persistence boundaries; conformance tests SHOULD NOT wait for real elapsed time. The canonical-record bytes are test inputs, not outputs reconstructed from transport fixtures. Any mismatch in leaf digests, artifact bytes, artifact digests, roots, assignments, or expected failures is a conformance failure.

Vector bundles SHOULD include the commitment_profile_id.

10. Operational Considerations

This section consolidates deployment guidance for operators and follows the operational topics described in [I-D.ietf-opsawg-rfc5706bis]. It does not make operator policy part of the cryptographic commitment output, but it identifies the state and configuration that determine whether the committed evidence remains useful and verifiable.

10.1. Record Timestamps and UTC Health

Any ingest_time or device_time value is already part of the canonical-record byte string at the profile boundary. Its assignment, source authentication, accuracy, leap-second handling, and clock-health policy are upstream responsibilities. The ledger producer MUST preserve that value unchanged and MUST NOT use it for segment selection, renumbering, or reopening. Segment closure uses only the elapsed-time rules in Section 10.2.

10.2. Segment Sequencing and Closure

Operators MUST persist the active ledger_id, next emitted segment number, current closure-policy snapshot, open-interval state, record and byte counters, and artifact-write state across restart. Admission, artifact publication, and sequence-state advancement MUST use the atomic or recoverable protocol in Section 4.4 so a crash cannot lose an accepted record or reuse a published serial. Redundant gateways MUST use single-writer fencing or atomic shared allocation.

Operators SHOULD monitor elapsed-timer health, closure delay, unexpected early-close reasons, serial conflicts, policy changes, and recovery closures. If deadline state cannot be recovered, the gateway MUST follow Section 4.4 rather than consulting UTC to reconstruct elapsed boundaries.

10.3. Health and Fault Management

Operators SHOULD monitor at least the following signals:

  • canonical-record handoff, validation, admission, and durable-persistence failures,
  • ledger-identity and segment-sequence persistence, writer fencing, and serial-conflict events,
  • elapsed-timer health, closure delay, closure reason, and closure-policy revision,
  • invalid canonical-record encoding and oversize-input rejection rates,
  • segment-artifact write success, digest production, and segment-root calculation,
  • anchoring backlog, calendar reachability, and proof-upgrade lag for OTS,
  • status of the mandatory-to-implement [RFC3161] channel when selected for deployment use and of peer-signature channels when configured, and
  • local storage pressure for retained record artifacts, segment artifacts, proof artifacts, and manifests.

An operator-visible fault state SHOULD distinguish an invalid commitment artifact from a delayed or failed external anchoring channel. A delayed OTS proof, for example, is not by itself evidence that the authoritative segment artifact is malformed.

10.4. Configuration Management

Deployments SHOULD document the maximum canonical-record byte length, admission backpressure and durable-write behavior, closure_policy, record and size limits, permitted early-close triggers, artifact and proof retention periods, OTS calendars, optional TSA identities, anchoring policy, verifier strictness for optional channels, and any peer-signature quorum threshold and identity set. These settings are distinct and MUST NOT be silently substituted for one another.

Transport, decryption, anti-replay, source buffering, source identity, and source-to-record mapping configuration are upstream of this profile. When one implementation contains both upstream and ledger functions, operator documentation SHOULD still identify the byte-level handoff and distinguish upstream failures from ledger admission or commitment failures. A configuration change that alters the canonical-record byte syntax or another commitment output requires the versioning action specified in Section 8.

When OTS is used, ledger producers SHOULD submit to multiple calendars operated by administratively distinct entities and retain disclosed OTS proof artifacts for at least as long as the corresponding segment artifacts remain available for verification.

10.5. Fault-to-Verifier-Result Mapping

Operational faults do not all have the same verifier meaning. Verifier output MUST distinguish at least the following cases when the condition is visible from disclosed artifacts or local verifier policy:

OTS proof exists but is incomplete or awaiting upgrade
Report the OTS channel as pending. Place x-ots-verification in checks_skipped with reason pending_proof unless validation was attempted and failed. Overall success is permitted only when local policy does not require completed OTS evidence.
[RFC3161] timestamp response is absent
Report the TSA channel as missing when required by policy, or skipped with reason disabled when the channel is not configured. Report tsa_verification exactly once in either executed or skipped checks when applicable.
Canonical-record handoff or admission durability is reported as uncertain
Report the operational continuity condition and do not claim input completeness. Verification of a disclosed sealed segment can still succeed when its artifacts are internally consistent, but that success does not establish which upstream records should have been admitted.
Segment sequence or elapsed-time state is lost
Report a continuity break and any recovery closure. Do not report segment_chain_validation as successful across an unknown predecessor, serial conflict, or newly created ledger.

10.6. Performance and Scaling

Artifact size grows primarily with the number of accepted canonical records and the number of batches in a segment. Class A verification requires access to the disclosed canonical-record artifacts and scales with the number of records that must be decoded, hashed, and reduced into the segment root. Class C verification can be substantially smaller because it validates the segment-artifact digest and disclosed proof channels without public record-level recomputation. OTS submission traffic is one digest submission per emitted segment artifact per selected calendar; using multiple calendars increases availability but also increases submission attempts and proof-status tracking.

Shorter segment intervals reduce the normal time to sealing and anchoring but increase artifact count, anchor submissions, storage, verifier work, and cadence metadata leakage. Longer intervals reduce that overhead but increase the amount of unsealed material and the size of each record-level verification. In emit mode, idle deployments also pay one artifact and anchor submission per interval; suppress mode avoids that cost but makes no continuous- coverage claim.

10.7. Verifying Correct Operation

Operators SHOULD periodically run an independent verifier against a recently produced bundle using the same disclosure class that consumers are expected to rely on. A healthy run should confirm that disclosed artifacts are present, the commitment_profile_id is supported, the authoritative segment artifact is well formed, the segment-artifact digest matches binding metadata, disclosed adjacency passes segment-chain validation, expected checks appear exactly once in either checks_executed or checks_skipped, and configured proof channels report a status permitted by local policy and reported according to Section 10.5. Operators SHOULD alert when required checks are silently absent, when OTS proofs remain pending beyond local policy, or when canonical-record handoff, elapsed-timer health, serial allocation, writer fencing, or segment- artifact-write faults occur.

11. Security Considerations

This profile does not introduce new cryptographic primitives. Its security depends on a byte-preserving canonical-record handoff, deterministic commitment encoding, trustworthy ledger admission and elapsed-time handling, accurate verifier reporting, and disciplined artifact and proof handling. The threats below are stated in the threat-and- remediation style described by [RFC3552]. Unless explicitly stated otherwise, a successful verification result establishes only that the disclosed artifacts are internally consistent with this profile and with any validated proof channels.

Gateway Compromise and Pre-Commit Omission

An attacker can compromise the ledger producer or its canonical-record handoff and then fabricate byte strings, suppress proposed inputs before commitment, substitute different bytes, or assign a record to the wrong segment. This profile does not by itself detect a malicious producer; it makes outputs tamper-evident only after commitment, as described in Section 1.2. Operational guidance for admission persistence, elapsed time, health, and verification checks is consolidated in Section 10.

Segment Sequence Rollback, Fork, and Truncation

An attacker or failed multi-writer deployment can reuse or roll back a segment number, emit conflicting artifacts for one ledger and serial, substitute a predecessor from another ledger, or disclose only a chain prefix or suffix. Fresh ledger identity, single-writer fencing, contiguous serials, and full predecessor-artifact digest validation detect conflicts when the relevant artifacts are disclosed. They do not prove global completeness to an isolated verifier: a producer can still withhold undisclosed segments or a chain suffix. Verifier output MUST therefore distinguish validated adjacency from a completeness claim.

Upstream Admission and Semantic Substitution

An attacker can exploit an upstream transport, replay mechanism, credential system, decryption path, identifier mapping, or payload parser so that incorrect, duplicated, or misattributed record bytes are presented at the profile boundary. Those controls are outside this document. This profile neither prevents nor detects such an attack once the resulting byte string has been admitted. A separate upstream specification is needed for claims about source authentication, anti-replay, confidentiality, or source-to-record semantics, and a successful ledger verification MUST NOT be reported as validation of those claims.

Canonicalization, Profile, and Metadata Confusion

An attacker can exploit differences in CBOR validation, re-encoding, record occurrence handling, hash composition, or non-authoritative metadata handling while implementations still claim the same commitment_profile_id. An attacker can also present a verifier-facing manifest, batch-metadata projection, or OTS sidecar that does not match the authoritative segment artifact in the hope that a verifier will treat convenience metadata as authoritative. The mitigation is that this profile fixes the canonical-record byte syntax, deterministic encoding, and hash rules; requires producers and verifiers to hash the exact authoritative record bytes without re-encoding; treats the authoritative segment artifact as the cryptographic source of truth; requires verifiers to recompute commitment material from authoritative artifacts; requires the applicable commitment_profile_id to be disclosed and bound to the same segment-artifact digest, and requires standalone metadata projections and sidecars to match the authoritative artifact. Any future semantic or hash-composition change MUST use a new commitment_profile_id.

Artifact Mutation and Proof Substitution

An attacker can modify a committed segment artifact after disclosure, or can present a valid proof over the wrong artifact digest. The mitigation is that verifiers recompute the authoritative segment-artifact digest independently and compare it with the disclosed binding metadata before accepting any proof result. Mutation or substitution therefore changes the digest or its binding and causes verification to fail.

Calendar Withholding and Optional-Channel Downgrade

An attacker can operate or compromise a timestamping or attestation service so that proof issuance is delayed, withheld, or selectively unavailable, can present pending or placeholder proofs as if they were final attestations, or can exploit verifier policy that silently ignores a missing required channel. The channel-status vocabulary is defined in Section 6.3.3, and operational reporting for missing or pending channels is described in Section 10.5.

UTC Timestamp Manipulation

An attacker can alter an upstream UTC source so that canonical records carry misleading ingest_time or device_time values. Timestamp assignment and source authentication are outside this profile, as described in Section 10.1. Verification can detect byte or artifact inconsistencies, but it cannot reconstruct true real-world time from a false admitted value. UTC changes MUST NOT affect segment membership or reopen sealed segments.

Segment Policy and Elapsed-Time Manipulation

An attacker can lengthen the closure interval, regress or freeze the elapsed-time source, alter an active policy, misstate a close reason, or race boundary processing in order to delay anchoring or assign a record to a different segment. Committing the policy snapshot and close reason makes the gateway's claim tamper-evident after sealing, while the serialized boundary algorithm and operational monitoring reduce accidental races. These controls do not independently prove that the gateway honestly observed real elapsed time. Likewise, a validated OTS proof establishes that the artifact existed no later than the validated timestamp; it does not prove when the segment opened or that every configured deadline was honored.

Resource Exhaustion

An attacker can flood a ledger producer with malformed, oversized, or excessive-rate canonical-record inputs in order to exhaust admission capacity, artifact storage, or verifier computation. Producers need deployment-appropriate input-size limits, rate controls, and backpressure at the byte-level handoff; relevant operational signals and sizing considerations are described in Section 10.3 and Section 10.6. This profile does not define a complete denial-of-service defense.

Verification Scope, Completeness, and Disclosure

An attacker can rely on a successful verification result being misread as proof of dataset completeness, physical truth of measurements, or authorization for autonomous actuation. An attacker can also obtain sensitive information if disclosed bundles expose more record material than intended for the chosen disclosure class. This profile mitigates those risks only partially: verifier output is required to state the exercised verification scope, a successful result establishes internal consistency and proof binding for the disclosed bundle rather than completeness of all observed or emitted telemetry, and disclosure classes constrain what is expected to be published. Deployments that need stronger completeness, safety, or confidentiality guarantees must add external operational controls, independent observation, and access-control and retention policies that match the sensitivity of the disclosed artifacts.

Even when payloads are withheld, manifests, segment artifacts, proof sidecars, and operational summaries can disclose source-activity metadata such as record counts, outage windows, and anchoring delay. Segment serials, interval values, close reasons, and the difference between emitted and suppressed empty intervals can add cadence and activity information. Deployments SHOULD account for that metadata exposure in disclosure and retention policy.

12. Privacy Considerations

Telemetry payloads can include sensitive operational data. Operators should:

Privacy-preserving disclosures remain valid, but they MUST NOT be described as publicly recomputable unless Class A conditions are met.

Disclosure of verifier-facing manifests, canonical-record artifacts, segment artifacts, proof sidecars, and operational summaries can reveal source-activity patterns, outage windows, configured segment duration, empty-interval policy, anchoring cadence, and operational incidents even when payload values are withheld. Short intervals and suppress mode can make activity timing especially visible. Operators SHOULD treat these artifacts as metadata-bearing evidence and apply disclosure, retention, and access-control policy accordingly.

13. IANA Considerations

This section follows the guidance in [RFC8126] and provides the complete instructions for the Internet Assigned Numbers Authority (IANA).

13.1. Media Types Registry

IANA is requested to register the following media types in the standards tree of the "Media Types" registry in accordance with [RFC6838]:

Because this document is intended for publication on the Independent Submission Stream, the standards-tree registrations in this section require IESG approval under [RFC6838].

Type name: application

Subtype name: verifiable-telemetry-segment+cbor

Required parameters: none

Optional parameters: none

Encoding considerations: binary

Security considerations: see Section 11, especially profile and metadata confusion, artifact mutation, proof substitution, disclosure scope, and resource exhaustion.

Interoperability considerations: this media type identifies the authoritative segment-artifact family defined by Section 4.2, Section 4.3, Section 4.4, Section 4.5, and Section 4.6. A recipient uses the artifact's in-band commitment_profile_id to select canonical CBOR, hash, and Merkle semantics for a verification claim.

Published specification: this document, especially Section 4.2, Section 4.3, Section 4.4, Section 4.5, and Section 4.6.

Applications that use this media type: producers, verifiers, disclosure tools, and archival or audit systems that exchange or retain authoritative segment artifacts.

Fragment identifier considerations: no fragment identifier syntax is defined by this document for application/verifiable-telemetry-segment+cbor. Fragment identifiers, if present, are processed according to the +cbor structured syntax suffix rules in [RFC8949].

Additional information:

  • Magic number(s): none
  • File extension(s): none
  • Macintosh file type code(s): none

Person & email address to contact for further information: Bilal El Khatabi <elkhatabibilal@gmail.com>

Intended usage: COMMON

Restrictions on usage: none

Author: Bilal El Khatabi

Change controller: IESG

Type name: application

Subtype name: verifiable-telemetry-manifest+json

Required parameters: none

Optional parameters: none

Encoding considerations: binary

Security considerations: see Section 11, especially profile and metadata confusion, artifact mutation, stale or substituted manifests, disclosure scope, and resource exhaustion.

Interoperability considerations: this media type identifies the verification manifest defined by Section 5, Section 6.5, and Verification Manifest and Result CDDL. The manifest is a metadata and digest-binding surface; it is not an authoritative commitment artifact. A recipient still needs the referenced authoritative artifact and MUST compare the manifest's commitment_profile_id with the artifact's in-band value to interpret and verify a claim. The JSON representation conforms to [RFC8259].

Published specification: this document, especially Section 5, Section 6.5, and Verification Manifest and Result CDDL.

Applications that use this media type: producers, verifiers, disclosure tools, publication services, and archival or audit systems that exchange verification manifests.

Fragment identifier considerations: no fragment identifier syntax is defined by this document for application/verifiable-telemetry-manifest+json.

Additional information:

  • Magic number(s): none
  • File extension(s): none
  • Macintosh file type code(s): none

Person & email address to contact for further information: Bilal El Khatabi <elkhatabibilal@gmail.com>

Intended usage: COMMON

Restrictions on usage: none

Author: Bilal El Khatabi

Change controller: IESG

13.2. No CBOR Tag Allocation

This document requests no new CBOR tag allocation. Commitment bytes defined by Section 4.2 forbid CBOR tags, and the authoritative segment artifact defined by Section 4.5 does not require additional tag semantics for exchange.

13.3. commitment_profile_id Registry

IANA is requested to create the Verifiable Telemetry Ledger Commitment Profiles registry under a new Verifiable Telemetry Ledger Parameters registry group. This registry is tied to the application/verifiable-telemetry-segment+cbor media type registered in Section 13.1 and records values of the commitment_profile_id sub-code carried in that representation. Registry change control belongs to the Independent Stream. The registry records four columns: Identifier, Description, Reference, and Change Controller.

A registered identifier is 1 through 63 lower-case ASCII characters. It begins with a letter, ends with a letter or digit, and otherwise contains only lower-case letters, digits, and single hyphens between non-hyphen characters. Comparison is case-sensitive; an identifier containing an upper-case letter is invalid. Identifiers beginning with x- are reserved for Private Use, are not registered, and MUST NOT be used as interoperable public profile identifiers.

The registration policy is RFC Required as defined by [RFC8126] and constrained by [RFC8726] for the Independent Submission Stream.

A registration request MUST provide all four registry fields and an RFC reference. The referenced RFC MUST define the canonical input bytes, deterministic encoding rules, hash and tree calculation, authoritative artifact schema, verification procedure, profile identifier binding, positive and negative conformance vectors, and relevant security considerations. An identifier that does not satisfy the syntax above is invalid and MUST NOT be registered.

An update request requires authorization from the registered change controller and an RFC reference. An update MUST NOT change commitment bytes or verification semantics for an existing identifier; such a change requires a new identifier. A deprecated entry remains recorded with its reference and MUST NOT be reassigned.

This registry is created by a document published on the Independent Submission Stream. Any issues that arise with management of the registry will be resolved by IANA in consultation with the Independent Submissions Editor.

Table 2: Initial Commitment Profile Registration
Identifier Description Reference Change Controller
verifiable-telemetry-canonical-cbor-v2 Deterministic CBOR canonical-record and serial-segment profile with domain-separated SHA-256 tree commitments This document Independent Stream

This document requests no CoAP Content-Format entry.

14. Applicability and Deployment Models

This profile standardizes the durable evidence object produced after local telemetry admission and before external publication. It is useful where the source protocol and application semantics vary, but later auditors need a common way to recompute exactly what bytes were committed, how they were grouped, and which timestamped artifact binds them.

This profile is not appropriate when an application needs proof of sensor truth, source authentication, complete upstream ingestion, or the semantics of source-to-record projection; those properties require upstream specifications and evidence. It also does not replace SCITT or another publication system: such a system can publish a VTL artifact, while this document defines how the local artifact is formed and verified.

15. Future Extension Points

The following items are outside the baseline profile defined by this document. They identify extension surfaces that would require separate specification before they are used as interoperability claims.

16. References

16.1. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8949]
Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, DOI 10.17487/RFC8949, , <https://www.rfc-editor.org/rfc/rfc8949>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/rfc/rfc6838>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, , <https://www.rfc-editor.org/rfc/rfc8126>.
[RFC8726]
Farrel, A., "How Requests for IANA Action Will Be Handled on the Independent Stream", RFC 8726, DOI 10.17487/RFC8726, , <https://www.rfc-editor.org/rfc/rfc8726>.
[RFC3161]
Adams, C., Cain, P., Pinkas, D., and R. Zuccherato, "Internet X.509 Public Key Infrastructure Timestamp Protocol (TSP)", RFC 3161, DOI 10.17487/RFC3161, , <https://www.rfc-editor.org/rfc/rfc3161>.
[RFC8610]
Bormann, C. and P. Hoffman, "Concise Data Definition Language (CDDL): A Notational Convention to Express CBOR and JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, , <https://www.rfc-editor.org/rfc/rfc8610>.
[RFC9162]
Laurie, B., Messeri, E., and R. Stradling, "Certificate Transparency Version 2.0", RFC 9162, DOI 10.17487/RFC9162, , <https://www.rfc-editor.org/rfc/rfc9162>.
[RFC8259]
Bray, T., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, , <https://www.rfc-editor.org/rfc/rfc8259>.
[RFC6234]
3rd, D. E. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, DOI 10.17487/RFC6234, , <https://www.rfc-editor.org/rfc/rfc6234>.

16.2. Informative References

[I-D.ietf-opsawg-rfc5706bis]
Claise, B., Clarke, J., Farrel, A., Barguil, S., Pignataro, C., and R. Chen, "Guidelines for Considering Operations and Management in IETF Specifications", Work in Progress, Internet-Draft, draft-ietf-opsawg-rfc5706bis-05, , <https://datatracker.ietf.org/doc/draft-ietf-opsawg-rfc5706bis/>.
[RFC3552]
Rescorla, S. and B. Korver, "Guidelines for Writing RFC Text on Security Considerations", BCP 72, RFC 3552, DOI 10.17487/RFC3552, , <https://www.rfc-editor.org/rfc/rfc3552>.
[RFC8785]
Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785, , <https://www.rfc-editor.org/rfc/rfc8785>.
[OTS]
OpenTimestamps Project, "OpenTimestamps Protocol and Tooling", , <https://opentimestamps.org/>.

Appendix A. Example Verification Manifest

This appendix shows a representative verification manifest. A concrete deployment can carry additional operational fields in the defined extension containers; the example below captures the baseline verification surface described here. Operational summaries can be carried as deployment-specific extensions, but they are not substitutes for canonical-record or segment-artifact authority and are not required by the disclosure classes.

{
 "version": 2,
 "ledger_id": "b7a1d5e40c6f438e9a75db27c96f31aa",
 "site_id": "an-001",
 "segment_number": "7",
 "commitment_profile_id": "verifiable-telemetry-canonical-cbor-v2",
 "disclosure_class": "A",
 "artifacts": {
  "segment_cbor": {
   "path": "segments/00000000000000000007.cbor",
   "sha256": "<64 hex chars>"
  },
  "predecessor_segment_cbor": {
   "path": "segments/00000000000000000006.cbor",
   "sha256": "<64 hex chars>"
  },
  "records": [
   {
    "path": "records/device-003-00000006.cbor",
    "sha256": "<64 hex chars>"
   },
   {
    "path": "records/device-003-00000007.cbor",
    "sha256": "<64 hex chars>"
   }
  ],
  "segment_json": {
   "path": "segments/00000000000000000007.json",
   "sha256": "<64 hex chars>"
  },
  "segment_sha256": {
   "path": "segments/00000000000000000007.cbor.sha256",
   "sha256": "<64 hex chars>"
  },
  "tsa_tsr": {
   "path": "segments/00000000000000000007.tsr",
   "sha256": "<64 hex chars>"
  },
  "segment_ots": {
   "path": "segments/00000000000000000007.cbor.ots",
   "sha256": "<64 hex chars>"
  },
  "segment_ots_meta": {
   "path": "segments/00000000000000000007.ots.meta.json",
   "sha256": "<64 hex chars>"
  }
 },
 "anchoring": {
  "tsa": { "status": "complete" },
  "ots": { "status": "complete" },
  "peer": { "status": "skipped" }
 }
}

A verifier result is a separate object. For example:

{
 "version": 2,
 "artifact_sha256": "<64 hex chars>",
 "commitment_profile_id": "verifiable-telemetry-canonical-cbor-v2",
 "disclosure_class": "A",
 "verification_scope": "public_recompute",
 "checks_executed": [
  "bundle_disclosure_validation",
  "verification_manifest_validation",
  "segment_artifact_validation",
  "segment_chain_validation",
  "record_level_recompute",
  "batch_metadata_validation",
  "segment_digest_binding",
  "tsa_verification"
 ],
 "checks_skipped": [],
 "channels": {
  "tsa": { "status": "verified" },
  "ots": { "status": "verified", "check": "x-ots-verification" }
 },
 "policy": { "optional_channel_failure": "warn" },
 "record_multiset_root": "<64 hex chars>",
 "overall": "success"
}

Appendix B. Conformance Vector Material

The figure below is a reader-oriented sketch of the verifiable-telemetry-canonical-cbor-v2 conformance-vector bundle shape and naming only. It is illustrative and is not itself a complete machine-readable vector corpus.

The exact compact known-answer vector later in this appendix is normative for verifiable-telemetry-canonical-cbor-v2. The surrounding reader-oriented sketches remain illustrative.

Wrapped hexadecimal values in this appendix are presentation-only; a verifier or implementer should concatenate adjacent lines without inserting whitespace.

The fixtures below are reader-oriented decoded views, not upstream transport or projection fixtures. A machine-readable vector corpus for this profile MUST carry the exact canonical-record byte strings as its starting inputs together with their expected leaf digests.

In these reader-oriented sketches, kind is shown as the unsigned value carried in the authoritative CBOR array. Its application meaning is outside this profile.

commitment_profile_id:
  verifiable-telemetry-canonical-cbor-v2

fixture record_a:
  device_id: "0000000000000065"
  fc: 1
  ingest_time: 1772366400
  device_time: null
  kind: 250
  payload.temp_c: 21.5

fixture record_b:
  device_id: "0000000000000066"
  fc: 2
  ingest_time: 1772367000
  device_time: null
  kind: 250
  payload.temp_c: 22.0

fixture record_c:
  device_id: "0000000000000067"
  fc: 3
  ingest_time: 1772367600
  device_time: null
  kind: 250
  payload.temp_c: 22.5

segment_record_v2:
  version: 2
  commitment_profile_id: verifiable-telemetry-canonical-cbor-v2
  ledger_id: b7a1d5e40c6f438e9a75db27c96f31aa
  site_id: an-001
  segment_number: 7
  closure_policy.version: 1
  closure_policy.interval_ms: 86400000
  closure_policy.batch_record_limit: 1024
  closure_policy.record_limit: null
  closure_policy.size_limit_bytes: null
  closure_policy.empty_mode: suppress
  close_reason: interval
  prev_segment_sha256: <SHA-256 of exact segment 6 CBOR>
  batches: <ordered batch objects>
  segment_root: <root over the segment leaf multiset>

class-a-bundle-v2:
  disclosure_class: A
  commitment_profile_id: verifiable-telemetry-canonical-cbor-v2
  required_artifact_1: records/<record-id>.cbor
  required_artifact_2: segments/<segment-number>.cbor
  required_artifact_3: segments/<segment-number>.tsr
  verifier_check_1: bundle_disclosure_validation
  verifier_check_2: segment_artifact_validation
  verifier_check_3: segment_chain_validation
  verifier_check_4: record_level_recompute
  verifier_check_5: batch_metadata_validation
  verifier_check_6: segment_digest_binding
  verifier_check_7: tsa_verification

required_fail_cases:
  - serial reuse, decrease, gap, or wrap
  - wrong predecessor artifact digest or ledger identity
  - record accepted exactly at deadline assigned to old interval
  - timestamp-driven reassignment or reopening of sealed segment
  - in-place closure-policy mutation
  - invalid empty-mode behavior
  - batch identity, number, count, ordering, or root mismatch
  - batch partition does not follow batch_record_limit
  - manifest profile identifier differs from the in-band artifact value
  - proof covers segment_root instead of segment artifact digest
Figure 3

The following compact known-answer vector is normative for verifiable-telemetry-canonical-cbor-v2. Hexadecimal values are lowercase and unprefixed. It encodes the epoch segment: the outer segment and both embedded batches use segment_number = 0, and prev_segment_sha256 is 32 zero octets. The segment uses batch_record_limit = 2.

record_1 = 87014800000000000000010100f600f6
leaf_1 = b83bc27f2d8be3a66373af24e6af3eeffff99ff0696ae18c70e379e853796d26
record_2 = 87014800000000000000020201f600f6
leaf_2 = b5227357cf5d0619914971d8dc5218c5a99260bc5d5e1b60cb1083a911a2acaf
record_3 = 87014800000000000000030302f600f6
leaf_3 = 4f82e3e7ee90a111774dd951471a31d4582e0908a0bd5fd63c0080c0231f40cc

sorted_leaves =
  4f82e3e7ee90a111774dd951471a31d4582e0908a0bd5fd63c0080c0231f40cc
  b5227357cf5d0619914971d8dc5218c5a99260bc5d5e1b60cb1083a911a2acaf
  b83bc27f2d8be3a66373af24e6af3eeffff99ff0696ae18c70e379e853796d26
batch_0_root = 554491e4edf28061622396b83a870db4652211557127c664c6be1c4ad66471ff
batch_1_root = b83bc27f2d8be3a66373af24e6af3eeffff99ff0696ae18c70e379e853796d26
segment_root = bc6502552ed0c515f58d1c632e54db37594042609b59838eb0d5b3d5842aa054

segment_cbor =
  aa676261746368657382a865636f756e740267736974655f696466616e2d303031
  6776657273696f6e02696c65646765725f69647820623761316435653430633666
  34333865396137356462323763393666333161616b6c6561665f68617368657382
  784034663832653365376565393061313131373734646439353134373161333164
  343538326530393038613062643566643633633030383063303233316634306363
  784062353232373335376366356430363139393134393731643864633532313863
  356139393236306263356435653162363063623130383361393131613261636166
  6b6d65726b6c655f726f6f74784035353434393165346564663238303631363232
  333936623833613837306462343635323231313535373132376336363463366265
  3163346164363634373166666c62617463685f6e756d626572006e7365676d65
  6e745f6e756d62657200a865636f756e740167736974655f696466616e2d3030
  316776657273696f6e02696c65646765725f696478206237613164356534306336
  6634333865396137356462323763393666333161616b6c6561665f686173686573
  817840623833626332376632643862653361363633373361663234653661663365
  656666666639396666303639366165313863373065333739653835333739366432
  366b6d65726b6c655f726f6f747840623833626332376632643862653361363633
  373361663234653661663365656666666639396666303639366165313863373065
  333739653835333739366432366c62617463685f6e756d626572016e7365676d
  656e745f6e756d6265720067736974655f696466616e2d303031677665727369
  6f6e02696c65646765725f696478206237613164356534306336663433386539
  6137356462323763393666333161616c636c6f73655f726561736f6e68696e74
  657276616c6c7365676d656e745f726f6f747840626336353032353532656430
  633531356635386431633633326535346462333735393430343236303962353938
  333865623064356233643538343261613035346e636c6f737572655f706f6c69
  6379a66776657273696f6e016a656d7074795f6d6f6465687375707072657373
  6b696e74657276616c5f6d731a05265c006c7265636f72645f6c696d6974f670
  73697a655f6c696d69745f6279746573f67262617463685f7265636f72645f6c
  696d6974026e7365676d656e745f6e756d6265720073707265765f7365676d65
  6e745f73686132353678403030303030303030303030303030303030303030303030
  30303030303030303030303030303030303030303030303030303030303030303030
  3030303030303075636f6d6d69746d656e745f70726f66696c655f69647826766572
  69666961626c652d74656c656d657472792d63616e6f6e6963616c2d63626f722d76
  32
segment_sha256 = ce76302d1fcbf713097c0d70070b6a651bcd97e7855213aaf422b0ff9226708c

three_identical_record_1_root =
  05ddc48e556d67534bf7960a70209696ca9eeb6f18d5595358e7f4804ec87701
four_identical_record_1_root =
  d5d26faa3f54d81d8173700a48d9286179c9d35685d464183a99b1e966f1dfd8

A published machine-readable vector set can carry exact canonical bytes, digests, expected roots, and the applicable commitment_profile_id. The reader-oriented sketches in this appendix are illustrative; the exact compact known-answer vector above is normative.

Appendix C. Verification Manifest and Result CDDL

This appendix defines the Concise Data Definition Language (CDDL) ([RFC8610]) shape for the verification producer manifest and the separate verifier result. It captures the verification surface described here and provides explicit containers for deployment-specific additions. Producer manifests and verifier results MUST be UTF-8 JSON texts under [RFC8259] and MUST reject duplicate object member names.

Check names are drawn from the standardized vocabulary defined in Section 6.5; deployment-specific extensions MUST use separate names beginning with x- that do not redefine those identifiers.

The relative-path rule below is intentionally structural. RFC 8610 regular expressions use the XML Schema dialect and cannot portably express all cross-platform path and filesystem-containment checks. Implementations MUST apply the semantic path rules in Section 5, including backslash, drive-prefix, UNC, colon, control-character, dot-component, symbolic-link, reparse-point, and race-resistant containment checks.

segment_cbor is the only universally required convenience-key entry. Record lists, standalone batch projections, JSON projections, digest files, and operational summaries are optional at the schema level; disclosure-class rules determine when record or proof material is required. A Class C manifest does not require source identifiers, upstream transport counters, or a records directory.

segment_number is a JSON string containing the shortest unsigned base-10 representation of a uint64: 0, or a digit from 1 through 9 followed by zero or more digits. Its numeric value MUST NOT exceed 18446744073709551615. This avoids loss of precision in JSON implementations whose exact integer range ends at 2^53-1. The lexical rules for relative-path, uint64-decimal, hex32, hex64, and extension check names are normative prose constraints in addition to the structural CDDL.

verification-manifest-v2 = {
  "version": 2,
  "ledger_id": hex32,
  "site_id": tstr,
  "segment_number": uint64-decimal,
  "commitment_profile_id": "verifiable-telemetry-canonical-cbor-v2",
  "disclosure_class": disclosure-class,
  "artifacts": artifacts,
  "anchoring": anchoring,
  ? "operational_summary": { * tstr => json-data },
  ? "extensions": { * tstr => json-data },
}

artifacts = {
  "segment_cbor": artifact-ref,
  ? "predecessor_segment_cbor": artifact-ref,
  ? "records": [* artifact-ref],
  ? "batches": [* artifact-ref],
  ? "segment_json": artifact-ref,
  ? "segment_sha256": artifact-ref,
  ? "segment_ots": artifact-ref,
  ? "segment_ots_meta": artifact-ref,
  ? "peer_attest": artifact-ref,
  ? "tsa_info": artifact-ref,
  ? "tsa_tsr": artifact-ref,
  ? "extensions": { * tstr => artifact-ref }
}

artifact-ref = {
  "path": relative-path,
  "sha256": hex64
}

anchoring = {
  ? "tsa": producer-channel-state,
  ? "ots": producer-channel-state,
  ? "peer": producer-channel-state
}

producer-channel-state = {
  "status":
    "verified" / "pending" / "missing" /
    "failed" / "skipped" / "complete"
}

verification-result-v2 = {
  "version": 2,
  "artifact_sha256": hex64,
  "commitment_profile_id": "verifiable-telemetry-canonical-cbor-v2",
  "disclosure_class": disclosure-class,
  "verification_scope":
    "public_recompute" / "partial_verification" / "anchor_only",
  "checks_executed": [* check-name],
  "checks_skipped": [* skipped-check],
  ? "channels": { * tstr => verifier-channel-result },
  ? "policy": { * tstr => json-data },
  ? "record_multiset_root": hex64,
  "overall": "success" / "partial" / "failure"
}

check-name = standardized-check-name / extension-check-name

standardized-check-name =
  "bundle_disclosure_validation" /
  "verification_manifest_validation" /
  "segment_artifact_validation" /
  "segment_chain_validation" /
  "record_level_recompute" /
  "batch_metadata_validation" /
  "segment_digest_binding" /
  "tsa_verification"

extension-check-name = tstr

skipped-check = {
  "check": check-name,
  "reason": tstr
}

verifier-channel-result = {
  "status":
    "verified" / "pending" / "missing" /
    "failed" / "skipped" / "complete",
  ? "reason": tstr,
  ? "detail": tstr,
  ? "diagnostic": tstr,
  ? "check": check-name
}

disclosure-class = "A" / "B" / "C"
relative-path = tstr
uint64-decimal = tstr
hex32 = tstr
hex64 = tstr
json-data =
  nil / bool / int / float / tstr /
  [* json-data] / { * tstr => json-data }

Appendix D. Segment Artifact CDDL

This appendix gives the structural CDDL for v2 segment and embedded batch artifacts. The lexical and cross-field requirements in Section 4.5, the formation rules in Section 4.4, and the chain rules in Section 4.6 are normative in addition to this structural shape.

segment-record-v2 = {
  "version": 2,
  "commitment_profile_id": "verifiable-telemetry-canonical-cbor-v2",
  "ledger_id": hex32,
  "site_id": tstr,
  "segment_number": uint64,
  "closure_policy": segment-closure-policy-v1,
  "close_reason": close-reason,
  "prev_segment_sha256": hex64,
  "batches": [* segment-batch-v2],
  "segment_root": hex64
}

segment-batch-v2 = {
  "version": 2,
  "ledger_id": hex32,
  "site_id": tstr,
  "segment_number": uint64,
  "batch_number": uint64,
  "merkle_root": hex64,
  "count": positive-uint64,
  "leaf_hashes": [+ hex64]
}

segment-closure-policy-v1 = {
  "version": 1,
  "interval_ms": positive-uint64,
  "batch_record_limit": positive-uint64,
  "record_limit": positive-uint64 / nil,
  "size_limit_bytes": positive-uint64 / nil,
  "empty_mode": "emit" / "suppress"
}

close-reason =
  "interval" /
  "reconfigure" /
  "record_limit" /
  "size_limit" /
  "shutdown" /
  "recovery" /
  "manual"

uint64 = 0..18446744073709551615
positive-uint64 = 1..18446744073709551615
hex32 = tstr
hex64 = tstr

Acknowledgments

The author thanks the OpenTimestamps project for the public calendar infrastructure used during validation.

The author thanks Joe Clarke for OPSDIR review feedback that improved the operational considerations and deployment guidance.

Author's Address

Bilal El Khatabi
Independent
Morocco