Skip to content
This repository was archived by the owner on Jun 5, 2026. It is now read-only.

Commit a19d99b

Browse files
authored
Chat Content Frames (#82)
* Core dump * update background and context * Add content definition * Focus on interoperability * Towards SemBr * Fixed domain_id * Update wordlist
1 parent 95916da commit a19d99b

2 files changed

Lines changed: 183 additions & 0 deletions

File tree

.wordlist.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ closeChannel
2929
config
3030
ConnectionStatus
3131
ConnectionStatusEvent
32+
ContentFrame
3233
contentTopic
3334
contentTopics
3435
createNode
@@ -131,6 +132,7 @@ MessageSentEvent
131132
MessageValidation
132133
MiB
133134
multiaddr
135+
namespace
134136
NetworkConfig
135137
NetworkingConfig
136138
nim
@@ -151,11 +153,13 @@ PascalCase
151153
Pax
152154
plaintext
153155
PoV
156+
permissionless
154157
pluggable
155158
Prathi
156159
pre
157160
Prem
158161
ProtocolsConfig
162+
protobuf
159163
pubsub
160164
rateLimitConfig
161165
Req
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
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

Comments
 (0)