2-RRC: RRC Message Types and Session Behavior¶
Version: 0.1.1
This document defines how RRC clients and hubs actually talk to each other once a Link exists. 1-RRC explained the philosophy and the shape of the system. This document explains the verbs. These are the messages, the expectations around them, and the very small amount of shared discipline required for the system not to devolve into interpretive networking.
Nothing here requires the hub to remember the past. Everything here assumes the present is fleeting and fragile, like all good conversations.
Sessions and First Contact¶
An RRC session begins when a client establishes a Reticulum Link to a hub’s RRC destination. There is no separate handshake protocol layered on top. The Link itself proves identity and establishes encryption. If the Link exists, the session exists. If the Link drops, the session is over. There is no graceful afterlife.
Once the Link is up, the client should immediately announce itself. This announcement is not a request for permission. It is a declaration of intent. The hub may accept it or reject it, but there is no negotiation phase where both sides pretend to be polite.
The first message a client sends should be a HELLO. If it sends something else first, the hub is allowed to be confused and uncooperative.
Message Types Overview¶
RRC messages are identified by a numeric type field. The numbers themselves are not magical. They are simply agreed-upon labels so both sides can understand what is happening without guessing.
Message types fall into a few broad categories. Some establish or modify session state. Some interact with rooms. Some carry chat text. Some exist purely so one side can tell the other that something went wrong.
This document defines the core set. Extensions may add more later, but the ones here should be enough to build a functioning system without inventing new semantics every afternoon.
One note before we begin: messages may include an optional envelope nickname field. It is advisory. It is not identity. It is not binding. It is a label someone typed. Treat it accordingly.
HELLO¶
The HELLO message is how a client introduces itself to the hub after a Link has been established.
The body of a HELLO message, if present, is a CBOR map using unsigned integer keys. These keys are scoped only to the HELLO message body and are intended to carry optional session-specific information (for exchanging version information and program capabilities) as well as human-facing metadata.
Human-facing metadata in HELLO is considered an extension of the protocol and outside the scope of this specification. Unknown keys must be ignored.
All fields in the HELLO body are advisory. They exist to improve usability and allow polite feature negotiation, not to establish identity or authority. The hub must not trust or rely on any information in the HELLO body beyond basic formatting. The only authoritative identity is the Reticulum identity bound to the Link itself.
Unknown HELLO body keys must be ignored. Clients may include additional fields for experimentation or future extensions without breaking compatibility.
If the hub accepts the session, it should respond with a WELCOME message. If it does not accept the session, it may send an ERROR and close the Link shortly thereafter. Silence is also a valid response, although hubs that do this should expect clients to leave quietly and never come back.
HELLO is expected exactly once per session. Sending it multiple times does not improve your odds and may shorten the session instead.
WELCOME¶
The WELCOME message is the hub acknowledging that a session exists and that the client may proceed with normal operation.
Like HELLO, the body of a WELCOME message is an optional CBOR map using unsigned integer keys scoped specifically to this message type. The hub may include session-specific information (for exchanging version information and program capabilities) as well as human-facing metadata.
Human-facing metadata in WELCOME is considered an extension of the protocol and outside the scope of this specification. Unknown keys must be ignored.
All fields in the WELCOME body are informational. Clients must not assume that any particular field will be present, and must not require them in order to function.
Unknown WELCOME body keys must be ignored. This allows hubs to add new fields over time without breaking existing clients.
Once a client receives WELCOME, it may begin joining rooms and sending messages. If a client does not receive WELCOME, it should assume the session was not accepted or is otherwise non-functional and behave accordingly, which usually means disconnecting and moving on with its life.
JOIN¶
JOIN is how a client requests to enter a room.
The payload contains the room name. The room name is treated as a logical label. If the room already exists, the client is added to its membership. If the room does not exist, the hub creates it on demand.
There is no persistence requirement here. Creating a room does not imply commitment. Rooms exist only as long as someone is using them.
If the JOIN succeeds, the hub should send a JOINED event back to the client and may optionally notify other room members that someone has arrived. If the JOIN fails, the hub should send an ERROR explaining why, assuming it has the emotional bandwidth to do so.
JOINED¶
JOINED confirms that the client is now a member of a room.
This message exists primarily so the client knows it can start talking without shouting into the void. It may include a list of current members, but it does not have to. Presence is a convenience, not a guarantee.
Clients should not assume JOINED implies permanence. If the Link drops, membership evaporates.
PART¶
PART is how a client leaves a room.
Once PART is processed, the hub removes the client from the room’s membership list. Other room members may be notified, or they may simply notice the silence. Both outcomes are acceptable.
If the PART succeeds, the hub should send a PARTED event back to the client and may optionally notify other room members that someone has left. If the PART fails, the hub should send an ERROR or ignore the request, depending on whether it is feeling communicative.
PART does not destroy the room. If other members remain, the room continues to exist. If no members remain, the room effectively ceases to exist without ceremony.
Clients are encouraged to PART politely, but disconnecting without warning is also considered a valid life choice.
PARTED¶
PARTED confirms that the client is no longer a member of a room.
This message exists for the same reason JOINED does: so the client can update its internal state without having to infer everything from vibes.
PARTED may include a remaining-member list or other presence hints, but it does not have to. Presence is still a convenience, not a treaty.
MSG¶
MSG is the entire reason this system exists.
A MSG carries chat text intended for a specific room. The hub does not interpret the content. It does not sanitize it. It does not store it. It forwards it to all currently connected members of the room and then forgets it.
The payload typically contains text, but the protocol does not restrict this to a single representation. Clients may agree on richer structures if they wish. Hubs are expected to treat the payload as opaque.
If a client sends MSG to a room it is not a member of, the hub may reject it, ignore it, or respond with an ERROR. Clients should not rely on undefined behavior here to express creativity.
NOTICE¶
NOTICE is like MSG, but without the expectation of conversation.
It is intended for informational messages, bot output, or system announcements. Clients may choose to display NOTICE differently, or not at all. The protocol does not enforce semantics beyond delivery.
NOTICE exists because sometimes you want to say something without inviting a reply storm.
PING and PONG¶
PING exists so one side can check whether the other side is still responsive at the application level, not to determine whether the connection itself still exists.
Either the client or the hub may send a PING at any time during an active session. The receiver may respond with PONG if it is able and willing to do so. A PONG indicates that the peer is alive, receiving messages, and capable of responding in a timely manner.
PING is explicitly not a presence mechanism and not a keepalive for Reticulum. The lifetime of a session is governed entirely by the underlying RNS Link. If the peer becomes unreachable, Reticulum will eventually close the Link and notify both sides without any help from PING.
Failure to respond to PING messages should be interpreted as reduced responsiveness, not disappearance. A client or hub that stops answering PINGs may be busy, stalled, or misbehaving, but it is still considered present until the Link itself closes.
Implementations may use PING and PONG for courtesy checks, latency measurement, UI feedback, or to decide whether an otherwise idle session is worth keeping around. They must not treat missed PINGs as authoritative proof that a peer is gone.
In short, PING asks “are you awake,” while the Link answers “are you still here.”
ERROR¶
ERROR is how the hub or client communicates that something has gone wrong.
The payload should contain a short, human-readable explanation. This is not a debugging interface. It is a courtesy message so the other side knows why things stopped working.
After sending ERROR, the sender may choose to continue the session or close it. Clients must not assume ERROR is recoverable unless explicitly stated.
ERROR messages should be rare. If your implementation sends them constantly, that is a design smell.
Event Delivery Expectations¶
All messages sent by the hub are delivered only to clients that are currently connected and eligible to receive them. There is no buffering for clients that are slow, temporarily disconnected, or thinking about reconnecting.
Clients should assume that silence means nothing happened, not that something is waiting for them later.
This applies equally to chat messages, join notifications, and notices. RRC does not attempt to smooth over reality.
Rate Limiting and Sanity¶
Hubs are allowed to impose rate limits. The protocol does not define exact numbers because networks differ and people behave unpredictably.
If a client sends messages too quickly, joins and parts rooms repeatedly, or otherwise behaves like a malfunctioning script, the hub may respond with ERROR or simply close the Link.
Clients should not interpret disconnection as personal hostility. Sometimes it is just math.
Extensibility¶
Clients and hubs must ignore message types they do not recognize. This allows future extensions without breaking older implementations.
Extensions should be documented separately and should not redefine the meaning of existing message types. If you need to do that, you are probably designing a new protocol and should name it something else.