|
| 1 | +--- |
| 2 | +title: CONTENTFRAME |
| 3 | +name: |
| 4 | +category: Standards Track |
| 5 | +tags: |
| 6 | +editor: Jazzz |
| 7 | +contributors: |
| 8 | +--- |
| 9 | + |
| 10 | +## Abstract |
| 11 | + |
| 12 | +This specification defines ContentFrame, a self-describing message format for decentralized chat networks. |
| 13 | +ContentFrame wraps content payloads with metadata identifying their type and governing specification repository. |
| 14 | +Using a `(domain, tag)` tuple, applications can uniquely identify message types and locate authoritative documentation for parsing unfamiliar content. |
| 15 | +This approach enables permissionless innovation while maintaining the context needed for interoperability, allowing applications to gracefully handle messages from sources they don't explicitly know about. |
| 16 | + |
| 17 | +## Motivation |
| 18 | + |
| 19 | +In an interoperable chat network, participants cannot be assumed to use the same software to send and receive messages. |
| 20 | +Users may employ different versions of the same application or different applications entirely. |
| 21 | +This heterogeneity creates a fundamental challenge: how can applications support extensible message types without prior knowledge of every possible format? |
| 22 | + |
| 23 | +Two naive approaches each have significant drawbacks: |
| 24 | + |
| 25 | +**Developer-defined types** would allow flexibility but create fragmentation. |
| 26 | +When developers define their own message types, the context for parsing these messages remains tightly coupled to the software that created them. |
| 27 | +Other applications receiving these messages lack the necessary context to interpret them correctly. |
| 28 | +This leads to multiple definitions of basic types such as `Text` and `Image` that are not compatible across applications. |
| 29 | + |
| 30 | +**Fixed type systems** would ensure universal understanding but restrict innovation. |
| 31 | +A predetermined set of message types eliminates ambiguity but adds friction for developers who want to extend functionality. |
| 32 | +In a permissionless, decentralized protocol, requiring centralized approval for new message types contradicts core design principles. |
| 33 | + |
| 34 | +The core challenge is managing fragmentation in a decentralized protocol while preserving developer freedom to innovate. |
| 35 | + |
| 36 | +**Solution:** A self-describing message format that encodes both the payload and the metadata needed to parse it. |
| 37 | +This approach directs application developers on how a message should be parsed while providing a clear path to learn about unfamiliar content types they encounter. |
| 38 | +By decoupling the encoded data from the specific software that created it, applications can gracefully handle messages from diverse sources without sacrificing extensibility. |
| 39 | + |
| 40 | + |
| 41 | +## Theory / Semantics |
| 42 | + |
| 43 | +### ContentFrame |
| 44 | + |
| 45 | +A ContentFrame provides a self-describing format for payload types by encoding both the type identifier and its administrative origin. |
| 46 | +The core principle is that each payload should declare which entity is responsible for its definition and provide a unique type discriminator within that entity's namespace. |
| 47 | + |
| 48 | +A ContentFrame consists of two key components: |
| 49 | + |
| 50 | +- **Domain**: Points to a specification repository that defines and governs a collection of types |
| 51 | +- **Tag**: A unique identifier within that domain that specifies which type the payload conforms to |
| 52 | + |
| 53 | +Together, the tuple `(domain, tag)` serves two purposes: |
| 54 | + |
| 55 | +1. **Identification**: Uniquely identifies the payload type without ambiguity |
| 56 | +2. **Discovery**: Provides a path for developers to learn how to parse and support unfamiliar types |
| 57 | + |
| 58 | +**Benefits:** |
| 59 | + |
| 60 | +This approach provides several advantages for decentralized interoperability: |
| 61 | + |
| 62 | +- **No naming collisions**: Developers can independently create types without coordinating with others, as each domain manages its own namespace |
| 63 | +- **Type reuse**: Well-defined, established types can be shared across applications, reducing fragmentation |
| 64 | +- **Graceful extensibility**: Applications encountering unknown types can direct developers to the authoritative specification |
| 65 | +- **Decentralized governance**: No central authority is required to approve new types; domains manage their own specifications |
| 66 | + |
| 67 | +By separating the "who defines this" (domain) from the "what is this" (tag), ContentFrame enables permissionless innovation while maintaining the context needed for interoperability. |
| 68 | + |
| 69 | + |
| 70 | +### Concept Mapping |
| 71 | + |
| 72 | +The following diagram illustrates the relationship between ContentFrame components and their specifications: |
| 73 | +```mermaid |
| 74 | +flowchart TD |
| 75 | + d[Domain ID] -->|references| D |
| 76 | + D[Domain] -->|Defines| T[Tag] |
| 77 | + T -->|References| Specification |
| 78 | +``` |
| 79 | + |
| 80 | +### Domain |
| 81 | + |
| 82 | +A domain identifies the authority responsible for defining and governing a set of content types. |
| 83 | +By including the domain, receiving applications can locate the authoritative specification for a type, regardless of which application originally sent it. |
| 84 | + |
| 85 | +**Requirements:** |
| 86 | + |
| 87 | +- A domain MUST be a valid URL as defined in [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) |
| 88 | +- A domain MUST host or reference definitions for all content types within its namespace |
| 89 | +- A domain SHOULD be a specification repository or index that developers can reference |
| 90 | + |
| 91 | +**Specification Format:** |
| 92 | + |
| 93 | +Domains are responsible for describing their types in whatever format is most appropriate. |
| 94 | +The only requirement is that the information needed to parse and understand each type is accessible from the domain URL. |
| 95 | + |
| 96 | + |
| 97 | +**Domain ID Mapping:** |
| 98 | + |
| 99 | +To minimize payload size, domains are mapped to integer identifiers. |
| 100 | +Each domain is assigned a unique `domain_id` which is used in the wire format instead of the full URL. |
| 101 | + |
| 102 | +- A `domain_id` MUST be a positive integer value |
| 103 | +- A `domain_id` MUST correspond to exactly one unique domain |
| 104 | +- The canonical mapping of `domain_id` to domains can be found in [Appendix A: Domains](#appendix-a-domains) |
| 105 | + |
| 106 | +### Tag |
| 107 | + |
| 108 | +A tag is a numeric identifier that uniquely specifies a content type within a domain's namespace. |
| 109 | +After resolving the domain and tag, application developers have all the information needed to locate the definition and parse the payload. |
| 110 | + |
| 111 | +**Requirements:** |
| 112 | + |
| 113 | +- A tag MUST be a positive integer value |
| 114 | +- A tag MUST uniquely identify a single type within its domain |
| 115 | +- Two payloads with the same `(domain, tag)` tuple MUST conform to the same type specification |
| 116 | +- A tag's meaning MUST NOT change after it has been assigned within a domain |
| 117 | + |
| 118 | +**Domain Responsibility:** |
| 119 | + |
| 120 | +Each domain is responsible for: |
| 121 | +- Assigning and managing tag values within its namespace |
| 122 | +- Documenting how each tag maps to a type specification |
| 123 | +- Ensuring tag assignments remain stable and unambiguous |
| 124 | + |
| 125 | +Tags are scoped to their domain, meaning the same tag value can represent different types in different domains without conflict. |
| 126 | + |
| 127 | + |
| 128 | + |
| 129 | +## Wire Format Specification / Syntax |
| 130 | +```protobuf |
| 131 | +message ContentFrame { |
| 132 | + uint32 domain_id = 1; |
| 133 | + uint32 tag = 2; |
| 134 | + bytes payload = 3; |
| 135 | +} |
| 136 | +``` |
| 137 | + |
| 138 | +**Field Descriptions:** |
| 139 | + |
| 140 | +- **domain_id**: Identifies the domain that governs this content type |
| 141 | +- **tag**: Identifies the specific content type within the domain's namespace |
| 142 | +- **payload**: The encoded content data |
| 143 | + |
| 144 | +All fields are required. |
| 145 | + |
| 146 | + |
| 147 | +## Implementation Suggestions |
| 148 | + |
| 149 | +### Tags to Specifications |
| 150 | + |
| 151 | +Where possible, tag values should directly correspond to specification identifiers. |
| 152 | +Using specification IDs as tags removes the need to maintain a separate mapping between tags and specifications. |
| 153 | + |
| 154 | +### Fragmentation |
| 155 | + |
| 156 | +This protocol allows multiple competing definitions of similar content types. |
| 157 | +Having multiple definitions of `Text` or `Image` increases fragmentation between applications. |
| 158 | +Where possible, reusing existing types will reduce burden on developers and increase interoperability. |
| 159 | + |
| 160 | +Domains should focus on providing types unique to their service or use case. |
| 161 | + |
| 162 | + |
| 163 | +# Appendix A: Domains |
| 164 | + |
| 165 | +![TODO] Find appropriate home for this registry. |
| 166 | + |
| 167 | +Domain IDs are assigned sequentially on a first-come, first-served basis. |
| 168 | +New domains are added via pull request. |
| 169 | + |
| 170 | +**Registry Rules:** |
| 171 | + |
| 172 | +- A domain MUST only appear once in the table |
| 173 | +- A domain MAY be updated by the original submitter if the repository has been moved |
| 174 | + |
| 175 | +**Registry:** |
| 176 | + |
| 177 | +| domain_id | specification repository | |
| 178 | +|-----------|--------------------------------------| |
| 179 | +| 1 | https://github.com/waku-org/specs | |
0 commit comments