refactor: model message schemas after IRC RFC 1459/2812
Replace c2s/s2c/s2s taxonomy with IRC-native structure: - schema/commands/ — IRC command schemas (PRIVMSG, NOTICE, JOIN, PART, QUIT, NICK, TOPIC, MODE, KICK, PING, PONG) - schema/numerics/ — IRC numeric reply codes (001-004, 322-323, 332, 353, 366, 372-376, 401, 403, 433, 442, 482) - schema/message.json — base envelope mapping IRC wire format to JSON Messages use 'command' field with IRC command names or 3-digit numeric codes. 'body' is a string (IRC trailing parameter), not object/array. 'from'/'to' map to IRC prefix and first parameter. Federation uses the same IRC commands (no custom RELAY/LINK/SYNC). Update README message format, command tables, and examples to match.
This commit is contained in:
142
schema/README.md
142
schema/README.md
@@ -1,81 +1,87 @@
|
||||
# Message Schema Index
|
||||
# Message Schemas
|
||||
|
||||
JSON Schema (draft 2020-12) definitions for the IRC-style message protocol.
|
||||
JSON Schema definitions (draft 2020-12) for the chat protocol. Messages use
|
||||
**IRC command names and numeric reply codes** (RFC 1459/2812) encoded as JSON
|
||||
over HTTP.
|
||||
|
||||
All messages share a common envelope defined in
|
||||
[`message.schema.json`](message.schema.json).
|
||||
## Envelope
|
||||
|
||||
## Base Envelope
|
||||
Every message is a JSON object with a `command` field. The format maps directly
|
||||
to IRC wire format:
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-----------|-----------------|----------|-------------|
|
||||
| `command` | string | ✓ | IRC command name or numeric reply code |
|
||||
| `from` | string | | Sender nick or server name |
|
||||
| `to` | string | | Destination channel or nick |
|
||||
| `params` | array\<string\> | | Additional IRC-style parameters |
|
||||
| `body` | array \| object | varies | Message body (never a raw string) |
|
||||
| `meta` | object | | Extensible metadata (signatures, etc.) |
|
||||
| `id` | string (uuid) | | Server-assigned message ID |
|
||||
| `ts` | string (date-time) | | Server-assigned timestamp |
|
||||
```
|
||||
IRC: :nick PRIVMSG #channel :hello world
|
||||
JSON: {"command": "PRIVMSG", "from": "nick", "to": "#channel", "body": "hello world"}
|
||||
|
||||
## Client-to-Server (C2S)
|
||||
IRC: :server 353 nick = #channel :user1 @op1 +voice1
|
||||
JSON: {"command": "353", "to": "nick", "params": ["=", "#channel"], "body": "user1 @op1 +voice1"}
|
||||
```
|
||||
|
||||
| Command | Schema | Description |
|
||||
|----------|--------|-------------|
|
||||
| PRIVMSG | [`c2s/privmsg.schema.json`](c2s/privmsg.schema.json) | Send message to channel or user |
|
||||
| NOTICE | [`c2s/notice.schema.json`](c2s/notice.schema.json) | Send a notice |
|
||||
| JOIN | [`c2s/join.schema.json`](c2s/join.schema.json) | Join a channel |
|
||||
| PART | [`c2s/part.schema.json`](c2s/part.schema.json) | Leave a channel |
|
||||
| QUIT | [`c2s/quit.schema.json`](c2s/quit.schema.json) | Disconnect |
|
||||
| NICK | [`c2s/nick.schema.json`](c2s/nick.schema.json) | Change nick |
|
||||
| MODE | [`c2s/mode.schema.json`](c2s/mode.schema.json) | Set/query modes |
|
||||
| TOPIC | [`c2s/topic.schema.json`](c2s/topic.schema.json) | Set/query topic |
|
||||
| KICK | [`c2s/kick.schema.json`](c2s/kick.schema.json) | Kick user |
|
||||
| PING | [`c2s/ping.schema.json`](c2s/ping.schema.json) | Client keepalive |
|
||||
| PUBKEY | [`c2s/pubkey.schema.json`](c2s/pubkey.schema.json) | Announce public key |
|
||||
Common fields (see `message.json` for full schema):
|
||||
|
||||
## Server-to-Client (S2C)
|
||||
| Field | Type | Description |
|
||||
|-----------|----------|-------------------------------------------------------|
|
||||
| `id` | integer | Server-assigned ID (monotonically increasing) |
|
||||
| `command` | string | IRC command or 3-digit numeric code |
|
||||
| `from` | string | Source nick or server name (IRC prefix) |
|
||||
| `to` | string | Target: #channel or nick |
|
||||
| `params` | string[] | Middle parameters (mainly for numerics) |
|
||||
| `body` | string | Trailing parameter (message text) |
|
||||
| `ts` | string | ISO 8601 timestamp (server-assigned, not in raw IRC) |
|
||||
| `meta` | object | Extensible metadata (not in raw IRC) |
|
||||
|
||||
### Named Commands
|
||||
## Commands
|
||||
|
||||
| Command | Schema | Description |
|
||||
|----------|--------|-------------|
|
||||
| PRIVMSG | [`s2c/privmsg.schema.json`](s2c/privmsg.schema.json) | Relayed message |
|
||||
| NOTICE | [`s2c/notice.schema.json`](s2c/notice.schema.json) | Server or user notice |
|
||||
| JOIN | [`s2c/join.schema.json`](s2c/join.schema.json) | User joined channel |
|
||||
| PART | [`s2c/part.schema.json`](s2c/part.schema.json) | User left channel |
|
||||
| QUIT | [`s2c/quit.schema.json`](s2c/quit.schema.json) | User disconnected |
|
||||
| NICK | [`s2c/nick.schema.json`](s2c/nick.schema.json) | Nick change |
|
||||
| MODE | [`s2c/mode.schema.json`](s2c/mode.schema.json) | Mode change |
|
||||
| TOPIC | [`s2c/topic.schema.json`](s2c/topic.schema.json) | Topic change |
|
||||
| KICK | [`s2c/kick.schema.json`](s2c/kick.schema.json) | User kicked |
|
||||
| PONG | [`s2c/pong.schema.json`](s2c/pong.schema.json) | Server pong |
|
||||
| PUBKEY | [`s2c/pubkey.schema.json`](s2c/pubkey.schema.json) | Relayed public key |
|
||||
| ERROR | [`s2c/error.schema.json`](s2c/error.schema.json) | Server error |
|
||||
IRC commands used for client↔server and server↔server communication.
|
||||
|
||||
### Numeric Replies
|
||||
| Command | File | RFC | Description |
|
||||
|-----------|---------------------------|-----------|--------------------------------|
|
||||
| `PRIVMSG` | `commands/PRIVMSG.json` | 1459 §4.4.1 | Message to channel or user |
|
||||
| `NOTICE` | `commands/NOTICE.json` | 1459 §4.4.2 | Notice (no auto-reply) |
|
||||
| `JOIN` | `commands/JOIN.json` | 1459 §4.2.1 | Join a channel |
|
||||
| `PART` | `commands/PART.json` | 1459 §4.2.2 | Leave a channel |
|
||||
| `QUIT` | `commands/QUIT.json` | 1459 §4.1.6 | User disconnected |
|
||||
| `NICK` | `commands/NICK.json` | 1459 §4.1.2 | Change nickname |
|
||||
| `TOPIC` | `commands/TOPIC.json` | 1459 §4.2.4 | Get/set channel topic |
|
||||
| `MODE` | `commands/MODE.json` | 1459 §4.2.3 | Set channel/user modes |
|
||||
| `KICK` | `commands/KICK.json` | 1459 §4.2.8 | Kick user from channel |
|
||||
| `PING` | `commands/PING.json` | 1459 §4.6.2 | Keepalive |
|
||||
| `PONG` | `commands/PONG.json` | 1459 §4.6.3 | Keepalive response |
|
||||
|
||||
| Code | Name | Schema | Description |
|
||||
|------|--------------------|--------|-------------|
|
||||
| 001 | RPL_WELCOME | [`s2c/001.schema.json`](s2c/001.schema.json) | Welcome after registration |
|
||||
| 002 | RPL_YOURHOST | [`s2c/002.schema.json`](s2c/002.schema.json) | Server host info |
|
||||
| 322 | RPL_LIST | [`s2c/322.schema.json`](s2c/322.schema.json) | Channel list entry |
|
||||
| 353 | RPL_NAMREPLY | [`s2c/353.schema.json`](s2c/353.schema.json) | Names list |
|
||||
| 366 | RPL_ENDOFNAMES | [`s2c/366.schema.json`](s2c/366.schema.json) | End of names list |
|
||||
| 372 | RPL_MOTD | [`s2c/372.schema.json`](s2c/372.schema.json) | MOTD line |
|
||||
| 375 | RPL_MOTDSTART | [`s2c/375.schema.json`](s2c/375.schema.json) | Start of MOTD |
|
||||
| 376 | RPL_ENDOFMOTD | [`s2c/376.schema.json`](s2c/376.schema.json) | End of MOTD |
|
||||
| 401 | ERR_NOSUCHNICK | [`s2c/401.schema.json`](s2c/401.schema.json) | No such nick/channel |
|
||||
| 403 | ERR_NOSUCHCHANNEL | [`s2c/403.schema.json`](s2c/403.schema.json) | No such channel |
|
||||
| 433 | ERR_NICKNAMEINUSE | [`s2c/433.schema.json`](s2c/433.schema.json) | Nick in use |
|
||||
## Numeric Replies
|
||||
|
||||
## Server-to-Server (S2S)
|
||||
Three-digit codes for server responses, per IRC convention.
|
||||
|
||||
| Command | Schema | Description |
|
||||
|---------|--------|-------------|
|
||||
| RELAY | [`s2s/relay.schema.json`](s2s/relay.schema.json) | Relay message to linked server |
|
||||
| LINK | [`s2s/link.schema.json`](s2s/link.schema.json) | Establish server link |
|
||||
| UNLINK | [`s2s/unlink.schema.json`](s2s/unlink.schema.json) | Tear down link |
|
||||
| SYNC | [`s2s/sync.schema.json`](s2s/sync.schema.json) | Synchronize state |
|
||||
| PING | [`s2s/ping.schema.json`](s2s/ping.schema.json) | Server ping |
|
||||
| PONG | [`s2s/pong.schema.json`](s2s/pong.schema.json) | Server pong |
|
||||
### Success / Informational (0xx–3xx)
|
||||
|
||||
| Code | Name | File | Description |
|
||||
|-------|-------------------|-----------------------|--------------------------------|
|
||||
| `001` | RPL_WELCOME | `numerics/001.json` | Welcome after session creation |
|
||||
| `002` | RPL_YOURHOST | `numerics/002.json` | Server host info |
|
||||
| `003` | RPL_CREATED | `numerics/003.json` | Server creation date |
|
||||
| `004` | RPL_MYINFO | `numerics/004.json` | Server info and modes |
|
||||
| `322` | RPL_LIST | `numerics/322.json` | Channel list entry |
|
||||
| `323` | RPL_LISTEND | `numerics/323.json` | End of channel list |
|
||||
| `332` | RPL_TOPIC | `numerics/332.json` | Channel topic |
|
||||
| `353` | RPL_NAMREPLY | `numerics/353.json` | Channel member list |
|
||||
| `366` | RPL_ENDOFNAMES | `numerics/366.json` | End of NAMES list |
|
||||
| `372` | RPL_MOTD | `numerics/372.json` | MOTD line |
|
||||
| `375` | RPL_MOTDSTART | `numerics/375.json` | Start of MOTD |
|
||||
| `376` | RPL_ENDOFMOTD | `numerics/376.json` | End of MOTD |
|
||||
|
||||
### Errors (4xx)
|
||||
|
||||
| Code | Name | File | Description |
|
||||
|-------|----------------------|-----------------------|--------------------------------|
|
||||
| `401` | ERR_NOSUCHNICK | `numerics/401.json` | No such nick/channel |
|
||||
| `403` | ERR_NOSUCHCHANNEL | `numerics/403.json` | No such channel |
|
||||
| `433` | ERR_NICKNAMEINUSE | `numerics/433.json` | Nickname already in use |
|
||||
| `442` | ERR_NOTONCHANNEL | `numerics/442.json` | Not on that channel |
|
||||
| `482` | ERR_CHANOPRIVSNEEDED | `numerics/482.json` | Not channel operator |
|
||||
|
||||
## Federation (S2S)
|
||||
|
||||
Server-to-server messages use the same command format. Federated servers relay
|
||||
messages with an additional `origin` field in `meta` to track the source server.
|
||||
The PING/PONG commands serve as inter-server keepalives. State sync after link
|
||||
establishment uses a burst of JOIN, NICK, TOPIC, and MODE commands.
|
||||
|
||||
Reference in New Issue
Block a user