README.md (Nick Semantics) rules that nicks are case-sensitive: "Alice and alice are different nicks", because case-insensitive comparison is "a perpetual source of IRC bugs". The database already follows it: sessions.nick is unique by exact case and every lookup is nick = ?. But some comparisons ignore case (strings.EqualFold):
the IRC listener's relay, internal/ircserver/relay.go (own-message checks in the PRIVMSG/NOTICE, JOIN, PART, NICK and QUIT delivery), so an IRC listener user alice never sees these from Alice;
user MODE on both transports, internal/ircserver/commands.go (handleUserMode) and internal/handlers/utility.go (handleUserMode), so MODE Alice from alice is treated as her own nick.
Reading: the README decides this, so nicks compare by exact case everywhere. (An earlier version of this issue took the opposite reading; it contradicted the README and is withdrawn.)
Definition of done
Every nick comparison in the code is exact: the five relay checks and both handleUserMode checks use ==; no nick comparison ignores case anywhere.
Tests: an IRC listener user alice receives a PRIVMSG, JOIN, PART, NICK and QUIT from Alice in a shared channel; MODE Alice from alice gets 502 on both transports; Alice can register while alice exists.
README.md: drop "Nick comparison is case-insensitive." (User modes bullet) and the "One gap remains" paragraph under Bridge to HTTP API; Nick Semantics stays as it is.
One reviewed PR against next.
Judgement call: the 005 reply keeps CASEMAPPING=ascii. IRC defines no value for case-sensitive nicks, and a server that sends none is read as rfc1459, which also ignores case.
Model: opus-5-5
`README.md` (Nick Semantics) rules that nicks are case-sensitive: "`Alice` and `alice` are different nicks", because case-insensitive comparison is "a perpetual source of IRC bugs". The database already follows it: `sessions.nick` is unique by exact case and every lookup is `nick = ?`. But some comparisons ignore case (`strings.EqualFold`):
- the IRC listener's relay, `internal/ircserver/relay.go` (own-message checks in the PRIVMSG/NOTICE, JOIN, PART, NICK and QUIT delivery), so an IRC listener user `alice` never sees these from `Alice`;
- user `MODE` on both transports, `internal/ircserver/commands.go` (`handleUserMode`) and `internal/handlers/utility.go` (`handleUserMode`), so `MODE Alice` from `alice` is treated as her own nick.
Found by the README review at https://git.eeqj.de/sneak/neoirc/pulls/120#issuecomment-133596.
Reading: the README decides this, so nicks compare by exact case everywhere. (An earlier version of this issue took the opposite reading; it contradicted the README and is withdrawn.)
## Definition of done
1. Every nick comparison in the code is exact: the five relay checks and both `handleUserMode` checks use `==`; no nick comparison ignores case anywhere.
2. Tests: an IRC listener user `alice` receives a PRIVMSG, JOIN, PART, NICK and QUIT from `Alice` in a shared channel; `MODE Alice` from `alice` gets 502 on both transports; `Alice` can register while `alice` exists.
3. `README.md`: drop "Nick comparison is case-insensitive." (User modes bullet) and the "One gap remains" paragraph under Bridge to HTTP API; Nick Semantics stays as it is.
4. One reviewed PR against `next`.
Judgement call: the `005` reply keeps `CASEMAPPING=ascii`. IRC defines no value for case-sensitive nicks, and a server that sends none is read as `rfc1459`, which also ignores case.
Model: opus-5-5
clawbot
self-assigned this 2026-10-08 10:31:19 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
README.md(Nick Semantics) rules that nicks are case-sensitive: "Aliceandaliceare different nicks", because case-insensitive comparison is "a perpetual source of IRC bugs". The database already follows it:sessions.nickis unique by exact case and every lookup isnick = ?. But some comparisons ignore case (strings.EqualFold):internal/ircserver/relay.go(own-message checks in the PRIVMSG/NOTICE, JOIN, PART, NICK and QUIT delivery), so an IRC listener useralicenever sees these fromAlice;MODEon both transports,internal/ircserver/commands.go(handleUserMode) andinternal/handlers/utility.go(handleUserMode), soMODE Alicefromaliceis treated as her own nick.Found by the README review at #120 (comment).
Reading: the README decides this, so nicks compare by exact case everywhere. (An earlier version of this issue took the opposite reading; it contradicted the README and is withdrawn.)
Definition of done
handleUserModechecks use==; no nick comparison ignores case anywhere.alicereceives a PRIVMSG, JOIN, PART, NICK and QUIT fromAlicein a shared channel;MODE Alicefromalicegets 502 on both transports;Alicecan register whilealiceexists.README.md: drop "Nick comparison is case-insensitive." (User modes bullet) and the "One gap remains" paragraph under Bridge to HTTP API; Nick Semantics stays as it is.next.Judgement call: the
005reply keepsCASEMAPPING=ascii. IRC defines no value for case-sensitive nicks, and a server that sends none is read asrfc1459, which also ignores case.Model: opus-5-5