Naptify Guild Protocol 1.0 (Draft)

An extension to the OpenNap protocol that links OpenNap servers run by different operators. The English version is authoritative.

This document is the authoritative text. The Japanese version is a translation; where the two differ, this English version prevails. This document is licensed under CC BY-ND 4.0. Anyone is free to implement this specification, and no royalties are charged.

0. About This Document

Item Description
Extension name Naptify Guild Protocol (NGP for short; written “Guild” in English)
Version Document: 1.0 draft (2026-09-28); protocol version: 1
Publisher The Naptify project
Published at https://naptify.net/ (fixed per-version URLs are not yet decided)
Conformance Conforms to the original protocol specification published by the OpenNap project [NAP] (§18) (§1)
Applicability Can be implemented by any OpenNap-family server that implements the client-facing [NAP] messages whose payloads this document reuses (§1.1). The server needs to implement neither the 8000-series server links nor the OpenNap server-to-server messages (the 10010 series)
Relationship to existing links Independent. It neither uses nor changes the 8000 series (SlavaNap-style links) or the OpenNap server-to-server messages. It can coexist on the same listening port (§6.1). Servers connected by links form a link cluster, which takes part in Guilds as a single server (§3.2). A Guild is never established within one link cluster, and two link clusters are connected by at most one Guild connection (§3.3). A link cluster that includes a server that cannot take part, such as SlavaNap or FaceNap, does not take part in Guilds (§3.4)

What a Guild is. A Guild is a mechanism by which OpenNap servers run by different owners connect directly, one to one, to peers that they have registered with each other.

  • Relayed: chat, IMs, presence, browsing, searching, the arrangement of file transfers, and the other messages that a server passes from one user to another (§12.4).
  • Not relayed: wallops and announcements, the messages by which a server’s operators address its users (§13).
  • Not shared: registered users, bans, levels, points, and restrictions.
  • Each server is responsible only for the users logged in to that server.
  • A set of servers connected by links (a link cluster) takes part as one server, through one of its servers (§3.2).

1. What Is Conformed To and What Is Added

1.1 Points of Conformance

  • Framing. Follows the format of [NAP] §2: a 4-byte header consisting of a 2-byte length and a 2-byte type, both little-endian, followed by the payload.
  • String format. Follows [NAP] §2.
  • Fields are separated by a single space (0x20).
  • Values that may contain spaces are enclosed in ".
  • No CR or LF is appended at the end of the line.
  • The meaning of existing messages is not changed. The payloads of the following messages are carried inside messages defined by this document, in their [NAP] format as is.
  • 200, 201 (search request and result)
  • 203, 204, 206 (download request, acknowledgment, and error)
  • 205 (IM, in its server-to-client form)
  • 211, 212, 213 (browse)
  • 403, 406, 407, 410 (channel message, join, part, and topic)
  • 501 (acknowledgment across a firewall)
  • 609 (upload refusal)
  • 824 (emote)
  • 430, 619, 626, 640, 641, 751, 752 (channel invitation, queue limit, data port error, direct browse request and acceptance, user ping and pong; in their client-to-server forms, §12.4)
  • No new messages are sent to clients. Peer servers’ users are presented to clients using existing messages only.

1.2 Additions Specific to This Extension

  • The allocation of types 9000–9199 and their meanings (§5–§13).
  • Mutual authentication, version and capability negotiation, presence synchronization, display-name rules, request IDs, and reason codes for disconnection and refusal.
  • Specifying UTF-8 as the character encoding of Guild message payloads (§4.2).
  • Treating a link cluster as a single server, and announcing the composition of link clusters (§3.2, §3.3).
  • A generic relay for the messages that a server passes from one user to another (§12.4).

1.3 What This Document Does Not Specify

  • The procedures between clients and servers (as in [NAP]).
  • The 8000-series links, and how a representative passes messages within its link cluster (§3.2 specifies only the result that peers observe).
  • The client-to-client transfers themselves (as in [NAP] §5).

2. Terminology and Key Words

Term Meaning
Server A server that accepts OpenNap clients
Peer A server that has been mutually registered as a Guild
Guild connection A single authenticated TCP connection with a peer
Initiator / acceptor The side that opened / accepted that TCP connection
Local users Users logged in to that server as clients. For the representative of a link cluster, this also includes the users logged in to the other servers of the cluster (§3.2). Peer users are never local users
Peer users Local users of a peer server who have been announced through presence (§8). Identified by the pair of user name and origin
Link cluster A set of servers run by the same owner and connected by links (such as the 8000 series). A server without links is a link cluster by itself (§3.2)
Representative The one server of a link cluster that holds the cluster’s Guild connections (§3.2)
Origin The name of the server that created a message
Display name The name under which a peer user is shown to local users (§8.3)
Capability A short word indicating that an optional feature is implemented (§6.5)
Key A secret byte string shared in advance by the operators of the two servers (§6.4)
Request ID A number that ties a search or browse request to its responses (§11)

The key words “MUST”, “MUST NOT”, “SHOULD”, “SHOULD NOT”, and “MAY” in this document are to be interpreted as described in RFC 2119 and RFC 8174 [RFC2119][RFC8174] when, and only when, they appear in all capitals, as shown here.

3. Overall Architecture

3.1 Principles

  1. Direct connections only. Each server connects directly only to the peers it has registered. – A server MUST NOT forward presence, messages, or requests received from a peer to any other peer, whether directly or through other servers. – Within its own link cluster, a representative passes them to the other servers of the cluster as described in §3.2. It MUST NOT pass them to any server outside the cluster. – Because nothing is forwarded between peers, the connections are allowed to form loops. – When A and B, and B and C, are Guilds, nothing is exchanged between A and C. For A and C to communicate, A and C form a Guild directly.
  2. Announce only your own users. Presence MUST announce local users only (for a representative, these include the users of the other servers of its link cluster, §3.2). Peer users learned through any Guild connection MUST NOT be announced to any peer.
  3. Send events, not commands. – What a message carries is the result of something a local user did (spoke, joined, and so on). – This extension has no commands that change the state of peer users or of servers. – The receiver MUST NOT change its local users or the information it stores on the grounds of a peer’s level.
  4. Rules are applied by the server where the user is. – Muting, flood limits, download conditions, and so on are applied, before sending, by the server the user is logged in to. – For transfer requests, the server that receives the request also applies its own limits on requests (§12.3). – The receiver MAY, at its own discretion, stop delivery to its local users.

Servers that are run by the same owner and connected by links (such as the 8000-series links) form a link cluster. Seen from the Guild, a link cluster is one server. A server without links is a link cluster by itself; everything in this section then reduces to the behavior of a single server.

  1. The representative. A link cluster takes part in Guilds through one of its servers, the representative, which holds all of the cluster’s Guild connections. – A link cluster MUST NOT have more than one server that holds Guild connections. If two servers of one cluster held Guild connections, the peer users that one of them passes into the cluster would reach the other as ordinary users of the cluster and be announced to its peers, which item 1 of §3.1 forbids. – The other servers of the cluster hold no Guild connections and need not implement the messages of this extension. However, every server of the cluster MUST be one that can take part in a cluster (§3.4). – The representative uses its own name in the handshake (§6) and as the origin of every message it sends (§4.4). Peers see the users of the whole cluster as users of the representative.
  2. From the cluster to peers. The representative treats the users of the other servers of its cluster as local users. – Presence (§8) covers every user of the cluster. When a user of another server of the cluster logs in or logs out, or leaves because a link is lost, the representative sends 9010 or 9011 accordingly. – Channel messages, IMs, requests, and relays (§9–§12) from users of the other servers, which reach the representative through its links, are sent to peers in the same way as those of its own clients. The rules of the server where the user is logged in have already been applied (item 4 of §3.1); the representative MAY additionally apply its own.
  3. From peers to the cluster. Whatever the representative would deliver to its own clients, it also passes to the other servers of the cluster through its links, presenting each peer user as a user of the representative under the display name (§8.3). – Searches and browses from a peer cover the whole cluster. The representative expands them through its links in the same way as for a request from one of its own clients, and returns the combined results with a single end message (§11). – Transfer arrangements and relays addressed to a user of another server of the cluster are passed to that server through the links (§12). – The other servers of the cluster see peer users only as users of the representative.
  4. No forwarding between peers. The representative knows which of the users it presents to the cluster are peer users, and from which peer each came. It MUST NOT include them in the presence it sends to any peer, and MUST NOT pass anything that originates with one peer’s users to another peer. For example, a search received from one peer is expanded within the cluster only, never to other peers.
  5. Addresses. For a user of another server of the cluster, the IP address and data port that the representative gives to peers (§11, §12) are those that the cluster would give to a user of another of its servers, that is, the values known through the link.
  6. When the representative stops. If the representative stops or its Guild connection is lost, the whole cluster disappears from that peer. Version 1 provides no automatic takeover by another server of the cluster.

Two link clusters are connected by at most one Guild connection.

  • Each side announces the composition of its link cluster with 9008: first in the initial list (§8.2), and again whenever the composition changes.
  • For a peer P, let C(P) be the set consisting of P’s name and the names in P’s latest 9008. For the local server, let C(local) be the set consisting of its own name and the names of the other servers of its link cluster. Names are compared after conversion to ASCII lowercase.
  • Registration. An implementation SHOULD refuse, with an error shown to the operator, to register as a peer a name that is in C(local), or in C(P) for any established peer P.
  • Detection after establishment. After receiving 9008, and whenever its own link cluster changes, a server checks the following and closes connections with 9006 (13).
  • If C(P) and C(local) have a name in common, the peer belongs to the local link cluster. A Guild is not established within one cluster, so P is closed.
  • If C(P) and C(Q) have a name in common for two established peers P and Q, the two peers belong to the same link cluster. The connection with the peer whose name (as a lowercase byte string) is smaller is kept, and the other is closed. Because every server applies the same rule, servers connected to both converge on the same peer.
  • The server that closes a connection for this reason SHOULD notify its operator of the peer names involved.
No. Name Direction Fields and types Behavior on receipt
9008 GUILD_CLUSTER Both srv origin, rest members (the names of the other servers of the sender’s link cluster, each a srv, separated by single spaces; - if there are none) Replace the stored composition of that peer’s cluster with the one received, and check it as described above
  • The composition includes the servers connected through other servers of the cluster, not only those connected directly.
  • The names of servers that cannot be written as a srv are omitted. Such a server cannot be registered as a peer under that name in the first place.
  • A server without links sends 9008 with -.

3.4 Servers That Cannot Take Part

A link cluster takes part in Guilds only while every server in it can take part in a cluster.

  • A server cannot take part if it is of an implementation that is not known to keep to this section and §3.2: in particular, servers of implementations that predate this extension, such as SlavaNap and FaceNap. Such a server cannot carry anything that tells the peer users passed into the cluster (item 3 of §3.2) apart from ordinary users, and cannot tell the other servers whether it holds Guild connections. Leakage of peer users to other peers through a second representative (item 1 of §3.2) can then be neither prevented nor detected within the cluster.
  • While its link cluster includes a server that cannot take part, a server MUST NOT hold Guild connections.
  • It closes its established Guild connections with 9006 (14).
  • It answers 9000 with 9006 (14) (§6.3), and does not initiate connections.
  • It SHOULD show its operator that the Guild is unavailable, naming the servers that cannot take part.
  • When no such server remains in the cluster, the server takes part again: it initiates connections and accepts 9000 as usual (§7.1).
  • How a server learns the implementations of the other servers of its cluster is outside the scope of this document (§1.3). (Informative: Naptify decides from the version string that the 8000-series links announce for every server of the network, in 8000/8001 for a direct link and in 8011 for every other server; no message is added to the links.)

4. Common Rules for Messages

4.1 Framing

+--------+--------+--------+--------+----------------+
| len lo | len hi | typ lo | typ hi | payload (len)  |
+--------+--------+--------+--------+----------------+
  • len and typ are unsigned 16-bit little-endian integers.
  • The receiver MUST accept payloads of up to 65535 bytes.
  • The big-endian form MUST NOT be used.

4.2 Character Encoding

  • Guild message payloads MUST be UTF-8. A message containing invalid UTF-8 MUST be discarded, and the receiver MAY return 9007 (reason 6).
  • A server that talks to its clients in another encoding (CP932, CP1252, etc.) converts to UTF-8 before sending to the Guild, and converts received data to its clients’ encoding.
  • Names, channel names, and file names containing characters that cannot be represented in the local clients’ encoding MUST NOT be shown with those characters replaced by ? or the like. They are treated as undisplayable (that user or that result is not shown to that client).
  • Note on round-tripping file names (informative). A file name sent by a CP932 client is normally a byte string that Windows produced by converting from Unicode, so converting it to UTF-8 and back to CP932 yields the same byte string. The exception is a file name that contains a character having two encodings (some of the NEC-selected IBM extended characters and NEC special characters) in its non-standard encoding. Such a name turns into a different byte string after the round trip, so a download across the Guild can fail.

4.3 Field Types

Type Format
srv Server name. ASCII letters, digits, ., -, and _ only; 1–63 bytes. Compared after conversion to ASCII lowercase
nick User name. 1–255 bytes in UTF-8. Does not contain a space (U+0020), ", or control characters (U+0000–U+001F, U+007F)
ch Channel name. 1–255 bytes in UTF-8. Does not contain a space (U+0020), ", or control characters (U+0000–U+001F, U+007F)
token Printable ASCII characters, not containing a space. 1–255 bytes
int Non-negative decimal integer. No leading zeros (except for 0 itself). The upper limit is given for each field. In messages after the handshake is complete, a value exceeding its upper limit is treated as a format error (reason 6 in §14). During the handshake (9000–9003), §6.2 applies
hex Lowercase hexadecimal
md5 Same as the md5 field of [NAP] 204 and 501. Carried as is, without changing the value
qstr A string enclosed in ". Does not contain "
abbr Server abbreviation. A short name that each server’s operator configures for their own server. 1–16 characters counted in Unicode code points, and no more than 64 bytes in UTF-8. Does not contain a space, ", (, ), or control characters. If none is configured, - is sent
rest Everything from that position to the end of the payload. May contain spaces. Used only for the last field
body(N) The payload of [NAP] message N, as is. Always placed last
  • User names are compared treating only ASCII uppercase and lowercase letters as equal; everything else is compared byte by byte.
  • If an implementation, under its own rules, treats a broader set of names as equal (such as full-width letters), it MUST also treat names it considers equal in that way as the same name.

4.4 The Origin Field

  • 9008 and the messages concerning users (9010 and above) carry the origin srv as their first field.
  • In version 1, the origin MUST be the same as the name of the peer on the connection (as authenticated in §6). A representative uses its own name as the origin for every user of its link cluster (§3.2).
  • A message whose origin differs SHOULD be discarded, with 9007 (reason 14) returned. If this recurs, the receiver MAY close the connection with 9006 (12).

4.5 Verifying the Actor

  • When a message contains the name of a peer user as its actor (the speaker, the IM sender, the requester, the downloader, the uploader, or the actor of a relay), the receiver MUST verify that the name is present in that peer’s presence.
  • If it is not, the message is discarded (reason 13).

4.6 Ordering and Unknown Messages

  • The receiver MUST process messages in the order received.
  • Unknown types within 9000–9199 MUST be ignored. The receiver MAY return 9007 (reason 8).
  • Types outside that range arriving on a Guild connection MUST also be ignored.
  • Messages of types 9000–9199 arriving on a client connection MUST NOT be treated as Guild messages. The only exception is the first 9000 before login (§6.1).

5. Number Allocation

Range Use
9000–9008 Connection, authentication, keepalive, disconnection, composition of link clusters (§3.3, §6, §7)
9010–9012 Presence (§8)
9020–9024 Channels (§9)
9030–9031 IM (§10)
9040–9043 Browsing and cancellation (§11)
9050–9052 Search (§11)
9060–9065 Transfers (§12)
9070 Unassigned (formerly the wallop; §13). MUST NOT be reassigned in version 1
9080–9081 Relays between users (§12.4)
Gaps between the above, 9082–9099 Spare for version 1.x
9100–9189 Reserved for future versions
9190–9199 For implementers’ testing. Never formally allocated. MUST NOT be sent unless the peer has agreed

6. Connection and Handshake

6.1 Distinguishing Connections

  • The initiator opens a TCP connection to the peer’s OpenNap listening port and sends 9000 as the first frame.
  • The acceptor distinguishes connections by the type of the first frame before login.
  • 9000: a Guild handshake.
  • An existing link message (8000, etc.): a link.
  • Anything else: a client.
  • The payload of 9000 MUST begin with the ASCII string GUILD. If it does not, the acceptor closes the connection with 9006 (reason 2).
  • An operator MAY open a separate port dedicated to the Guild.

6.2 Flow

Initiator I                                           Acceptor A
  | 9000 GUILD <vmin> <vmax> <nameI> <nI> <capsI> <abbrI>  --> |  check that I is a registered peer
  |  <-- 9001 <ver> <nameA> <nA> <capsA> <abbrA>               |
  | 9002 <proofI>  -->                                         |  verify proofI
  |  <-- 9003 <proofA>                                         |
  | verify proofA                                              |
  |======= both sides send their presence lists (§8.2) ========|
  • The entire handshake MUST be completed within 30 seconds. If it is exceeded, either side MAY close the connection with reason 2.
  • If any message other than 9000–9003 and 9006 is received before the handshake is complete, the connection is closed with 9006 (reason 2).
  • If a message containing a format error or a value exceeding its upper limit is received during the handshake (9000–9003), the connection is closed with 9006 (reason 2).

6.3 Messages

No. Name Direction Fields and types Behavior on receipt
9000 GUILD_HELLO Initiator→acceptor token "GUILD", int lowest version (max 65535), int highest version (max 65535), srv initiator name, hex nI (32 digits, 128 bits), token capabilities, abbr abbreviation Check in the following order. ① If the format is wrong, 9006 (2). ② If the name is not registered, 9006 (4). ③ If the registration is a link, 9006 (10). ④ If it has been disabled, 9006 (7). ⑤ If the local link cluster includes a server that cannot take part (§3.4), 9006 (14). ⑥ If there is no common version, 9006 (3). ⑦ If none of the above applies, return 9001
9001 GUILD_CHALLENGE Acceptor→initiator int chosen version (max 65535), srv acceptor name, hex nA (32 digits), token capabilities, abbr abbreviation If the acceptor name differs from the name of the peer as registered locally, 9006 (12). The initiator MUST verify that the chosen version is within the range it sent in 9000. If it is not, 9006 (3). If neither applies, return 9002
9002 GUILD_AUTH Initiator→acceptor hex proofI (64 digits) Compare in constant time. If it does not match, 9006 (5). If it matches, return 9003 and consider the connection established
9003 GUILD_WELCOME Acceptor→initiator hex proofA (64 digits) If it does not match, 9006 (5). If it matches, the connection is established
  • nI and nA MUST be generated from a cryptographically secure random source. The same value MUST NOT be used twice.

6.4 Computing the Proof

input = "GUILD1" SP role SP nameI SP nameA SP nI SP nA SP ver SP capsI SP capsA SP abbrI SP abbrA
proof = hex( HMAC-SHA256( key, input ) )
  • The role is initiator for proofI and acceptor for proofA.
  • Names are converted to ASCII lowercase. Capabilities use the exact spelling that was sent. SP is a single space.
  • Abbreviations are used as the exact byte strings (UTF-8) that were sent.
  • HMAC follows [RFC2104], and SHA-256 follows [FIPS180-4].
  • The key is a byte string of at least 16 bytes (32 bytes recommended), shared by the operators of the two servers outside this extension.
  • It SHOULD be exchanged as a hexadecimal string.
  • The key itself MUST NOT be carried in any message.
  • Because the capabilities are part of the input, tampering that strips capabilities from the list in transit causes the proof to fail.

6.5 Versions and Capabilities

  • A version is an integer. The acceptor chooses the highest version common to both sides’ ranges.
  • Capabilities are written as comma-separated words. If there are none, - is used.
Capability Meaning Required
(none) 9008 (§3.3), presence (§8), and §7 Required
chat §9, and 430 in §12.4 Optional
im §10, and 751 and 752 in §12.4 Optional
browse Browsing in §11, and 640 and 641 in §12.4 Optional
search Searching in §11 Optional
xfer §12.1–§12.3, and 619 and 626 in §12.4 Optional
  • The usable capabilities are only those present on both sides.
  • Messages for a feature that is not usable MUST NOT be sent. If received, they are ignored, and the receiver MAY return 9007 (8).
  • Unknown words MUST be ignored. tls is a reserved word and has no meaning in version 1. wallop, used by earlier drafts, is withdrawn (§13); a receiver ignores it like any unknown word, and it MUST NOT be reassigned in version 1.

6.6 Two Connections to the Same Peer

When there are two established connections to the same peer, both sides apply the same rule and close one of them with 9006 (6).

  • If both were opened by the same side, the newer one is kept.
  • If they were opened in opposite directions, the connection whose initiator name (as a lowercase byte string) is smaller is kept.

6.7 Example (Test Vectors)

Conditions: – key = 000102…1e1f (32 bytes) – I = alpha.example, A = beta.example – nI = 00112233445566778899aabbccddeeff, nA = ffeeddccbbaa99887766554433221100 – capsI = chat,im,search,browse,xfer, capsA = chat,im – Abbreviations: A for I, B for A – Version 1

Messages: – The 9000 header is 55 00 28 23. The payload is GUILD 1 1 alpha.example 00112233445566778899aabbccddeeff chat,im,search,browse,xfer A (85 bytes). – The 9001 header is 39 00 29 23. The payload is 1 beta.example ffeeddccbbaa99887766554433221100 chat,im B (57 bytes). – proofI = 40b84fa36f627cd9988ec893353ca1ff16478b218fa9d2866846ae231a6a024f – proofA = 9bd22197252d05512ccdbe0a7d6df7618cd60c5d9b174788cc2690110cddb5d3

(Values computed with Python’s hmac and hashlib. To be verified again with an independent implementation before publication.)

7. Keepalive, Errors, and Disconnection

No. Name Direction Fields and types Behavior on receipt
9004 GUILD_PING Both rest cookie (ASCII, 32 bytes or less) MUST return 9005 with the same cookie
9005 GUILD_PONG Both rest cookie Record that the peer is alive
9006 GUILD_CLOSE Both int reason (table below; max 255), rest description (optional) Close the TCP connection without replying, and log it. Reconnect according to §7.1
9007 GUILD_ERROR Both int target type (max 65535), int reason (§14; max 255), rest description (optional) Informational only; the connection is kept. Log it
  • If nothing has been sent for 60 seconds, a server SHOULD send 9004.
  • If nothing has been received for 180 seconds, a server MAY close the connection with 9006 (8).

Disconnection reasons

No. Meaning Automatic reconnection
1 Normal termination (operator action, shutdown) Wait at least 30 minutes
2 Protocol violation (format, ordering, handshake timeout) Not until an operator intervenes
3 Version mismatch No
4 Name not registered as a peer Yes, with increasing intervals
5 Authentication failure No
6 Duplicate connection (the connection kept under §6.6 is used) No
7 The peer has been disabled by the operator No
8 Keepalive timeout Yes, with increasing intervals
9 Resource limit (send queue overflow, presence count limit) Yes, with increasing intervals
10 Kind mismatch (this peer is registered as a link) No
11 Restart (expected to return shortly) Yes, starting after 30 seconds
12 Name mismatch (peer name, origin) No
13 Same link cluster (the peer belongs to the local link cluster, or to the same link cluster as another peer; §3.3) Yes, with increasing intervals
14 The link cluster of the sender includes a server that cannot take part in Guilds (§3.4) Yes, with increasing intervals

7.1 Reconnection

  • “With increasing intervals” means starting at 30 seconds and doubling each time, up to a maximum of 10 minutes. The interval starts again at 30 seconds once a connection has been established.
  • Reason 4 usually means that the peer’s operator has not registered this server yet; each side registers the other separately. The initiator therefore keeps reconnecting with increasing intervals, and the connection is established once the peer registers it.
  • Reason 13 is retried because link clusters change. Once the clusters no longer overlap, the connection is established. The 10-minute maximum interval keeps the load on the acceptor small.
  • Reason 14 is retried for the same reason. Once the server that cannot take part has left the sender’s cluster, the connection is established. The sender of reason 14 itself does not initiate connections while that server remains (§3.4).
  • A side disconnected for a reason marked “No” SHOULD NOT reconnect automatically.

7.2 Send Queue Overflow

  • Presence messages and channel join/part messages MUST NOT be dropped. If they cannot be sent, the connection is closed with 9006 (9).
  • Search and browse results MAY be dropped. However, the end message MUST NOT be dropped. Whether it is sent follows the rules in §11.

8. Presence

8.1 Messages

No. Name Direction Fields and types Behavior on receipt
9010 GUILD_USER Both srv origin, nick name, int login time (UNIX seconds, UTC; max 2^63−1), token level (User, Moderator, Admin, Elite, Leech), int share count (max 4294967295), int speed (0–10), qstr client, int flags (max 4294967295) Add the presence entry. If the same name from the same peer already exists, replace its fields. If the login time has changed, treat it as the user having left and come back. Determine the display name according to §8.3
9011 GUILD_USER_QUIT Both srv origin, nick name Remove that presence entry. Also remove all of that user’s channel memberships and send 407 to local users. The hotlist 210 is also sent at this point
9012 GUILD_SYNC_END Both srv origin, int number of 9010 messages sent (max 4294967295) The initial list is considered complete. If the number does not match the number of 9010 messages received, the receiver MAY log it. The connection is kept
  • Levels are for display only. The receiver MUST NOT use levels for authorization decisions.
  • Flags: bit 0 (value 1) means “do not list”. The receiver MUST NOT show this user in lists, channel member lists, or whois. Unknown bits are ignored.
  • If qstr client contains ", the sender removes it.
  • IP addresses and data ports are not included in presence. They appear only in transfers and relays (§12) and in search results (the 201 payload).

8.2 The Initial List

Once the connection is established, each side sends the following, in this order.

  1. 9008 (the composition of its link cluster, §3.3).
  2. 9010 for every local user.
  3. If the capability chat has been negotiated, 9020 (joins of all members) and 9024 (topic) for the shared channels.
  4. Finally, 9012.
  • Messages of any other kind MUST NOT be sent before 9012.
  • When the connection is lost, the receiver MUST remove all of that peer’s presence entries and channel memberships.

8.3 How Names Are Displayed

Peer users are identified by the pair of user name and origin. Users with the same user name may be present on different servers at the same time. No user is disconnected or refused login on account of the Guild (except as in item 3 below). A representative determines the display names for its whole link cluster (§3.2).

  1. Names that do not collide are displayed as is. If a peer user’s name is not the same as any of the following, it is shown to local users under that name as is. – The name of a local user (currently logged in) – A name registered on the local server (even if that user is offline) – The name of another peer user already being displayed as is
  2. Colliding names are qualified with the origin. If the name is the same as any of the above, it MUST be displayed with the origin attached. – The recommended form is name(origin) (e.g., masa(guild-b.example)). The parentheses are ASCII ( and ), which clients using any character encoding can represent. – A peer user MUST NOT be displayed under the same name as a local user or a registered name, as is. This is to prevent impersonation. – An implementation MAY always display the origin-qualified form, including when there is no collision. – @ SHOULD NOT be used as the separator. Users commonly use @ as part of their names. – Instead of the origin, the implementation MAY use the abbreviation the peer announced in the handshake (abbr in §4.3). Example: masa(B). However, an abbreviation that falls under any of the following MUST NOT be used; the server name is used instead.
    • - (not configured)
    • The same as another peer’s abbreviation or server name
    • The same as the local server name or the local abbreviation
    • Names are compared in the same way as user names in §4.3 (only ASCII uppercase and lowercase letters are treated as equal).
  3. Reservation of display names. Login and registration by local users under the following names MUST be refused. – A name under which a peer user is being displayed as is (using the [NAP] “already logged in” refusal). – A name in the origin-qualified form. In the recommended form, this is a name ending in (peer server name). – An implementation SHOULD reject, as forbidden words, all names that contain a peer’s server name or abbreviation (and the local server name and abbreviation). However, because 1- or 2-character abbreviations readily occur inside ordinary names, only the (abbreviation) form needs to be rejected for them. Because names are rejected regardless of form, this also prevents claiming a name with the parentheses written differently. – When a peer is registered later, existing registered names that contain its name MAY remain usable as they are. However, the operator SHOULD be notified, so that such users are not mistaken for peer users.
  4. Rewriting the destination. When a local user requests an IM, whois, browse, or download addressed to a display name (including the origin-qualified form), the server rewrites it to the peer user (the pair of name and origin) and sends it to that peer. The name in the message sent to the peer is the original name, without the origin.
  5. Even when a display name becomes free because a peer sent 9011 or the connection was lost, there is no need to change the display names of other peer users midway. They MAY be changed. If they are changed, it is presented to local users as if the user left and rejoined, using 407 and 406.
  6. Names passed into the link cluster. Toward the other servers of its cluster, a representative SHOULD present peer users in the origin-qualified form, even when the name does not collide. The other servers may have registered names that the representative cannot see, and a name collision on a link may be resolved by disconnecting users. If a name used in the cluster collides later, the representative changes it as in item 5. The origin-qualified form is always accepted as a destination (item 4), including at a representative that shows the same peer user to its own clients under the name as is.

9. Channels (Capability chat)

No. Name Direction Fields and types Behavior on receipt
9020 GUILD_CHAN_JOIN Both srv origin, body(406) = ch nick int share count int speed (share count max 4294967295; speed 0–10) If the local server also shares that channel, add the user to the member list (408, 825) under the display name, and send 406 to the local users in the channel. If it does not share it, ignore the message
9021 GUILD_CHAN_PART Both srv origin, body(407) Remove the user from the member list and send 407
9022 GUILD_CHAN_PUBLIC Both srv origin, body(403) = ch nick rest text Send 403 under the display name to the local users in the channel
9023 GUILD_CHAN_EMOTE Both srv origin, body(824) = ch nick "text" Send 824 to the local users in the channel
9024 GUILD_CHAN_TOPIC Both srv origin, body(410) = ch rest topic The server MAY apply it as the topic of its own channel. If it does, send 410
  • Each server decides which channels to share. For a link cluster, the representative decides. The sender MUST NOT send messages for channels it does not share, and the receiver ignores them.
  • Channel names are compared case-insensitively for ASCII letters.
  • The sender applies muting, flood limits, and channel rules to its local users before sending.
  • The receiver MAY decline to deliver a peer user’s messages to its local users on the grounds of its own channel rules.
  • Kicks, bans, operator appointments, and mode changes are not carried.

10. IM (Capability im)

No. Name Direction Fields and types Behavior on receipt
9030 GUILD_PRIVMSG Sender’s server→recipient’s server srv origin, nick recipient, body(205) = nick sender rest text If the recipient is a local user, deliver 205 under the sender’s display name. If not present, return 9031 (1). If the message is not delivered because of the recipient’s settings (such as an ignore list), silently discard it or return 9031 (2)
9031 GUILD_PRIVMSG_FAIL Recipient’s server→sender’s server srv origin, nick original sender, nick original recipient, int reason (max 255) If the original sender is a local user, notify them with 404
  • Recipients who are not online. The recipient’s server handles a 9030 whose recipient is not online as it would a message from one of its own users to a user who is not online. For example, a server with an offline message service stores the message and delivers it at the recipient’s next login. It returns 9031 (1) in either case.
  • A sender’s server MAY send 9030 addressed to a user who is not in the peer’s presence when the destination names that peer in the origin-qualified form (§8.3), so that the recipient’s server can handle it as above.
  • For a representative, the original sender of 9031 may be a user of another server of its link cluster; it notifies that user through its links (§3.2). However, it does not notify the sender again for a 9031 answering a 9030 whose sender has already been told that the recipient is offline (for example, a message that a link server stored in its own offline message service and answered with 404, and that the representative then forwarded).
  • A message for a peer user who is not online is kept by that user’s server, not by a server of the sender’s link cluster. When another server of the cluster keeps a message addressed to a peer user in the origin-qualified form (for example, after the representative has told the cluster that the peer user logged out) and passes it on through its links, the representative sends it to that peer in 9030 instead of keeping it.
  • A request ID is an int from 1 to 4294967295. The requester SHOULD assign it incrementally, starting from 1, per connection and per direction, and MUST NOT reuse an ID whose response has not yet been completed.
No. Name Direction Fields and types Behavior on receipt
9040 GUILD_BROWSE Requester→responder srv origin, int request ID, nick requester, int maximum count (1–4294967295), body(211) = nick target If the target is a local user, send 9041 messages not exceeding the maximum count, and finally send 9042 (0). If not present, 9042 (1). If browsing is disabled, (5). If refused by policy, (3)
9041 GUILD_BROWSE_ITEM Responder→requester srv origin, int request ID, body(212) Deliver 212 to the requester (with the user name converted to the display name)
9042 GUILD_BROWSE_END Responder→requester srv origin, int request ID, int reason (max 255), body(213) Deliver 213 to the requester. If the reason is not 0, the server MAY notify with 404 beforehand
9043 GUILD_QUERY_CANCEL Requester→responder srv origin, int request ID The responder SHOULD abort that request. The end message is handled as described in “Limits and aborting” below
9050 GUILD_SEARCH Requester→responder srv origin, int request ID, nick requester, int maximum count (1–1000), body(200) Search only the shares of local users (for a representative, those of its whole link cluster, §3.2), with the same semantics as for local clients. The shares of peer users are never searched. The number of results does not exceed the smaller of the maximum count and MAX_RESULTS in the payload. Send the resulting 9051 messages, and finally send 9052 (the end message is handled as described in “Limits and aborting” below)
9051 GUILD_SEARCH_ITEM Responder→requester srv origin, int request ID, body(201) Deliver 201 to the requester (with the user name converted to the display name). Discard any results beyond the server’s own policy limit on the number of results
9052 GUILD_SEARCH_END Responder→requester srv origin, int request ID, int reason (max 255), int number of results sent (max 4294967295) That peer’s part is considered finished

Limits and aborting – For each request received, the responder MUST send an end message (9042 or 9052) exactly once. The only exception is a request cancelled by 9043, for which the responder MAY omit it. – The responder MUST NOT forward a request to any other peer. A representative expanding a request within its own link cluster is not forwarding (§3.2). – The responder SHOULD NOT refuse on the grounds of the requester’s level or share count. Such rules are applied by the requester’s server. – The responder MAY set the number of requests it processes concurrently per peer. Requests beyond that are refused with reason 4 in the end message. – The requester SHOULD NOT have more than 16 concurrent requests outstanding to a single peer. – The responder SHOULD send the end message within 60 seconds. A representative that expands a request through its links SHOULD stop waiting for them in time to meet this. – The requester MAY abort the part of a peer that has not finished after 90 seconds. When aborting, the requester SHOULD send 9043 to the responder. Anything that arrives with that request ID after the abort is discarded. – Once the local results and the end (or abort) of every peer are all in, 202 is sent to the user. – The IP addresses in results (the fields of 201 and 213) are filled in by the responder as “externally reachable addresses” (for users of the other servers of a link cluster, see item 5 of §3.2). – When the connection is lost, all requests on that connection are considered finished.

12. Arranging File Transfers (Capability xfer) and Relays Between Users

The transfer itself is performed directly between the clients ([NAP] §5). The messages in this section carry only the arrangements. The payload is created by the server where the actor is, and that server fills in the IP address and port with the externally reachable values for its local user (for users of the other servers of a link cluster, see item 5 of §3.2).

12.1 Messages

No. Name Direction Fields and types Behavior on receipt
9060 GUILD_XFER_REQUEST Downloader’s server→uploader’s server srv origin, nick downloader, body(203) = nick uploader "file name" If the uploader is a local user, apply the rules of §12.3. If allowed, deliver 607 downloader's display name "file name" speed; if refused, return 9065. If not present, 9063
9061 GUILD_XFER_ACCEPT Uploader’s server→downloader’s server srv origin, nick downloader, body(204) = nick uploader int ip int port "file name" md5 int speed (ip max 4294967295; port max 65535; speed 0–10) Deliver 204 to the downloader
9062 GUILD_XFER_REFUSE Same as above srv origin, nick downloader, body(609) The uploader (the client) refused. Deliver 609
9063 GUILD_XFER_NOTFOUND Same as above srv origin, nick downloader, body(206) = nick peer "file name" Deliver 206
9064 GUILD_XFER_PUSH Downloader’s server→uploader’s server srv origin, nick uploader, body(501) = nick downloader int ip int port "file name" md5 int speed (ip max 4294967295; port max 65535; speed 0–10) If the uploader is a local user, apply the rules of §12.3. If allowed, deliver 501 to the uploader; if refused, return 9065 to the origin. If not present, return 9063 to the origin
9065 GUILD_XFER_DENY Uploader’s server→downloader’s server srv origin, nick downloader, int reason (§14; max 255), body(609) = nick uploader "file name" The uploader’s server refused under its rules (§12.3). Deliver 609 to the downloader. Reason 2 is presented in the same way as the uploader being offline. For other reasons, the server MAY notify with 404 beforehand

12.2 Flow

D is a user of S_D; U is a user of S_U.

  • Normal download: 1. D sends 203 to S_D. 2. S_D checks D under its own rules (§12.3) and sends 9060 to S_U. 3. S_U checks the request under its own rules (§12.3) and delivers 607 to U. If S_U refuses, it sends 9065 to S_D, and S_D delivers 609 to D. 4. If U returns 608, S_U sends 9061 to S_D, and S_D delivers 204 to D. If U returns 609, 9062 and 609.
  • Across a firewall (when the port in 204 is 0): D sends 500 to S_D, S_D sends S_U a 9064 containing D’s externally reachable IP address and port, and S_U checks it under its own rules and delivers 501 to U (or returns 9065).

12.3 Rules of Both Servers

A transfer request is subject to the rules of both servers: those of the downloader’s server and those of the uploader’s server.

  • The downloader’s server applies its rules to the downloader before sending 9060 or 9064, in the same way as for a download from one of its local users: points, limits on the number of download and queue requests, sharing conditions, and so on. If it refuses, it answers the downloader itself, and nothing is sent to the peer.
  • Both behind firewalls. A request is refused because both users are behind firewalls (16) only when both data ports are 0 and the IPv4 addresses of both users are known. A user whose IPv4 address is not known, such as a user connected over IPv6 (whose IP address is carried as 0), is not treated as behind a firewall on the grounds that its data port is 0. The same applies to 640 and 641 (§12.4) and to excluding search results.
  • The uploader’s server applies, on receiving 9060 or 9064, the limits it places on requests from users of other servers, together with the uploader’s own settings.
  • Limits on requests, such as a limit on the number of requests in a period. Counts are kept per peer user (the pair of user name and origin).
  • The uploader’s settings, such as the ignore list, and the conditions the uploader must meet on that server (such as having accepted the terms of use).
  • It MUST NOT use the downloader’s level (§8.1). It SHOULD NOT apply rules that depend on information held only by the downloader’s server, such as the downloader’s points or registration.
  • If it refuses, it returns 9065 with the reason: 2 for the uploader’s settings, 15 when a limit on requests is exceeded, and 3 for its other rules. It MUST NOT disconnect, ban, or change the level of the peer user, because a server has no authority over peer users (§17).
  • The receiver verifies the actor’s presence (§4.5). If the delivery target is not a local user, the message is discarded.
  • 218–221 (transfer count notifications) are handled within each server only and are not carried. What changes on 219 and 221, such as points and transfer counts, is changed by each user’s own server.

12.4 Relays Between Users

Besides the transfer arrangements, [NAP] has client messages that a server passes from one user to another: the queue limit (619→620), the data port error (626), direct browsing (640–642), user ping and pong (751, 752), and channel invitations (430). They are carried by the generic relay 9080, so that each is processed with the same meaning as between two users of one server.

  1. The actor’s server applies its rules for message N to the actor, as it would for a local target, and rewrites the destination as in item 4 of §8.3. It then sends 9080. body(N) is the client-to-server payload of N, with the target’s original name as its first field.
  2. The target’s server processes body(N) as message N received from the actor, using the actor’s display name as the actor’s name. It applies only the rules it applies for the target and for requests from users of other servers, not the rules for the actor, and it MUST NOT use the actor’s level. It then delivers to the target the server-to-client message that it would deliver for N. If the target is not a local user, or if its rules refuse the message, it returns 9081 with the reason.
  3. On receiving 9081, the actor’s server tells the actor what it would tell a local user in the same case (642 for 640 and 641; for the other types, what it would tell a user whose target is offline). Reason 2 is presented in the same way as reason 1, as [NAP] servers do for ignore lists.
  4. Only the types in the table below may be carried. A type not in the table MUST NOT be sent in 9080. If one is received, 9081 (8) is returned. A type MUST NOT be sent unless the capability shown for it is usable (§6.5).
No. Name Direction Fields and types Behavior on receipt
9080 GUILD_RELAY Actor’s server→target’s server srv origin, int type (N in the table below; max 65535), nick actor, int ip (max 4294967295), int port (max 65535), body(N) As in item 2. ip and port are the actor’s externally reachable IP address and data port; they are filled in for 640 and 641, and are 0 for the other types
9081 GUILD_RELAY_FAIL Target’s server→actor’s server srv origin, int type (max 65535), nick original actor, nick original target, int reason (§14; max 255) If the original actor is a local user, notify them as in item 3
N body(N) (client-to-server form) Delivered to the target Checked by the target’s server (reason on refusal) Capability
430 nick target ch 430, as for an invitation from a local user The target’s server would share a channel of that name: a channel of that name that exists there and is one it does not share (such as a private or anonymous channel) is refused (12). A name that does not exist there is not refused chat
619 nick target "file name" [int limit] 620 actor "file name" size limit. The size, and the limit when it is omitted, are determined as for a local 619 None xfer
626 nick target [rest] 626 actor [rest] None xfer
640 nick target 640 actor, followed by the actor’s ip port if the target’s data port is 0 Ignore list (2); both behind firewalls (16, §12.3) browse
641 nick target 641 actor ip port Ignore list (2); both behind firewalls (16, §12.3) browse
751 nick target [rest] 751 actor [rest] Ignore list (2) im
752 nick target [rest] 752 actor [rest] None im
  • actor in the delivered message is the actor’s display name (§8.3).
  • 642 is not carried. It is the answer from the actor’s own server, which produces it from 9081.
  • The actor’s server sends 430 only for a channel that it shares (§9). The target joins the channel of that name on its own server; if the channel does not exist there, it is created under that server’s rules, and it is then shared. An invitation (430) from a peer user does not by itself let the target into a channel that requires an invitation; the target’s server decides this under its own channel rules. The actor is not in the channel on the target’s server, and the target’s server does not check whether the actor may invite (such as whether the actor is in the channel); the actor’s server has checked this (item 1). Within a link cluster, the other servers deliver an invitation that the representative passes on through its links in the same way. 431 and 432 are handled within each server only and are not carried.
  • 600 (link speed) is answered from presence (§15).

13. Wallops and Announcements (Not Carried)

Wallops (627) and announcements (628) are how a server’s operators address that server’s users. Peers do not share operators (§17), so neither is carried.

  • This extension has no message corresponding to 627 or 628. They MUST NOT be sent on a Guild connection in any form.
  • 9070 is unassigned. It was allocated to a wallop message (GUILD_WALLOP) in earlier drafts. A 9070 received is an unknown type (§4.6).
  • The capability wallop is withdrawn (§6.5).
  • Within a link cluster, the links carry wallops and announcements as usual; the representative does not pass them to peers.

14. Refusal Reason Codes

Used in 9007, 9031, 9042, 9052, 9065, and 9081.

No. Meaning
0 Success (normal end)
1 The user is not online
2 Refused by the user’s settings
3 Refused by server policy
4 Busy (concurrent request limit)
5 Suspended (searching/browsing disabled)
6 Malformed (contains invalid UTF-8, or a field value exceeds its upper limit)
7 Characters cannot be represented
8 Not supported (capability absent, unknown type)
11 Cannot be handled as a name
12 The channel is not shared
13 Actor mismatch (the name is not in that peer’s presence)
14 Origin mismatch (the origin differs from the name of the peer on the connection)
15 A limit on requests has been exceeded (such as the number of requests in a period)
16 Both users are behind firewalls (both data ports are 0, §12.3)

(9 and 10 are unassigned.)

15. Presentation to Clients (Informative, Not Normative)

  • whois (603): The receiver may build 604 on the spot from presence. An offline peer user is reported as “not online”. Indicating which server the user belongs to is recommended.
  • Lists, channel member lists, and hotlists (830, 408, 825, 209, 210): Peer users may be included under their display names.
  • Link speed (600): The receiver may answer 601 from the speed in presence.

16. Compatibility

  1. Connecting to a server that does not know this extension. 9000 is treated as an unknown message from a client before login. Either there is no response or the connection is closed immediately. The initiator SHOULD abandon the handshake after 30 seconds and indicate to the operator that “the peer does not support the Guild”, and SHOULD lengthen the automatic reconnection interval.
  2. Different versions. The highest common version is chosen as in §6.5. If there is none, the connection is closed with reason 3.
  3. Partial implementations. Everything other than presence is negotiated through capabilities, so partial implementations can still connect.
  4. Unknown types. They are ignored as described in §4.6. Messages added in version 1.x rely on this rule.
  5. Clients. New message numbers never reach clients. Clients need not be changed. A display name may have (origin) attached (§8.3).
  6. Coexistence with links. On the same port, connections are distinguished by the first message. A Guild is not established within one link cluster (§3.3). Information learned through the Guild MAY be passed only within the link cluster, as described in §3.2, and MUST NOT be passed to servers outside it.
  7. Implementations that do not reconnect after reason 4. They still interoperate. The connection is established when the side that registered the other later connects to it, or when an operator reconnects manually.
  8. Link clusters that include servers of other implementations. A link cluster that includes a server that cannot take part, such as SlavaNap or FaceNap, does not take part in Guilds (§3.4); its links themselves are not affected. The other servers of a cluster that takes part need not implement the messages of this extension; they receive peer users through the links as ordinary users of the representative (§3.2).

17. Security Considerations

  1. Authentication. Mutual verification by HMAC-SHA256; the key is never carried in messages. 128-bit single-use random nonces and the role word prevent proofs from being reused or reflected. Including the capabilities in the input prevents tampering that forces features to be dropped.
  2. No protection after authentication. Version 1 provides neither encryption nor tamper detection (as with OpenNap itself). When traffic passes over an untrusted path, a VPN or TLS tunnel SHOULD be used. tls is reserved for the future.
  3. Key handling. Use a separate random key for each peer and deliver it outside this extension. Keys SHOULD be encrypted when stored. If a key is leaked, replace it.
  4. No authority over peers. There are no messages that change a peer’s state. Levels are used for display only. Administrative operations, bans, registrations, settings, wallops, and announcements are not carried.
  5. Impersonation. As specified in §8.3, a peer user MUST NOT be displayed under the same name as a local user or a registered name, as is.
  6. Personal information. Presence does not include IP addresses. They are included in search results, transfer arrangements, and relays for direct browsing (as with OpenNap itself). Operators SHOULD inform their users that joining a Guild can make local users’ IP addresses visible to peer users.
  7. Resource exhaustion attacks. The receiver MAY set per-peer limits on the number of presence entries, the number of concurrent requests, and the number of messages per second. If the presence limit is exceeded, the connection is closed with reason 9. The 30-second handshake timeout and a per-source limit on the number of connections SHOULD be applied.
  8. Connections under unregistered names. Reason 4 reveals whether a name is registered. Operators who are concerned about this MAY return 5 instead of 4. Note that reason 5 stops automatic reconnection (§7), so the initiator does not connect again by itself after it has been registered; an operator has to reconnect manually. Reconnection after reason 4 is limited by the 10-minute maximum interval (§7.1), so it does not place a significant load on the acceptor.
  9. Claims about link clusters. The composition in 9008 is a claim made by an authenticated peer. By naming another peer’s server in it, a peer can cause that peer’s connection to be closed (§3.3). Operators register only peers they trust, and the notification to the operator names the peers involved.
  10. Relays. 9080 carries only the types listed in §12.4, so administrative commands cannot be passed through it. The target’s server does not use the actor’s level.

18. References

  • [NAP] drscholl@users.sourceforge.net (OpenNap project), “napster messages”. Original dated 2000-04-07; change log through 2001-04-07. https://opennap.sourceforge.net/napster.txt. The document describes itself at the outset as “an open specification”. Sections referenced by this document use the original’s section numbers as is: §2 (Client-Server protocol; framing and strings); §3 (Message Types; 200–206, 209–213, 218–221, 403, 404, 406–410, 430–432, 500, 501, 600, 601, 603, 604, 607–609, 619, 620, 626–628, 640–642, 751, 752, 824, 825, 830); §5.1, §5.2, and §5.3 (5.1 Normal Downloading, 5.2 Firwalled Downloading [sic], and 5.3 Client to Client Browsing within Client-Client Protocol; client-to-client transfers and browsing).
  • [NAP-JA] 『Nap プロトコル仕様書』 (Nap Protocol Specification), Japanese translation v1.0 (2002-02-08). A translation of [NAP] and its revised version. Informative only; not a normative reference.
  • [RFC2119] Key words for use in RFCs to Indicate Requirement Levels.
  • [RFC8174] Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words.
  • [RFC2104] HMAC: Keyed-Hashing for Message Authentication.
  • [FIPS180-4] Secure Hash Standard.
  • [RFC3629] UTF-8, a transformation format of ISO 10646.

The original was checked on 2026-09-27 (section structure, definitions of the referenced messages, and field order). A byte-level check will be performed before publication.

Appendix A. Change Log

  • 1.0 draft (2026-09-27): Initial draft.
  • 1.0 draft (2026-09-27): Reason 4 (name not registered as a peer) now leads to automatic reconnection with increasing intervals (§7, §7.1, §16, §17).
  • 1.0 draft (2026-09-27): A link cluster now takes part as a single server through its representative, which passes Guild traffic within the cluster but never between peers (§0, §1, §2, §3.1, §3.2, §4.4, §8.3, §9, §11, §12, §16).
  • 1.0 draft (2026-09-27): Added 9008 GUILD_CLUSTER and disconnection reason 13, so that two link clusters are connected by only one Guild connection (§3.3, §4.4, §5, §6.5, §7, §7.1, §8.2, §17).
  • 1.0 draft (2026-09-27): Transfer requests are now subject to the rules of both servers, and the uploader’s server refuses with the new 9065 GUILD_XFER_DENY; added refusal reason 15 (§3.1, §12.1–§12.3, §14).
  • 1.0 draft (2026-09-27): Added the generic relay 9080 GUILD_RELAY and 9081 GUILD_RELAY_FAIL for 430, 619, 626, 640, 641, 751, and 752; added refusal reason 16 (§0, §1.1, §1.2, §4.5, §5, §6.5, §8.1, §12.4, §14, §15, §17, §18).
  • 1.0 draft (2026-09-27): A link cluster that includes a server that cannot take part, such as SlavaNap or FaceNap, does not take part in Guilds; added disconnection reason 14 (§0, §3.2, §3.4, §6.3, §7, §7.1, §8.3, §16).
  • 1.0 draft (2026-09-27): An invitation (430) may name a channel that does not yet exist on the target’s server (§12.4).
  • 1.0 draft (2026-09-28): The recipient’s server handles an IM to a recipient who is not online as it would a message from one of its own users (for example, keeping it for the next login), and a sender’s server may send such an IM to a peer named in the origin-qualified form (§10).
  • 1.0 draft (2026-09-28): A message for a peer user who is not online is kept by that user’s server, also when another server of the cluster first kept it (§10); the target’s server does not check whether the actor of an invitation (430) may invite (§12.4); users whose IPv4 address is not known, such as users connected over IPv6, are not refused as both behind firewalls (§12.3, §12.4, §14).
  • 1.0 draft (2026-09-28): Wallops are no longer carried: 9070 GUILD_WALLOP and the capability wallop are withdrawn and left unassigned, and the test vectors are recomputed without wallop (§0, §1.1, §3.2, §4.5, §5, §6.5, §6.7, §13, §17).