<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.39 (Ruby 3.1.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-holmgren-at-repository-03" category="std" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.33.0 -->
  <front>
    <title abbrev="AT Repo">Authenticated Transfer: Repository and Synchronization</title>
    <seriesInfo name="Internet-Draft" value="draft-holmgren-at-repository-03"/>
    <author fullname="Daniel Holmgren">
      <organization>Bluesky Social</organization>
      <address>
        <email>daniel@blueskyweb.xyz</email>
      </address>
    </author>
    <author fullname="Bryan Newbold">
      <organization>Bluesky Social</organization>
      <address>
        <email>bryan@blueskyweb.xyz</email>
      </address>
    </author>
    <date year="2026" month="September" day="23"/>
    <area>Applications and Real-Time Area</area>
    <workgroup>Authenticated Transfer</workgroup>
    <abstract>
      <?line 82?>

<t>This document specifies a repository data structure and synchronization mechanisms for public data as part of the Authenticated Transfer Protocol (ATP). It describes encoding formats for both individual data records and entire repositories. The repository data structure is content-addressable and cryptographically authenticated. For synchronization, it specifies both a low-latency streaming protocol over WebSocket, and a full-repository fetch mechanism over HTTP.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-holmgren-at-repository/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Authenticated Transfer Working Group mailing list (<eref target="mailto:atp@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/atp/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/atp/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/ietf-wg-atp/drafts"/>.</t>
    </note>
  </front>
  <middle>
    <?line 86?>

<section anchor="intro">
      <name>Introduction</name>
      <t>The Authenticated Transfer Protocol (ATP) enables the creation of decentralized networks for publication of self-certifying data. An introduction to the overall protocol architecture is given in <xref target="AT-ARCH"/>.</t>
      <t>User accounts publish structured data records to the network by including them in their public repository. Records within a repository are identified by a unique path and current content version (hash). Records can be created, updated, and deleted at any time. Repositories contain the complete set of current records for the account, and do not include or reveal the existence of previous content.</t>
      <t>The repository structure includes the account's persistent identifier, and the overall repository structure is cryptographically signed. The authenticity of the entire repository can be verified by resolving the account identifier to the current public key. Data records are not signed individually. Details of account identifier systems and their resolution process are out of scope for this document.</t>
      <t>Large binary data such as images and media files are not stored directly within repositories. Instead, such data is stored externally and referenced in records by a content hash link.</t>
      <t>The protocol provides efficient synchronization mechanisms for propagating public repository state changes across the network, supporting both low-latency streaming updates and bulk synchronization scenarios. Synchronization can take place between any two parties, from an upstream publisher to a downstream consumer. Intermediate parties can redistribute ("relay") data, and consumers can cryptographically verify the integrity and authenticity of received repository data. This allows for flexibility in network topology to improve overall network resilience and efficiency.</t>
      <t>Consumers can confirm the integrity over the entire repository to detect dropped or withheld updates. The protocol allows consumers to maintain partial replicas (eg, of only specific record types). It is also possible to request verifiable "inclusion proofs" for individual records on demand.</t>
      <t>This document describes two synchronization mechanisms. Complete serialized repositories can be fetched over HTTP as a snapshot. Updates to one or more repositories can be distributed as a stream of messages. This document describes both a generic structure and semantics for streaming messages, and a specific WebSocket transport and message encoding scheme.</t>
      <t>This document describes version <tt>3</tt> of the repository format.</t>
    </section>
    <section anchor="repo-semantics">
      <name>Repository Semantics</name>
      <t>Records within a repository are discrete units of structured data, identified by a unique path and versioned by content hash. Records conform to a generic data model, but the content, schema, and semantics of record is varied and application-specific. Records are grouped by type under "collections".</t>
      <t>The current state of a repository is summarized in a signed "commit". Any change to the contents of the repository updates the current commit. Commits for an individual account's repository are serialized using a monotonically-increasing "revision" identifier.</t>
      <t>Updates to repositories may include operations on multiple records in a batch mutation that results in a single signed commit. Implementations should apply practical limits on batch sizes to support efficient processing and distribution of repository changes.</t>
      <section anchor="account-ids">
        <name>Account Identifiers</name>
        <t>Repository commit objects (<xref target="commits"/>) contain a persistent account identifier, which indicates the publisher of the repository. This account identifier can be resolved to obtain the current cryptographic public keys for the account, and those keys can be used to verify the authenticity of the repository and the records it contains.</t>
        <t>The keys associated with an account may be rotated over time. The most recent commit must always be verifiable using the currently resolvable signing key. When rotating signing keys, a new repository commit must be created, even if the contents and structure of the repository remain unchanged.</t>
        <t>This document does not include details or recommendations on account identifier systems.</t>
      </section>
      <section anchor="revs">
        <name>Revisions</name>
        <t>Repository commits include a revision field (<tt>rev</tt>) which acts as a logical clock for updates to the repository over time. The revision string is a Timestamp Identifier (TID) as described in <xref target="tid"/>.</t>
        <t>Revisions may be used when comparing two versions of a repository to determine which is more recent. This is particularly relevant when synchronizing repositories indirectly, or from multiple sources over time.</t>
        <t>If a commit TID value corresponds to a timestamp in the future (beyond a short period to accommodate clock drift) the commit SHOULD be ignored. This is to ensure that a newly published commit (with a TID corresponding to the current time) will reliably be accepted as current by the entire network.</t>
      </section>
    </section>
    <section anchor="repo-structure">
      <name>Repository Structure</name>
      <t>Repositories are structured as a Merkle Search Tree (<xref target="mst"/>) with a cryptographically signed commit object referencing the tree root.</t>
      <t>The MST structure provides several fundamental properties for repository operations. As a content-addressed structure, it enables efficient verification of data. The MST maintains lexicographic key ordering, enabling structural sharing of intermediate tree nodes for related records. It is probabilistically self-balancing, offering consistent performance characteristics. Additionally the MST exhibits unicity, meaning that any given set of keys and values will always produce the same tree structure and root hash regardless of insertion order.</t>
      <t>Repository contents are encoded using deterministic CBOR serialization and organized as a directed acyclic graph where data objects reference each other through content hashes. These hash-identified data objects, referred to as "blocks," include three distinct types: commit objects, MST internal nodes, and data records.</t>
      <section anchor="repo-path">
        <name>Record Paths</name>
        <t>Records within a repository are identified by a non-empty case-sensitive ASCII string called the "path". Records are stored sorted lexicographically by path, and the efficiency of some repository operations is impacted by sort order.</t>
        <t>A path string is the combination of a collection type name and a record key, joined by a single forward slash character: <tt>&lt;collection&gt;/&lt;record-key&gt;</tt>. A path MUST consist of exactly two segments separated by <tt>/</tt>, with no leading or trailing slash.</t>
        <t>Collection names use the Namespaced Identifier (NSID) syntax described in <xref target="nsid"/>. They have a prefix-ordered namespace structure, which means that records of the same collection are stored adjacently, and that collections under the same authority are grouped together.</t>
        <t>Record keys uniquely identify records within a collection. Record keys are case-sensitive and MUST satisfy the following syntax:</t>
        <ul spacing="normal">
          <li>
            <t>Allowed characters are ASCII alphanumerics (<tt>A-Z</tt>, <tt>a-z</tt>, <tt>0-9</tt>), period (<tt>.</tt>), hyphen (<tt>-</tt>), underscore (<tt>_</tt>), colon (<tt>:</tt>), and tilde (<tt>~</tt>)</t>
          </li>
          <li>
            <t>Length between 1 and 512 characters (inclusive)</t>
          </li>
          <li>
            <t>The literal values <tt>.</tt> and <tt>..</tt> are prohibited</t>
          </li>
        </ul>
        <t>The syntax of record keys may be constrained further on a per-collection basis at the application layer. A common choice is to use the Timestamp Identifier <xref target="tid"/> syntax, which results in lexicographic sorting by time within a collection. This means that "new" records are all grouped together within a given collection.</t>
        <t>Note that both the NSID and record key string syntaxes are valid path components as defined in Section 3.3 of <xref target="RFC3986"/>. It is important to maintain this property.</t>
      </section>
      <section anchor="commits">
        <name>Commit Objects</name>
        <t>Commit objects serve as the authoritative root of each repository, establishing cryptographic ownership and providing a verifiable reference to the state of a repository at a particular point in time. Each commit is digitally signed by the repository account owner and contains metadata necessary for verification.</t>
        <t>A commit object contains the following data fields:</t>
        <ul spacing="normal">
          <li>
            <t><strong><tt>did</tt></strong> (string, required): The resolvable account identifier associated with the repository as described in <xref target="account-ids"/></t>
          </li>
          <li>
            <t><strong><tt>version</tt></strong> (integer, required): Repository format version, fixed value of <strong><tt>3</tt></strong> for the current specification</t>
          </li>
          <li>
            <t><strong><tt>data</tt></strong> (CID link, required): Content hash link to the root of the repository’s MST structure</t>
          </li>
          <li>
            <t><strong><tt>rev</tt></strong> (string, required): Repository revision identifier that functions as a logical clock and must increase monotonically (see <xref target="revs"/>). Syntax MUST match <xref target="tid"/>.</t>
          </li>
          <li>
            <t><strong><tt>prev</tt></strong> (CID link, nullable): Optional content hash link to the previous commit object in the repository's history chain. While included for backward compatibility with version 2 repositories, this field is typically <tt>null</tt> in version 3 implementations</t>
          </li>
          <li>
            <t><strong><tt>sig</tt></strong> (byte array, required): Cryptographic signature over the commit contents.</t>
          </li>
        </ul>
        <t>Commit objects are signed by the key declared by the repository owner’s resolvable identifier. Neither the signature nor the signed commit object contains information about the curve type or specific public key used for signing. This information must be obtained by resolving the account identifier as described in <xref target="account-ids"/>.</t>
        <t>The procedure for signing commit objects:</t>
        <ol spacing="normal" type="1"><li>
            <t>Encode the unsigned commit object (with <tt>sig</tt> field entirely absent) as CBOR</t>
          </li>
          <li>
            <t>Sign the encoded bytes as described in <xref target="crypto"/></t>
          </li>
          <li>
            <t>Include the signature bytes in the <tt>sig</tt> field</t>
          </li>
        </ol>
        <t>To verify the signature, remove the <tt>sig</tt> field and encode the unsigned commit object as CBOR. Then verify the signature against those encoded bytes.</t>
      </section>
      <section anchor="records">
        <name>Records</name>
        <t>Records stored within a repository are always objects (or "maps") encoded as CBOR, following the data model and encoding rules described in <xref target="data-model"/>. Each record must include a top-level field named <tt>$type</tt> with a string value matching the collection type name (NSID) of the path that the record is stored at.</t>
        <t>Invalid or corrupt data in individual records should not impact processing of the overall repository data structure, or the processing of other valid records in the same repository.</t>
      </section>
    </section>
    <section anchor="mst">
      <name>Merkle Search Tree</name>
      <t>The Merkle Search Tree (MST) structure is deterministically reproducible from any given key-value mapping, where keys are non-empty byte strings (corresponding to a path) and values are content hash link references to records. This deterministic construction ensures that identical input sets always produce the same root hash regardless of insertion order.</t>
      <t>The tree's structural organization depends solely on the keys present, not on the record values they reference. When a record value changes, the new content hash propagates up through the tree nodes to the root, but the tree's shape and node organization remain unchanged.</t>
      <t>The MST data structure was first published in <xref target="MSTPAPER"/>.</t>
      <section anchor="mst-structure">
        <name>Tree Structure</name>
        <t>Each MST node contains a list of key-value entries and references to child subtrees. Entries and subtree links are maintained in lexicographic order, with all keys in a linked subtree falling within the range corresponding to that link's position. The ordering proceeds from left (lexicographically first) to right (lexicographically last).</t>
        <t>Keys are assigned to tree levels based on a layer value computed from the key itself. Nodes at each level contain all keys with the corresponding layer value, while subtree links point to nodes containing keys that fall within specific lexicographic ranges but have lower layer values. Adjacent keys may appear within the same node, but adjacent subtrees must be separated by at least one key entry to prevent structural ambiguity.</t>
      </section>
      <section anchor="mst-layer">
        <name>Layer Calculation</name>
        <t>The layer for a given key is calculated using SHA-256 with a 2-bit grouping scheme that provides an average fanout of 4:</t>
        <ol spacing="normal" type="1"><li>
            <t>Compute the SHA-256 hash of the key (byte string) with binary output</t>
          </li>
          <li>
            <t>Count the number of leading binary zeros in the hash</t>
          </li>
          <li>
            <t>Divide by 2, rounding down to the nearest integer</t>
          </li>
        </ol>
        <t>Examples of layer calculation:</t>
        <ul spacing="normal">
          <li>
            <t><tt>key1</tt>: SHA-256 begins <tt>100000010111...</tt> → layer 0</t>
          </li>
          <li>
            <t><tt>key7</tt>: SHA-256 begins <tt>000111100011...</tt> → layer 1</t>
          </li>
          <li>
            <t><tt>key515</tt>: SHA-256 begins <tt>000000000111...</tt> → layer 4</t>
          </li>
        </ul>
        <t>When processing the MST structure, implementations must verify the layer assignment and ordering of keys. While this verification is most essential for untrusted inputs, implementations should perform these checks consistently regardless of data source. Additional validation of node size limits and other structural parameters is required to prevent resource exhaustion attacks, as detailed in Security Considerations (<xref target="security"/>).</t>
      </section>
      <section anchor="mst-example">
        <name>MST Construction Example</name>
        <t>The following is a Merkle Search Tree containing 9 records with keys A-I. Each key would include a pointer to some record hash, though that hash is irrelevant to the construction of the tree. Each asterisk (<tt>*</tt>) represents a content hash link to the subtree under it.</t>
        <t>For the sake of illustration assume the following layer calculations:</t>
        <ul spacing="normal">
          <li>
            <t><tt>layer(D) = 2</tt></t>
          </li>
          <li>
            <t><tt>layer(A|E|I) = 1</tt></t>
          </li>
          <li>
            <t><tt>layer(B|C|F|G|H) = 0</tt></t>
          </li>
        </ul>
        <figure anchor="f-mst-example">
          <name>Example MST Structure</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="240" width="168" viewBox="0 0 168 240" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 24,80 L 24,120" fill="none" stroke="black"/>
                <path d="M 40,144 L 40,184" fill="none" stroke="black"/>
                <path d="M 80,32 L 80,56" fill="none" stroke="black"/>
                <path d="M 136,80 L 136,120" fill="none" stroke="black"/>
                <path d="M 136,136 L 136,184" fill="none" stroke="black"/>
                <path d="M 32,64 L 128,64" fill="none" stroke="black"/>
                <path d="M 16,128 L 32,128" fill="none" stroke="black"/>
                <path d="M 120,128 L 152,128" fill="none" stroke="black"/>
                <path d="M 32,192 L 48,192" fill="none" stroke="black"/>
                <path d="M 120,192 L 152,192" fill="none" stroke="black"/>
                <circle cx="24" cy="96" r="6" class="closeddot" fill="black"/>
                <circle cx="40" cy="160" r="6" class="closeddot" fill="black"/>
                <circle cx="80" cy="32" r="6" class="closeddot" fill="black"/>
                <circle cx="136" cy="96" r="6" class="closeddot" fill="black"/>
                <circle cx="136" cy="160" r="6" class="closeddot" fill="black"/>
                <g class="text">
                  <text x="80" y="84">|</text>
                  <text x="80" y="100">D</text>
                  <text x="8" y="148">|</text>
                  <text x="112" y="148">|</text>
                  <text x="160" y="148">|</text>
                  <text x="8" y="164">A</text>
                  <text x="112" y="164">E</text>
                  <text x="160" y="164">I</text>
                  <text x="24" y="212">|</text>
                  <text x="56" y="212">|</text>
                  <text x="112" y="212">|</text>
                  <text x="136" y="212">|</text>
                  <text x="160" y="212">|</text>
                  <text x="24" y="228">B</text>
                  <text x="56" y="228">C</text>
                  <text x="112" y="228">F</text>
                  <text x="136" y="228">G</text>
                  <text x="160" y="228">H</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
         *
         |
   -------------
  |      |      |
  *      D      *
  |             |
 ---          -----
|   |        |  |  |
A   *        E  *  I
    |           |
   ---        -----
  |   |      |  |  |
  B   C      F  G  H
]]></artwork>
          </artset>
        </figure>
      </section>
      <section anchor="mst-empty-nodes">
        <name>Empty Nodes</name>
        <t>An empty repository containing no records is represented as a single MST node with no entries. This is the only case where a node without entries is permitted.</t>
        <t>Nodes that contain no key entries but do contain subtree links are allowed at intermediate positions, provided those subtrees eventually contain key entries. However, such nodes MUST NOT appear at the root position — the root MUST either contain key entries or be the special case of a completely empty repository. Similarly, nodes without key entries MUST NOT appear at leaf positions except for the empty repository case.</t>
        <t>This structure ensures that nodes lacking key-value entries are pruned from the top and bottom of the tree while preserving intermediate nodes that maintain proper height relationships and prevent subtree links from skipping layers.</t>
      </section>
      <section anchor="mst-nodes">
        <name>MST Node Schema</name>
        <t>Given their prevalence through the repository structure, MST nodes require a compact binary representation for storage efficiency. Keys within each node use prefix compression, where each entry specifies the number of bytes it shares with the preceding key in the array. The first entry in each node contains the complete key with a prefix length of zero. This compression applies only within individual nodes and does not extend across node boundaries. The compression scheme is mandatory to ensure deterministic MST structure across all implementations.</t>
        <t>MST nodes contain the following fields:</t>
        <ul spacing="normal">
          <li>
            <t><tt>l</tt> (CID link, nullable): Reference to a subtree node at a lower layer containing keys that sort lexicographically before all keys in the current node</t>
          </li>
          <li>
            <t><tt>e</tt> (array, required): Ordered array of entry objects, each containing:
            </t>
            <ul spacing="normal">
              <li>
                <t><tt>p</tt> (integer, required): Number of bytes shared with the previous entry in this node</t>
              </li>
              <li>
                <t><tt>k</tt> (byte string, required): Key suffix remaining after removing the shared prefix bytes</t>
              </li>
              <li>
                <t><tt>v</tt> (CID link, required): Reference to the record data for this entry</t>
              </li>
              <li>
                <t><tt>t</tt> (CID link, nullable): Reference to a subtree node at a lower layer containing keys that sort after this entry's key but before the next entry's key in the current node</t>
              </li>
            </ul>
          </li>
        </ul>
        <t>Content hash links appearing within an MST node — the <tt>l</tt> and <tt>t</tt> subtree links, and the <tt>v</tt> record link — MUST use the constrained format defined in <xref target="cid-link"/>.</t>
      </section>
      <section anchor="mst-node-example">
        <name>MST Node example</name>
        <t>The following example shows an MST node at layer 1 containing two subtree pointers and two key-value entries. The node contents in order are:</t>
        <ul spacing="normal">
          <li>
            <t>Left subtree: content hash link <tt>0x01711220643b9326...</tt></t>
          </li>
          <li>
            <t>Entry: <tt>key7</tt> → record content hash link <tt>0x017112202d9aa87e...</tt></t>
          </li>
          <li>
            <t>Right subtree: content hash link <tt>0x0171122047e2886f...</tt></t>
          </li>
          <li>
            <t>Entry: <tt>key10</tt> → record content hash link <tt>0x0171122010b6da2c...</tt></t>
          </li>
        </ul>
        <t>This node would be encoded as follows:</t>
        <artwork><![CDATA[
{
  l: 0x01711220643b9326...
  e: [
    {
      p: 0,
      k: "key7",
      v: 0x017112202d9aa87e...
      t: 0x0171122047e2886f...
    },
    {
      p: 3,
      k: "10",
      v: 0x0171122010b6da2c...
      t: null
    }
  ]
}
]]></artwork>
      </section>
    </section>
    <section anchor="serialization">
      <name>Repository Serialization Format</name>
      <t>Repositories are serialized for transmission and storage as a concatenated sequence of block data, where blocks represent the CBOR-encoded records, MST nodes, and commit objects that comprise the repository structure. The serialization is prefixed with a header that identifies the root block, typically the repository's commit object.</t>
      <t>Serialized repositories may contain partial repository state, such as when transmitting cryptographic proofs for specific records. In these situations, they may not include unrelated MST nodes or records outside the proof path.</t>
      <t>The block-and-header layout described here is compatible with Content-Addressable archive (CAR) formats such as <xref target="DASL-CAR"/>.</t>
      <section anchor="serialization-header">
        <name>Header Format</name>
        <t>The header is constructed by CBOR-encoding an object with the following fields:</t>
        <ul spacing="normal">
          <li>
            <t><tt>version</tt> (integer, required): Fixed value of <tt>1</tt></t>
          </li>
          <li>
            <t><tt>roots</tt> (CID link array, required): Single-element array containing the content hash link of the commit block</t>
          </li>
        </ul>
        <t>The CBOR-encoded header is prefixed with its byte length encoded as an unsigned LEB128 integer as described in Section 5.2.2 of <xref target="WEBASSEMBLY"/>.</t>
      </section>
      <section anchor="serialization-blocks">
        <name>Block Format</name>
        <t>Following the header, each repository block is serialized by concatenating:</t>
        <ol spacing="normal" type="1"><li>
            <t>The combined byte length of the following two components, encoded as an unsigned LEB128 integer</t>
          </li>
          <li>
            <t>The block's content hash in binary encoding as specified in <xref target="cid-link"/></t>
          </li>
          <li>
            <t>The CBOR-encoded block data</t>
          </li>
        </ol>
        <figure anchor="f-serialization">
          <name>Repository Serialization Layout</name>
          <artset>
            <artwork type="svg"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="64" width="600" viewBox="0 0 600 64" class="diagram" text-anchor="middle" font-family="monospace" font-size="13px" stroke-linecap="round">
                <path d="M 16,32 L 64,32" fill="none" stroke="black"/>
                <path d="M 136,32 L 184,32" fill="none" stroke="black"/>
                <path d="M 216,32 L 376,32" fill="none" stroke="black"/>
                <path d="M 432,32 L 584,32" fill="none" stroke="black"/>
                <g class="text">
                  <text x="8" y="36">|</text>
                  <text x="100" y="36">Header</text>
                  <text x="192" y="36">|</text>
                  <text x="208" y="36">|</text>
                  <text x="404" y="36">Data</text>
                  <text x="592" y="36">|</text>
                  <text x="16" y="52">[</text>
                  <text x="40" y="52">len</text>
                  <text x="64" y="52">|</text>
                  <text x="100" y="52">header</text>
                  <text x="152" y="52">block</text>
                  <text x="184" y="52">]</text>
                  <text x="216" y="52">[</text>
                  <text x="240" y="52">len</text>
                  <text x="264" y="52">|</text>
                  <text x="292" y="52">hash</text>
                  <text x="320" y="52">|</text>
                  <text x="352" y="52">block</text>
                  <text x="384" y="52">]</text>
                  <text x="400" y="52">[</text>
                  <text x="424" y="52">len</text>
                  <text x="448" y="52">|</text>
                  <text x="476" y="52">hash</text>
                  <text x="504" y="52">|</text>
                  <text x="536" y="52">block</text>
                  <text x="568" y="52">]</text>
                  <text x="584" y="52">…</text>
                </g>
              </svg>
            </artwork>
            <artwork type="ascii-art"><![CDATA[
|------- Header -------| |--------------------- Data --------------------|
 [ len | header block ]   [ len | hash | block ] [ len | hash | block ] …
]]></artwork>
          </artset>
        </figure>
        <t>The block content hash MUST match the block data.</t>
      </section>
      <section anchor="serialization-ordering">
        <name>Block Ordering</name>
        <t>Producers SHOULD emit blocks in pre-order traversal of the included repository portion: header, commit object, root MST node, then a recursive depth-first interleaving of subtree nodes and the records they reference.</t>
        <t>Preorder traversal enables streaming verification of repositories, allowing parsers to walk the MST structure and output key-to-record mappings while maintaining minimal MST state in memory. This approach supports efficient stream processing of large repositories without requiring complete buffering of the serialized data.</t>
        <t>Parsers MUST tolerate other block orderings, duplicate occurrences of the same block, and additional unrelated blocks. Specifically:</t>
        <ul spacing="normal">
          <li>
            <t>Duplicate blocks SHOULD be deduplicated rather than treated as an error.</t>
          </li>
          <li>
            <t>Dangling references — for example, content hash links pointing to records or blobs that are not present in the serialized data — MAY be present and unresolvable; this is not an error in itself.</t>
          </li>
          <li>
            <t>Unrelated blocks not referenced by the repository structure SHOULD be ignored. Excessive quantities of such blocks MAY be treated as a form of resource abuse; see <xref target="security"/>.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="accounts">
      <name>Account Hosting</name>
      <t>Each node in the network which synchronizes, stores, and distributes repository data maintains hosting status for each account. The status indicates whether the account is overall "active", or has been temporarily or permanently removed from the network, in which case repository data should not be synchronized further. Hosting status can be set by the account holder themselves or their canonical hosting provider, and changes propagate to downstream consumers throughout the network. Each downstream service or node in the network may set a local inactive hosting status, declining to distribute that account's repository data.</t>
      <t>Each account has a persistent identifier which can be resolved to both a public key and a canonical hosting location. Account identifier systems and their resolution mechanisms are out of scope for this document. Account hosting status is maintained and transmitted over the synchronization protocol, separate from the lifecycle of account identifiers.</t>
      <t>The hosting status itself for accounts may always be redistributed, even for inactive accounts.</t>
      <section anchor="account-status">
        <name>Hosting Status</name>
        <t>Account hosting status at any point in time can be summarized as the boolean state of being "active" or not. If the account hosting status is not active, repository data for that account MUST NOT be redistributed. Additional context may be provided using a "status" vocabulary, represented as a string. Account status is represented and transmitted as an <tt>active</tt> boolean (required) and a <tt>status</tt> string (optional) together.</t>
        <t>The defined status values and their meanings are:</t>
        <ul spacing="normal">
          <li>
            <t><tt>deleted</tt> (<tt>active</tt> is false): the user or host has deleted the account. Account data SHOULD be removed from the service's infrastructure within a reasonable time frame. Implied to be permanent, but MAY be reverted.</t>
          </li>
          <li>
            <t><tt>deactivated</tt> (<tt>active</tt> is false): the user has temporarily paused the account. Account data MUST NOT be redistributed but does not need to be deleted from infrastructure. Implied time-limited.</t>
          </li>
          <li>
            <t><tt>takendown</tt> (<tt>active</tt> is false): the host or service has taken down the account. Implied to be indefinite in duration, but MAY be reverted.</t>
          </li>
          <li>
            <t><tt>suspended</tt> (<tt>active</tt> is false): the host or service has temporarily paused the account. Implied time-limited.</t>
          </li>
        </ul>
        <t>Two additional status values are relevant to the synchronization process itself, and do not imply that the overall hosting status is inactive:</t>
        <ul spacing="normal">
          <li>
            <t><tt>desynchronized</tt> (<tt>active</tt> MAY be true): the service has detected a problem synchronizing the account's repository and may be missing content.</t>
          </li>
          <li>
            <t><tt>throttled</tt> (<tt>active</tt> MAY be true): the service has paused processing of new content for this account because a rate limit has been exceeded.</t>
          </li>
        </ul>
        <t>There are no defined status strings to represent generic active status (<tt>active</tt> is true) or generic inactive status. The status string MAY be omitted.</t>
        <t>New status values may be defined in the future. Producers MAY emit <tt>status</tt> strings not listed above, and consumers MUST tolerate unrecognized values. Consumers MUST use the <tt>active</tt> boolean as the authoritative indicator of overall account visibility, treating the <tt>status</tt> string as clarification that may inform more specific behavior (for example, whether to delete cached data versus retain it pending reactivation).</t>
        <t>Producers expose an HTTPS request-response operation that, given an account identifier, returns the producer's current hosting status for that account. This allows consumers to query the present state of an account without subscribing to the message stream — for example, when establishing initial state for an account they have not seen before, or when reconciling diverging upstream reports.</t>
        <t>The details of the HTTPS request endpoint, the URL path, and the response media type are not specified by this document.</t>
      </section>
      <section anchor="account-status-propagation">
        <name>Status Propagation</name>
        <t>Account hosting status is not cryptographically authenticated. Status propagates hop-by-hop via streaming synchronization (<xref target="stream-sync"/>): each node emits an <tt>#account</tt> message (<xref target="msg-account"/>) to downstream consumers when the hosting status for an account changes. For intermediate synchronization nodes, this includes changes driven by an <tt>#account</tt> message received from an upstream.</t>
        <t>Intermediaries MAY override their upstream's status. For example, a relaying node may take down an account that an upstream still reports as active. Such overrides are propagated downstream as <tt>#account</tt> messages from the intermediary.</t>
        <t>When an upstream service is unreachable, downstream services SHOULD retain the previously reported status for some implementation-defined period rather than immediately changing the account to an inactive state. This preserves availability across short upstream outages, and increases resiliency of the network.</t>
        <t>When account status reported by different upstreams diverges (for example, due to differing moderation policies, or a transient network partition between an upstream and its own upstream), services apply their own policies to reconcile. Querying the account's current authoritative hosting service directly is one way to resolve such ambiguity.</t>
      </section>
    </section>
    <section anchor="snapshot-sync">
      <name>Snapshot Sync</name>
      <t>Consumers can retrieve a full serialized snapshot of an account's current repository at any point in time. This can be used to initialize synchronization state for the account during a bootstrap or backfill phase, or to re-synchronize (<xref target="resync"/>) and reconcile after any discontinuity in the streaming synchronization mechanism. It is also an option for applications and use-cases which do not require continuous updates or synchronization over time.</t>
      <t>Producers expose an HTTP API endpoint which takes an account identifier as a parameter, and returns the serialized repository as the response body. If the account hosting status at the producer is not "active", this is indicated in an error response.</t>
      <t>A producer MAY redirect the request to another producer that holds the requested data — for example, a relaying service redirecting to the account's canonical host, or to a mirroring service with the content cached. Consumers SHOULD follow such HTTP redirects when re-synchronizing per <xref target="resync"/>.</t>
    </section>
    <section anchor="stream-sync">
      <name>Streaming Sync</name>
      <t>This section describes a low-latency streaming synchronization mechanism which allows consumers to receive repository updates with minimal latency through a pull-based WebSocket <xref target="RFC6455"/> connection. Streams can contain updates from many distinct account repositories, even aggregating all updates in the network. In addition to repository updates, they include updates to account hosting status and network identities. Whether encompassing the full network or any subset of it, a stream is often referred to as a "firehose".</t>
      <t>To ensure reliable delivery, each message on a given stream is given a monotonically-increasing sequence number. Consumers can track their progress on processing messages and reconnect to the stream using the last-processed sequence number as a cursor value as needed. Producers can maintain a "backfill window" of recently transmitted messages. All consumers receive the same messages in the same order with the same sequence numbers.</t>
      <t>The stream synchronization mechanism allows consumers to maintain complete indices of authenticated repository contents without needing to store complete copies of the repository MST structure. This significantly reduces storage overhead.</t>
      <section anchor="diffs">
        <name>Repository Diffs</name>
        <t>A repository diff carries the data that changed between two repository revisions: the new commit, any new MST nodes, and any created or updated record blocks. Applying a diff to a copy of the prior repository state results in the complete repository at the new revision. Repository diffs are used in the streaming synchronization mechanism.</t>
        <t>The commits within diffs are signed. Receiving parties can always verify those signatures, and the integrity of the blocks in the diff itself. But unless the receiving party has a full copy of the repository just prior to the diff, it can not verify the overall integrity of the diff or the final state of the repository. In particular, if record deletion operations were included in the diff, the receiving party can not enumerate or verify which records were impacted just from the diff.</t>
        <t>This section describes an "operation inversion" mechanism which allows receiving parties to verify the integrity of diffs when combined with metadata about the record-level operations encapsulated by the diff.</t>
        <section anchor="diff-format">
          <name>Diff Serialization Format</name>
          <t>Diffs use the same serialization format as complete repositories (described in <xref target="serialization"/>), with the commit block serving as the root. A diff MUST include:</t>
          <ul spacing="normal">
            <li>
              <t>The new commit block.</t>
            </li>
            <li>
              <t>All created and updated record blocks.</t>
            </li>
            <li>
              <t>All MST nodes in the current repository that did not exist in the prior revision.</t>
            </li>
          </ul>
          <t>Required blocks MUST be included in the diff regardless of their presence in earlier repository history. For example, if an MST node was previously present in the repository, then deleted, and subsequently reintroduced during the range that the diff represents, the diff MUST include that block.</t>
          <t>Deleted records and prior versions of updated records are excluded from diffs.</t>
          <t>With the exception of deleted record data, a diff MAY include additional blocks; receivers SHOULD ignore them.</t>
        </section>
        <section anchor="operation-inversion">
          <name>Operation Inversion</name>
          <t>A diff can be accompanied by an explicit operation list declaring the record-level creates, updates, and deletes it represents, along with a claimed previous repository tree root hash. Operation inversion verifies that this declared list is accurate and complete.</t>
          <t>To invert a diff against its declared operations:</t>
          <ol spacing="normal" type="1"><li>
              <t>Extract the diff's MST nodes into a partial tree structure</t>
            </li>
            <li>
              <t>For each entry in the operation list, apply the inverse operation to the partial MST: each "create" becomes a "delete", "delete" becomes "create", and "update" reverts the record value to the previous version</t>
            </li>
            <li>
              <t>Compute the root hash of the resulting MST</t>
            </li>
            <li>
              <t>Compare the computed root hash to the claimed previous root hash</t>
            </li>
          </ol>
          <t>If the hashes match, the operation list is accurate and exhaustive. If they differ, either the operation list is incomplete or the diff is internally inconsistent; in either case the diff MUST be rejected.</t>
          <t>Producers of diffs intended to support operation inversion MUST include, in addition to the blocks required by <xref target="diff-format"/>, the MST nodes for keys directly adjacent (in lexicographic order) to mutated keys. Without these adjacent nodes, the inverse operation cannot be correctly applied to the partial MST. Diffs carried in streaming synchronization messages (<xref target="msg-commit"/>) MUST satisfy this requirement, since stateless consumers rely on operation inversion for verification.</t>
          <t>Receivers can track repository root hash values for each account and verify the claimed root hashes provided with the diff. This fixed-size state is significantly smaller than maintaining full repository data.</t>
        </section>
      </section>
      <section anchor="websocket">
        <name>WebSocket Transport</name>
        <t>A consumer (client) establishes a WebSocket connection <xref target="RFC6455"/> to the producer's (server) stream endpoint. Secure WebSockets (using TLS) MUST be used for any internet-facing deployment.</t>
        <t>Once the connection is established, the producer sends a sequence of binary WebSocket frames to the consumer. Each frame carries a single message. Servers SHOULD ignore stream messages sent by the consumer: the protocol defined in this document is server-to-client only.</t>
        <t>Servers and clients SHOULD implement a keepalive system using Ping and Pong WebSocket messages.</t>
        <section anchor="frame-format">
          <name>Frame Format</name>
          <t>Each binary WebSocket frame contains two CBOR-encoded objects concatenated together: a header followed by a payload. Both objects MUST follow the deterministic CBOR encoding rules defined in <xref target="cbor-encoding"/>.</t>
          <t>The header contains:</t>
          <ul spacing="normal">
            <li>
              <t><tt>op</tt> (integer, REQUIRED): the frame operation. The value <tt>1</tt> indicates a normal message; the value <tt>-1</tt> indicates an error.</t>
            </li>
            <li>
              <t><tt>t</tt> (string, REQUIRED when <tt>op = 1</tt>): the message-type name, prefixed with <tt>#</tt>. For example, <tt>#commit</tt> for a commit message.</t>
            </li>
          </ul>
          <t>The payload is a CBOR object whose schema is determined by the message type indicated in the header. Payloads are always CBOR objects, never arrays or scalars.</t>
          <t>Producers MAY include additional fields beyond those defined for a given message type, and consumers MUST tolerate unknown fields. Strict schema validation is not performed on stream messages.</t>
          <t>A frame MUST NOT exceed 5 MB in total size, inclusive of the header, payload, and CBOR encoding overhead.</t>
        </section>
        <section anchor="error-frames">
          <name>Error Frames</name>
          <t>When <tt>op</tt> is <tt>-1</tt>, the frame is an error frame. The payload contains:</t>
          <ul spacing="normal">
            <li>
              <t><tt>error</tt> (string, REQUIRED): a short machine-readable error name.</t>
            </li>
            <li>
              <t><tt>message</tt> (string, OPTIONAL): a human-readable description of the error.</t>
            </li>
          </ul>
          <t>After sending an error frame, the producer MUST close the WebSocket connection.</t>
        </section>
        <section anchor="pre-upgrade-errors">
          <name>Pre-Upgrade HTTP Errors</name>
          <t>If the producer rejects the WebSocket upgrade request itself, it responds with a standard HTTP status code rather than an error frame. Response bodies SHOULD be JSON containing <tt>error</tt> and <tt>message</tt> fields matching the error-frame schema, but consumers MUST tolerate other body content.</t>
        </section>
      </section>
      <section anchor="cursors">
        <name>Cursors and Resumption</name>
        <t>Synchronization streams include per-message sequence numbers to improve transmission reliability. Sequence numbers are positive integers that increase monotonically across the stream. Sequence semantics are flexible, and they may contain arbitrary gaps between consecutive messages.</t>
        <t>Consumers track the last sequence number they successfully processed and can specify this as a cursor when reconnecting to receive any missed messages within the provider's backfill window. Consumers are responsible for managing and persisting cursor state themselves: producers do not maintain consumer-specific state across connections. The scope of a cursor is the (hostname, endpoint) pair: a cursor value is meaningful only when reconnecting to the same host and stream endpoint that issued it.</t>
        <t>Sequence numbers MUST NOT be repeated by producers on the same (hostname, endpoint) pair. If a producer must reset sequence numbers for any reason, it MUST start with a number higher than any previously broadcast.</t>
        <t>Sequence numbers are integers in the range <tt>[1, 2^53)</tt>. The upper bound is chosen so that cursors are exactly representable in 64-bit IEEE-754 floating point.</t>
        <t>Stream behavior depends on the cursor value specified during connection:</t>
        <ul spacing="normal">
          <li>
            <t><strong>No cursor specified</strong>: The provider begins transmitting from the current stream position, providing only new messages generated after the connection is established.</t>
          </li>
          <li>
            <t><strong>Future cursor</strong>: When the requested cursor exceeds the current stream sequence number, the provider sends an error message and closes the connection.</t>
          </li>
          <li>
            <t><strong>Cursor within backfill window</strong>: The provider transmits all persisted messages with sequence numbers greater than or equal to the requested cursor, in order, then continues with the stream once caught up.</t>
          </li>
          <li>
            <t><strong>Cursor older than backfill window</strong>: The provider sends an informational message indicating that the requested cursor is too old, then begins transmission at the oldest available message, sends the entire backfill window, and continues with the stream.</t>
          </li>
          <li>
            <t><strong>Cursor value of 0</strong>: The provider treats this as a request for the complete available history, starting at the oldest available message, transmitting the entire backfill window, then continuing with the stream.</t>
          </li>
        </ul>
      </section>
      <section anchor="msg-types">
        <name>Message Types</name>
        <t>The repository synchronization stream uses four message types: <tt>#commit</tt>, <tt>#sync</tt>, <tt>#account</tt>, and <tt>#identity</tt>. This section describes the schema and semantics of these messages. Some fields are common across all message types.</t>
        <section anchor="msg-common">
          <name>Common Message Fields</name>
          <t>The following fields are common to all message payloads:</t>
          <ul spacing="normal">
            <li>
              <t><tt>seq</tt> (integer, REQUIRED): the sequence number (cursor; see <xref target="cursors"/>) of this message.</t>
            </li>
            <li>
              <t><tt>did</tt> (string, REQUIRED): the account identifier of the repository this message concerns. For historical reasons the <tt>#commit</tt> message uses the field name <tt>repo</tt> rather than <tt>did</tt> for this purpose; the value has the same meaning.</t>
            </li>
            <li>
              <t><tt>time</tt> (string, REQUIRED): an ISO 8601 datetime string indicating when the message was emitted. This timestamp is informational and is not authoritative for any verification purpose.</t>
            </li>
          </ul>
        </section>
        <section anchor="msg-commit">
          <name><tt>#commit</tt> Message</name>
          <t>A <tt>#commit</tt> message represents a repository update, as an atomic set of record operations. The message contains a repository diff combined with supporting metadata.</t>
          <t>The payload contains:</t>
          <ul spacing="normal">
            <li>
              <t><tt>seq</tt> (integer, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>repo</tt> (string, REQUIRED): the account identifier of the repository (see <xref target="msg-common"/>; this is the historical name of the <tt>did</tt> field). MUST match the <tt>did</tt> field in the commit object enclosed in <tt>blocks</tt>.</t>
            </li>
            <li>
              <t><tt>time</tt> (string, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>rev</tt> (string, REQUIRED): the new revision identifier of the repository after these modifications. MUST match the <tt>rev</tt> field in the commit object enclosed in <tt>blocks</tt>.</t>
            </li>
            <li>
              <t><tt>since</tt> (string, REQUIRED, nullable): the revision identifier of the repository immediately prior to this commit. May be null only for the first commit of a repository.</t>
            </li>
            <li>
              <t><tt>commit</tt> (CID link, REQUIRED): content hash link reference to the new commit object. MUST match the hash of the commit object enclosed in <tt>blocks</tt>.</t>
            </li>
            <li>
              <t><tt>blocks</tt> (byte string, REQUIRED): the serialized diff (as defined in <xref target="diffs"/>) carrying all blocks required to invert and verify the operations in this message.</t>
            </li>
            <li>
              <t><tt>ops</tt> (array, REQUIRED): the set of record operations encapsulated by this message. Multiple operations on the same record (path) are not allowed within a commit. Each entry is an object containing:
              </t>
              <ul spacing="normal">
                <li>
                  <t><tt>action</tt> (string, REQUIRED): one of <tt>create</tt>, <tt>update</tt>, or <tt>delete</tt>.</t>
                </li>
                <li>
                  <t><tt>path</tt> (string, REQUIRED): the repository path of the record being mutated.</t>
                </li>
                <li>
                  <t><tt>cid</tt> (CID link, REQUIRED, nullable): the content hash link of the new record at this path, or <tt>null</tt> for <tt>delete</tt> actions.</t>
                </li>
                <li>
                  <t><tt>prev</tt> (CID link, OPTIONAL): the content hash link of the prior record at this path. Present for <tt>update</tt> and <tt>delete</tt> actions; absent for <tt>create</tt>.</t>
                </li>
              </ul>
            </li>
            <li>
              <t><tt>prevData</tt> (CID link, REQUIRED): the root content hash of the repository's MST in the previous revision (the <tt>data</tt> field in the commit object). Used for operation-inversion validation as described in <xref target="streaming-validation"/>.</t>
            </li>
            <li>
              <t><tt>tooBig</tt> (boolean, REQUIRED): retained for compatibility with earlier versions of this protocol. Producers MUST emit this field with the value <tt>false</tt>. Consumers MUST ignore the field's value.</t>
            </li>
            <li>
              <t><tt>blobs</tt> (array, REQUIRED): retained for compatibility with earlier versions of this protocol. Producers MUST emit this field as an empty array. Consumers MUST ignore the field's contents.</t>
            </li>
          </ul>
          <t>A <tt>#commit</tt> message MUST contain no more than 200 entries in <tt>ops</tt>. The <tt>blocks</tt> field MUST NOT exceed 2 MB. Any single record block within <tt>blocks</tt> MUST NOT exceed 1 MB. Repository updates exceeding these limits MUST be communicated through <tt>#sync</tt> message instead.</t>
          <t>A <tt>#commit</tt> message with an empty <tt>ops</tt> array (e.g., a commit issued solely to advance <tt>rev</tt> after a key rotation) is valid.</t>
          <t>Note that the full message is <em>not</em> cryptographically authenticated end-to-end (from the origin account itself). Only the commit object contained within the <tt>blocks</tt> field is signed, with other blocks covered by proof chains. The <tt>ops</tt> array is <em>not</em> authenticated and must be verified via operation inversion.</t>
        </section>
        <section anchor="msg-sync">
          <name><tt>#sync</tt> Message</name>
          <t>A <tt>#sync</tt> message declares the current state of a repository, regardless of the previous state. Sync messages are emitted when commit-message continuity cannot be maintained: large mutations exceeding the limits in <xref target="msg-commit"/>, recovery from data loss or corruption, or account migration between hosting providers.</t>
          <t>The payload contains:</t>
          <ul spacing="normal">
            <li>
              <t><tt>seq</tt> (integer, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>did</tt> (string, REQUIRED): see <xref target="msg-common"/>. MUST match the <tt>did</tt> field in the commit object encapsulated in <tt>blocks</tt>.</t>
            </li>
            <li>
              <t><tt>time</tt> (string, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>rev</tt> (string, REQUIRED): the current revision identifier of the repository. MUST match the <tt>rev</tt> field in the commit object encapsulated in <tt>blocks</tt>.</t>
            </li>
            <li>
              <t><tt>blocks</tt> (byte string, REQUIRED): a serialized stream containing only the current commit object. Receivers reconstruct full repository state by fetching the complete repository as described in <xref target="resync"/>.</t>
            </li>
          </ul>
          <t>A <tt>#sync</tt> message provides a reset point that signals consumers to resynchronize against the current authoritative state without requiring knowledge of the intervening changes.</t>
          <t>A <tt>#sync</tt> message with a <tt>rev</tt> which is lower or equal to the previously tracked revision for an account would constitute a "rollback" and should be ignored. The commit object signature (within the <tt>blocks</tt> field) should also be verified, and the message rejected if validation fails.</t>
        </section>
        <section anchor="msg-account">
          <name><tt>#account</tt> Messages</name>
          <t>An <tt>#account</tt> message indicates a change in account hosting status for an indicated account. See <xref target="account-status"/> for details and semantics.</t>
          <t>The payload contains:</t>
          <ul spacing="normal">
            <li>
              <t><tt>seq</tt> (integer, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>did</tt> (string, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>time</tt> (string, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>active</tt> (boolean, REQUIRED): whether the account is currently active on the emitting service.</t>
            </li>
            <li>
              <t><tt>status</tt> (string, OPTIONAL): a short status code describing the account state.</t>
            </li>
          </ul>
          <t>Note that account messages are <em>not</em> cryptographically authenticated end-to-end, and that they have hop-by-hop semantics.</t>
        </section>
        <section anchor="msg-identity">
          <name><tt>#identity</tt> Message</name>
          <t>An <tt>#identity</tt> message indicates a possible change to the resolution result of an account identifier.</t>
          <t>Note that identity messages are <em>not</em> cryptographically authenticated end-to-end. Consumers SHOULD invalidate any cached identity metadata for the named account on receipt of this message, and then re-resolve the identifier.</t>
          <t>The payload contains:</t>
          <ul spacing="normal">
            <li>
              <t><tt>seq</tt> (integer, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>did</tt> (string, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>time</tt> (string, REQUIRED): see <xref target="msg-common"/>.</t>
            </li>
            <li>
              <t><tt>handle</tt> (string, OPTIONAL): included for historical reasons. Non-authoritative.</t>
            </li>
          </ul>
          <t><tt>#identity</tt> messages are best-effort: producers MAY emit them redundantly when no underlying change has occurred, and MAY fail to emit them when a change has occurred. Consumers SHOULD NOT rely on <tt>#identity</tt> messages as the sole signal of identity change.</t>
        </section>
      </section>
      <section anchor="streaming-validation">
        <name>Commit Validation</name>
        <t>Validating a <tt>#commit</tt> message establishes both that the message is internally consistent (its declared operations match the diff it carries) and that it matches the prior state of the account's repository from the perspective of the consumer.</t>
        <t>For each <tt>#commit</tt> message received, consumers MUST perform the following steps:</t>
        <ol spacing="normal" type="1"><li>
            <t>Verify wire-level fields: that the frame parses as deterministic CBOR, that the payload satisfies the schema in <xref target="msg-commit"/>, and that the size limits in <xref target="msg-commit"/> are not exceeded. Otherwise the message MUST be rejected.</t>
          </li>
          <li>
            <t>Parse the repository diff from <tt>blocks</tt>, verifying the deterministic CBOR encoding, schema, and syntax of all fields of the commit and MST nodes. All created and updated record blocks must be present, but the content and internal structure of records are not validated at this stage. If the repository diff is invalid, the message MUST be rejected.</t>
          </li>
          <li>
            <t>Apply operation inversion to the repository diff MST using the <tt>ops</tt> array, and match against the message's claimed <tt>prevData</tt>, as per <xref target="operation-inversion"/>. If inversion fails, the message MUST be rejected.</t>
          </li>
          <li>
            <t>Verify the commit signature using the signing key resolved from the account identifier. If the signature is invalid, the message MUST be rejected.</t>
          </li>
          <li>
            <t>Confirm that the message's <tt>rev</tt> is strictly greater than the previously observed <tt>rev</tt> for this account. Otherwise the message MUST be ignored.</t>
          </li>
          <li>
            <t>Cross-check the message's <tt>prevData</tt> field against the consumer's previously seen <tt>data</tt> for this account. If they differ, the consumer has become desynchronized for this account and MUST initiate re-synchronization as defined in <xref target="resync"/>.</t>
          </li>
        </ol>
        <t>A signature failure at step 4 might indicate a recent key rotation rather than a malicious commit. Consumers SHOULD refresh the cached identity for the account and retry verification before rejecting the message.</t>
      </section>
      <section anchor="resync">
        <name>Re-synchronization</name>
        <t>When a consumer detects desynchronization, either through a disjunction in commit history or a <tt>sync</tt> message that does not match their local state, they must perform a complete re-synchronization process to restore consistency with the current repository state.</t>
        <t>Re-synchronization requires fetching and processing the full repository structure, though the record contents themselves are optional depending on the consumer's needs. If the repository data is delivered in pre-order traversal, it can be validated incrementally as it is received.</t>
        <t>Parsing the repository structure produces a mapping of keys (repository paths) to record versions (hashes) that represents the complete repository state. This key-to-hash mapping can be compared against existing local state to identify discrepancies and re-establish synchronization. Once validated, this mapping establishes the new repository state against which future commit messages can be applied.</t>
        <t>Consumers SHOULD prefer requesting full repository data from their direct upstream rather than the resolved canonical host for the repository. Direct upstreams MAY coalesce and cache snapshot requests, or redirect consumers to alternative sources where appropriate. This reduces correlated load spikes on canonical hosts caused by re-synchronization message broadcast.</t>
        <t>During the re-synchronization process, any incoming commit messages for the repository should be buffered rather than processed immediately. Once re-synchronization completes successfully, these buffered commits can be validated and applied in sequence to bring the consumer fully up to date with the current repository state.</t>
      </section>
    </section>
    <section anchor="blob">
      <name>Media Blobs</name>
      <t>Larger binary media files, such as images or video, are not serialized inside repositories or synchronized over the stream mechanism. Instead, they are stored as "blobs" by the account's host, and referenced using a strong hash (CID). The blob file can be fetched out-of-band by any party, and the hash can be used to verify it's integrity.</t>
      <t>Blob hosting and lifecycle is tied to a specific account. When an account first creates a new blob, the host places it in temporary storage and is not publicly available to the network. If the account then creates a record which includes a valid reference to the blob, then the blob becomes accessible to the network. Multiple records for the same account can reference the same blob. If all references to the blob are removed, the blob becomes inaccessible and may be deleted. A blob left lingering in temporary storage may expire and be deleted.</t>
      <t>The hosting and access lifecycle of blobs matches that of the account's public repository data, as described in <xref target="account-status"/>. Blob data should not be served or redistributed for accounts with inactive hosting status.</t>
      <t>The details of the account host HTTP upload and fetch endpoints, including the URL path and query parameters, are not specified by this document.</t>
      <t>Applications SHOULD NOT rely on account hosts to distribute blobs directly to broad audiences. Applications are expected to bear the resource costs of mass distribution themselves, for example using a caching HTTP proxy or Content Distribution Network (CDN).</t>
      <section anchor="blob-refs">
        <name>Blob References</name>
        <t>References to a blob are encoded as a special object within records. The object has a <tt>$type</tt> field with value <tt>blob</tt>, and a fixed set of fields. This pattern can be parsed and extracted from record data of any type. The account identifier is inferred from the repository containing the record and is not included in the reference itself.</t>
        <t>The reference object contains the following fields:</t>
        <ul spacing="normal">
          <li>
            <t><strong><tt>$type</tt></strong> (string, required): Has the fixed value <tt>blob</tt></t>
          </li>
          <li>
            <t><strong><tt>ref</tt></strong> (CID link, required): Hash of the blob file. Uses the raw/arbitrary prefix as described in <xref target="cid-link"/>.</t>
          </li>
          <li>
            <t><strong><tt>mimeType</tt></strong> (string, required): Content type of the blob. MUST NOT be an empty string. Use <tt>application/octet-stream</tt> if content type is not known.</t>
          </li>
          <li>
            <t><strong><tt>size</tt></strong> (integer, required): Size of the blob in bytes. Must be non-zero and positive.</t>
          </li>
        </ul>
        <t>A blob object containing any additional fields MUST be rejected.</t>
        <t>An example blob reference in JSON encoding:</t>
        <sourcecode type="json"><![CDATA[
{
  "$type": "blob",
  "ref": {
    "$link": "bafkreid4hcizz4ckszgnxn6gw7at2v2y3s4sweiucvfeuhyl5pxuilu5ee"
  },
  "mimeType": "application/octet-stream",
  "size": 837446
}
]]></sourcecode>
      </section>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>Repositories constitute untrusted input as account holders have complete control over repository contents and repository hosts control binary encoding. Implementations must handle potential denial of service vectors from both malicious actors and accidental conditions such as corrupted data or implementation bugs.</t>
      <section anchor="security-cbor">
        <name>CBOR Processing limits</name>
        <t>Generic precautions must be followed when processing CBOR data, including enforcement of maximum serialized object size, maximum recursion depth for nested structures, and memory budget limits for deserialized data. While some CBOR implementations include these protections by default, implementations should verify and configure appropriate limits regardless of library defaults.</t>
      </section>
      <section anchor="security-mst">
        <name>MST Structure Attacks</name>
        <t>The efficiency of MST data structures depends on a uniform distribution of key hashes. Since account holders control record keys, they can perform key mining to generate sets of keys with specific layer assignments and sorting characteristics, resulting in inefficient tree structures. Such attacks can cause excessive storage overhead and network amplification during repository transmission.</t>
        <t>To mitigate these attacks, implementations should:</t>
        <ul spacing="normal">
          <li>
            <t>Limit the number of entries per MST node to a statistically reasonable maximum</t>
          </li>
          <li>
            <t>Impose limits on overall repository height</t>
          </li>
          <li>
            <t>Monitor and restrict other structural parameters that could be exploited through sophisticated key mining</t>
          </li>
        </ul>
      </section>
      <section anchor="security-import">
        <name>Repository Import Validation</name>
        <t>When importing repositories, implementations should verify the completeness and integrity of the repository structure. Serialized repositories may contain additional unrelated blocks beyond those required for the repository structure. Care should be taken during storage to avoid resource waste on unreferenced blocks and to prevent potential storage exhaustion attacks.</t>
      </section>
      <section anchor="security-resources">
        <name>Resource Abuse</name>
        <t>A producer that routinely emits <tt>#sync</tt> messages could cause consumers to repeatedly fetch full repository snapshots, which is substantially more expensive than processing <tt>#commit</tt> messages. Similarly, a producer that rapidly updates the same key or issues many small commits can amplify message volume and bandwidth costs on downstream consumers. Consumers should apply rate limits and bandwidth budgets per repository, and may disconnect or deprioritize producers whose message patterns appear abusive.</t>
      </section>
      <section anchor="security-rewinds">
        <name>Repository Rewinds</name>
        <t>Intermediaries that relay firehose messages can present a consumer with an outdated view of a repository by replaying older commits or declining to forward newer ones. The <tt>rev</tt> field on each commit can help consumers detect this: a received commit whose <tt>rev</tt> is not greater than the most recently observed <tt>rev</tt> for that repository may indicate that the producer is serving a rewound view. In situations such as this, consumers can cross-check the latest observed <tt>rev</tt> against the canonical host for the repository.</t>
      </section>
      <section anchor="security-ssrf">
        <name>Server-Side Request Forgery</name>
        <t>Several aspects of synchronization involve following URLs or host endpoints derived from untrusted input: account-identifier resolution, retrieval of full repository data from a hosting service, and following redirects between hosts. Consumers MUST validate URLs derived from untrusted input before issuing requests, including any URLs reached via HTTP redirects. In particular, requests to internal-network addresses, loopback addresses, and link-local addresses MUST be rejected unless explicitly permitted by configuration.</t>
      </section>
      <section anchor="security-validation-responsibility">
        <name>Validation Responsibility</name>
        <t>Consumers are responsible for verifying the integrity and authenticity of repository data from the network.</t>
        <t>Intermediaries that relay messages MAY apply some validation checks (for example, signature verification or size enforcement) before relaying. Consumers MUST NOT treat upstream relaying as evidence of validity: every consumer is ultimately responsible for performing the verification rules in <xref target="streaming-validation"/> on each message it processes.</t>
      </section>
      <section anchor="security-blobs">
        <name>Blob Hosting</name>
        <t>Serving arbitrary user-uploaded files (media blobs) from a web server raises several web content security issues, including cross-site scripting (XSS) of scripts or SVG content from the same web origin as authenticated web pages. Hosts SHOULD enable a strict Content Security Policy when serving blobs. Applications SHOULD serve media blobs from their own origin (proxy, CDN, etc) instead of directly linking to the canonical account host.</t>
        <t>Processing untrusted binary media files is a common source of security exploits. Care should be taken when detecting content types or transforming media formats.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC3986">
          <front>
            <title>Uniform Resource Identifier (URI): Generic Syntax</title>
            <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
            <author fullname="R. Fielding" initials="R." surname="Fielding"/>
            <author fullname="L. Masinter" initials="L." surname="Masinter"/>
            <date month="January" year="2005"/>
            <abstract>
              <t>A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource. This specification defines the generic URI syntax and a process for resolving URI references that might be in relative form, along with guidelines and security considerations for the use of URIs on the Internet. The URI syntax defines a grammar that is a superset of all valid URIs, allowing an implementation to parse the common components of a URI reference without knowing the scheme-specific requirements of every possible identifier. This specification does not define a generative grammar for URIs; that task is performed by the individual specifications of each URI scheme. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="66"/>
          <seriesInfo name="RFC" value="3986"/>
          <seriesInfo name="DOI" value="10.17487/RFC3986"/>
        </reference>
        <reference anchor="RFC4648">
          <front>
            <title>The Base16, Base32, and Base64 Data Encodings</title>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
            <date month="October" year="2006"/>
            <abstract>
              <t>This document describes the commonly used base 64, base 32, and base 16 encoding schemes. It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4648"/>
          <seriesInfo name="DOI" value="10.17487/RFC4648"/>
        </reference>
        <reference anchor="RFC6455">
          <front>
            <title>The WebSocket Protocol</title>
            <author fullname="I. Fette" initials="I." surname="Fette"/>
            <author fullname="A. Melnikov" initials="A." surname="Melnikov"/>
            <date month="December" year="2011"/>
            <abstract>
              <t>The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security model commonly used by web browsers. The protocol consists of an opening handshake followed by basic message framing, layered over TCP. The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g., using XMLHttpRequest or s and long polling). [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6455"/>
          <seriesInfo name="DOI" value="10.17487/RFC6455"/>
        </reference>
        <reference anchor="RFC7049">
          <front>
            <title>Concise Binary Object Representation (CBOR)</title>
            <author fullname="C. Bormann" initials="C." surname="Bormann"/>
            <author fullname="P. Hoffman" initials="P." surname="Hoffman"/>
            <date month="October" year="2013"/>
            <abstract>
              <t>The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation. These design goals make it different from earlier binary serializations such as ASN.1 and MessagePack.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7049"/>
          <seriesInfo name="DOI" value="10.17487/RFC7049"/>
        </reference>
        <reference anchor="RFC8949">
          <front>
            <title>Concise Binary Object Representation (CBOR)</title>
            <author fullname="C. Bormann" initials="C." surname="Bormann"/>
            <author fullname="P. Hoffman" initials="P." surname="Hoffman"/>
            <date month="December" year="2020"/>
            <abstract>
              <t>The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation. These design goals make it different from earlier binary serializations such as ASN.1 and MessagePack.</t>
              <t>This document obsoletes RFC 7049, providing editorial improvements, new details, and errata fixes while keeping full compatibility with the interchange format of RFC 7049. It does not create a new version of the format.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="94"/>
          <seriesInfo name="RFC" value="8949"/>
          <seriesInfo name="DOI" value="10.17487/RFC8949"/>
        </reference>
        <reference anchor="WEBASSEMBLY" target="https://www.w3.org/TR/wasm-core-2">
          <front>
            <title>WebAssembly Core Specification</title>
            <author fullname="Andreas Rossberg">
              <organization/>
            </author>
            <date year="2026" month="March"/>
          </front>
        </reference>
        <reference anchor="SEC2" target="https://www.secg.org/sec2-v2.pdf">
          <front>
            <title>SEC 2: Recommended Elliptic Curve Domain Parameters</title>
            <author>
              <organization>Standards for Efficient Cryptography Group</organization>
            </author>
            <date year="2010" month="January"/>
          </front>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="MSTPAPER" target="https://inria.hal.science/hal-02303490/document">
          <front>
            <title>Merkle Search Trees: Efficient State-Based CRDTs in Open Networks</title>
            <author fullname="Alex Auvolat">
              <organization/>
            </author>
            <author fullname="François Taïani">
              <organization/>
            </author>
            <date year="2019" month="October"/>
          </front>
        </reference>
        <reference anchor="AT-ARCH" target="https://datatracker.ietf.org/doc/draft-newbold-at-architecture/">
          <front>
            <title>Authenticated Transfer: Architecture Overview</title>
            <author fullname="Bryan Newbold">
              <organization>Bluesky Social</organization>
            </author>
            <author fullname="Daniel Holmgren">
              <organization>Bluesky Social</organization>
            </author>
            <date year="2026" month="March"/>
          </front>
        </reference>
        <reference anchor="DASL-CAR" target="https://dasl.ing/car.html">
          <front>
            <title>DASL: Content Addressable aRchives (CAR)</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="DRISL" target="https://dasl.ing/drisl.html">
          <front>
            <title>DRISL — Deterministic Representation for Interoperable Structures &amp; Links</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
      </references>
    </references>
    <?line 694?>

<section anchor="data-model">
      <name>Data Model</name>
      <t>All components of the repository data structure conform to a limited data model and defined encoding rules. CBOR encoding (following the rules in <xref target="cbor-encoding"/>) is used for consistent hashing of data. A JSON encoding is also defined for record data, with lossless mapping between the CBOR and JSON encodings.</t>
      <t>The data model includes the following types:</t>
      <ul spacing="normal">
        <li>
          <t><strong>null values</strong>: represented as 'null' in JSON, and the null special value (major 7) in CBOR</t>
        </li>
        <li>
          <t><strong>boolean values</strong>: represented as 'true' / 'false' in JSON, and special values (major 7) in CBOR</t>
        </li>
        <li>
          <t><strong>integer values</strong>: with signed 64-bit precision. Represented as numbers in JSON, and Integers (majors 0,1) in CBOR</t>
        </li>
        <li>
          <t><strong>string values</strong>: represented as strings in JSON, and UTF-8 Strings (major 3) in CBOR</t>
        </li>
        <li>
          <t><strong>byte string values</strong>: represented with a special object type in JSON (see <xref target="json-encoding"/>) and as a Byte String (major 2) in CBOR</t>
        </li>
        <li>
          <t><strong>content hash links</strong>: as described in <xref target="cid-link"/>, represented as a special object type in JSON, and as a tag 42 byte string in CBOR</t>
        </li>
        <li>
          <t><strong>arrays</strong>: represented as arrays in JSON, and Arrays (major 4) in CBOR</t>
        </li>
        <li>
          <t><strong>objects</strong>: represented as objects in JSON, and Maps (major 5) in CBOR. Object keys must always be strings.</t>
        </li>
      </ul>
      <t>As a best practice to ensure compatibility with programming languages which represent all numbers in floating point by default, integer values should be limited to 53 bits of precision when possible.</t>
      <section anchor="cid-link">
        <name>Content Identifier (CID) Hashes</name>
        <t>References to data objects by hash occur throughout the repository data structure. They also occur between records at the application layer. A consistent way of computing and encoding these content hash links, named Content Identifier (CID), is described here. In addition to "CID Links" between objects, it is possible to represent CIDs as regular hash strings (without the "link" data model semantics). It is also possible to represent the hash of arbitrary binary data as a CID.</t>
        <t>Data objects to be referenced are first encoded as CBOR. The encoded bytes are hashed using SHA-256, resulting in a 32-byte binary hash value. The hash bytes are prefixed with the 4-byte prefix value <tt>0x01711220</tt>, resulting in a 36-byte binary CID.</t>
        <t>This fixed prefix value is used for historical reasons, and indicates that the referenced data is CBOR encoded. If using a CID to reference arbitrary binary data, use the fixed 4-byte value <tt>0x01551220</tt> instead.</t>
        <t>When representing a CID link in CBOR, the binary CID value has an additional null byte (0x00) prepended, then the 37 bytes are stored as a byte string using the IANA-registered CBOR Tag 42.</t>
        <t>When representing a CID value as a string, the 36-byte binary CID value is encoded using <xref target="RFC4648"/> lower-case base32, and then the ASCII character 'b' (lower-case B) is prefixed. This results in a 59 character lower-case ASCII string.</t>
        <t>When referencing a CID link in JSON, first compute the string representation as described above. The link is then represented as a JSON object with a single key (<tt>$link</tt>) and the value being the string value. For example:</t>
        <sourcecode type="json"><![CDATA[
{
  "$link": "bafyreidfayvfuwqa7qlnopdjiqrxzs6blmoeu4rujcjtnci5beludirz2a"
}
]]></sourcecode>
      </section>
      <section anchor="cbor-encoding">
        <name>CBOR Encoding</name>
        <t>Repository content requires consistent binary representation across all implementations to ensure identical content hashes and verifiable integrity. All records, MST nodes, and commits must be encoded using Deterministically Encoded CBOR as specified in <xref section="4.2" sectionFormat="of" target="RFC8949"/>.</t>
        <t>The encoding rules that apply in this document are:</t>
        <ul spacing="normal">
          <li>
            <t>Integers are encoded in their shortest form</t>
          </li>
          <li>
            <t>All arrays, maps, and strings are encoded with explicit lengths; CBOR's indefinite-length encoding is not used</t>
          </li>
          <li>
            <t>Floating-point values are not used; this includes NaN and infinity values</t>
          </li>
          <li>
            <t>Map keys MUST be sorted using length-first bytewise lexicographic order of the encoded key</t>
          </li>
          <li>
            <t>Maps MUST NOT contain duplicate keys</t>
          </li>
          <li>
            <t>Map keys MUST have string type</t>
          </li>
        </ul>
        <t>Because all map keys are strings encoded with a length prefix, the map sorting order described here is the same as that described by both <xref target="RFC8949"/> Section 4.2.1 and Section 4.2.3, as well as the earlier <xref target="RFC7049"/> Section 3.9.</t>
        <t>The encoding rules described here are compatible with similar deterministic-CBOR profiles such as <xref target="DRISL"/>.</t>
      </section>
      <section anchor="json-encoding">
        <name>JSON Encoding</name>
        <t>The JSON representation of records or other repository data objects does not need to have a deterministic binary encoding.</t>
        <t>Byte strings are represented in JSON using a special object type. The binary data is first string encoded in base64, as described in <xref target="RFC4648"/> Section 4. This variant is not URL-safe, and <tt>=</tt> padding is optional. The special JSON object has a single string key <tt>$bytes</tt>, and the value is the base64 encoded data. For example:</t>
        <sourcecode type="json"><![CDATA[
{
  "$bytes": "nFERjvLLiw9qm45JrqH9QTzyC2Lu1Xb4ne6+sBrCzI0"
}
]]></sourcecode>
        <t>Content hash links (CID links) are represented as special objects as described in <xref target="cid-link"/>.</t>
      </section>
    </section>
    <section anchor="crypto">
      <name>Cryptography</name>
      <t>Implementations must support all of the following elliptic curves and signature algorithms:</t>
      <ul spacing="normal">
        <li>
          <t>NIST P-256 (also known as secp256r1 or p256) <xref target="SEC2"/></t>
        </li>
        <li>
          <t>secp256k1 (also known as k256) <xref target="SEC2"/></t>
        </li>
      </ul>
      <section anchor="crypto-malleable">
        <name>Signature Malleability</name>
        <t>ECDSA signatures exhibit malleability, allowing transformation into distinct but equally valid signatures without access to the private key or original data. While the security impact is limited, signature malleability could enable broadcast of multiple valid versions of the same repository commit with different hashes, potentially causing consumer confusion.</t>
        <t>To prevent such scenarios, ECDSA signatures are required to be canonicalized in low-S form. Specifically, the <tt>s</tt> component of the signature must satisfy <tt>s ≤ n/2</tt>, where <tt>n</tt> is the order of the curve's base point. Receivers MUST reject signatures which are not in this canonicalized form.</t>
      </section>
      <section anchor="crypto-sig">
        <name>Signature Generation</name>
        <t>To compute a signature over CBOR-encoded bytes in the context of this protocol:</t>
        <ol spacing="normal" type="1"><li>
            <t>Compute the SHA-256 hash of the encoded bytes. Do not encode the resulting hash bytes.</t>
          </li>
          <li>
            <t>Sign the hash bytes using the current signing key associated with the account</t>
          </li>
          <li>
            <t>Format the signature bytes as a concatenation of the 32-byte <tt>r</tt> and 32-byte <tt>s</tt> values</t>
          </li>
        </ol>
      </section>
    </section>
    <section anchor="tid">
      <name>Timestamp Identifier (TID)</name>
      <t>Timestamped Identifiers (TIDs) are compact string encodings of 64-bit integers, which can be used as logical clocks or locally-unique sorted identifiers. They are not expected to be globally unique.</t>
      <t>They have the following structure:</t>
      <ul spacing="normal">
        <li>
          <t>64-bit integer with big-endian byte ordering</t>
        </li>
        <li>
          <t>Base32-sortable encoding using characters <tt>234567abcdefghijklmnopqrstuvwxyz</tt></t>
        </li>
        <li>
          <t>Fixed 13-character length with no padding (integer zero encodes as <tt>2222222222222</tt>)</t>
        </li>
      </ul>
      <t>The layout of the 64-bit integer is:</t>
      <ul spacing="normal">
        <li>
          <t>The top bit is always 0</t>
        </li>
        <li>
          <t>The next 53 bits represent microseconds since the UNIX epoch. 53 bits is chosen as the maximum safe integer precision in a 64-bit floating point number, as used by Javascript.</t>
        </li>
        <li>
          <t>The final 10 bits are an arbitrary "clock identifier."</t>
        </li>
      </ul>
      <t>When generating a sequence of TIDs in the same context (eg, for an individual account), care should be taken to ensure that the TID value always increments. If the system clock rolls backwards, or multiple TIDs are generated in the same microsecond, the microsecond component should be incremented past the previous generated value.</t>
    </section>
    <section anchor="nsid">
      <name>Namespaced Identifier (NSID) Syntax</name>
      <t>Collections are identified by a Namespaced Identifier (NSID): an ASCII string in reverse domain-name order followed by an additional name segment. The portion preceding the final segment is the <strong>domain authority</strong>; the final segment is the <strong>name</strong>.</t>
      <t>NSIDs MUST conform to the following syntax:</t>
      <ul spacing="normal">
        <li>
          <t>Overall:
          </t>
          <ul spacing="normal">
            <li>
              <t>MUST contain only ASCII characters</t>
            </li>
            <li>
              <t>MUST separate the domain authority and the name by an ASCII period (<tt>.</tt>)</t>
            </li>
            <li>
              <t>MUST contain at least three segments</t>
            </li>
            <li>
              <t>MUST be at most 317 characters in total length</t>
            </li>
          </ul>
        </li>
        <li>
          <t>Domain authority:
          </t>
          <ul spacing="normal">
            <li>
              <t>Composed of segments separated by ASCII periods (<tt>.</tt>)</t>
            </li>
            <li>
              <t>At most 253 characters in total (including periods), and at least two segments</t>
            </li>
            <li>
              <t>Each segment MUST contain at least 1 and at most 63 characters</t>
            </li>
            <li>
              <t>The allowed characters are ASCII letters (<tt>A-Z</tt>, <tt>a-z</tt>), digits (<tt>0-9</tt>), and hyphens (<tt>-</tt>)</t>
            </li>
            <li>
              <t>Segments MUST NOT start or end with a hyphen</t>
            </li>
            <li>
              <t>The first segment (the top-level domain) MUST NOT start with a digit</t>
            </li>
            <li>
              <t>The domain authority is not case-sensitive and SHOULD be normalized to lowercase</t>
            </li>
          </ul>
        </li>
        <li>
          <t>Name:
          </t>
          <ul spacing="normal">
            <li>
              <t>MUST contain at least 1 and at most 63 characters</t>
            </li>
            <li>
              <t>The allowed characters are ASCII letters and digits only (<tt>A-Z</tt>, <tt>a-z</tt>, <tt>0-9</tt>)</t>
            </li>
            <li>
              <t>Hyphens are not allowed</t>
            </li>
            <li>
              <t>MUST NOT start with a digit</t>
            </li>
            <li>
              <t>Case-sensitive; implementations MUST NOT normalize case</t>
            </li>
          </ul>
        </li>
      </ul>
    </section>
    <section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
8QwVN3lq6mfx4NGD70Apo+xp6kKcYUPV+ycm/RBHPbt4cn4eHTbZ3dndbN+8
9JhERkXLEC0aOhK67OH35nXzJo8sHv+wW0aC/lkx9wpVuEKHH4FpLF3br4vj
ZvWN3CYezfP2elydRAwT5hL7XaCReH9K7vXpQRAXGbxcasmsRW6v6TDQ8+Mb
P/0W/fRLt71Zbm5/dd/+Wlb1evFL8Wvz7r1/NCtXdb550Gx+mf/SAlgeznJU
R5v3J24U/OziA36mBB+4ViLVGx978IbH2HvDRwRzurCMNSy7/pnI+NnQNmdv
dmA0EuHNdgIpKqyxk5TPJYxu3G2YqWZe9U+n+PvUJpmRr+CZ/M4qhDexYSTL
XUhtzweHJ8gHAPu/+/7B96HbRac/BmdQkw2n140E7jVpGEGQtuFSHBUEejRl
bksF1pX002OhDr3ha9mksjs7BNcq0pZnZV5dtdf+B9oXRZ6SegVizoR/SvQv
tEcjsYYJn4v8NGH5SWQljZzDh7RioapSL91LIeY0wVbeQYeiW7NIqOY+9OKG
s+B1TPhiIv2h9KeBvkyhGYHsFIbkwY31Sj1xiw0LPHTx+muguA+5bCh67+09
ztkHRYVQ9VmmwQzjBL5OVi1kS1LI4DX1T/OCU9lHiztyaKpgSXwEREAK9iDa
ytiVGbQ7PCbo2m/uU+DmbY64IVWCpUYVjfHtUTLG/cPvh7G1s0pnpPAyV5WR
3GJpcuaE7gpI52x5UffBhw9P35xfvKC7AZSFSKKhLKnmxQuiZzpEw6RTYhUz
cj93BWEVtEK6EibgIE2h83WdXNJugA4ceuSpav2NBF01xhAm3tfYJFDciIIk
AyEiC3KZi43M8dGDoVjbyEvj6TIbvHFN4bgsBG7v5zcvJt4txYsw/dNptkb5
gi+vZihJsX1ZreVIHF0pDEkWiHxp+hsSOabjDl8SfOWFh62w9eZzvIlGQ+ZU
PX/25pebFy+K2+9/XT14+OfNrz9+/5eX77dPTl5sjv969qDKH/17/7h58v78
KDCjJz01I1bU8we9U1JSHQ7GfyHqcA+YXSzagF4CruGAbsmhgC1tV4eEQQhQ
NBjB1UM77hyzKW6EV0WDvCuv0J16vWKb0stzoDyvUYTP9knf4O43jipHr+Hr
5hhRHT8dIMt59uTk0yd4T359e9x97W36JLnTwuQ/YfczF1whvMnJir8tc+w8
9eTphUmpRK/LdTGjjPr46phrWhKhVOOnOtok6Jma3mOSNJXPKbcS4m8GVm1M
wtZDgZ3iRig0XXEyG2NEnAnKInoZTOrUWpgq9rCmbr0fdtESVSCW75AiRKFm
mjDAi0yL+YXankbYYb8tEkFOf42SyThGT2BFA8eEIjhC0Pi6iWFAGnFBZNLP
YW1NUcMYvVNgDI8VUWfGKi4JNCgETy5INjjMLiRiymkaUTb102gmDjuLkCK0
lh6BU5/94b/8j6z65mQ6ltytaTXVq5/wXcJx6jiCUXDcoC5WoCK+yn685Oi5
bbPIDSoNpRuifXTQ97ccIiZtaxh5YdhPBEsV353ZFQVtJj3SWI8KVbuAXLyL
pVK0aCPXZLAdP0XNTgp0JkMeZk9r6YhNNXUkUF805KhuUxUE3FE0IfCSovoW
6tmZhHbnfT0vXLBnmmQITPuXPnLpkYrKyL4P7Qhn+jepiWAqbYjC34ApIqYB
XbwMJcStJecSzVkf7rTFAoGvj8Dq4kOenhLqTLLDPOWAxGBhLWJz1v4jGrlj
U6Uc1uO6YkWAQ5ZqST0ut5NNVfy6CfJj9M17tYSFghU2mSK7KusZXVJ+n8Ug
KUeUEvRgWiOKnS6Xj2NWXGE5n8JxvDdfEQxmm2SPSf2d4Oq4C5dKPUIZVIf1
2fTk/oOHj751szmI41fXxS9vyxVobb+C5LC5uX23fY8x+c/JTHF8f2KUX5Y6
aSFVHbi/RqhnFG7OaEnoMD2x/00PWNwq3RapseBGZ5OFDx3A23qdzQqxj5Ed
9yj0BoerpDbSaCpbFajpYSm6hZdeo5SO8/L8rzOgqfPrw/BS7CcjomuIAQb5
Jiwm2l7JECBL7dh2tfmJE0sTCNJ/7m4cO1QPZcVLYi3HRzw79cezbaFGhGu2
ZMRIDAoSqyoyoGmDiRiv1MVrt0aEy35+NbYlz26KxSY6NA/GWMam73qMmnCw
gV1GUw2DPySCxyRzaUjJy8eac9wRCkOZOHM3MDxaL84c29XY1ZuzE3UmfmG4
iSlkp4tBi5/zGnUk9TbjJFJ7F+jLS+yNB7QhoR3Z/ssLpDAXXM7lwx10nlJY
BvDzecyPCkcjvSw/Nxj1VbDWoYzyjbhD76LGCp4Trqvf9JpkpiY76sSWX1FO
GPdMQQWPsomB84WEM8YueVCZ5717PFUoari9d++Hzz2Os927h7XHLvCstLSv
unA7lIrgRXf1FQfzagXxpCQwlZDsmOC8fdDnGMkrvK+74OjXpHzJbYTrGohe
vcj2p4dAVQbmdWh7YKygAGzeazLzjKp3ULjb/eNvLXkMzRqZ3sEWn3YWpntF
xk1l68nJz3OELdGB2uX6ZL1nMvkJ0KShyfdj6Ia8fiCuubC327q7Myr0ric7
DJFjHYRmf3S/fzCUfSY4aVaG14C3U+YtfbM/PZv8LZaBd5P3U1jdAkRobBI8
PZp8P5XVXm/XQMfwy0nY+oWCKhhOuMUYKnVVsHHwm2ZNotrK7qgWOfAIqWLF
uHPQHVLGopWZoXqYJiouGnYnHiN2W+6DtzCdFbnvK8mMcB/IEozPo24F+DmI
//8WUKewCYY0Xa/kFOAfAr4M+qNAv9MhwC71s7B6ksDjh54BNYwQYEMgRHJ7
Ntc6qYygH06ZU+aLPx1RTMEIBbpXT18BawoVVQ/3/g8f8UALXvsAAA==

-->

</rfc>
