docs(ergo): user guide and admin/moderator cheat sheet

Two quick-reference documents, written to be scanned rather than read:

- USER-GUIDE.md for people new to IRC -- connecting, claiming a nickname,
  the dozen commands that matter, scrollback, and a plain-language privacy
  section (cloaked IP, channels logged for the configured retention, how to
  turn off DM storage).
- ADMIN-CHEATSHEET.md split by where you work: from IRC as an operator
  (UBAN, KILL, DEFCON, ChanServ, NickServ) and on the host via ergoctl, plus
  mode tables and a "when things go wrong" section.

Both use the same placeholder convention as ergo.motd and are rendered by
deploy.sh into $STACK_DIR/docs/ with the network's real name, domain and
retention, so they can be handed straight to users and moderators. Refreshed
on every run, like the other installed files.

Command and mode references were checked against the v2.19.1 sources rather
than written from memory: irc/modes/modes.go for every mode letter, and
irc/chanserv.go and irc/nickserv.go for the service subcommands and which
require an oper capability.

build.sh's embed guard caught the docs being added to FILES without being
added to deploy.sh's EMBEDDED manifest -- the exact failure it was added to
prevent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-02 21:48:01 -05:00
co-authored by Claude Opus 5
parent 73eeb981b8
commit 6dba4a5f09
5 changed files with 1006 additions and 660 deletions
+150
View File
@@ -0,0 +1,150 @@
# __NETWORK_NAME__ — admin & moderator cheat sheet
Two places to work:
- **From IRC**, as an operator — moderation, accounts, channels. Any moderator.
- **On the host**, via `ergoctl` — the server itself. Needs root/SSH.
---
## Become an operator
```
/OPER <name> <password>
```
Per connection: do it again each time you reconnect. Operator status is hidden
from ordinary users. Passwordless login by TLS certificate is available — see
"Operators" in the deployment README.
---
## Moderation — from IRC
`UBAN` is the one command for bans; it works out whether you gave it an IP, a
CIDR, a `nick!user@host` mask or an account name.
| Task | Command |
|---|---|
| Look someone up first | `UBAN INFO <nick>` (shows their real IP) |
| Ban an address | `UBAN ADD 203.0.113.9 DURATION 1d spamming` |
| Ban a range | `UBAN ADD 203.0.113.0/24 DURATION 7d` |
| Suspend an account | `UBAN ADD <account> DURATION 30d` |
| Lift a ban | `UBAN DEL <target>` |
| List bans | `UBAN LIST` |
| Disconnect someone | `KILL <nick> :reason` |
| Require accounts, network-wide | `DEFCON 4` (`DEFCON 5` = normal) |
> A **bare name** is treated as an *account*, not a connected nick. For someone
> who isn't registered, `UBAN INFO` them and ban the IP.
Durations: `1y 12mo 31d 10h 8m 13s`. Omit `DURATION` for permanent.
**Always-on users** stay reachable while disconnected — banning the account
(`UBAN ADD <account>`) is what removes them, not `KILL`.
### Channels
| Task | Command |
|---|---|
| Join a channel you can't enter | `SAJOIN #channel` |
| Force a mode change | `SAMODE #channel +m` |
| Kick | `/kick #channel nick reason` |
| Ban from a channel | `/mode #channel +b nick!*@*` |
| Ask the server how best to ban | `/msg ChanServ HOWTOBAN #channel <nick>` |
| Blacklist a channel entirely | `/msg ChanServ PURGE ADD #channel reason` |
| Undo that | `/msg ChanServ PURGE DEL #channel` |
### Accounts
| Task | Command |
|---|---|
| Register for someone | `/msg NickServ SAREGISTER <user> <password>` |
| Reset a password | `/msg NickServ PASSWD <user> <newpassword>` |
| Suspend | `/msg NickServ SUSPEND ADD <nick> DURATION 30d reason` |
| Unsuspend / list | `/msg NickServ SUSPEND DEL <nick>` · `SUSPEND LIST` |
| Erase permanently | `/msg NickServ ERASE <user>` (two-step, returns a code) |
Two-step commands (`ERASE`, `CS UNREGISTER`, `TRANSFER`, `PURGE`) reply with a
confirmation code — repeat the command with the code appended.
---
## The server — on the host
```bash
ergoctl status # health, versions, TLS, users, scheduled jobs
ergoctl users # who's on
ergoctl logs -f # live server log
ergoctl announce <text> # notice to everyone
ergoctl cmd <raw IRC> # run any of the above as the admin oper
```
| Task | Command |
|---|---|
| Edit config (validates, then applies) | `ergoctl edit` |
| Edit the rules shown on connect | `ergoctl motd` |
| Apply config without disconnecting anyone | `ergoctl rehash` |
| Restart (drops every user) | `ergoctl restart` |
| Add a moderator | `ergoctl oper add <name> chat-moderator` |
| Add an admin | `ergoctl oper add <name> server-admin` |
| Certificate login for an oper | `ergoctl oper certfp <name> <nick> --auto` |
| Back up config + database + history | `ergoctl backup` |
| Restore | `ergoctl restore <file>` |
| Check / renew TLS | `ergoctl cert` · `ergoctl cert sync` |
| Check for updates | `ergoctl update check` |
| Update now (snapshot + rollback) | `ergoctl update update` |
| Message history backend | `ergoctl history [sqlite\|postgres\|off]` |
`ergoctl help` lists everything.
---
## Mode reference
**Channel modes**`/mode #channel +X`
| | | | |
|---|---|---|---|
| `i` | invite only | `m` | moderated (voiced+ may speak) |
| `k` | requires a key | `n` | no messages from outside |
| `l` | user limit | `s` | secret (hidden from `/list`) |
| `R` | registered users only | `t` | ops set the topic |
| `M` | registered users may speak | `C` | no CTCP |
| `U` | op-moderated (unvoiced msgs go to ops) | `u` | auditorium |
| `b` | ban mask | `e` | ban exception |
| `I` | invite exception | `f` | forward to another channel |
**Member prefixes**`/mode #channel +o nick`
| | | | | |
|---|---|---|---|---|
| `q` `~` | founder | `a` `&` | admin | `o` `@` | op |
| `h` `%` | half-op | `v` `+` | voice | | |
Make any of these stick across reconnects with
`/msg ChanServ AMODE #channel +o account`.
**User modes**`/mode yournick +X`
| | | | |
|---|---|---|---|
| `i` | invisible | `R` | only registered users may PM you |
| `T` | block CTCP | `B` | mark as a bot |
| `Z` | secure connection (automatic) | `s` | receive server notices (opers) |
---
## When things go wrong
| Symptom | Do this |
|---|---|
| Clients reject the certificate | `ergoctl cert` — if it says SELF-SIGNED, check DNS and ports 80/443, then `ergoctl cert sync` |
| Config change didn't take | Some settings only apply at startup — `ergoctl restart` |
| Rehash refused a change | The file is kept and reverted; the server's own error is printed |
| Server won't start after an edit | `ergoctl logs` shows the failing line; restore `ircd.yaml.last-good` |
| Update broke something | It rolls back automatically; `ergoctl status` confirms, and `backups/` holds a database snapshot |
| Locked out of `/OPER` | The password is in `secrets/admin.pass` on the host — `ergoctl passwd show` |
| Spam flood in progress | `DEFCON 4` requires accounts network-wide until you set `DEFCON 5` |
Full detail lives in [`README.md`](README.md).
+3 -1
View File
@@ -380,7 +380,9 @@ file_server }` block into `caddy/etc/conf.d/` (see `00-readme.caddy`), then
| `docker-compose.postgres.yml` | Optional PostgreSQL overlay for `HISTORY=postgres` (loopback-only, pinned major). |
| `Caddyfile` | ACME, `/webirc` websocket proxy, text landing page, `admin off`, no h3; imports `conf.d/*.caddy`. |
| `conf.d-readme.caddy` | Installed once as `caddy/etc/conf.d/00-readme.caddy` (operator drop-ins; Gamja example). |
| `ergo.motd` | MOTD template (`__NETWORK_NAME__`, `__DOMAIN__`). |
| `ergo.motd` | MOTD template (`__NETWORK_NAME__`, `__DOMAIN__`, `__HISTORY_NOTE__`). |
| [`USER-GUIDE.md`](USER-GUIDE.md) | Quick-start for people new to IRC. Rendered to `docs/` on the host. |
| [`ADMIN-CHEATSHEET.md`](ADMIN-CHEATSHEET.md) | Moderator and admin quick reference. Rendered to `docs/` on the host. |
| `ergolib.sh` | Shared helpers: `.env`, compose, health/IRC probes, `--smoke` validator, oper edits, certsync, ntfy. |
| `update.sh` | Updater + certsync + Caddy update + scheduling. |
| `ergoctl` | Host admin CLI. |
+119
View File
@@ -0,0 +1,119 @@
# __NETWORK_NAME__ — new to IRC? Start here
IRC is group chat. You pick a nickname, join channels (chat rooms whose names
start with `#`), and talk. Commands start with `/`.
---
## 1. Connect
| | |
|---|---|
| **Server** | `__DOMAIN__` |
| **Port** | `6697` |
| **TLS/SSL** | **on** (required) |
| **Network** | __NETWORK_NAME__ |
Any IRC client works. Good starting points: **HexChat** (Windows/Linux),
**Textual** or **Halloy** (macOS), **Revolution IRC** (Android), **Goguma** (iOS).
> If your client asks for a "network" and a "server", the network is just a
> label — the server address above is what matters.
---
## 2. Claim your nickname
On this network your nickname *is* your account, so register it or someone else
could use it later.
```
/msg NickServ REGISTER your-password
```
Then tell your client to log in automatically: enable **SASL**, method
**PLAIN**, with your nickname as the username and that password. Most clients
have this in the same dialog as the server address.
Not using SASL yet? Log in by hand each time:
```
/msg NickServ IDENTIFY your-password
```
Someone else on your nick? `/msg NickServ GHOST yournick` disconnects them.
---
## 3. Talk
| Do this | Command |
|---|---|
| Join a channel | `/join #channel` |
| Leave | `/part #channel` |
| Private message | `/msg someone hello` |
| See who's here | `/names` |
| Look someone up | `/whois someone` |
| Set yourself away | `/away back in 10` (`/away` to return) |
| Change nick | `/nick newnick` |
| List channels | `/list` |
| Quit | `/quit see you` |
Type normally to speak in the channel you're looking at. `/me waves` writes an
action line.
---
## 4. Scrollback
Messages are stored for **__HISTORY_DAYS__**, so you see what you missed while
away — no need to stay connected. Most modern clients fetch it automatically;
otherwise `/history #channel 50` pulls the last 50 lines.
To have a channel's recent messages replayed every time you join:
```
/msg NickServ SET autoreplay-lines 25
```
---
## 5. Privacy, plainly
- Your IP address is **hidden** from other users (you'll see a scrambled
hostname). Server staff can still see it.
- Channels are **logged for __HISTORY_DAYS__**. Treat anything you type as
recorded — including private messages, which are stored for logged-in users.
- Turn off storage of your own DMs with `/msg NickServ SET dm-history off`.
- Connections are encrypted (TLS). Your client shows `+Z` when secure.
---
## 6. Making your own channel
Just join one that doesn't exist yet — you become its founder:
```
/join #mychannel
/msg ChanServ REGISTER #mychannel
```
Registering keeps it yours. A few useful settings once you own it:
| Want | Command |
|---|---|
| Invite-only | `/mode #mychannel +i` then `/mode #mychannel +I nickname` |
| Registered users only | `/mode #mychannel +R` |
| Set the topic | `/topic #mychannel Welcome!` |
| Give someone ops | `/msg ChanServ OP #mychannel nickname` |
| Make that permanent | `/msg ChanServ AMODE #mychannel +o nickname` |
---
## 7. Stuck?
- `/msg NickServ HELP` and `/msg ChanServ HELP` list everything.
- `/motd` shows the network's rules.
- `/admin` shows who runs the server.
Be kind, and enjoy yourself.
+2
View File
@@ -21,6 +21,8 @@ FILES=(
Caddyfile
conf.d-readme.caddy
ergo.motd
USER-GUIDE.md
ADMIN-CHEATSHEET.md
.env.example
ergolib.sh
update.sh
+732 -659
View File
File diff suppressed because it is too large Load Diff