LOGSEARCH [pattern] searches the incident log newest-first: match a bare
id (as stamped into a kick reason), or any word from the summary; no
argument lists the most recent. Auspex-gated (read-only investigation).
To make it comprehensive, the command audit trail now records every
notable action to the same incident log (not just to the audit channel,
and regardless of whether one is configured) — so registrations, drops,
akills, suspensions, vhosts, notes, and the like are all findable
alongside the kicks and kills stamped at the removal choke-point.
- SHUN <user@host> silences a matching user network-wide without
disconnecting them — another kind ("SHUN") in the generalized X-line
handler (m_shun is loaded), same event-sourced list and lazy expiry as
AKILL/SQLINE/SNLINE.
- CHANKILL <#channel> [reason] AKILLs every distinct member host in one
shot to clear a spam or attack channel; the G-lines the ircd applies
also kill the sessions. Deduped by host, and never bans the operator who
ran it. Both admin-only.
JUPE <server.name> [reason] introduces a fake server holding the name so
the real one can't link; JUPE DEL <name> squits it; JUPE LIST shows them.
Node-local (the introducing node owns the jupe, so it isn't federated —
that would collide SIDs across nodes) and re-asserted at burst. A fake
server id is allocated per jupe. New JupeServer/Squit actions serialise to
the mid-link SERVER introduction and SQUIT. Admin-only.
The connection that puts an IP over its allowance is killed on connect.
The ircd's per-user IP (UID param 7) is now plumbed through UserConnect and
tracked per-IP in the live network view (incremented on connect, released
on quit).
- [session] default_limit sets the base allowance (0/absent = off).
- OperServ SESSION LIST <min> / VIEW <ip> inspect live counts.
- OperServ EXCEPTION ADD <ip-mask> <limit> [reason] / DEL / LIST override
the limit per IP-mask (limit 0 = unlimited); event-sourced so they
federate and survive restart, matched most-permissive-wins.
All admin-gated.
SNLINE ADD [+expiry] <realname-regex> <reason> / DEL / LIST — a realname
R-line the ircd matches against connecting users' realnames. It's just
another kind ("R") in the generalized X-line handler: same event-sourced
list, lazy expiry, and burst re-assertion as AKILL/SQLINE, keyed by
(kind, mask). The mask is kept verbatim (a single-token regex; use . or
\\s for spaces) and an all-wildcard pattern is refused. STATS now counts
it too.
OPER ADD <account> <priv[,priv]> / DEL <account> / LIST grants or revokes
services-operator privileges (auspex, suspend, admin) at runtime, without
editing config and restarting. Runtime grants are event-sourced (Global,
so they federate and survive restart) and UNIONED with the declarative
[[oper]] config at the engine, so either source makes an account an
operator; a config oper can't be revoked here. Admin-only.
Factored the privilege-name parsing into Privs::from_names (+ names/union)
so config loading and runtime grants share one definition.
NEWS ADD <LOGON|OPER> <text> / DEL <LOGON|OPER> <number> / LIST. Logon news
is shown to every user as they connect; oper news is shown to an operator
when they log in. Admin-only to manage. Each item carries a stable id
assigned at add time and embedded in the log, so deletion is order-
independent under replay (DEL by number resolves to that id).
Enabling groundwork: the replicated network-wide lists (bans, now news)
are consolidated into one NetData struct threaded through apply() as a
single parameter — this replaces the akill parameter rather than adding
one, so the fold stays within its argument budget as the lists grow.
INFO ADD <target> <note> / DEL <target> / <target> attaches a staff note
to an account or channel (a #name is a channel, else an account). The note
is shown in that service's INFO — but to operators only (Priv::Auspex),
never to the account's own owner. Admin-only to set.
Follows the typed-field-on-the-entity pattern: an oper_note field folded
through AccountOperNoteSet (Global) / ChannelOperNoteSet (Local) events,
read via dedicated Store getters so it stays out of the public views and
the directory feed.
Force a user's nick change or channel join, reusing the ForceNick and
ForceJoin actions the daemon already relies on (guest renames, auto-join)
so the ircd support is proven. SVSNICK validates the new nick; SVSJOIN
takes an optional key. Both admin-gated and resolve the target via
NetView.
STATS reports the live counts OperServ holds — AKILL and SQLINE bans by
kind, and services ignores — as a quick at-a-glance check. Read-only, so
any operator can run it.
IGNORE ADD [+expiry] <mask> [reason] / DEL <mask> / LIST. While a user
matches, the dispatch choke-point drops their service commands silently.
A mask with an @ matches nick!*@host (ident isn't tracked); a bare mask
matches the nick; matching is case-insensitive with lazy expiry. Admin-
only, and an operator is never ignored (so staff can't lock themselves
out). Node-local and in-memory, like the auth and request throttles — a
fast transient moderation tool, not persisted or federated.
Two channel operator tools:
- MODE <#chan> <modes> [params] forces a channel mode change (TS 1, so it
applies regardless of the current TS). A status-mode target may be given
as a nick — it's resolved to the uid the ircd's FMODE expects.
- KICK <#chan> <nick> [reason] removes a user, sourced from OperServ and
attributed to the operator.
Both admin-gated. To resolve status-mode params, channel-mode parameter
arity became one shared helper (chanmode_takes_param + STATUS_MODES in the
api): the ircd module now delegates to it instead of keeping its own copy,
so burst-parsing and MODE-building can never drift.
Generalise the network-ban store to carry the ircd X-line kind (defaulted
to the user@host G-line for existing records) so one event-sourced,
lazily-expiring, burst-reasserted list backs every ban type, and drive
ADD/DEL/LIST from one implementation per kind:
- AKILL stays the user@host G-line; SQLINE is a nick Q-line, its mask
validated as a nick glob (an @ is refused so an AKILL-shaped mask can't
become an over-broad nick ban). Both are keyed by (kind, mask).
- GLOBAL <message> announces to every user via a $* server-glob notice.
- KILL <nick> [reason] disconnects a user, attributed to the operator.
All four are admin-gated, and OperServ itself stays invisible to non-opers.
Bans and kills go out as typed actions (AddLine/DelLine/KillUser) the ircd
link serialises to ADDLINE/DELLINE/KILL.
The first operator module. AKILL manages network bans as a typed,
event-sourced list with lazy expiry, mirroring the patterns the other
modules use:
- AKILL ADD [+expiry] <user@host> <reason> stores the ban and drives an
ircd G-line (applied to matching users already online and to future
connections); AKILL DEL <mask|number> lifts it; AKILL LIST [pattern]
shows the live list, numbered. Admin-only.
- Bans are Global events, so every node holds the list and re-asserts each
one at burst with its remaining duration. Expired bans are hidden lazily
and dropped at compaction.
- Masks are normalised to user@host (a nick! prefix is stripped, both
sides lowercased) and an all-wildcard mask is refused.
Email (send_email) is already reachable from the api via ServiceCtx, and
adds AddLine/DelLine to the action vocabulary for any future X-line kinds.