Content-Addressed Storage

      All data in Seed Hypermedia is stored as blobs — binary data identified by its content hash (CID, Content Identifier). This is the same approach used by IPFS and Git: the address of data IS the hash of the data.

      This has powerful properties:

      • Integrity — If you have a CID and the data, you can verify they match

      • Deduplication — Identical content always has the same CID, stored once

      • Cacheability — Content never changes, so it can be cached indefinitely

      • Distribution — Any peer with the data can serve it, no need for a specific server

    Blob Types

      SHM uses several types of blobs, all CBOR-encoded:

      Change Blobs

        Change blobs contain document modifications — adding blocks, editing text, updating metadata. Each change references its parent changes, forming a DAG (Directed Acyclic Graph) of the document's history.

        Change Blob:
          - author: Ed25519 public key
          - deps: [parent change CIDs]
          - action: "Update" | "Create"
          - ops: [list of operations]
          - signature: Ed25519 signature
          - timestamp: HLC (Hybrid Logical Clock)

      Ref Blobs

        Ref blobs create references between documents — redirects, branches, and tombstones. They enable URL management and document forking.

        Ref Blob:
          - author: Ed25519 public key  
          - capability: CID of the capability granting permission
          - genesis: CID of the original document
          - target: {"version": [change CIDs]}
          - signature: Ed25519 signature

      Capability Blobs

        Capability blobs grant permissions. An account owner signs a capability giving another key the WRITER or EDITOR role for specific paths.

      Media Blobs

        Images, videos, and files are stored as raw IPFS blobs. They're referenced from document blocks using their CID with the ipfs:// scheme.

        # Upload a file blob
        grpcurl -plaintext -d '{
          "blobs": [{"cid": "...", "data": "<base64>"}]
        }' localhost:55002 \
          com.seed.daemon.v1alpha.Daemon/StoreBlobs

    CID Format

      SHM uses CIDv1 with the following parameters:

      • Codec: dag-cbor (0x71) for structured data, raw (0x55) for media

      • Hash: SHA2-256

      • Encoding: base32 (bafy2bz... prefix)

      CIDs are used everywhere: as document versions, blob identifiers, and in HM URLs to reference specific versions of documents.

    CBOR Encoding

      CBOR (Concise Binary Object Representation) is the serialization format for all structured blobs. It's like JSON but binary, more compact, and with deterministic encoding (important for content addressing).

      SHM uses DAG-CBOR specifically, which adds IPLD link semantics. This means CID references within blobs are first-class concepts, enabling efficient graph traversal.

    Operations Inside Blobs

      Change blobs contain a sequence of CRDT operations:

      • SetKey (type 4) — Set top-level metadata key/value

      • MoveBlock (type 2) — Position a block in the tree (parent + left sibling)

      • ReplaceBlock (type 3) — Set or update block content

      • DeleteBlock (type 5) — Remove a block from the tree

      • SetAttributes (type 7) — Set nested metadata via key path arrays

      These operations are CRDTs (Conflict-free Replicated Data Types), meaning concurrent edits by different authors are automatically merged without conflicts.

    Version DAG

      Each document's history forms a DAG where change blobs reference their parents via the deps field. This is conceptually similar to Git commits:

      Change A (create)  ←  Change B (edit)  ←  Change D (merge)
                          ←  Change C (edit)  ←

      The current version of a document is the set of leaf changes (changes with no descendants). When there's only one leaf, that's a clean linear history. When there are multiple leaves, changes were made concurrently and the CRDT merges them.