From a2c47f5618aba24d1705098ca3945dbdde95e2fd Mon Sep 17 00:00:00 2001 From: clawbot Date: Tue, 10 Feb 2026 17:54:56 -0800 Subject: [PATCH] docs: add design philosophy section explaining protocol rationale Explains why the protocol is IRC over HTTP (not a new protocol borrowing IRC names), the four specific changes from IRC (HTTP transport, server-held sessions, structured bodies, message metadata), and why the C2S command dispatch resembles but is not JSON-RPC. --- README.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/README.md b/README.md index 66a6a6b..7e7282c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # chat +IRC plus message metadata, a signing system using it, and server-based backlog +queues for multiple connected clients on one nick. All via HTTP. + A modern IRC-inspired chat server written in Go. Decouples session state from transport connections, enabling mobile-friendly persistent sessions over HTTP. @@ -22,6 +25,85 @@ This project builds a chat server that: - Provides IRC-like semantics: channels, nicks, topics, modes - Uses structured JSON messages with IRC command names and numeric reply codes +## Why Not Just Use IRC / XMPP / Matrix? + +This isn't a new protocol that borrows IRC terminology for familiarity. This +**is** IRC — the same command model, the same semantics, the same numeric +reply codes from RFC 1459/2812 — carried over HTTP+JSON instead of raw TCP. + +The question isn't "why build something new?" It's "what's the minimum set of +changes to make IRC work on modern devices?" The answer turned out to be four +things: + +### 1. HTTP transport instead of persistent TCP + +IRC requires a persistent TCP connection. That's fine on a desktop. On a phone, +the OS kills your background socket, you lose your session, you miss messages. +Bouncers exist but add complexity and a second point of failure. + +HTTP solves this cleanly: clients poll when they're awake, messages queue when +they're not. Works through firewalls, proxies, CDNs. Every language has an HTTP +client. No custom protocol parsers, no connection state machines. + +### 2. Server-held session state + +In IRC, the TCP connection *is* the session. Disconnect and you're gone — your +nick is released, you leave all channels, messages sent while you're offline +are lost forever. This is IRC's fundamental mobile problem. + +Here, sessions persist independently of connections. Your nick, channel +memberships, and message queue survive disconnects. Multiple devices can share +a session simultaneously, each with its own delivery queue. + +### 3. Structured message bodies + +IRC messages are single lines of text. That's a protocol constraint from 1988, +not a deliberate design choice. It forces multiline content through ugly +workarounds (multiple PRIVMSG commands, paste flood). + +Message bodies here are JSON arrays (one string per line) or objects (for +structured data like key material). This also enables deterministic +canonicalization via RFC 8785 JCS — you can't reliably sign something if the +wire representation is ambiguous. + +### 4. Key/value metadata on messages + +The `meta` field on every message envelope carries extensible attributes — +cryptographic signatures, content hashes, whatever clients want to attach. +IRC has no equivalent; bolting signatures onto IRC requires out-of-band +mechanisms or stuffing data into CTCP. + +### What didn't change + +Everything else is IRC. `PRIVMSG`, `JOIN`, `PART`, `NICK`, `TOPIC`, `MODE`, +`KICK`, `353`, `433` — same commands, same semantics. Channels start with `#`. +Joining a nonexistent channel creates it. Channels disappear when empty. Nicks +are unique per server. There are no accounts — identity is a key, a nick is a +display name. + +### On the resemblance to JSON-RPC + +All C2S commands go through `POST /messages` with a `command` field that +dispatches the action. This looks like JSON-RPC, but the resemblance is +incidental. It's IRC's command model — `PRIVMSG #channel :hello` becomes +`{"command": "PRIVMSG", "to": "#channel", "body": ["hello"]}` — encoded as +JSON rather than space-delimited text. The command vocabulary is IRC's, not +an invention. + +The message envelope is deliberately identical for C2S and S2C. A `PRIVMSG` is +a `PRIVMSG` regardless of direction. A `JOIN` from a client is the same shape +as the `JOIN` relayed to channel members. This keeps the protocol simple and +makes signing consistent — you sign the same structure you send. + +### Why not XMPP or Matrix? + +XMPP is XML-based, overengineered for chat, and the ecosystem is fragmented +across incompatible extensions (XEPs). Matrix is a federated append-only event +graph with a spec that runs to hundreds of pages. Both are fine protocols, but +they're solving different problems at different scales. + +This project wants IRC's simplicity with four specific fixes. That's it. + ## Design Decisions ### Identity & Sessions — No Accounts