Skip to content

Latest commit

 

History

History
146 lines (117 loc) · 7.61 KB

File metadata and controls

146 lines (117 loc) · 7.61 KB

Channel moderation

Status: account-backed role, ban, and limit modes; KICK and channel INVITE implemented; shared-key mode designed

The IRC edge projects durable channel authority through the familiar status modes:

Durable role IRC presentation Mutable mode
owner @nick projected through o; ownership changes require explicit transfer
operator @nick +o / -o
voice +nick +v / -v
member or no public-room role nick no prefix

NAMES, channel WHO/WHOX, and WHOIS use the same projection. The server advertises PREFIX=(ov)@+, MODES=1, and bare WHOX; it does not claim a separate owner prefix that existing authority cannot faithfully represent.

An authenticated account that creates a public room becomes its durable owner. An anonymously created public room remains ownerless until the stopped-listener owner-assignment command is used. Private rooms retain the owner selected when they are provisioned.

Owners and operators may apply one status change per MODE command. The nickname selects a currently joined connection, but the resulting role belongs to its authenticated account. Every device for that account therefore gains the same prefix immediately and after restart. Anonymous connections cannot receive a durable status mode. An owner cannot be deopped through MODE; use the explicit ownership-transfer operation so the previous owner's disposition is unambiguous and atomic.

Roles form one hierarchy rather than independent flags. Promoting an account to operator supersedes voice. Removing operator or voice returns an invite-only participant to durable member and removes the status role from a public-room participant. Removing a lower status from an account that already has a higher role is an idempotent no-op.

MODE #channel reports +i for a provisioned private room and + for a public room. The current adapter deliberately refuses +i and -i mutations: a public transcript cannot safely be relabeled private after clients may have retained it, and private-to-public publication should not happen accidentally. Private rooms are created through the explicit provisioning path instead.

Role changes commit through the revisioned channel-policy store and metadata-only authority audit before their MODE line is broadcast. Neither a nickname nor the deliberately opaque anon.invalid host presentation is an authority key.

Account bans

Owners and operators can set durable account bans with MODE #channel +b Nick for an online authenticated nickname, or MODE #channel +b $a:account for a known account whether it is online or not. The server always broadcasts and lists the normalized $a:canonical-account mask. MODE #channel b (or +b without a parameter) returns the standard 367/368 ban list, and MODE #channel -b $a:account removes an entry.

This deliberately implements the IRCv3 account extban advertised as EXTBAN=$,a and ACCOUNTEXTBAN=a; it does not accept nickname, username, hostname, or IP wildcard masks. Those transient or privacy-sensitive values never become durable authority keys. Anonymous users therefore cannot be ban targets. The list is bounded to 100 entries per room and advertised with MAXLIST=b:100.

A ban denies later JOIN attempts with numeric 474. It does not eject a client that is already joined: IRC keeps +b and KICK as separate operations, so an operator can review or revoke status before choosing whether to kick. The ban survives empty rooms, nickname changes, multiple devices, and server restarts. Owners cannot be banned without first transferring ownership. Conversely, ownership cannot be assigned or transferred to an account until its ban is explicitly removed.

In an invite-only room, a ban takes precedence over durable membership. A banned account cannot JOIN or receive a channel invitation, but its previous role is retained so removing the ban restores the preexisting access policy. This avoids smuggling a second membership mutation into +b.

Channel member limits

Owners and operators can set a durable live-membership limit with MODE #channel +l 20 and remove it with MODE #channel -l. The bound must be between 1 and 10,000. MODE #channel includes l and its current parameter, and the server advertises it with the other channel modes as CHANMODES=b,k,l,i (with type-B k, parameter-when-set l, and immutable invite-only i in the final group).

Once the number of joined connections reaches the limit, later JOIN attempts receive standard numeric 471. The count is per live IRC connection, matching established IRC behavior; several devices on one account therefore occupy several slots. Bans and invite-only membership are checked first so a private room does not leak its occupancy to an unauthorized account.

Lowering a limit beneath current occupancy never ejects participants. It only prevents new joins until enough connections leave or an operator raises or removes the limit. The limit survives an empty room and server restart and is part of the same revisioned channel policy and metadata audit as roles and bans.

Shared channel keys

Mode +k is implemented as an independent shared-key JOIN condition, not a durable membership system. Public +k rooms admit a server-admitted connection that presents the key, avoiding account-by-account channel invitations. An invite-only +ik room requires both a durable account role and the key; neither the key nor INVITE bypasses the other condition. Bans and member limits remain authoritative.

Key use is connection-scoped and creates no role, invitation edge, or durable attempt record. Every device supplies it again after reconnect. Only an authenticated owner or operator may set, rotate, or clear it, and the server stores an Argon2id verifier rather than recoverable plaintext. The detailed JOIN, history, rotation, disclosure, and abuse-control contract is in shared-key channels.

Channel invitations

INVITE Nick #channel retains its familiar live notification and 341 reply. In a public room it is only a notification: any joined participant may send it, and it grants no role or durable relationship.

In an invite-only room, only an authenticated owner or operator may invite. The target must also be authenticated. If it has no channel role, the server commits a durable member grant before notifying the target or acknowledging the inviter. A banned target is refused without a notification or role grant. The account can then join from any device, including after restart. Inviting an account that already has access is an idempotent live reminder, not a duplicate role or audit record.

Channel INVITE is deliberately unrelated to the random bearer codes used for server account onboarding. It neither creates an account nor consumes, reveals, or delegates an onboarding invitation.

KICK behavior

Owners and operators may KICK a currently joined nickname. In a public room, this removes only the selected connection. It is not a ban and does not silently rewrite a durable status role; the participant may rejoin, and an operator that should lose authority must first be deopped explicitly.

In an invite-only room, a kick revokes the target account's durable channel role. The policy change commits first, then every joined device for that account receives a KICK and is removed. A later JOIN is denied until a new channel invite or out-of-band membership grant restores access.

Owners cannot be kicked. Ownership must first move through the explicit atomic transfer path, which records exactly what role the previous owner retains. These rules make private-room ejection durable without pretending that a normal public-room kick is a ban.