<?xml version="1.0" encoding="UTF-8"?>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude"
     ipr="trust200902"
     category="info"
     submissionType="independent"
     docName="draft-elkhatabi-verifiable-telemetry-ledgers-04"
     version="3">
  <front>
    <title abbrev="TrackOne VTL">Verifiable Telemetry Ledgers for Resource-Constrained Environments</title>
    <seriesInfo name="Internet-Draft" value="draft-elkhatabi-verifiable-telemetry-ledgers-04"/>

    <author fullname="Bilal El Khatabi" initials="B." surname="El Khatabi">
      <organization>TrackOne Project</organization>
      <address>
        <postal>
          <country>Morocco</country>
        </postal>
        <email>elkhatabibilal@gmail.com</email>
      </address>
    </author>

    <date year="2026" month="April" day="24"/>
    <area>General</area>
    <workgroup>Independent Submission</workgroup>
    <keyword>telemetry</keyword>
    <keyword>merkle</keyword>
    <keyword>timestamping</keyword>
    <keyword>iot</keyword>

    <abstract>
      <t>
        This document specifies a verifiable telemetry ledger profile for
        accepted telemetry in resource-constrained sensing environments. The
        profile begins after local policy has admitted a device and the gateway
        accepts its telemetry under the active transport and anti-replay
        contract. From that point onward, it defines a reference framed
        transport profile, deterministic accepted-telemetry-to-canonical-record
        projection, authoritative canonical-record and day artifacts,
        verifier-facing manifests, disclosure classes, and the binding of day
        artifacts to external timestamp evidence.
        OpenTimestamps (OTS) is the default anchoring channel; RFC 3161
        timestamp responses and peer signatures are optional parallel channels.
      </t>
      <t>
        The goal is interoperability and independent auditability, not a full
        device-lifecycle system or new cryptographic primitives.
        Verification claims are limited by the disclosed artifacts, the
        claimed disclosure class, and the checks the verifier actually
        executes. A successful result establishes internal consistency and
        correct proof binding for the disclosed bundle; it does not by itself
        establish dataset completeness, physical truth of measurements, or
        safety for autonomous actuation.
      </t>
    </abstract>
  </front>

  <middle>
    <section numbered="true" toc="include" anchor="introduction">
      <name>Introduction</name>
      <t>
        Long-lived telemetry deployments need evidence that disclosed
        telemetry is the same telemetry a gateway committed when it was
        accepted, even when uplink is intermittent and verification happens
        later.
      </t>
      <t>
        This profile standardizes the gateway-side commitment contract for
        accepted telemetry. In this document, the commitment contract is the
        set of deterministic rules for accepted-telemetry-to-canonical-record projection,
        commitment encoding, day-artifact structure, verifier-facing
        manifests, disclosure classes, and proof binding.
      </t>
      <t>
        The profile begins at an explicit handoff. Before this profile
        applies, lifecycle or control-plane systems determine whether a device is
        known, onboarded, admitted, credentialed, and allowed to send. This
        profile begins once local policy has accepted telemetry under the
        active transport and anti-replay contract and then turns that
        telemetry into authoritative, verifier-facing evidence.
      </t>
      <t>
        Device reporting cadence and gateway artifact cadence are distinct. A
        device can report at fixed or irregular intervals, but this profile uses
        one Coordinated Universal Time (UTC) day as the batching unit for
        authoritative artifacts. Other batching intervals are possible design
        choices for future profiles; they are not implicit variations of this
        one. One UTC day is used in the current profile because it gives a
        predictable rollover boundary, bounded artifact size, and a stable unit
        for later disclosure, export, and audit. The gateway, not the device, is
        responsible for assigning accepted records to UTC day boundaries.
      </t>
      <t>
        The one-day artifact cadence is a gateway batching rule, not a device
        reporting requirement. A device can emit every few hours, every few weeks,
        or irregularly; if the gateway accepts those records, it assigns each
        record to the applicable UTC day artifact. A day artifact therefore
        represents the set of accepted canonical records assigned to one UTC
        day. This profile also defines the deterministic empty-day root for
        deployments that emit explicit empty day artifacts, but it does not
        require every deployment to publish an artifact for every UTC day.
      </t>
      <figure anchor="arch-flow">
        <name>Reference Architecture and Trust Boundaries</name>
        <artwork type="ascii-art"><![CDATA[

Device A --\     +------------------+ --> day artifact --> Verifier
Device B ---+--> | Single Gateway   |
Device C --/     | admit + batch    |
Control  ---->   | assign UTC day   |
plane            | maintain UTC time|
                 +------------------+

Verifier --> timestamp channels: OTS / RFC 3161 / peers
Later publication beyond this profile is separate
]]></artwork>
      </figure>
      <t>
        Figure 1 shows the acceptance handoff and the verifier-facing trust
        boundary. Lifecycle systems remain responsible for whether a device is
        admitted; this profile begins at accepted telemetry. The lower line in
        the figure is not an additional ingest hop; it shows optional
        verifier-side timestamp-validation channels over the same day-artifact
        digest. The gateway is expected to maintain UTC time for
        <tt>ingest_time</tt> assignment and day-artifact rollover. The device is
        not required to keep UTC wall-clock time for this profile.
      </t>
      <t>
        In the deployment model assumed here, intermittency primarily applies
        on the device-to-gateway path. External timestamping or later publication
        can also be delayed, but those delays do not change the
        accepted-telemetry commitment contract once the gateway has admitted
        the telemetry.
      </t>
      <t>
        A deployment can separately publish verifier-facing manifests or
        exported evidence bundles through a supply chain integrity,
        transparency, and trust (SCITT) service only under a
        publication profile defined elsewhere. Such a publication profile
        would need to specify the submitted statement content, the submission
        procedure, and any verifier use of SCITT state. This profile defines
        none of those behaviors. Verification defined here does not consume
        SCITT state, and SCITT is not required to create the underlying
        commitment artifacts.
      </t>

      <section numbered="true" toc="include" anchor="evidence-plane-boundary">
        <name>Scope Boundary</name>
        <t>
          This profile covers processing after accepted telemetry exists:
        </t>
        <ul>
          <li>transport validation, anti-replay, and canonical record admission;</li>
          <li>deterministic batching into authoritative artifacts;</li>
          <li>verifier-facing manifests, disclosure, and export behavior; and</li>
          <li>artifact hashing, anchoring, and independent verification.</li>
        </ul>
        <t>
          It does not specify manufacturer identity, onboarding, fleet
          inventory, public key infrastructure (PKI) policy, network admission
          enforcement, or firmware and update orchestration.
        </t>
      </section>

      <section numbered="true" toc="include" anchor="publication-relationship">
        <name>Relationship to Publication and Adjacent Systems</name>
        <ul>
          <li>
            <em>Certificate Transparency</em> (<xref target="RFC9162"/>):
            Certificate Transparency logs publish append-only records about
            certificate issuance. They are a useful analogy for later
            transparency publication and audit, but they do not define the
            local commitment artifacts, disclosure classes, or baseline
            verification behavior specified here.
          </li>
          <li>
            <em>Supply Chain Integrity, Transparency, and Trust
            (SCITT)</em> (<xref target="SCITT"/>): SCITT publishes claims
            about verifier manifests or exported evidence bundles only when a
            deployment separately defines such publication across a
            transparency-service trust boundary. Verifiers defined here do not
            consume SCITT state.
          </li>
          <li>
            <em>COSE Merkle Tree Proofs</em> (<xref target="COSE-MERKLE"/>):
            COSE-MERKLE defines proof encodings that future disclosure bundles
            could adopt.
          </li>
          <li>
            <em>Remote ATtestation procedureS (RATS)</em>
            (<xref target="RFC9334"/>): RATS can supply attestation inputs
            that influence admission decisions before this profile applies.
          </li>
        </ul>
        <t>
          These systems are adjacent to this profile; they do not define the
          accepted-telemetry commitment contract specified here.
        </t>
        <t>
          Certificate Transparency and SCITT are both publication systems:
          they make externally visible statements available for later audit.
          This profile instead defines the local evidence contract that exists
          before any such publication.
        </t>
        <t>
          More concretely, this profile differs from SCITT in that it does not
          require a transparency service to create or verify its baseline
          artifacts. It fixes the local accepted-telemetry contract itself:
          deterministic accepted-telemetry-to-canonical-record projection, authoritative
          day artifacts, verifier-facing manifests, disclosure classes, and
          proof binding. A deployment can later publish those outputs through
          SCITT only if a separate specification defines the publication
          semantics and any verifier processing of SCITT state. Such
          publication remains outside baseline verification defined here.
        </t>
        <t>
          This profile also differs from COSE-MERKLE in scope. COSE-MERKLE can
          supply proof encodings for future disclosure bundles, but this
          profile fixes the telemetry-specific behavior around those proofs:
          how admitted telemetry becomes canonical commitment inputs, how daily
          batching and day chaining are computed, and what verifiers report
          about exercised scope, executed checks, and skipped checks. RATS and
          similar attestation systems remain pre-admission inputs; this
          profile begins only once accepted telemetry exists.
        </t>
        <t>
          For architectural background on transparency-service publication and
          prospective Merkle proof encodings related to later disclosure
          workflows, see <xref target="SCITT"/> and
          <xref target="COSE-MERKLE"/>.
        </t>
      </section>

    </section>

    <section numbered="true" toc="include" anchor="terminology">
      <name>Conventions and Terminology</name>
      <t>
        The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
        "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>",
        "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>",
        "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>",
        "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and
        "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
        described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/>
        when, and only when, they appear in all capitals, as shown here.
      </t>
      <t>Terms:</t>
      <ul>
        <li>Frame: In the reference framed transport profile, one UTF-8 JavaScript Object Notation (JSON) text serialized as a single newline-delimited JSON (NDJSON) record, containing header and authenticated encryption with associated data (AEAD; <xref target="RFC5116"/>) fields.</li>
        <li>Canonical record: Canonical telemetry record admitted after gateway validation and projection. The term refers to the committed record shape, not to physical truth of the underlying measurement.</li>
        <li>Commitment profile: The serialization, hash, and Merkle rules that produce deterministic commitment outputs.</li>
        <li>Commitment contract: The full interoperable commitment behavior defined by this profile, including accepted telemetry admission, accepted-telemetry-to-canonical-record projection, commitment encoding, day-artifact structure, verifier-facing manifests, disclosure classes, and verification rules. The commitment profile is one component of this broader contract.</li>
        <li>Connectivity window: The deployment-defined maximum outage or buffering interval across which a device or an adjacent trusted transport component must preserve enough durable state to retransmit or disambiguate counters without replay ambiguity. It is selected by deployment policy and sizing assumptions; it is not itself a conformance timer and does not require the device to keep UTC wall-clock time.</li>
        <li>Day artifact: The authoritative canonical day record written as <tt>day/YYYY-MM-DD.cbor</tt>.</li>
        <li>Authoritative: Used for the canonical artifact that verifiers MUST treat as the cryptographic source of truth.</li>
        <li>Projection: A non-authoritative representation (for example JSON) derived from an authoritative artifact.</li>
        <li>Block metadata: A standalone projection of a batch object (for example <tt>blocks/YYYY-MM-DD-00.block.json</tt>) exported for convenience. When disclosed, it MUST match the corresponding batch object in the authoritative day artifact.</li>
        <li>OTS metadata sidecar: <tt>day/YYYY-MM-DD.ots.meta.json</tt>, a separate non-authoritative metadata file associated with an OTS proof and authoritative day artifact, linking the artifact digest to the proof path. It is not a commitment input.</li>
        <li>Anchor evidence: The proof artifacts and binding metadata disclosed for an external timestamping or attestation channel.</li>
        <li>Peer signature quorum: A deployment-defined set or threshold of peer signatures over the same day-artifact digest or day root, treated as one optional parallel attestation channel.</li>
        <li>Replay unit: The deployment-defined unit consumed exactly once for replay prevention. In the reference framed transport profile, it is the pair <tt>(dev_id, fc)</tt>, where <tt>fc</tt> is a frame counter for device <tt>dev_id</tt>.</li>
        <li>Verification scope: The set of disclosed artifacts, checks executed, and claim boundaries that a verifier actually asserts for a verification result.</li>
        <li>Day boundary: A UTC calendar day boundary. Day labels in this profile use <tt>YYYY-MM-DD</tt> in UTC.</li>
        <li>Disclosure class: The level of artifact disclosure associated with a verification claim.</li>
      </ul>
    </section>

    <section numbered="true" toc="include" anchor="roles">
      <name>System Roles</name>
      <t>
        In this document, optional parallel attestation channels are not
        required for baseline conformance. A conforming deployment MUST
        implement at least one anchoring channel, with OTS as the default
        channel described here. RFC 3161 timestamp responses and peer
        signatures MAY be absent entirely; when present, they MUST bind to the
        same authoritative day-artifact digest and verifiers MUST report their
        results separately.
      </t>
      <ul>
        <li>Device: Produces telemetry for gateway admission. Under the reference framed transport profile, that telemetry is framed as described in <xref target="frame-contract"/>.</li>
        <li>Gateway: Applies the active transport validation and anti-replay contract, projects accepted telemetry into canonical records, batches, and anchors day artifacts.</li>
        <li>Verifier: Recomputes commitments and validates proofs from disclosed artifacts.</li>
        <li>OTS Calendar(s): Provides OTS attestations for day artifact hashes.</li>
        <li>Timestamp authority (TSA): An RFC 3161 timestamp authority over the same digest, when that optional channel is used.</li>
        <li>Peers: Co-sign daily roots for short-term provenance, when that optional channel is used.</li>
      </ul>
    </section>

    <section numbered="true" toc="include" anchor="data-model">
      <name>Data and Commitment Model</name>
      <t>
        This section separates one reference framed transport profile from the
        reusable commitment contract. The most deployment-specific surface is
        the transport profile in <xref target="frame-contract"/>. The
        interoperable core is the deterministic accepted-telemetry-to-canonical-record
        projection, commitment encoding, Merkle calculation,
        day artifact, disclosure model, and verification behavior.
      </t>

      <section numbered="true" toc="include" anchor="frame-contract">
        <name>Reference Framed Transport Profile</name>
        <t>
          This section defines one reference framed transport profile. Use of
          this profile is not required for every deployment that produces the
          canonical records and day artifacts defined by this document. A
          deployment that uses a different transport MUST define equivalent
          accepted-input, anti-replay, field-source, and projection rules
          before claiming interoperability with a commitment profile.
        </t>
        <t>
          Under this reference profile, a frame is transported as
          newline-delimited JSON (NDJSON) with fields:
        </t>
        <figure>
          <artwork type="json"><![CDATA[
{
  "hdr": { "dev_id": 101, "msg_type": 1, "fc": 42, "flags": 0 },
  "nonce": "base64-24B",
  "ct": "base64-ciphertext",
  "tag": "base64-16B"
}
]]></artwork>
        </figure>
        <t>
          This reference profile uses XChaCha20-Poly1305 authenticated
          encryption with associated data (AEAD) in the sense of
          <xref target="RFC5116"/>. XChaCha20-Poly1305 is an extended-nonce
          variant of the ChaCha20-Poly1305 construction described by
          <xref target="RFC8439"/>; it is named here as a profile algorithm, and
          this document does not register a new IETF AEAD algorithm name. The
          wire shape shown here carries the encrypted payload in <tt>ct</tt>,
          carries the authentication tag separately in <tt>tag</tt>, and leaves
          <tt>hdr</tt> in cleartext. Gateways claiming this reference framed
          transport profile MUST validate header field presence, header ranges,
          nonce binding, and AEAD authentication before canonical-record
          emission.
        </t>
        <ul>
          <li><tt>hdr.dev_id</tt> MUST be an unsigned integer in the range 0..65535.</li>
          <li><tt>hdr.msg_type</tt> MUST be an unsigned integer in the range 0..255.</li>
          <li><tt>hdr.fc</tt> MUST be an unsigned integer in the range 0..(2^32-1).</li>
          <li><tt>hdr.flags</tt> MUST be an unsigned integer in the range 0..255.</li>
          <li><tt>nonce</tt> MUST be base64 text that decodes to exactly 24 bytes.</li>
          <li><tt>tag</tt> MUST be base64 text that decodes to exactly 16 bytes.</li>
        </ul>
        <t>
          A deployment claiming conformance to this reference framed transport
          profile MUST use XChaCha20-Poly1305 and MUST identify the
          key-distribution method, key epoch, and device-to-gateway key binding
          used for frame validation. For the reference wire shape shown here,
          the associated data (AAD) supplied to the AEAD algorithm is exactly
          four octets:
          <tt>uint16_be(hdr.dev_id) || uint8(hdr.msg_type) ||
          uint8(hdr.flags)</tt>. Receivers MUST derive those bytes from the
          received cleartext header before AEAD verification. A frame whose
          cleartext header values do not produce the same AAD bytes
          authenticated by the sender MUST fail validation.
        </t>
        <t>
          The reference framed transport profile fixes the 24-octet nonce
          construction to <tt>nonce = salt8 || uint64_be(hdr.fc) || tail8</tt>.
          The <tt>salt8</tt> field is the provisioned per-device
          gateway salt. The <tt>uint64_be(hdr.fc)</tt> field MUST equal the
          cleartext frame counter encoded as an unsigned 64-bit big-endian
          integer. The <tt>tail8</tt> field is deployment-generated tail
          material. The full 24-octet nonce value MUST NOT repeat under the
          same AEAD key. If a sender can emit overlapping counter-ranges after
          reset, replay-state loss, device replacement, or tail regeneration,
          the deployment MUST rotate the affected AEAD key or perform an
          explicit resynchronization before further frames are accepted. The
          <tt>nonce</tt> and <tt>tag</tt> lengths fixed here are profile-defined
          transport parameters; they are not generic AEAD defaults.
        </t>
        <ul>
          <li>Receivers MUST reject a frame whose decoded <tt>nonce</tt> length is not 24 octets.</li>
          <li>Receivers MUST reject a frame whose nonce salt does not match the device <tt>salt8</tt>.</li>
          <li>Receivers MUST reject a frame whose nonce counter does not match <tt>hdr.fc</tt>.</li>
          <li>Receivers MUST reject a frame whose <tt>hdr.flags</tt> value is not <tt>0</tt>.</li>
          <li>Receivers MUST reject AEAD failures before canonical-record commitment and MUST NOT produce committed canonical records from them.</li>
        </ul>
        <t>
          Frames that fail parse, range, nonce, or AEAD validation MUST be
          rejected before canonical-record commitment and MUST NOT produce
          committed canonical records. The <tt>hdr.fc</tt> field is bound
          through the nonce-counter check above and the anti-replay admission
          rules in <xref target="anti-replay"/>. The <tt>hdr.flags</tt> field
          has no v1 commitment or payload-interpretation semantics and MUST be
          <tt>0</tt> in this reference profile. Future semantic flags require
          a new transport profile and AAD rule.
        </t>
        <t>
          Other deployments MAY use different transport framing or different
          cryptographic suites if they preserve the acceptance semantics needed
          to produce the same canonical-record objects under
          <xref target="record-projection"/>. Such deployments MUST NOT claim
          conformance to this reference framed transport profile unless they
          use the envelope, AAD, nonce, and rejection rules defined in this
          section.
        </t>
        <t>
          The minimum device-side requirements needed to emit frames under this
          reference profile are summarized in <xref target="appendix-c"/>.
        </t>
      </section>

      <section numbered="true" toc="include" anchor="anti-replay">
        <name>Anti-Replay Admission Criterion</name>
        <t>
          For the reference framed transport profile, the replay unit is
          <tt>(dev_id, fc)</tt>. A gateway MUST commit a canonical record from
          a frame only if all of the following hold:
        </t>
        <ol>
          <li>No canonical record has already been committed for the same replay unit <tt>(dev_id, fc)</tt>.</li>
          <li>The frame counter <tt>fc</tt> is within the configured acceptance window for that device relative to durable replay state.</li>
          <li>No continuity-break, reset, or replay-state-loss condition requires explicit resynchronization before further acceptance.</li>
        </ol>
        <t>
          Frames that do not satisfy these conditions MUST NOT produce
          committed canonical records.
        </t>
        <t>
          The RECOMMENDED default acceptance window is 64 frame counter values
          per device. Frames with <tt>fc</tt> more than <tt>window_size</tt>
          behind the highest accepted counter for a device MUST be rejected.
          In the reference gateway profile defined by this document, frames
          with <tt>fc</tt> more than <tt>window_size</tt> ahead of the highest
          accepted counter MUST also be rejected, rather than silently
          accepted across a large discontinuity.
        </t>
        <t>
          The acceptance window in this section is counter-based, not a
          required wall-clock interval. Deployments can size buffering,
          retry, and resynchronization policy according to the configured
          connectivity window, but conformance here is defined by durable
          replay state and accepted counter progression rather than by device
          timekeeping.
        </t>
        <t><strong>Structured Rejection Evidence</strong></t>
        <t>
          Gateways SHOULD produce structured rejection evidence for frames
          rejected during parsing, header validation, AEAD authentication,
          anti-replay admission, or continuity-break handling. A rejection
          record SHOULD include at minimum:
        </t>
        <ul>
          <li><tt>dev_id</tt>: the received <tt>hdr.dev_id</tt> if parseable, else <tt>null</tt>;</li>
          <li><tt>fc</tt>: the received <tt>hdr.fc</tt> if parseable, else <tt>null</tt>;</li>
          <li><tt>stage</tt>: a short machine-usable stage indicator such as <tt>parse</tt>, <tt>header_validation</tt>, <tt>aead_authentication</tt>, <tt>anti_replay_admission</tt>, or <tt>continuity</tt>;</li>
          <li><tt>reason</tt>: a short machine-usable reason string;</li>
          <li><tt>observed_at_utc</tt>: the gateway-assigned observation time as an <xref target="RFC3339"/> UTC timestamp ending in <tt>Z</tt>; and</li>
          <li><tt>frame_sha256</tt>: lowercase hexadecimal SHA-256 over the exact received NDJSON octet string, excluding only trailing line terminators.</li>
        </ul>
        <t>
          The core rejection reasons defined by this profile are
          <tt>parse_error</tt>, <tt>header_range_error</tt>,
          <tt>aead_auth_failure</tt>, <tt>replay_duplicate</tt>,
          <tt>replay_window_exceeded</tt>, <tt>continuity_break</tt>, and
          <tt>resync_required</tt>. Deployments MAY add more specific reason
          values, but they SHOULD preserve these core categories when they
          apply.
        </t>
        <t>
          Rejection evidence is an audit artifact and MUST NOT be hashed into
          ledger commitments. It MUST NOT be represented as accepted telemetry
          and MUST NOT be used as a substitute for canonical-record artifacts.
        </t>
        <t><strong>Replay State Persistence</strong></t>
        <t>
          Gateways SHOULD persist replay state across restart. If replay state
          is lost, gateways SHOULD record a continuity break event and SHOULD
          NOT silently re-accept counters that could already have been
          committed.
        </t>
        <t><strong>Scope Limitation</strong></t>
        <t>
          This profile provides tamper-evidence for committed canonical
          records. It does
          not prove the absence of selective pre-commitment drops by a
          malicious gateway.
        </t>
      </section>

      <section numbered="true" toc="include" anchor="record-projection">
        <name>Accepted-Telemetry-to-Canonical-Record Projection</name>
        <t>
          The accepted-telemetry-to-canonical-record projection transforms an
          input that has passed the active transport validation and anti-replay
          contract into a canonical record suitable for commitment. The
          committed canonical record is a structured record derived from the
          accepted logical payload, not a copy of transport bytes.
        </t>
        <t>
          When the reference framed transport profile is not used, the
          deployment profile MUST define the equivalent accepted input,
          anti-replay unit, payload interpretation, and field-source rules
          before applying the canonical-record and commitment rules below.
        </t>
        <t>
          For the reference framed transport profile, the projection steps are:
        </t>
        <ol>
          <li>The gateway MUST verify AEAD authentication.</li>
          <li>The gateway MUST decrypt the ciphertext.</li>
          <li>The gateway MUST parse the decrypted plaintext according to the frame's <tt>msg_type</tt>.</li>
          <li>The gateway MUST construct a canonical-record object.</li>
          <li>The gateway MUST serialize that canonical-record object under the gateway commitment profile.</li>
          <li>The canonical-record bytes are then hashed for Merkle inclusion.</li>
        </ol>
        <t>A committed canonical record under this profile MUST contain at minimum:</t>
        <ul>
          <li><tt>pod_id</tt>,</li>
          <li><tt>fc</tt>,</li>
          <li><tt>ingest_time</tt>,</li>
          <li><tt>pod_time</tt>,</li>
          <li><tt>kind</tt>, and</li>
          <li><tt>payload</tt>.</li>
        </ul>
        <t>
          Interoperability depends on two distinct layers: the projection
          contract that maps accepted telemetry into a canonical-record object,
          and the commitment profile that serializes that canonical-record
          object and reduces the resulting digests. Independent implementations
          claiming the same
          result MUST agree on both layers.
        </t>
        <t>
          A commitment profile or deployment profile claiming conformance MUST
          fix the type and source of each committed field so independent
          implementations can construct identical canonical-record bytes.
        </t>
        <t>
          For each committed field, the applicable projection contract MUST
          state whether the field is transport-derived, payload-derived,
          gateway-assigned, or deployment metadata-derived. Independent
          implementations MUST NOT substitute a different field source while
          claiming the same projection contract.
        </t>
        <t>
          For <tt>trackone-canonical-cbor-v1</tt>, the committed canonical-record object
          has six logical fields: <tt>pod_id</tt>, <tt>fc</tt>,
          <tt>ingest_time</tt>, <tt>pod_time</tt>, <tt>kind</tt>, and
          <tt>payload</tt>. Its authoritative commitment encoding is a fixed
          Concise Binary Object Representation (CBOR) array whose positional
          elements are:
        </t>
        <ol>
          <li>schema/version discriminator, currently <tt>1</tt>;</li>
          <li><tt>pod_id</tt> encoded as an 8-byte byte string;</li>
          <li><tt>fc</tt>;</li>
          <li><tt>ingest_time</tt>;</li>
          <li><tt>pod_time</tt> or <tt>null</tt>;</li>
          <li><tt>kind</tt> as the profile-defined family discriminator; and</li>
          <li><tt>payload</tt> encoded under the applicable payload family.</li>
        </ol>
        <t>The profile-specific field definitions are:</t>
        <ul>
          <li><tt>pod_id</tt> MUST be a deterministic device identifier. When framed telemetry is used, the profile MUST define a deterministic mapping from <tt>hdr.dev_id</tt> or equivalent deployment alias to <tt>pod_id</tt>. In reader-facing JSON projections and vector notes, this profile renders the identifier as lowercase hexadecimal text such as <tt>0000000000000065</tt>. In authoritative CBOR commitment bytes, the same identifier is encoded as the corresponding 8-byte byte string.</li>
          <li><tt>fc</tt> MUST be the accepted monotonic counter as a non-negative integer. Under the reference framed transport profile, this is <tt>hdr.fc</tt>.</li>
          <li><tt>ingest_time</tt> MUST be a UTC integer timestamp fixed by the projection contract.</li>
          <li><tt>pod_time</tt> MUST be either a device-supplied integer timestamp or <tt>null</tt> when the device does not supply one.</li>
          <li><tt>kind</tt> MUST identify the record family under the applicable projection contract. In authoritative CBOR commitment bytes, this field is the numeric family discriminator defined by the commitment profile. For the current profile, the discriminator mapping is <tt>Env=1</tt>, <tt>Pipeline=2</tt>, <tt>Health=3</tt>, and <tt>Custom=250</tt>.</li>
          <li><tt>payload</tt> MUST be the parsed logical payload associated with the accepted telemetry input. Under the reference framed transport profile, this is the decrypted plaintext object.</li>
        </ul>
        <t>
          The field names <tt>pod_id</tt> and <tt>pod_time</tt> are stable
          commitment-field names for <tt>trackone-canonical-cbor-v1</tt>. They
          do not require a deployment to use pod-based lifecycle semantics.
        </t>
        <t>
          A different deployment profile MAY define additional logical fields,
          but such an extension is not compatible with
          <tt>trackone-canonical-cbor-v1</tt> unless it is given a distinct
          <tt>commitment_profile_id</tt> and corresponding conformance
          vectors.
        </t>
        <t>
          An implementation claiming parity with
          <tt>trackone-canonical-cbor-v1</tt> MUST reproduce that exact
          logical record and its fixed array encoding before applying the
          deterministic CBOR rules in <xref target="cbor-profile"/>.
        </t>
        <t>
          Ciphertext, raw transport bytes, and the authentication tag MUST NOT
          be part of the committed canonical-record object. The exact payload schema is
          deployment-specific; the deterministic projection contract is the
          normative requirement and MUST be published for any commitment profile
          that claims interoperability.
        </t>
        <t>
          Published conformance vectors for a commitment profile MUST include
          the post-projection canonical-record objects used as commitment
          inputs, not only transport inputs.
        </t>
      </section>

      <section numbered="true" toc="include" anchor="cbor-profile">
        <name>Deterministic Concise Binary Object Representation (CBOR) Commitment Encoding</name>
        <t>
          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 <tt>trackone-canonical-cbor-v1</tt> names this
          commitment recipe so verifiers can tell which byte-level rules were
          used.
        </t>
        <t>
          The authoritative commitment artifacts, namely CBOR canonical-record
          artifacts and the canonical day artifact, use a constrained
          subset of deterministic encoding under Section 4.2.1 of
          <xref target="RFC8949"/>. For commitment bytes in this profile, the
          following concrete choices apply:
        </t>
        <ul>
          <li>All commitment-path items MUST use definite-length encoding.</li>
          <li>Integers MUST use the shortest encoding width permitted by <xref target="RFC8949"/>.</li>
          <li>Map keys MUST be CBOR text strings.</li>
          <li>Map keys MUST be sorted by encoded key length ascending, then by lexicographic order of the encoded key bytes.</li>
          <li>Finite floating-point values MUST be encoded using the shortest of float16, float32, or float64 that exactly preserves the value.</li>
          <li>NaN, positive infinity, and negative infinity MUST be rejected in commitment paths.</li>
          <li>CBOR tags MUST NOT appear in commitment bytes.</li>
          <li>Supported values are unsigned integers, negative integers, byte strings, text strings, arrays, maps, booleans, null, and deterministic finite floats.</li>
        </ul>
        <t>
          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.
        </t>
        <t>
          JSON projections of canonical-record artifacts and day artifacts are
          optional and non-authoritative. They MUST NOT be used as
          commitment inputs. When produced, such projections SHOULD follow
          <xref target="RFC8785"/>.
        </t>
        <t>
          Device-side or embedded components MAY use other internal encodings,
          including different deterministic CBOR layouts optimized for local
          constraints. Those encodings are not the authoritative commitment
          encoding described here unless they are explicitly identified by a
          distinct <tt>commitment_profile_id</tt> and verified under their own
          rules.
        </t>
      </section>

      <section numbered="true" toc="include" anchor="merkle-policy">
        <name>Deterministic Commitment Tree Calculation</name>
        <t>
          For a given day <tt>D</tt>, the current commitment profile computes a
          daily root from the canonical-record commitment bytes produced under
          <xref target="cbor-profile"/>. The following steps describe that
          calculation.
        </t>
        <t><strong>Leaf Digests</strong></t>
        <ul>
          <li>Each canonical-record byte string is hashed with <tt>SHA-256</tt>, yielding a 32-byte leaf digest.</li>
        </ul>
        <t><strong>Digest Ordering</strong></t>
        <ul>
          <li>To make the daily root independent of file order or ingest order, leaf digests MUST be sorted in ascending byte order before reduction.</li>
          <li>Lowercase hexadecimal is a representation format for artifacts and examples only; internal Merkle computation operates on raw hash bytes.</li>
          <li>Sorting by lowercase hexadecimal is equivalent to bytewise ascending order over the raw digests.</li>
        </ul>
        <t><strong>Pairwise Reduction</strong></t>
        <ul>
          <li>The sorted digests are reduced pairwise by computing <tt>SHA-256(left_child_bytes || right_child_bytes)</tt>, where both operands are raw 32-byte digests.</li>
          <li>If a layer has an odd number of digests, the final digest is duplicated to form the last pair.</li>
          <li>The current commitment profile does not prepend domain-separation bytes to leaf or parent hashes.</li>
        </ul>
        <t>
          This profile relies on fixed-size 32-octet child operands for parent
          hashes and on leaf digests computed over canonical-record bytes. The
          resulting tree is a deterministic commitment profile for this document;
          it is not a general-purpose Merkle proof format. Implementations MUST
          NOT mix this hash construction with a domain-separated construction
          under the same <tt>commitment_profile_id</tt>.
        </t>
        <t><strong>Empty Day</strong></t>
        <ul>
          <li>If no canonical records are committed for the day, the daily root is the <tt>SHA-256</tt> digest of zero bytes: <tt>e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</tt>.</li>
        </ul>
        <t>
          The resulting daily root is deterministic for the set of committed
          canonical records. Because the leaf digests are sorted before
          reduction, the result depends on the committed record set rather than
          on ingestion
          order.
        </t>
        <t>
          Any future change to this calculation that alters commitment bytes
          (for example, adding domain separation) MUST use a new
          <tt>commitment_profile_id</tt>.
        </t>
      </section>

      <section numbered="true" toc="include" anchor="day-artifact-schema">
        <name>Day Artifact Schema</name>
        <t>
          The authoritative day artifact is a CBOR-encoded day record produced
          under <xref target="cbor-profile"/>. The day record contains the
          following fields:
        </t>
        <t>
          The day artifact is the stable day-scoped object of commitment
          verification in this profile. It commits to accepted canonical
          records for one UTC day through embedded batch metadata and
          <tt>day_root</tt>. It is not a transport envelope, not a publication
          statement, and not by itself a complete verification claim.
        </t>
        <t>
          A day artifact is interpreted only under an explicit
          <tt>commitment_profile_id</tt>. For
          <tt>trackone-canonical-cbor-v1</tt>, that identifier is verifier-visible
          claim context supplied by the verifier-facing day manifest or an
          explicitly profiled equivalent; it is not an in-band field of the day
          record. Verifiers MUST NOT infer the commitment profile from the file
          name, media type, day-record <tt>version</tt>, or proof sidecar alone.
        </t>
        <ul>
          <li><tt>version</tt> (uint): day-record schema version, currently 1.</li>
          <li><tt>site_id</tt> (tstr): site identifier.</li>
          <li><tt>date</tt> (tstr): UTC day label in <tt>YYYY-MM-DD</tt> form.</li>
          <li><tt>prev_day_root</tt> (tstr): previous day root as 64 lowercase hexadecimal characters.</li>
          <li><tt>batches</tt> (array): array of batch objects.</li>
          <li><tt>day_root</tt> (tstr): deterministic day root as 64 lowercase hexadecimal characters.</li>
        </ul>
        <t>Each batch object contains:</t>
        <ul>
          <li><tt>version</tt> (uint): batch-record schema version, currently 1.</li>
          <li><tt>site_id</tt> (tstr): site identifier.</li>
          <li><tt>day</tt> (tstr): UTC day label in <tt>YYYY-MM-DD</tt> form.</li>
          <li><tt>batch_id</tt> (tstr): batch identifier.</li>
          <li><tt>merkle_root</tt> (tstr): batch Merkle root as 64 lowercase hexadecimal characters.</li>
          <li><tt>count</tt> (uint): number of committed canonical records in the batch.</li>
          <li><tt>leaf_hashes</tt> (array of tstr): sorted leaf hashes as lowercase hexadecimal strings.</li>
        </ul>
        <t>
          The batch objects embedded in the day artifact are the authoritative
          batch metadata for verification.
        </t>
        <ul>
          <li>For each batch object, <tt>count</tt> MUST equal the length of <tt>leaf_hashes</tt>.</li>
          <li>For each batch object, <tt>merkle_root</tt> MUST equal the Merkle reduction of that batch's <tt>leaf_hashes</tt> under <xref target="merkle-policy"/>.</li>
          <li>The multiset union of all batch <tt>leaf_hashes</tt> for the day MUST equal the day's leaf digest multiset from which <tt>day_root</tt> is computed.</li>
        </ul>
        <t>
          <tt>day/YYYY-MM-DD.cbor</tt> is authoritative. The corresponding
          <tt>day/YYYY-MM-DD.json</tt> file is a projection only.
        </t>
        <t>
          The normative field tables in this section are consistent with the
          published commitment-family Concise Data Definition Language (CDDL)
          and vector corpus for this profile. An
          implementation claiming parity with <tt>trackone-canonical-cbor-v1</tt>
          MUST satisfy this text and reproduce the published machine-readable
          artifacts for that profile.
      </t>
      </section>

      <section numbered="true" toc="include" anchor="day-chaining">
        <name>Day Chaining</name>
        <t>Day records include <tt>prev_day_root</tt>.</t>
        <ul>
          <li>The epoch day (the first committed day) for a site MUST set <tt>prev_day_root</tt> to 64 zero characters, representing 32 zero bytes.</li>
          <li>Non-epoch days MUST set <tt>prev_day_root</tt> to the previous committed day's <tt>day_root</tt>.</li>
        </ul>
        <t>
          Because day labels are UTC-based, chaining semantics are also
          defined on UTC day boundaries.
        </t>
      </section>
    </section>

    <section numbered="true" toc="include" anchor="artifacts">
      <name>Artifacts and Verification Bundles</name>
      <t>Illustrative artifact layout:</t>
      <ul>
        <li><tt>records/&lt;record-id&gt;.cbor</tt> - authoritative canonical records</li>
        <li><tt>records/&lt;record-id&gt;.json</tt> - optional projections</li>
        <li><tt>day/YYYY-MM-DD.cbor</tt> - authoritative canonical day artifact</li>
        <li><tt>day/YYYY-MM-DD.json</tt> - optional projection</li>
        <li><tt>day/YYYY-MM-DD.verify.json</tt> - verifier-facing day manifest</li>
        <li><tt>blocks/YYYY-MM-DD-00.block.json</tt> - optional standalone block-metadata projection of one batch object</li>
        <li><tt>day/YYYY-MM-DD.cbor.sha256</tt> - convenience digest</li>
        <li><tt>day/YYYY-MM-DD.cbor.ots</tt> - OTS proof</li>
        <li><tt>day/YYYY-MM-DD.ots.meta.json</tt> - OTS binding metadata</li>
      </ul>
      <t>
        Deployments MAY store artifacts differently and MAY export them as
        bundles. The path shapes above are illustrative.
      </t>
      <t>
        Standalone block metadata files are convenience projections of batch
        objects already carried in the authoritative day artifact. They are not
        additional commitment inputs. Verifiers that process disclosed
        standalone block-metadata projections MUST compare them with the
        corresponding batch object in the authoritative day artifact and
        reject mismatches.
      </t>
      <t>
        Every verification bundle MUST disclose the
        <tt>commitment_profile_id</tt>. In this profile, the normal
        machine-readable disclosure surface is the verifier-facing day manifest
        <tt>day/YYYY-MM-DD.verify.json</tt>. That manifest carries artifact
        digests, disclosure class, channel state, and the executed or skipped
        verification checks together with the day-scoped verification result.
      </t>
      <t>
        The verifier-facing metadata binds claim semantics to the stable day
        artifact. A bundle that discloses <tt>day/YYYY-MM-DD.cbor</tt> and a
        timestamp proof but does not disclose the applicable
        <tt>commitment_profile_id</tt> can at most support artifact-digest and
        timestamp checks; it MUST NOT be represented as semantic verification
        of the day artifact.
      </t>
      <t>
        This document therefore uses the verifier manifest as the primary
        disclosure surface for verifier-visible metadata. A representative
        manifest shape is defined in <xref target="appendix-d"/>. Deployment-
        specific schemas can carry additional operational fields, but they
        MUST preserve the verifier-facing semantics defined here.
      </t>
      <t>At minimum, an OTS sidecar MUST bind:</t>
      <ul>
        <li><tt>artifact</tt>,</li>
        <li><tt>artifact_sha256</tt>, and</li>
        <li><tt>ots_proof</tt>.</li>
      </ul>
      <t>
        Verifiers MUST recompute the day artifact digest and compare it with
        the sidecar before accepting any proof validation result.
      </t>
    </section>

    <section numbered="true" toc="include" anchor="anchoring-verification">
      <name>Anchoring and Verification</name>

      <section numbered="true" toc="include" anchor="anchoring-contract">
        <name>Anchoring Contract</name>
        <t>
          The generic anchoring contract is simple: a gateway computes the
          SHA-256 digest of the authoritative day artifact and submits that
          digest to one or more external timestamping channels. Verifiers MUST
          first recompute the day artifact digest locally; proof validation
          occurs only after digest binding validation succeeds.
        </t>
        <t>
          A timestamp or attestation over the day-artifact digest proves only a
          binding to the artifact bytes. It does not identify the
          <tt>commitment_profile_id</tt>, disclosure class, or verifier checks
          exercised for a verification claim unless those semantics are also
          disclosed by verifier-facing metadata or an explicitly profiled
          publication statement.
        </t>
        <t>
          A deployment conforming to this profile MUST use at least one
          anchoring channel. OTS is the default channel described by this
          document; RFC 3161 and peer signatures are optional parallel
          channels.
        </t>
        <figure anchor="time-flow">
          <name>Illustrative Commitment and Proof Lifecycle</name>
          <artwork type="ascii-art"><![CDATA[
time ------------------------------------------------------------>

Device   |--frame-->|        |--frame-->|               |--frame-->|
Gateway  | validate | commit | validate | commit        | validate |
         |------ accepted records accumulate in one UTC day -------|
         |             write day/YYYY-MM-DD.cbor                   |
         |---------- submit digest to OTS / RFC 3161 ------------->|
Channel  |                pending / delayed proof        | upgrade |
Verifier |                                      verify later from  |
         |<---------------- disclosed bundle --------------------->|
]]></artwork>
        </figure>
        <t>
          <xref target="time-flow"/> illustrates the current lifecycle. The
          device-to-gateway transport can be intermittent, while proof
          completion or later publication can lag behind the authoritative
          day-artifact write.
        </t>
      </section>

      <section numbered="true" toc="include" anchor="ots-profile">
        <name>OTS Anchoring Profile</name>
        <t>
          When <xref target="OTS"/> is used, the gateway stamps
          <tt>SHA-256(day/YYYY-MM-DD.cbor)</tt> and stores an OTS proof plus an
          OTS sidecar.
        </t>
        <t>
          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.
        </t>

        <section numbered="true" toc="include" anchor="ots-lifecycle">
          <name>OTS Anchoring Lifecycle</name>
          <ol>
            <li><em>Submission</em>: the gateway submits the day artifact digest to one or more OTS calendars.</li>
            <li><em>Pending</em>: a calendar can return an incomplete proof while awaiting Bitcoin commitment.</li>
            <li><em>Upgrade</em>: the gateway or a background process can later upgrade the proof to include completed attestations.</li>
            <li><em>Verification</em>: a verifier recomputes the artifact digest and validates the proof.</li>
          </ol>
          <t>
            Gateways SHOULD submit to multiple independent calendars to reduce
            single-calendar unavailability risk.
          </t>
        </section>

        <section numbered="true" toc="include" anchor="delayed-anchoring">
          <name>Handling Delayed or Failed Anchoring</name>
          <t>
            If OTS submission fails, times out, or yields only an
            incomplete proof, the gateway MUST still write the
            authoritative day artifact and MUST treat OTS as a separate
            channel whose state is not yet complete. The gateway MAY
            retain a placeholder or incomplete proof artifact and MAY
            later replace or upgrade it as additional OTS evidence
            becomes available. Until a valid proof is disclosed and
            verified, verifiers MUST report the OTS channel as
            <tt>pending</tt>, <tt>missing</tt>, or <tt>failed</tt>
            according to the disclosed artifacts and local policy,
            rather than treating the day artifact itself as invalid. Any
            later replacement or upgrade of the OTS proof MUST continue
            to bind to the same authoritative day-artifact digest.
          </t>
          <t>
            Gateways MUST retain disclosed OTS proof artifacts for at
            least as long as the corresponding day artifacts remain
            available for verification under local retention policy.
          </t>
        </section>

        <section numbered="true" toc="include" anchor="proof-status-vocabulary">
          <name>Proof Status Vocabulary</name>
          <t>
            Verifiers and bundle manifests SHOULD use a consistent status
            vocabulary for OTS and optional parallel attestation channels:
          </t>
          <ul>
            <li><tt>verified</tt>: proof validation succeeded for the disclosed artifact binding.</li>
            <li><tt>pending</tt>: a proof exists but is incomplete or awaiting upgrade; this is not equivalent to invalid.</li>
            <li><tt>missing</tt>: the expected proof or channel artifact is absent.</li>
            <li><tt>failed</tt>: validation was attempted and did not succeed.</li>
            <li><tt>skipped</tt>: validation was not attempted because of disclosure class, verifier configuration, or local policy.</li>
          </ul>
          <t>
            Whether <tt>missing</tt>, <tt>pending</tt>, or <tt>skipped</tt>
            is verifier-fatal depends on the disclosure class, local verifier
            policy, and whether the relevant channel is required.
          </t>
        </section>
      </section>

      <section numbered="true" toc="include" anchor="parallel-attestation">
        <name>Optional Parallel Attestation</name>
        <t>Deployments MAY also produce:</t>
        <ul>
          <li>An <xref target="RFC3161"/> timestamp response over the same day-artifact digest.</li>
          <li>A deployment-specific peer signature quorum over the same day-artifact digest or day root.</li>
        </ul>
        <t>
          This document does not define an interoperable peer-signature
          validation profile. A deployment that reports
          <tt>peer_quorum_verification</tt> as an interoperable check MUST also
          disclose, or reference, a profile that defines the signed payload
          encoding, signature algorithm, public key or certificate identity
          model, quorum threshold, and verifier processing rules.
        </t>
        <t>
          When multiple channels are present, verifiers SHOULD validate all
          available channels independently and report per-channel results.
        </t>
        <t>
          If a verifier is configured in strict mode for optional channels,
          failure of those channels MUST cause overall verification failure.
        </t>
      </section>

      <section numbered="true" toc="include" anchor="verify">
        <name>Verification</name>
        <t>
          Verifiers MUST first determine the applicable
          <tt>commitment_profile_id</tt> from disclosed verifier metadata. When
          the authoritative day artifact does not carry that identifier
          in-band, the verifier MUST obtain it from
          <tt>day/YYYY-MM-DD.verify.json</tt> or an explicitly profiled manifest
          with equivalent verifier-visible fields and MUST reject absent or
          unsupported values.
        </t>
        <t>
          The verifier MUST treat <tt>commitment_profile_id</tt> as the semantic
          key for interpreting the authoritative day artifact. A structurally
          well-formed day artifact and a valid timestamp proof are insufficient
          for semantic verification if the applicable
          <tt>commitment_profile_id</tt> is absent, unsupported, or not bound to
          the same disclosed day-artifact digest.
        </t>
        <t>
          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.
        </t>
        <t>
          Verifiers SHOULD apply checks in the following fail-fast order,
          subject to the claimed disclosure class:
        </t>
        <ol>
          <li>Validate that disclosed artifacts are sufficient for the claimed disclosure class and disclose a <tt>commitment_profile_id</tt>, and report <tt>bundle_disclosure_validation</tt>.</li>
          <li>Validate the authoritative day artifact and, when disclosed or consumed, the verifier-facing manifest, and report <tt>day_artifact_validation</tt> and <tt>verification_manifest_validation</tt> as applicable.</li>
          <li>For Class A bundles, recompute canonical-record leaf digests from disclosed canonical-record CBOR artifacts, validate the batch metadata contract, and recompute <tt>day_root</tt>. Compare the recomputed result to the authoritative <tt>day_root</tt>, and report <tt>record_level_recompute</tt> and <tt>batch_metadata_validation</tt>.</li>
          <li>For Class B bundles, validate the authoritative day artifact and any disclosed batch metadata. If withheld material prevents public recomputation, report <tt>record_level_recompute</tt> in <tt>checks_skipped</tt>. Deployment-specific withheld-material checks MAY be reported only through extension names beginning with <tt>x-</tt>.</li>
          <li>For Class C bundles, report <tt>record_level_recompute</tt> and <tt>batch_metadata_validation</tt> in <tt>checks_skipped</tt> as out of scope, and treat the result as anchor-only evidence.</li>
          <li>Recompute <tt>SHA-256(day/YYYY-MM-DD.cbor)</tt> and compare it to the sidecar <tt>artifact_sha256</tt>, and report <tt>day_digest_binding</tt>.</li>
          <li>Validate the OTS proof when OTS is required or present, and report <tt>ots_verification</tt>.</li>
          <li>Validate optional RFC 3161 and peer attestations as configured, and report <tt>tsa_verification</tt> or <tt>peer_quorum_verification</tt> as applicable.</li>
        </ol>
        <t>
          When batch metadata is within the exercised verification scope,
          verifiers MUST apply the following checks before accepting a result:
        </t>
        <ul>
          <li>each batch <tt>count</tt> equals the length of its <tt>leaf_hashes</tt>;</li>
          <li>each batch <tt>merkle_root</tt> equals the Merkle reduction of its <tt>leaf_hashes</tt>;</li>
          <li>the union multiset of batch <tt>leaf_hashes</tt> equals the leaf digest multiset derived from disclosed canonical records when canonical-record artifacts are available; and</li>
          <li>any standalone block-metadata projection matches the corresponding batch object in the authoritative day artifact.</li>
        </ul>
        <t>
          Verifier implementations SHOULD expose machine-usable failure
          categories:
        </t>
        <ul>
          <li>malformed or missing artifacts,</li>
          <li>missing or unsupported <tt>commitment_profile_id</tt>,</li>
          <li>Merkle mismatch,</li>
          <li>batch metadata mismatch,</li>
          <li>missing or invalid OTS proof,</li>
          <li>sidecar mismatch or digest mismatch,</li>
          <li>insufficient disclosure for the claimed verification level, and</li>
          <li>optional-channel failure.</li>
        </ul>
        <t>
          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.
        </t>
        <t><strong>Standardized Check Identifiers</strong></t>
        <t>
          When verifier-facing manifests or verifier results report
          <tt>checks_executed</tt> or <tt>checks_skipped</tt>, this profile
          defines the following interoperable check identifiers:
        </t>
        <ul>
          <li><tt>bundle_disclosure_validation</tt>: disclosure-class sufficiency and <tt>commitment_profile_id</tt> presence were validated.</li>
          <li><tt>verification_manifest_validation</tt>: the verifier-facing manifest was validated.</li>
          <li><tt>day_artifact_validation</tt>: the authoritative day artifact was validated structurally and semantically under the claimed profile.</li>
          <li><tt>record_level_recompute</tt>: record-level recomputation from disclosed canonical-record artifacts was performed.</li>
          <li><tt>batch_metadata_validation</tt>: authoritative or disclosed batch metadata was validated against the day artifact and disclosed record material within scope.</li>
          <li><tt>day_digest_binding</tt>: the recomputed <tt>SHA-256(day/YYYY-MM-DD.cbor)</tt> digest was compared with disclosed binding metadata.</li>
          <li><tt>ots_verification</tt>: the OTS proof channel was validated.</li>
          <li><tt>tsa_verification</tt>: the RFC 3161 timestamp channel was validated.</li>
          <li><tt>peer_quorum_verification</tt>: the peer-signature quorum channel was validated.</li>
        </ul>
        <t>
          A manifest or 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 manifest or verifier result MUST
          report that check exactly once in either <tt>checks_executed</tt> or
          <tt>checks_skipped</tt>. 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.
        </t>
        <t>
          Applicability is determined as follows:
        </t>
        <ul>
          <li><tt>bundle_disclosure_validation</tt> and <tt>day_artifact_validation</tt> apply whenever verification proceeds on a disclosed bundle.</li>
          <li><tt>verification_manifest_validation</tt> applies when a verifier-facing manifest is disclosed or consumed to obtain verifier-visible metadata.</li>
          <li>For Class A bundles, <tt>record_level_recompute</tt>, <tt>batch_metadata_validation</tt>, and <tt>day_digest_binding</tt> apply. If required artifacts for one of these checks are absent, that check MUST appear in <tt>checks_skipped</tt> with a reason indicating insufficient disclosure or missing artifacts.</li>
          <li>For Class B bundles, <tt>batch_metadata_validation</tt> and <tt>day_digest_binding</tt> apply when the corresponding artifacts are disclosed. If withheld material prevents public recomputation, <tt>record_level_recompute</tt> MUST appear in <tt>checks_skipped</tt>.</li>
          <li>For Class C bundles, <tt>record_level_recompute</tt> and <tt>batch_metadata_validation</tt> MUST appear in <tt>checks_skipped</tt> as out of scope, while <tt>day_digest_binding</tt> applies when the day artifact and binding metadata are disclosed.</li>
          <li><tt>ots_verification</tt>, <tt>tsa_verification</tt>, and <tt>peer_quorum_verification</tt> apply only when the corresponding channel is disclosed or required by verifier policy.</li>
        </ul>
        <t>
          Additional deployment-specific checks MAY be reported, but they MUST
          NOT redefine these identifiers and MUST use a distinct extension
          name beginning with <tt>x-</tt>.
        </t>
        <t>
          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.
        </t>
      </section>
    </section>

    <section numbered="true" toc="include" anchor="disclosure-bundles">
      <name>Disclosure Classes</name>
      <t>
        Verification claims depend on what artifacts are disclosed. This
        profile defines three disclosure classes.
      </t>
      <ul>
        <li><strong>Class A (Public Recompute)</strong>: sufficient material for independent record-level recomputation.</li>
        <li><strong>Class B (Partner Audit)</strong>: controlled disclosure with redacted or partitioned record material.</li>
        <li><strong>Class C (Anchor-Only)</strong>: existence and timestamp evidence only.</li>
      </ul>
      <t>
        A verifier claim for any disclosure class MUST be limited to the
        verification scope supported by the disclosed artifacts.
      </t>
      <t>
        Class A is the public-recompute case. A Class A bundle MUST include:
      </t>
      <ul>
        <li>all canonical-record artifacts required to recompute the claimed day root,</li>
        <li>the canonical day artifact, including its authoritative batch objects,</li>
        <li>any disclosed standalone block-metadata projections, and</li>
        <li>the OTS proof plus its sidecar metadata.</li>
      </ul>
      <t>
        A Class A bundle SHOULD also include the verifier-facing day manifest
        and MUST record the <tt>commitment_profile_id</tt>.
      </t>
      <t>
        Class A permits record-level recomputation, batch-metadata
        validation, day-root recomputation, and anchor validation when the
        corresponding artifacts are disclosed and checked.
      </t>
      <t>
        Class B is the controlled-disclosure case. Class B outputs MUST NOT be
        represented as publicly recomputable. A Class B bundle SHOULD include
        the canonical day artifact, any disclosed standalone block-metadata
        projections, at least one timestamp proof plus its binding metadata,
        any disclosed commitments covering withheld material, and a policy
        artifact describing the withheld or partitioned material.
      </t>
      <t>
        This document defines the reporting boundary for Class B but does not
        require one universal withheld-material artifact format. Class B
        validation is therefore limited to the authoritative day artifact,
        disclosed batch metadata, any disclosed withheld-material commitments,
        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. If deployment-specific checks are
        reported for withheld-material commitments or policy artifacts, they
        MUST use extension names beginning with <tt>x-</tt>.
      </t>
      <t>
        A Class C disclosure MUST be labeled as existence and timestamp
        evidence only and MUST NOT claim record-level reproducibility.
      </t>
      <t>A Class C bundle MUST include:</t>
      <ul>
        <li>the canonical day artifact, and</li>
        <li>at least one timestamp proof artifact plus the metadata needed to bind it to the day artifact digest and disclose <tt>commitment_profile_id</tt>.</li>
      </ul>
      <t>
        Class C verification validates artifact-digest binding and external
        timestamp evidence only. It does not establish record-level
        reproducibility.
      </t>
      <t>
        Class C verifier output SHOULD be reported as anchor-only evidence.
      </t>
      <t><strong>Bundle Selection Guidance</strong></t>
      <ul>
        <li>Class A is appropriate when the goal is public recomputation from disclosed canonical records and authoritative artifacts, for example when a regulator or external researcher needs independent replay of the disclosed day.</li>
        <li>Class B is appropriate when the goal is partner or regulator review over a controlled disclosure set that still carries commitment and anchor evidence, for example when some record content must remain withheld while the committed day artifact is still audited.</li>
        <li>Class C is appropriate when the goal is existence and timestamp evidence without public record-level reproducibility, for example when a party only needs to show that a committed artifact existed by a given time.</li>
      </ul>
      <t>
        The verifier-facing manifest MUST include:
      </t>
      <ul>
        <li><tt>disclosure_class</tt>,</li>
        <li><tt>commitment_profile_id</tt>,</li>
        <li>artifact path and digest entries,</li>
        <li>per-channel anchor status,</li>
        <li>a list of checks executed using the standardized identifiers defined in <xref target="verify"/>, and</li>
        <li>a list of checks skipped, each with the standardized check identifier and the reason for the skip.</li>
      </ul>
    </section>

    <section numbered="true" toc="include" anchor="versioning">
      <name>Versioning</name>
      <t>
        This profile has several independent version surfaces:
      </t>
      <ul>
        <li>Document revision (for example <tt>-00</tt>, <tt>-01</tt>) is editorial and is not part of commitment output.</li>
        <li>Artifact schema versions are carried by the <tt>version</tt> fields in day and batch records.</li>
        <li><tt>commitment_profile_id</tt> identifies the canonical CBOR, hash, and Merkle rules that define commitment outputs.</li>
      </ul>
      <t>
        The commitment profile defined in this document is
        <tt>trackone-canonical-cbor-v1</tt>. If a verifier encounters an unsupported
        <tt>commitment_profile_id</tt>, it MUST reject the verification claim
        rather than silently using a fallback interpretation.
      </t>
      <t>
        This revision defines exactly one <tt>commitment_profile_id</tt> and
        does not define an allocation policy or registry for additional
        profile identifiers. Future <tt>commitment_profile_id</tt> values are
        out of scope for this document and would require separate
        specification and review.
      </t>
      <t>
        Bundles disclose the applicable <tt>commitment_profile_id</tt> via the
        verifier-facing day manifest. The required OTS sidecar metadata does
        not currently carry that identifier.
      </t>
      <t>
        A day-record <tt>version</tt> identifies the schema of the day artifact
        under a known commitment profile. It is not a substitute for
        <tt>commitment_profile_id</tt>. 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.
      </t>
    </section>

    <section numbered="true" toc="include" anchor="conformance-vectors">
      <name>Conformance Vectors</name>
      <t>
        Determinism claims in this profile are testable. Implementations that
        claim conformance to a published commitment profile MUST be able to
        reproduce its published machine-readable corpus. For
        <tt>trackone-canonical-cbor-v1</tt>, the authoritative
        commitment-family CDDL and vector corpus define the machine-readable
        conformance artifacts for this profile. The appendix in this document
        is explanatory only.
      </t>
      <t>Published vector sets should include coverage for:</t>
      <ul>
        <li>post-projection canonical-record fixtures with fixed field types and values,</li>
        <li>empty day,</li>
        <li>single canonical record,</li>
        <li>odd leaf count,</li>
        <li>power-of-two leaf count,</li>
        <li>duplicate leaf hashes,</li>
        <li>epoch chaining,</li>
        <li>non-epoch chaining, and</li>
        <li>a full Class A disclosure example.</li>
      </ul>
      <t>
        Cross-implementation checks MUST verify byte-for-byte parity across
        independent implementations. Any mismatch in canonical bytes or roots
        is a conformance failure.
      </t>
      <t>
        Published vector bundles MUST include the
        <tt>commitment_profile_id</tt>.
      </t>
    </section>

    <section numbered="true" toc="include" anchor="security">
      <name>Security Considerations</name>
      <t>
        This profile does not introduce new cryptographic primitives. Its
        security depends on correct AEAD use on the transport path,
        deterministic commitment encoding, trustworthy gateway admission and
        timekeeping, accurate verifier reporting, and disciplined artifact and
        proof handling. The threats below are stated in the threat-and-
        remediation style described by <xref target="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.
      </t>
      <t><strong>Gateway Compromise and Pre-Commit Omission</strong></t>
      <t>
        An attacker can compromise the gateway or the local admission path and
        then fabricate accepted telemetry, suppress received telemetry before
        commitment, or assign accepted telemetry to the wrong device or UTC day.
        This profile does not by itself detect a malicious gateway; it makes
        committed outputs tamper-evident only after commitment. Deployments that need
        stronger assurances should harden and audit the gateway, protect
        admission and replay state, protect gateway time sources, and add
        independent observation, device attestation inputs, or admission-path
        audit evidence.
      </t>
      <t><strong>Replay and Duplicate Submission</strong></t>
      <t>
        An attacker can replay a previously observed frame or resubmit a frame
        with reused <tt>(dev_id, fc)</tt> values in an attempt to create
        duplicate committed records or counter ambiguity. Gateways mitigate
        this attack by enforcing single-consumption of the replay unit
        <tt>(dev_id, fc)</tt>, by rejecting counters outside the configured
        acceptance window, and by recording continuity-break conditions
        instead of silently re-accepting ambiguous counters after
        replay-state loss.
      </t>
      <t><strong>Nonce Misuse and Transport-Key Compromise</strong></t>
      <t>
        An attacker can recover plaintext or forge framed transport messages if
        AEAD keys are disclosed, if nonce uniqueness fails under a key, or if
        weak generation causes nonce-tail repetition. Implementations
        mitigate this attack by rejecting frames that fail AEAD authentication
        before commitment, by enforcing the nonce construction and checks in
        <xref target="frame-contract"/>, by assigning a clear key epoch to each
        device-to-gateway key, and by using durable uniqueness discipline for
        the deployment-generated tail material and frame counter. Reuse of
        nonce under the same AEAD key can invalidate confidentiality and can
        also invalidate integrity, depending on the AEAD algorithm. If a durable
        counter or tail state is lost, or if a device can resume with an
        overlapping counter-range, the deployment MUST treat further frames
        under that key as unsafe until resynchronization or rekeying has
        occurred. This profile therefore depends on deployment key management
        to prevent unsafe key and nonce reuse and to retire compromised keys.
      </t>
      <t><strong>Canonicalization, Profile, and Metadata Confusion</strong></t>
      <t>
        An attacker can exploit differences in parsing, field typing, record
        ordering, hash composition, or non-authoritative metadata handling
        while implementations still claim the same
        <tt>commitment_profile_id</tt>. An attacker can also present a
        verifier-facing manifest, block-metadata projection, or OTS sidecar
        that does not match the authoritative day artifact in the hope that a
        verifier will treat convenience metadata as authoritative. The
        mitigation is that this profile fixes deterministic encoding and hash
        rules, treats the authoritative day artifact as the cryptographic
        source of truth, requires verifiers to recompute commitment material
        from authoritative artifacts, requires the applicable
        <tt>commitment_profile_id</tt> to be disclosed and bound to the same
        day-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
        <tt>commitment_profile_id</tt>.
      </t>
      <t><strong>Artifact Mutation and Proof Substitution</strong></t>
      <t>
        An attacker can modify a committed day artifact after disclosure, or
        can present a valid proof over the wrong artifact digest. The
        mitigation is that verifiers recompute the authoritative day-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.
      </t>
      <t><strong>Calendar Withholding and Optional-Channel Downgrade</strong></t>
      <t>
        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. Implementations mitigate this
        attack by treating timestamping and other attestations as separate
        channels, by disclosing per-channel status explicitly, by
        distinguishing <tt>pending</tt>,
        <tt>missing</tt>, and <tt>failed</tt> from <tt>verified</tt>, and by
        binding every exercised channel to the same authoritative day-artifact
        digest. Using multiple independent calendars reduces but does not
        eliminate coordinated withholding risk. Verifier policy must make
        clear which channels are required and must not treat an unverified
        required channel as success.
      </t>
      <t><strong>Time-Source Manipulation</strong></t>
      <t>
        An attacker can alter the gateway clock or day-rollover configuration
        so that accepted records are assigned to the wrong UTC day or are
        given misleading <tt>ingest_time</tt> values. The device is not the time
        authority in this profile; the gateway is. Implementations therefore
        mitigate this attack by maintaining a trustworthy gateway time source,
        monitoring rollover behavior, and treating UTC day assignment as a
        security-relevant operational function. Verification can detect
        internal inconsistencies in disclosed artifacts, but it cannot
        reconstruct true real-world time if the gateway time base was wrong at
        acceptance.
      </t>
      <t><strong>Resource Exhaustion</strong></t>
      <t>
        An attacker can flood a deployment with malformed, replayed, or
        excessive-rate frames in order to exhaust buffering, replay-state
        storage, artifact storage, or verifier computation. Implementations
        mitigate this attack by rejecting malformed or AEAD-invalid frames before
        commitment, bounding acceptance windows and retained replay state,
        sizing local storage and retention policy explicitly, and applying
        rate limits or other admission controls to untrusted senders. This
        profile does not define a complete denial-of-service defense.
      </t>
      <t><strong>Verification Scope, Completeness, and Disclosure</strong></t>
      <t>
        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.
      </t>
    </section>

    <section numbered="true" toc="include" anchor="privacy">
      <name>Privacy Considerations</name>
      <t>
        Telemetry payloads can include sensitive operational data. Operators
        should:
      </t>
      <ul>
        <li>minimize personally identifiable data in committed artifacts,</li>
        <li>separate identity metadata from measurement payload when possible,</li>
        <li>apply retention and access controls, and</li>
        <li>publish only data appropriate for the chosen disclosure class.</li>
      </ul>
      <t>
        Privacy-preserving disclosures remain valid, but they MUST NOT be
        described as publicly recomputable unless Class A conditions are met.
      </t>
    </section>

    <section numbered="true" toc="include" anchor="iana">
      <name>IANA Considerations</name>
      <t>
        This section follows the guidance in <xref target="RFC8126"/> and
        provides the complete instructions for the Internet Assigned
        Numbers Authority (IANA).
      </t>

      <section numbered="true" toc="default" anchor="iana-media-type">
        <name>Media Types Registry</name>
        <t>
          IANA is requested to register the following media type in the
          standards tree of the "Media Types" registry in accordance with
          <xref target="RFC6838"/>:
        </t>
        <t>
          Type name: <tt>application</tt>
        </t>
        <t>
          Subtype name: <tt>trackone-day+cbor</tt>
        </t>
        <t>
          Required parameters: none
        </t>
        <t>
          Optional parameters: none
        </t>
        <t>
          Encoding considerations: binary
        </t>
        <t>
          Security considerations: see <xref target="security"/>, especially
          profile and metadata confusion, artifact mutation, proof
          substitution, disclosure scope, and resource exhaustion.
        </t>
        <t>
          Interoperability considerations: this media type identifies the
          authoritative day-artifact family defined by
          <xref target="cbor-profile"/>, <xref target="merkle-policy"/>,
          <xref target="day-artifact-schema"/>, and
          <xref target="day-chaining"/>. A recipient still needs the
          applicable <tt>commitment_profile_id</tt> to interpret canonical
          CBOR, hash, and Merkle semantics for a verification claim.
        </t>
        <t>
          Published specification: this document, especially
          <xref target="cbor-profile"/>, <xref target="merkle-policy"/>,
          <xref target="day-artifact-schema"/>, and
          <xref target="day-chaining"/>.
        </t>
        <t>
          Applications that use this media type: gateways, verifiers,
          disclosure tooling, and archival or audit systems that exchange or
          retain authoritative day artifacts.
        </t>
        <t>
          Fragment identifier considerations: no fragment identifier syntax is
          defined by this document for <tt>application/trackone-day+cbor</tt>.
          Fragment identifiers, if present, are processed according to the
          <tt>+cbor</tt> structured syntax suffix rules in
          <xref target="RFC8949"/>.
        </t>
        <t>
          Additional information:
        </t>
        <ul>
          <li>Magic number(s): none</li>
          <li>File extension(s): none</li>
          <li>Macintosh file type code(s): none</li>
        </ul>
        <t>
          Person &amp; email address to contact for further information:
          Bilal El Khatabi &lt;elkhatabibilal@gmail.com&gt;
        </t>
        <t>
          Intended usage: COMMON
        </t>
        <t>
          Restrictions on usage: none
        </t>
        <t>
          Author: Bilal El Khatabi
        </t>
        <t>
          Change controller: IESG
        </t>
      </section>

      <section numbered="true" toc="default" anchor="iana-no-cbor-tag">
        <name>No CBOR Tag Allocation</name>
        <t>
          This document requests no new CBOR tag allocation. Commitment bytes
          defined by <xref target="cbor-profile"/> forbid CBOR tags, and the
          authoritative day artifact defined by
          <xref target="day-artifact-schema"/> does not require additional tag
          semantics for exchange.
        </t>
      </section>

      <section numbered="true" toc="default" anchor="iana-no-profile-registry">
        <name>No commitment_profile_id Registry</name>
        <t>
          This document requests no IANA registry for
          <tt>commitment_profile_id</tt>. This revision defines only the
          document-specific identifier <tt>trackone-canonical-cbor-v1</tt> and
          does not establish a registry or general allocation mechanism for
          future commitment-profile identifiers.
        </t>
        <t>
          This document also requests no CoAP Content-Format entry and no
          separate media-type registration for the verifier-facing day
          manifest.
        </t>
      </section>
    </section>

    <section numbered="true" toc="include" anchor="interop-notes">
      <name>Future Extension Points</name>
      <t>
        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.
      </t>
      <ul>
        <li>A future specification can register a media type for the verifier-facing day manifest.</li>
        <li>A future SCITT publication profile can define statement content, submission procedure, and verifier processing for published verifier manifests or exported evidence bundles.</li>
        <li>A future disclosure profile can standardize a universal Class B withheld-material artifact format.</li>
        <li>A future disclosure profile can adopt COSE-MERKLE proof encodings.</li>
        <li>A future registry policy can cover disclosure-class and anchor-status vocabularies if multiple independent specifications need shared allocation.</li>
        <li>A future commitment profile can introduce domain separation for leaf or parent hashes under a distinct <tt>commitment_profile_id</tt>.</li>
      </ul>
    </section>
  </middle>

  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
      <reference anchor="RFC2119" target="https://www.rfc-editor.org/rfc/rfc2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="Scott Bradner" initials="S." surname="Bradner"/>
          <date year="1997" month="March"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>
      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="Benjamin Leiba" initials="B." surname="Leiba"/>
          <date year="2017" month="May"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>
      <reference anchor="RFC8949" target="https://www.rfc-editor.org/rfc/rfc8949">
        <front>
          <title>Concise Binary Object Representation (CBOR)</title>
          <author fullname="Carsten Bormann" initials="C." surname="Bormann"/>
          <author fullname="Paul Hoffman" initials="P." surname="Hoffman"/>
          <date year="2020" month="December"/>
        </front>
        <seriesInfo name="STD" value="94"/>
        <seriesInfo name="RFC" value="8949"/>
        <seriesInfo name="DOI" value="10.17487/RFC8949"/>
      </reference>
      <reference anchor="RFC6838" target="https://www.rfc-editor.org/rfc/rfc6838">
        <front>
          <title>Media Type Specifications and Registration Procedures</title>
          <author fullname="Ned Freed" initials="N." surname="Freed"/>
          <author fullname="John Klensin" initials="J." surname="Klensin"/>
          <author fullname="Ted Hansen" initials="T." surname="Hansen"/>
          <date year="2013" month="January"/>
        </front>
        <seriesInfo name="BCP" value="13"/>
        <seriesInfo name="RFC" value="6838"/>
        <seriesInfo name="DOI" value="10.17487/RFC6838"/>
      </reference>
      <reference anchor="RFC3339" target="https://www.rfc-editor.org/rfc/rfc3339">
        <front>
          <title>Date and Time on the Internet: Timestamps</title>
          <author fullname="Graham Klyne" initials="G." surname="Klyne"/>
          <author fullname="Chris Newman" initials="C." surname="Newman"/>
          <date year="2002" month="July"/>
        </front>
        <seriesInfo name="RFC" value="3339"/>
        <seriesInfo name="DOI" value="10.17487/RFC3339"/>
      </reference>
      </references>

      <references>
        <name>Informative References</name>
      <reference anchor="RFC8126" target="https://www.rfc-editor.org/rfc/rfc8126">
        <front>
          <title>Guidelines for Writing an IANA Considerations Section in RFCs</title>
          <author fullname="Michelle Cotton" initials="M." surname="Cotton"/>
          <author fullname="Benjamin Leiba" initials="B." surname="Leiba"/>
          <author fullname="Thomas Narten" initials="T." surname="Narten"/>
          <date year="2017" month="June"/>
        </front>
        <seriesInfo name="BCP" value="26"/>
        <seriesInfo name="RFC" value="8126"/>
        <seriesInfo name="DOI" value="10.17487/RFC8126"/>
      </reference>
      <reference anchor="RFC3552" target="https://www.rfc-editor.org/rfc/rfc3552">
        <front>
          <title>Guidelines for Writing RFC Text on Security Considerations</title>
          <author fullname="S. Rescorla"/>
          <author fullname="B. Korver"/>
          <date year="2003" month="July"/>
        </front>
        <seriesInfo name="BCP" value="72"/>
        <seriesInfo name="RFC" value="3552"/>
        <seriesInfo name="DOI" value="10.17487/RFC3552"/>
      </reference>
      <reference anchor="RFC5116" target="https://www.rfc-editor.org/rfc/rfc5116.html">
        <front>
          <title>An Interface and Algorithms for Authenticated Encryption</title>
          <author fullname="D. McGrew"/>
          <date year="2008" month="January"/>
        </front>
        <seriesInfo name="RFC" value="5116"/>
        <seriesInfo name="DOI" value="10.17487/RFC5116"/>
      </reference>
      <reference anchor="RFC8439" target="https://www.rfc-editor.org/rfc/rfc8439">
        <front>
          <title>ChaCha20 and Poly1305 for IETF Protocols</title>
          <author fullname="Y. Nir"/>
          <author fullname="A. Langley"/>
          <date year="2018" month="June"/>
        </front>
        <seriesInfo name="RFC" value="8439"/>
        <seriesInfo name="DOI" value="10.17487/RFC8439"/>
      </reference>
      <reference anchor="RFC3161" target="https://www.rfc-editor.org/rfc/rfc3161">
        <front>
          <title>Internet X.509 Public Key Infrastructure Timestamp Protocol (TSP)</title>
          <author fullname="C. Adams"/>
          <author fullname="P. Cain"/>
          <author fullname="D. Pinkas"/>
          <author fullname="R. Zuccherato"/>
          <date year="2001" month="August"/>
        </front>
        <seriesInfo name="RFC" value="3161"/>
        <seriesInfo name="DOI" value="10.17487/RFC3161"/>
      </reference>
      <reference anchor="RFC8785" target="https://www.rfc-editor.org/rfc/rfc8785">
        <front>
          <title>JSON Canonicalization Scheme (JCS)</title>
          <author fullname="Anders Rundgren" initials="A." surname="Rundgren"/>
          <author fullname="B. Jordan"/>
          <author fullname="S. Erdtman"/>
          <date year="2020" month="June"/>
        </front>
        <seriesInfo name="RFC" value="8785"/>
        <seriesInfo name="DOI" value="10.17487/RFC8785"/>
      </reference>
      <reference anchor="RFC8610" target="https://www.rfc-editor.org/rfc/rfc8610">
        <front>
          <title>Concise Data Definition Language (CDDL): A Notational Convention to Express CBOR and JSON Data Structures</title>
          <author fullname="Carsten Bormann" initials="C." surname="Bormann"/>
          <author fullname="Paul Hoffman" initials="P." surname="Hoffman"/>
          <date year="2019" month="June"/>
        </front>
        <seriesInfo name="RFC" value="8610"/>
        <seriesInfo name="DOI" value="10.17487/RFC8610"/>
      </reference>
      <reference anchor="RFC9162" target="https://www.rfc-editor.org/rfc/rfc9162.html">
        <front>
          <title>Certificate Transparency Version 2.0</title>
          <author fullname="B. Laurie"/>
          <author fullname="E. Messeri"/>
          <author fullname="R. Stradling"/>
          <date year="2021" month="December"/>
        </front>
        <seriesInfo name="RFC" value="9162"/>
        <seriesInfo name="DOI" value="10.17487/RFC9162"/>
      </reference>
      <reference anchor="SCITT" target="https://datatracker.ietf.org/doc/draft-ietf-scitt-architecture/">
        <front>
          <title>An Architecture for Trustworthy and Transparent Digital Supply Chains</title>
          <author fullname="Henk Birkholz" initials="H." surname="Birkholz"/>
          <author fullname="Antoine Delignat-Lavaud" initials="A." surname="Delignat-Lavaud"/>
          <author fullname="Cedric Fournet" initials="C." surname="Fournet"/>
          <author fullname="Yogesh Deshpande" initials="Y." surname="Deshpande"/>
          <author fullname="Steve Lasker" initials="S." surname="Lasker"/>
          <date year="2024"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-scitt-architecture"/>
      </reference>
      <reference anchor="COSE-MERKLE" target="https://datatracker.ietf.org/doc/draft-ietf-cose-merkle-tree-proofs/">
        <front>
          <title>COSE Merkle Tree Proofs</title>
          <author fullname="Orie Steele" initials="O." surname="Steele"/>
          <author fullname="Henk Birkholz" initials="H." surname="Birkholz"/>
          <author fullname="Antoine Delignat-Lavaud" initials="A." surname="Delignat-Lavaud"/>
          <author fullname="Cedric Fournet" initials="C." surname="Fournet"/>
          <date year="2025"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-ietf-cose-merkle-tree-proofs"/>
      </reference>
      <reference anchor="OTS" target="https://opentimestamps.org/">
        <front>
          <title>OpenTimestamps Protocol and Tooling</title>
          <author>
            <organization>OpenTimestamps Project</organization>
          </author>
          <date year="2016"/>
        </front>
      </reference>
      <reference anchor="RFC9334" target="https://www.rfc-editor.org/rfc/rfc9334">
        <front>
          <title>Remote ATtestation procedureS (RATS) Architecture</title>
          <author fullname="Henk Birkholz" initials="H." surname="Birkholz"/>
          <author fullname="Dave Thaler" initials="D." surname="Thaler"/>
          <author fullname="Michael Richardson" initials="M." surname="Richardson"/>
          <author fullname="Ned Smith" initials="N." surname="Smith"/>
          <author fullname="Wei Pan" initials="W." surname="Pan"/>
          <date year="2023" month="January"/>
        </front>
        <seriesInfo name="RFC" value="9334"/>
        <seriesInfo name="DOI" value="10.17487/RFC9334"/>
      </reference>
      </references>
    </references>

    <section numbered="true" toc="include" anchor="appendix-a">
      <name>Example Verification Manifest</name>
      <t>
        This appendix shows a representative verifier-facing day manifest. A
        concrete deployment schema can carry additional operational fields, but
        the example below captures the verification surface described here.
        The <tt>frame_count</tt> and <tt>frames_file</tt> fields shown here are
        optional operational fields for a deployment using the reference framed
        transport profile; they are not required inputs to the baseline
        commitment or verification claim.
      </t>
      <figure>
        <artwork type="json"><![CDATA[
{
  "version": 1,
  "date": "2025-10-07",
  "site": "an-001",
  "device_id": "device-003",
  "frame_count": 7,
  "records_dir": "records",
  "frames_file": "frames.ndjson",
  "artifacts": {
    "day_cbor": {
      "path": "day/2025-10-07.cbor",
      "sha256": "<64 hex chars>"
    },
    "day_json": {
      "path": "day/2025-10-07.json",
      "sha256": "<64 hex chars>"
    },
    "day_ots": {
      "path": "day/2025-10-07.cbor.ots",
      "sha256": "<64 hex chars>"
    },
    "day_ots_meta": {
      "path": "day/2025-10-07.ots.meta.json",
      "sha256": "<64 hex chars>"
    }
  },
  "anchoring": {
    "policy": { "mode": "warn" },
    "channels": {
      "ots": { "enabled": true, "status": "verified" },
      "tsa": {
        "enabled": false,
        "status": "skipped",
        "reason": "disabled"
      },
      "peers": {
        "enabled": false,
        "status": "skipped",
        "reason": "disabled"
      }
    },
    "overall": "success"
  },
  "verification_bundle": {
    "disclosure_class": "A",
    "commitment_profile_id": "trackone-canonical-cbor-v1",
    "checks_executed": [
      "bundle_disclosure_validation",
      "day_artifact_validation",
      "verification_manifest_validation",
      "record_level_recompute",
      "batch_metadata_validation",
      "day_digest_binding",
      "ots_verification"
    ],
    "checks_skipped": [
      { "check": "tsa_verification", "reason": "disabled" },
      { "check": "peer_quorum_verification", "reason": "disabled" }
    ]
  },
  "verifier": {
    "verification": {
      "commitment_profile_id": "trackone-canonical-cbor-v1",
      "disclosure_class": "A"
    },
    "channels": {
      "ots": { "enabled": true, "status": "verified" }
    },
    "overall": "success"
  }
}
]]></artwork>
      </figure>
    </section>

    <section numbered="true" toc="include" anchor="appendix-b">
      <name>Illustrative Conformance Vector Bundle</name>
      <t>
        The figure below is a reader-oriented sketch of the
        <tt>trackone-canonical-cbor-v1</tt> conformance-vector bundle shape and
        naming only. It is illustrative and is not itself a complete
        machine-readable vector corpus.
      </t>
      <t>
        Wrapped hexadecimal values in this appendix are presentation-only; a
        verifier or implementer should concatenate adjacent lines without
        inserting whitespace.
      </t>
      <t>
        The fixtures below are reader-oriented logical record sketches, not
        the authoritative CBOR array encoding. They show the current
        post-projection logical content and the active commitment profile
        identifier, while the published vector corpus carries the exact
        encoded bytes and digests.
      </t>
      <t>
        In these reader-oriented sketches, <tt>kind</tt> is shown using the
        symbolic family name. In authoritative CBOR commitment bytes, the
        same field carries the numeric discriminator defined by the current
        profile; for the fixtures below, <tt>Custom</tt> corresponds to
        <tt>250</tt>.
      </t>
      <figure>
        <artwork type="ascii-art"><![CDATA[
commitment_profile_id:
  trackone-canonical-cbor-v1

fixture record_a:
  pod_id: "0000000000000065"
  fc: 1
  ingest_time: 1772366400
  pod_time: null
  kind: Custom
  payload.temp_c: 21.5

fixture record_b:
  pod_id: "0000000000000066"
  fc: 2
  ingest_time: 1772367000
  pod_time: null
  kind: Custom
  payload.temp_c: 22.0

fixture record_c:
  pod_id: "0000000000000067"
  fc: 3
  ingest_time: 1772367600
  pod_time: null
  kind: Custom
  payload.temp_c: 22.5

class-a-bundle-v1:
  disclosure_class: A
  commitment_profile_id: trackone-canonical-cbor-v1
  required_artifact_1: records/<record-id>.cbor
  required_artifact_2: day/YYYY-MM-DD.cbor
  required_artifact_3: day/YYYY-MM-DD.cbor.ots
  required_artifact_4: day/YYYY-MM-DD.ots.meta.json
  verifier_check_1: bundle_disclosure_validation
  verifier_check_2: day_artifact_validation
  verifier_check_3: record_level_recompute
  verifier_check_4: batch_metadata_validation
  verifier_check_5: day_digest_binding
  verifier_check_6: ots_verification
]]></artwork>
      </figure>
      <t>
        The published machine-readable vector set carries the exact canonical
        bytes, digests, expected roots, and the applicable
        <tt>commitment_profile_id</tt>. This appendix remains illustrative and
        is not an authoritative conformance corpus.
      </t>
    </section>

    <section numbered="true" toc="include" anchor="appendix-c">
      <name>Minimal Device Requirements</name>
      <t>
        This appendix records the minimum expectations for a constrained device
        that emits framed telemetry under the reference framed transport
        profile in <xref target="frame-contract"/>. It is descriptive of that
        deployment model, not a claim that all conforming deployments share
        identical hardware or use the same transport profile.
      </t>
      <ul>
        <li>The device is not required to sign assertions or to emit SCITT statements.</li>
        <li>The device MUST be able to produce framed transport messages consistent with <xref target="frame-contract"/>, including the nonce construction and uniqueness requirements defined there.</li>
        <li>Nonce generation MUST rely on a cryptographically strong pseudorandom source or an equivalent construction with explicit seed discipline. Weak or predictable generator state is out of profile.</li>
        <li>The device or an immediately adjacent trusted transport component MUST preserve enough durable state to avoid nonce reuse and replay ambiguity across the deployment-defined connectivity window.</li>
        <li>The device is not required to maintain UTC wall-clock time. If the device carries a local timestamp, that field is deployment input and not the source of UTC day boundaries in this profile.</li>
        <li>If uplink availability is intermittent, accepted-but-unsubmitted telemetry MUST either be durably buffered or be retransmittable from durable local state according to deployment policy.</li>
        <li>This document does not require one fixed storage budget. The practical tradeoff is between the configured connectivity window, frame rate, local retention policy, and the gateway's replay/admission contract.</li>
      </ul>
      <t>
        In the deployment model assumed here, the intermittency assumption
        primarily applies on the device-to-gateway path. The gateway is expected
        to maintain UTC time for <tt>ingest_time</tt> assignment, day-artifact
        rollover, and verifier-facing day labels. External timestamping or
        publication channels can also be delayed, but those delays do not
        change the device-side framing requirements.
      </t>
    </section>

    <section numbered="true" toc="include" anchor="appendix-d">
      <name>Verification Manifest CDDL</name>
      <t>
        This appendix gives a representative Concise Data Definition Language
        (CDDL) (<xref target="RFC8610"/>) shape for the verifier-facing day
        manifest. It captures the verification surface described here and
        leaves room for deployment-specific additions, provided those
        additions do not remove or change the verifier-facing semantics
        defined here.
      </t>
      <t>
        Check names are drawn from the standardized vocabulary defined in
        <xref target="verify"/>; deployment-specific extensions MUST use
        separate names beginning with <tt>x-</tt> that do not redefine those
        identifiers.
      </t>
      <sourcecode type="cddl"><![CDATA[
verification-manifest = {
  "version": 1,
  "date": tstr,
  "site": tstr,
  ? "device_id": tstr,
  ; Optional operational fields used by the reference framed example.
  ? "frame_count": uint,
  ? "frames_file": tstr,
  ? "records_dir": tstr,
  "artifacts": artifacts,
  "anchoring": anchoring,
  "verification_bundle": verification-bundle,
  ? "verifier": verifier-result,
  * tstr => any-data
}

artifacts = {
  "day_cbor": artifact-ref,
  ? "day_json": artifact-ref,
  ? "day_sha256": artifact-ref,
  ? "block": artifact-ref,
  ? "day_ots": artifact-ref,
  ? "day_ots_meta": artifact-ref,
  * tstr => artifact-ref
}

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

anchoring = {
  ? "policy": { * tstr => any-data },
  "channels": {
    ? "ots": channel-status,
    ? "tsa": channel-status,
    ? "peers": channel-status
  },
  ? "overall": tstr,
  * tstr => any-data
}

verification-bundle = {
  "disclosure_class": disclosure-class,
  "commitment_profile_id": tstr,
  "checks_executed": [* check-name],
  "checks_skipped": [* skipped-check],
  * tstr => any-data
}

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

standardized-check-name =
  "bundle_disclosure_validation" /
  "verification_manifest_validation" /
  "day_artifact_validation" /
  "record_level_recompute" /
  "batch_metadata_validation" /
  "day_digest_binding" /
  "ots_verification" /
  "tsa_verification" /
  "peer_quorum_verification"

extension-check-name = tstr .regexp "^x-[A-Za-z0-9._-]+$"

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

verifier-result = {
  ? "policy": { * tstr => any-data },
  ? "verification": {
    "commitment_profile_id": tstr,
    "disclosure_class": disclosure-class,
    * tstr => any-data
  },
  ? "checks": { * tstr => bool },
  ? "checks_executed": [* check-name],
  ? "checks_skipped": [* skipped-check],
  ? "channels": {
    ? "ots": channel-status,
    ? "tsa": channel-status,
    ? "peers": channel-status
  },
  ? "overall": tstr,
  * tstr => any-data
}

channel-status = {
  ? "enabled": bool,
  "status":
    "verified" / "pending" / "missing" / "failed" / "skipped",
  ? "reason": tstr,
  ? "detail": tstr,
  * tstr => any-data
}

disclosure-class = "A" / "B" / "C"
hex64 = text .regexp "[0-9a-f]{64}"
any-data =
  nil / bool / int / float / tstr / bstr /
  [* any-data] / { * tstr => any-data }
]]></sourcecode>
    </section>

    <section numbered="false" toc="include" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>
        Early structural drafts of this document were prepared with AI writing
        assistance. All technical content, design decisions, and normative
        requirements were reviewed against available implementation artifacts.
      </t>
      <t>
        The author thanks the OpenTimestamps project for the public calendar
        infrastructure used during validation.
      </t>
    </section>
  </back>
</rfc>
