Proof of concept mechanical port of ircnet/ircd to Rust as part of a bit about C being insecure for network services
0

Configure Feed

Select the types of activity you want to include in your feed.

ircd.rs / docs / superpowers / plans / 2026-06-13-p11-slice140-account-notify.md
5.2 kB

P11 slice 140 — account-notify (IRCv3)#

Area. account-notify / SASL track — the direct behavior-cap follow-on to slice 139 (services account identity via ENCAP * SU). Slice 139 built the read plane (a user carries an account name, surfaced on WHOIS 330 / WHO %a); this slice builds the push plane.

Scope#

When a user's services account changes — i.e. an inbound :<sid> ENCAP * SU <uid> [:<account>] logs <uid> in or out — deliver :nick!user@host ACCOUNT <account> to every local channel co-member of the changed user that negotiated account-notify, where <account> is the account name on login and the literal * on logout (the IRCv3 account-notify wire form). Also push to extended-monitor watchers (gated account_notify + extended_monitor), closing the documented gap in the [EXTENDED_MONITOR] doc ("leveva has no account-notify, so that one sub-notification never fires").

Account changes in leveva originate only from ENCAP * SU (leveva keeps no account DB), so that is the only trigger. The login-on-JOIN case (extended-join) and the @account message tag (account-tag) are separate later caps per the framework-vs-behavior rule — out of scope here.

Mechanism#

  1. cap.rs — register the cap (one entry, mirrors away-notify):

    • pub const ACCOUNT_NOTIFY: &str = "account-notify"; with a doc comment.
    • A Capability { name: ACCOUNT_NOTIFY, value: None } row in SUPPORTED.
    • A pub account_notify: bool field on ClientCaps + its line in client_caps() snapshot.
    • Amend the EXTENDED_MONITOR doc: leveva now does push ACCOUNT to extended-monitor watchers, so drop the "never fires" caveat.
  2. s2s/su.rs — add a notify_account fan-out (mirrors [s2s::away::notify_co_members]):

    • Resolve the changed user's mask from its registry record (record_of(uid) → nick/user/host; the registry is the SoT for both local and remote users). If the user is unknown, no-op (nothing visible to notify).
    • Build :nick!user@host ACCOUNT <account> where <account> is the account name on login or * on logout (a single middle param, per the account-notify spec — not a trailing).
    • Deliver to each local co_members(uid) whose caps_of(member).account_notify is set (self is excluded by co_members).
    • crate::monitor::notify_watchers(ctx, nick, uid, |c| c.account_notify, &wire) for the extended-monitor watchers that share no channel.
    • Call it from apply_encap_su after set_account, with the resolved new value (Some(name) → that name; None/logout → *). The invalid-account branch stays a no-op and notifies nothing (state untouched). The caller's verbatim split-horizon relay is intact.

Divergences (documented, leveva-native)#

  • Single-server-local push effect. Only our local cap co-members see the ACCOUNT line; the rest of the net learns of the login via the onward ENCAP * SU relay (each server applies + does its own account-notify push to its locals). The standing s2s::relay single-uplink divergence.
  • No leveva-integration differential — the C 2.11 oracle has no SU/account concept and emits no ACCOUNT, so there is nothing to pin against (as with slice 139).
  • Logout wire form is * (account-notify convention), distinct from WHO %a's 0 (WHOX not-logged-in convention). Both are leveva-native; the read plane (139) and push plane (140) use the form each spec mandates.
  • Trigger is SU-only. A registered local client cannot self-ACCOUNT (leveva has no client SASL yet); the only authority is a services SU broadcast.

Tests (TDD — RED first) + fuzz#

  • Unit (s2s/su.rs):
    • su_login_notifies_a_local_capable_co_member — peer SU-login → a local account-notify co-member receives :rover!… ACCOUNT RoverAcct.
    • su_logout_notifies_with_a_star (inverse) — a subsequent logout pushes … ACCOUNT *.
    • su_does_not_notify_a_non_cap_co_member — a co-member without the cap gets nothing (state still applies).
    • su_for_unknown_uid_notifies_nothing — unknown target → no push, no panic.
    • su_with_invalid_account_does_not_notify — invalid name → state + push both untouched.
  • Golden (golden_s2s_account.rs, extended): add a second local client carol who CAP REQ :account-notifys and joins #hub; assert she receives the live ACCOUNT RoverAcct on login and ACCOUNT * on logout (a new snapshot section; the existing WHOIS/WHO assertions and their snapshot are unchanged — account defaults to None).
  • Proptest (account_proptest.rs, extended): a property that drives arbitrary SU login/logout sequences through s2s::dispatch with a capable co-member attached and asserts the delivered ACCOUNT param always tracks the last valid account (name on login, * on logout), never panics, and a non-SU ENCAP delivers nothing.

Gate#

cargo test -p leveva (touched binaries) green; new su unit tests + extended golden snapshot + extended proptest pass; cargo clippy -p leveva --tests clean; cargo build --workspace 0 warnings; no existing snapshot churned.