The service pseudo-clients and the ircd protocol link sat flat at the
repo root, mixed in with the daemon core and the SDK. Move them all
under modules/ so the tree separates concerns cleanly: the daemon in
src/, the SDK every module links against in api/, and the loadable
modules — the pseudo-clients plus the protocol link — in modules/.
Workspace members, the daemon's per-crate dependency paths, and each
module's api path are updated to match; the docs follow. No code change.
SET <#channel> NOBOT <on|off> reserves (un)assigning a bot for services
operators (the founder is refused). SET <bot> PRIVATE <on|off> (admin
only) marks a bot operators-only to assign; it's flagged in BOT LIST and
the private flag survives BOT CHANGE. Both gates live in the ASSIGN path.
BOT CHANGE <oldnick> <newnick> [user [host [gecos]]] renames or
re-identifies a bot; omitted fields keep the current values. A rename
moves every channel the bot was assigned to onto the new nick. reconcile
now tracks each live bot's identity hash, so a change that keeps the nick
but alters user/host/gecos quits the stale pseudo-client and reintroduces
it (rejoining its channels) — a rename does the same via the registry.
Match the NickServ/ChanServ layout: lib.rs keeps only the service struct
and the on_command dispatcher, and each command moves to its own file
bridged with #[path]. No behaviour change.
BotServ: bot.rs, assign.rs.
MemoServ: send.rs, list.rs, read.rs, del.rs.