  - **Faithfulness notes.** `set_mode` tail: the sender cascade `s = IsServer(sptr) ? serv->sid : sptr->user ? user->uid : sptr->name`; `sendto_match_servs_v(chptr, cptr, SV_UID, …mbuf, upbuf)` (the UID‑form params in `upbuf`, name‑form in `pbuf`); the fake‑vs‑real branch (`IsServer(cptr) && !IsServer(sptr) && !ischop` → `sendto_flag(SCH_CHAN, "Fake:…")` + `ircstp->is_fake++`, else `sendto_channel_butserv(…pbuf)`); `return ischop ? count : -count`. The `k` key sanitizer (`,`→`.`, the `>0x7f`/`>0xa0` high‑byte mask, KEYLEN truncation) ported on `*mut u8` exactly. `reop` scheduling (`timeofday + LDELAYCHASETIMELIMIT + myrand()%300` for chanop self‑deop / server `+R`; `+r` from server sets `chptr->reop`) writes channel state (not wire — `myrand` non‑determinism is invisible to L2). parseNUH splits `nick!user@host` in place via `strchr`/`strrchr`, `make_bei`, restores the separators.
  - **Bug caught by the burst S2S test (the inverse paid off).** `aListItem.nick`/`user`/`host` are `*mut c_char` **pointers**, not arrays — the first port took `addr_of!((*al).nick)` (address of the pointer field) and `%s` printed the pointer's bytes as garbage (`:000A MODE #chan +b ``…`). The `golden_s2s_mode` relink‑burst diff caught it immediately; fixed to pass `(*al).nick` directly at all three sites (`send_mode_list`, the `beIR` list query, the reconstruction `nuh`). The simpler L2/outbound tests passed *without* this fix (they never serialize a stored `mlist` entry) — only the burst path re‑emits the list, so the S2S coverage was load‑bearing.
  - **L2 + L2‑S2S are the gates (no fresh L1 — set_mode's state mutation is already L1‑covered via the P5x membership + P5ff ban diffs through it).** New `golden_channel_mode_set` (L2): a chanop voices a second member (`+v bob`) — the relay reaches every member via `sendto_channel_butserv`, observed by bob; NAMES shows `+bob`; the **inverse** `-v bob` → NAMES shows plain `bob` (`change_chan_flag` MODE_DEL clears CHFL_VOICE). The 2‑client harness (the per‑host clone limit is 2, the P5cc finding) makes bob both target and observer. New `golden_s2s_mode` (L2‑S2S, 2 scenarios): **outbound** — a local chanop (the peer ops alice on a remote‑NJOIN'd #chan, since a split local client can't create one) sets `+m` then `+l 5`, and the peer receives the UID‑sourced `:000AAAAAA MODE #chan +m` / `+l 5` (`set_mode`'s `sendto_match_servs_v(SV_UID)` tail, `upbuf` form); **link burst** — a populated #chan, then the peer is dropped and **relinks** (the only way to burst a `#` channel: it can't exist before the single harness peer links), so the second burst replays `:000A NJOIN #chan :000AAAAAA` (`send_channel_members`) + `:000A MODE #chan +tnl 10` / `+b *!*@evil.host` (`send_channel_modes` → `channel_modes` + `send_mode_list`). Regression: `golden_channel_modes`/`ban`/`part` (L2) + `golden_s2s_ban`/`membership` (inbound server MODE through the Rust `set_mode`) stay byte‑identical ref‑C == Rust; full `ircd-golden` + `ircd-testkit` (L1) suites green; `cargo build` 0 warnings; no new canonicalizer masks. **Remaining channel.c (C):** only the **lifecycle group** — `reop_channel`/`collect_channel_garbage`/`setup_server_channels`/`free_channel`/`get_channel` — stays in `channel_link.o`. The channel.c mode + handler clusters are now fully Rust.

- **2026‑06‑03 — P5hh (channel.c lifecycle group — `get_channel`/`free_channel`/`reop_channel`/`setup_server_channels`/`collect_channel_garbage` + the `channel` global) merged.** The channel struct's birth/death cluster ported to `ircd-common/src/channel.rs`. **15th and FINAL channel.c sub‑phase** — every symbol channel.c defines now lives in ircd-common, so **`channel.o` is dropped outright** (added to `PORTED` in `ircd-sys/build.rs`; the P5t…P5gg `channel_link.o` second‑compile + its `-DPORT_CHANNEL_P5` link substitution removed entirely; the `cref` oracle keeps the unguarded `channel.o`). Plan: `docs/superpowers/plans/2026-06-03-p5hh-channel-lifecycle.md`.
  - **Symbols.** `get_channel` (channel.c:2226, file‑static, extern‑switched P5aa) + `free_channel` (:2378, file‑static, extern‑switched P5x) → `#[no_mangle] pub unsafe extern "C"` (their `extern`‑block decls in channel.rs removed; the still‑Rust callers `m_part`/`m_join`/`m_njoin`/`remove_user_from_channel`/`setup_server_channels` resolve to them). `reop_channel` (:3911, purely file‑static, `collect_channel_garbage`'s only caller) → private Rust `unsafe fn` (no oracle). `setup_server_channels` (:812) + `collect_channel_garbage` (:4026) are channel_ext.h exports called from `ircd.c:738` (boot) / `ircd.c:1188` (io_loop timer) → `#[no_mangle]`. The `channel` global list head (:52) → `#[no_mangle] pub static mut channel` (replaces the `channel as channel_list` bindgen import; the two read sites in m_list/the GC updated; the still‑C `s_debug` STATS resolves its `extern` decl to it).
  - **Config findings (locked config).** USE_IAUTH on → `setup_server_channels` creates the 14th channel `&AUTH`; CLIENTS_CHANNEL undef → no `&CLIENTS`; JAPANESE off → `get_channel`'s `jp_chname`/`FLAGS_JP` block dead; DEBUGMODE off → `collect`'s `del`/SCH_NOTICE + `reop`'s SCH_NOTICE blocks dead; LOG_SERVER_CHANNELS off → the still‑C `setup_svchans` (send.c) is just the `find_channel` relink loop. `MyFree(chptr)` → plain `free` (the macro's NULL‑out is dead on a by‑value param). The function‑local statics `max_nb`/`split` in `collect_channel_garbage` → module‑private `static mut MAX_NB`/`SPLIT` (persist across calls, faithful). `reop_channel`'s `!CHFL_REOPLIST` arg = the C logical‑not of a nonzero value = `0` (ported literally). istat decrements use `wrapping_sub` (cf. P5u/P5ff).
  - **Classification: utility/callee TU** (none of the six is a `msgtab` handler). `get_channel`/`free_channel`/`reop_channel` are file‑static → the `--prefix-symbols=cref_` rename keeps them **local** (no oracle); `setup_server_channels`/`collect_channel_garbage`/`channel`/`add_to_channel_hash_table` are exported → `cref_*` oracles exist.
  - **L1** (`ircd-testkit/tests/channel_lifecycle_diff.rs`, the two exported entries vs `cref_`; the three statics transitively covered). Both sides drive **separate** process globals (`channel` vs `cref_channel`, separate channel hash tables init'd per‑test via `inithashtables`/`cref_inithashtables` — NULL until boot otherwise, the L1 segfault finding — separate `istat`). (1) `setup_server_channels` create‑cluster: 14 server channels, identical chname/topic/mode.mode/`users==1`‑lone‑chanop walk (`get_channel` CREATE + global‑list prepend + hash insert + `add_user_to_channel` + topic `strcpy` + mode masks + `setup_svchans` relink). (2) **Inverse**: the oracle'd `remove_user_from_channel(mp, &ERRORS)` → `users`→0, history==0 → `free_channel` unlinks `&ERRORS` from both global lists **and** the hash (find now misses), the other 13 survive. (3) `collect_channel_garbage`: hand‑built `&dead` (empty+expired) vs `&live` → identical return `now+CHECKFREQ`, `&dead` freed (gone from list+hash), `&live` kept. **Finding:** `free_channel` re‑checks the *global* `timeofday >= chptr->history` (not collect's `now` param) → the test pins `timeofday`/`cref_timeofday` to `now` so the expired‑free path fires; the `myrand` reop arm needs a live opless `+r` channel (non‑deterministic) → not entered, review‑covered.
  - **No new L2‑S2S.** None of the six has an `IsServer(cptr)` dispatch branch or formats remote‑user fields (`get_channel`'s only client test is `MyClient(cptr)` chname truncation). `get_channel`/`free_channel` are already L2/S2S‑covered transitively by every JOIN/PART golden (`golden_channel*`, `golden_s2s_membership` — remote NJOIN/PART drive `get_channel(CREATE)`/`free_channel`); `collect_channel_garbage`/`reop_channel` are timer‑driven (300 s, unreachable in a short golden). Regression: full `ircd-golden` (83 tests) + `ircd-testkit` L1 suites byte‑identical ref‑C == Rust; `cargo build` 0 warnings; no new canonicalizer masks. **channel.c is now FULLY ported to Rust** — only the channel **lifecycle** remained after P5gg, and this closes it.

- **2026‑06‑03 — P5ii (s_serv.c informational query foundation cluster — `m_version`/`m_time`/`m_admin`) merged.** The three leaf informational query handlers (s_serv.c:109/2534/2547) ported to the new `ircd-common/src/s_serv.rs`. **First `s_serv.c` sub‑phase** — `s_serv.c` is the last (and largest) P5 TU (~3884 lines, ~14 file‑statics, ~40 handlers), ported in clusters; this one establishes the `s_serv_link.o` partial‑port mechanism. Plan: `docs/superpowers/plans/2026-06-03-p5ii-s_serv-informational.md`.
  - **Mechanism — establish `s_serv_link.o` (mirrors `s_user_link.o`).** A second compile of `s_serv.c` with the three ported handlers `#ifdef`'d out (`-DPORT_SERV_P5`), substituted into the link set via the new `"s_serv.o" => "s_serv_link.o"` map entry in `build.rs` `link_objs()`; the cref oracle keeps the unguarded `s_serv.o` in `CREF_OBJS`. The recipe carries the per‑object define `-DIRCDMOTD_PATH="\"$(IRCDMOTD_PATH)\""` (Makefile `s_serv.o` recipe line 346 — needed by the still‑C `m_motd`), driven through `make --eval` so the recursive path var expands identically. All three handlers take a **plain `#ifndef PORT_SERV_P5` guard** — no extern‑prototype switch: none is a file‑`static` and none is anyone's `static` callee. RED→GREEN confirmed: binary links clean (no undefined, no multiple‑definition) and `nm target/debug/ircd | grep ' T \(m_version\|m_time\|m_admin\)$'` shows all three defined in the binary (came from Rust).
  - **Callees, all already resolved.** C externs — `hunt_server` (still C, s_user.c; bindings decl), `find_admin` (still C, s_conf.c; bindings decl), `sendto_one` (variadic P8 trampoline; local `extern "C"` block, fmt `*mut c_char`). Rust — `replies[]` (P3, via `reply(i)`), `date` (P5c s_misc.rs, `date(0)`), `serveropts` (P5b s_debug.rs; the bindgen `[c_char; 0]` incomplete‑array extern → `addr_of!(serveropts) as *mut c_char` resolves to the real 12‑byte Rust static at link). Globals/consts — `me` (`me.name` self‑pointer; `(*me.serv).sid.as_ptr()` for the VERSION SID), `IRC_VERSION` (bindgen `&[u8;7]`), `HUNTED_ISME` (`0u32`). Inlined macros: `ME`=`me.name`, `BadTo`/`BadPtr` (struct_def.h:787), `IsRegistered`=`status >= STAT_SERVER || status == STAT_ME` (struct_def.h:132).
  - **Classification: handler cluster, no L1.** All three are in `msgtab` (`common/parse.c`) at col 1 (`m_version`/`m_time`) or all‑columns (`m_admin`), min‑params 0 → client‑reachable → **L2**. Each has a `hunt_server` forwarding branch (server‑reachable, exactly like P5z `m_list`) → **L2‑S2S**. `m_admin` additionally has the `IsRegistered(cptr)` head‑gate (unregistered clients skip the forward — a local branch, L2‑covered). **No L1** — like `m_list`/`m_topic`/`m_names`, these are pure wire handlers with **no socket‑free data op** (no allocator/list‑mutation/data‑returning lookup), so there is nothing for an L1 differential to drive.
  - **`format!` per user request — N/A, documented in‑module.** None of the three builds an ASCII/numeric reply string of its own — every wire line goes straight to the C variadic `sendto_one(replies[…], …)`; `date()` is the P5c Rust port returning its own static buffer. There is nothing to format.
  - **L2 + L2‑S2S are the gates.** `golden_s_serv_info` (L2): a lone registered client drives `VERSION`→351 RPL_VERSION, `TIME`→391 RPL_TIME (trailing localtime wall‑clock volatile → masked by the existing `canonicalize()` 391 rule), `ADMIN`→256‑259 RPL_ADMINME…RPL_ADMINEMAIL via minimal.conf's `A` line (`find_admin()` non‑null → the admin path, not ERR_NOADMININFO) — reference‑C == Rust byte‑identical. `golden_s2s_s_serv_info` (L2‑S2S): a local client targets `VERSION/TIME/ADMIN peer.test` → `hunt_server` matches the linked peer and forwards each command out the link; the peer receives byte‑identical forwarded lines under ref‑C and Rust (the forwarding short‑circuit the standalone harness can't reach). `cargo build` 0 warnings; full `ircd-golden` + `ircd-testkit` suites green; no new canonicalizer masks.

- **2026‑06‑03 — P5jj (s_serv.c network‑info query cluster — `m_info`/`m_links` + the file‑static `check_link`) merged.** The two remaining leaf network‑info query handlers (s_serv.c:1400/1438) + their shared per‑link load‑health gate `check_link` (s_serv.c:3419) ported into `ircd-common/src/s_serv.rs`, extending the existing `s_serv_link.o` partial port (`‑DPORT_SERV_P5`; three new guard regions). **Second `s_serv.c` sub‑phase.** Plan: `docs/superpowers/plans/2026-06-03-p5jj-s_serv-info-links.md`.
  - **First `s_serv.c` extern‑prototype switch.** `check_link` is file‑`static` in C and still called by the C remnant `m_stats` (×2) / `m_motd` → the **P5u/P5x mechanism**: its forward decl at s_serv.c:36 flips `static`→`extern` under `#ifdef PORT_SERV_P5` (body guarded out) so the C remnant resolves to the Rust `#[no_mangle]` def at link (linkage‑only, faithful). `m_info`/`m_links` take plain `#ifndef` guards (neither is a static / anyone's static callee — their decls parse.rs imports from `ircd_sys::bindings` resolve to Rust). RED→GREEN: binary links clean and `nm target/debug/ircd | grep -E ' T (m_info|m_links|check_link)$'` shows all three defined from Rust (`check_link` is now `T`, was a local `t`).
  - **Callees, all already resolved.** C externs — `hunt_server`, `sendto_one` (variadic P8 trampoline, local block fmt `*mut c_char`). version.c externs (still C) — `infotext` (`[*mut c_char; 0]` incomplete‑array → `addr_of!` + NULL‑walk), `creation`, `generation`. Rust — `replies[]` (P3 `reply()`), `myctime` (P1 support), `collapse`/`match_` (P1), `svrtop` (P2), `ircstp` (P5c). Globals/consts — `me` (`me.name`/`me.firsttime`/`(*me.serv)…`), `bootopt`+`BOOT_PROT`, `timeofday`, `Status_STAT_CLIENT`, `CHREPLLEN`=8192 (config.h:363, baked as a `const c_int` — not a bindgen const, cf. channel.rs). Inlined macros: `ME`/`BadTo`/`BadPtr`, `MyConnect`=`fd>=0`, `IsMasked`=`x && x->serv && x->serv->maskedby != x`, `DBufLength`=`(d)->length`. **Invariant kept:** `acptr->serv->up->name` is `(*(*(*acptr).serv).up).name` (deref the `*mut aClient`, never `.read()` an `aClient` by value).
  - **Classification: handler cluster, no L1.** INFO `{m_nop,m_info,m_info,m_nop,m_unreg}` + LINKS `{m_links×4,m_unreg}` (msgtab col 1, min‑params 0 → client‑reachable → **L2**); each has a `hunt_server` forward (INFO always; LINKS when `parc>2`) → **L2‑S2S**. **No L1** — like P5ii/`m_list`/`m_names`, pure wire handlers with no socket‑free data op. `check_link` *does* mutate `ircstp` counters, but it is file‑`static` → the `‑‑prefix‑symbols=cref_` rename keeps it **local** (no `cref_check_link` oracle), and its non‑zero branches need a remote client over a *loaded* link (SendQ>65536 / link‑age<60s / lastload timing) which a local client never reaches (`MyConnect` → return 0) and which is timing‑non‑deterministic over S2S → the return‑0 path is L2‑covered (every INFO/LINKS), the load branches are **review‑covered** (no deterministic harness path). So no L1 file.
  - **Two new canonicalizer masks (m_info's volatile 371 trailers).** INFO emits, after the deterministic `infotext[]` AUTHORS block, two `371 RPL_INFO` lines that differ between the separately‑built / separately‑booted ref‑C and Rust runs: `:Birth Date: <creation>, compile # <generation>` (version.c build timestamp + per‑build counter) and `:On‑line since <ctime(me.firsttime)>` (boot wall‑clock). Added a 371 rule to `canonicalize()` masking each volatile tail (keeps the label). `infotext[]` itself is byte‑identical across builds → not masked.
  - **`format!` per user request — N/A, documented in‑module.** Every wire line (INFO text/birth/online, the per‑server `364 RPL_LINKS`, the TRYAGAIN/ENDOF replies) goes straight to the C variadic `sendto_one`; `myctime()` returns its own static buffer. `m_links`'s only integer arg is `acptr->hopcount` (`%d`, already `c_int` — the P5c width rule is satisfied). Nothing to format.
  - **L2 + L2‑S2S are the gates.** `golden_s_serv_info_links` (L2): a lone registered client drives `INFO`→a run of `371` (masked birth/online) ending in `374 RPL_ENDOFINFO`, then bare `LINKS`→`364`/`365 RPL_ENDOFLINKS` — ref‑C == Rust byte‑identical; `check_link` returns 0 (local `MyConnect`) so no `263 RPL_TRYAGAIN`. `golden_s2s_s_serv_info_links` (L2‑S2S): the `hunt_server` forwards (`INFO peer.test`, `LINKS peer.test *`) reach the linked peer byte‑identical, **and** the bare‑LINKS tree walk before vs after the peer links (the positive/inverse pair — the lone server sees only `:irc.test 364 alice irc.test irc.test :0 000A L2 Test Server`, then after the link adds `:irc.test 364 alice peer.test irc.test :1 001B Peer Test Server`), the only way to exercise `m_links`'s remote‑server `up->name`/`sid`/`info` field formatting. `cargo build` 0 warnings; full `ircd-golden` + `ircd-testkit` suites green.

- **2026‑06‑04 — P5kk (s_serv.c informational stub cluster — `m_users`/`send_users`/`m_summon`/`m_help`) merged.** The three leaf informational stub handlers (s_serv.c:1500/2154/2247) + the file‑static helper `send_users` (s_serv.c:2202) ported into `ircd-common/src/s_serv.rs`, extending the existing `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Third `s_serv.c` sub‑phase.** Plan: `docs/superpowers/plans/2026-06-04-p5kk-s_serv-users-summon-help.md`.
  - **Config‑resolved bodies.** `USERS_RFC1459` off (`config.h:85 #undef`) → `m_users` takes the `send_users` arm: forward via `hunt_server(":%s USERS :%s", 1)` only when `parc>1`, then `send_users` emits `265 RPL_LOCALUSERS` (`is_myclnt`/`is_m_myclnt` ×2) + `266 RPL_GLOBALUSERS` (`is_user[0]+is_user[1]`/`is_m_users` ×2). `ENABLE_SUMMON` off (`config.h:77 #undef`) → `m_summon`, after the `parc<2`/empty `411 ERR_NORECIPIENT` guard, rewrites `parv[1..=4]` (user/host=ME‑or‑parv[2]/chname=`*`/NULL) and forwards via `hunt_server(":%s SUMMON %s %s %s", 2)`; the ISME path emits `445 ERR_SUMMONDISABLED`. `m_help` walks `msgtab[]` (the incomplete‑array extern, `addr_of!` + `cmd.is_null()` terminator) emitting `:%s NOTICE %s :%s` per command.
  - **`send_users` extern‑prototype switch (P5u/P5x).** `send_users` is `static` in C (s_serv.c:52 forward decl) and was GCC‑inlined into both callers as `.isra.0` (no global symbol in the oracle `s_serv.o` → no `cref_send_users`). But it has a **remaining C caller** — the still‑C `m_lusers` (s_serv.c:2386, `if (all) send_users(...)`) — so guarding out its definition left `s_serv_link.o` with an undefined local `send_users` (confirmed at RED: undefined `m_users`/`m_summon`/`m_help`/`send_users`). Fix: the forward decl flips `static`→`extern` under `#ifdef PORT_SERV_P5` and the Rust def is `#[no_mangle] pub extern "C"`, so `m_lusers` resolves to the Rust `send_users` at link. `nm target/debug/ircd | grep -E ' T (m_users|m_summon|m_help|send_users)$'` shows all four defined from Rust.
  - **Callees, all already resolved.** C externs — `hunt_server`, `sendto_one` (variadic P8 trampoline, local block fmt `*mut c_char`). Rust — `replies[]` (P3 `reply()`), `msgtab[]` (parse.rs, `static mut` resolves at link). Globals — `istat` (`istat_t`: `is_myclnt`/`is_m_myclnt`/`is_user[2]`/`is_m_users`, `u_long` counters passed verbatim to the variadic sender), `me`. Inlined macros — `ME`/`BadTo`/`BadPtr`. The `parv` rewrite in `m_summon` is faithful raw‑pointer stores (`*parv.add(n) = …`) into the parser's fixed MAXPARA+1 array.
  - **Classification: handler cluster, no L1.** USERS `{m_nop,m_users,m_users,m_users,m_unreg}` / SUMMON `{m_nop,m_summon,m_summon,m_nop,m_unreg}` / HELP `{m_nop,m_help,m_help,m_nop,m_unreg}` (msgtab col 1, min‑params 0 → client‑reachable → **L2**). `m_users`/`m_summon` each have a `hunt_server` forward → **L2‑S2S**; `m_help` has no forward/`IsServer` path → no S2S. **No L1** — like P5ii/P5jj/`m_list`, pure wire handlers with no socket‑free data op; `send_users` has no `cref_` oracle (inlined) so it too is L2‑covered, not L1.
  - **`format!` per user request — N/A.** Every wire line (the `265`/`266` counts, `411`/`445`, the HELP NOTICEs) goes straight to the C variadic `sendto_one`; nothing is assembled into a Rust string.
  - **L2 + L2‑S2S are the gates.** `golden_s_serv_stubs` (L2): a lone registered client drives `USERS`→`265`+`266`, `SUMMON nobody`→`445`, `HELP`→the NOTICE list anchored on the table's final `:ETRACE` entry — ref‑C == Rust byte‑identical. `golden_s2s_s_serv_stubs` (L2‑S2S): `USERS peer.test` / `SUMMON nobody peer.test` forward via `hunt_server` and the linked peer receives byte‑identical forwarded commands (`m_help`, having no forward, is excluded with a note). `cargo build` 0 warnings; both touched golden binaries green.

- **2026‑06‑04 — P5ll (s_serv.c LUSERS handler — `m_lusers`) merged.** The LUSERS network‑stats handler (s_serv.c:2272) ported into `ircd-common/src/s_serv.rs`, extending the existing `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Fourth `s_serv.c` sub‑phase.** This **closes the P5kk `send_users` loop**: `m_lusers`'s `all`‑path tail `if (all) send_users(...)` already resolves to the Rust `send_users` (P5kk), and now both live in Rust. Plan: `docs/superpowers/plans/2026-06-04-p5ll-s_serv-m_lusers.md`.
  - **Guard + RED→GREEN.** A single plain `#ifndef PORT_SERV_P5` guard around the C def (s_serv.c:2272‑2392); `m_lusers` is not a file‑static and not anyone's static callee. RED: `cargo build -p ircd-rs` → exactly one undefined symbol `m_lusers`. GREEN: `nm target/debug/ircd | grep ' T m_lusers$'` → defined from Rust; `cargo build` 0 warnings.
  - **Config‑resolved body (USERS_RFC1459 off).** Three counting paths feed RPL_LUSER{CLIENT 251, OP 252, UNKNOWN 253, CHANNELS 254, ME 255}: (1) bare `LUSERS` or `LUSERS *` → the **`all`** path reads `istat` (`is_serv`/`is_user[0..1]`/`is_unknown`/`is_oper`/`is_service`/`is_myclnt`/`is_myserv`/`is_myservice`) then tails into `send_users` (265/266); (2) `LUSERS <server>` → a remote `find_client`→`IsServer`→`serv->usercnt[0..2]`; (3) `LUSERS <mask>` → walks `svrtop` summing each `asptr->usercnt[]` (the `IsMe` arm grabs `is_myclnt`/…/`is_unknown`), then walks `svctop` counting matching services. `parc>2` forwards via `hunt_server(":%s LUSERS %s :%s", 2)` first.
  - **Callees, all already resolved.** C externs — `hunt_server`, `sendto_one` (variadic P8 trampoline, local block fmt `*mut c_char`). Rust — `collapse`/`match_` (P1), `find_client` (P4 parse.rs), `send_users` (P5kk). Globals — `istat`/`svrtop`/`svctop` (the `aServer.usercnt`/`nexts`/`bcptr` + `aService.servp`/`nexts` chains, raw‑pointer walked, never an `aServer`/`aService` read by value), `replies` (P3 `reply()`), `me`. New inline helpers `is_server`=`status==STAT_SERVER`, `is_me`=`status==STAT_ME` (struct_def.h:136/138).
  - **Faithfulness notes.** The `int` locals (`s_count`/`c_count`/`i_count`/`u_count`/`o_count`/`v_count`/`m_clients`/`m_servers`/`m_services`) stay `c_int`, assigned from `u_long` istat fields with `as c_int` (C's implicit `u_long`→`int` truncation). `istat.is_chan` is passed straight to the `%d` RPL_LUSERCHANNELS variadic as `u_long` — byte‑identical on x86‑64 SysV (the low 32 bits of the arg register match a small positive `int`), exactly as the already‑Rust `send_users` does. **Quirk ported literally:** RPL_LUSERUNKNOWN (253) is emitted with **`parv0`, not `BadTo(parv0)`** (s_serv.c:2380) — every other LUSERS reply uses `BadTo`.
  - **Classification: handler cluster, no L1.** `LUSERS {m_lusers, m_lusers, m_lusers, m_lusers, m_unreg}` (msgtab col 1 client‑reachable + col 2 server‑reachable, min‑params 0 → **L2**); the `hunt_server` forward (`parc>2`) **and** the remote‑server field formatting (`svrtop`/`find_client` `usercnt[]` + server names) → **L2‑S2S**. **No L1** — pure wire handler with no socket‑free data op (the lookups are read‑only counting terminating in `sendto_one`), cf. P5ii/P5jj/P5kk/`m_list`.
  - **`format!` per user request — N/A.** Every wire line (the five LUSER numerics + the `send_users` 265/266) goes straight to the C variadic `sendto_one`; nothing is assembled into a Rust string.
  - **L2 + L2‑S2S are the gates.** `golden_s_serv_lusers` (L2): a lone registered client drives a bare `LUSERS` → 251/254/255 then the `send_users` 265/266 (the `all` path), read through the always‑last `266` anchor — ref‑C == Rust byte‑identical. `golden_s2s_s_serv_lusers` (L2‑S2S): two server‑reachable facets after a peer links — (1) `LUSERS *.test` exercises the `svrtop` mask walk (the `*.test` matches both `irc.test` + `peer.test`, so the 251 server count reflects the link and the `IsMe` 253 arm fires), diffed from the **client** side through the 255 tail; (2) `LUSERS * peer.test` (`parc>2`) forwards via `hunt_server` and the **peer** receives the byte‑identical forwarded command. `cargo build` 0 warnings; both touched golden binaries green.

- **2026‑06‑04 — P5mm (s_serv.c map‑display cluster — `m_map`/`dump_map`/`dump_map_sid`) merged.** The MAP handler (s_serv.c:3748) + its two recursive file‑static tree renderers `dump_map` (plain names, s_serv.c:3666) and `dump_map_sid` (names + usercount + SID + version, s_serv.c:3599) ported into `ircd-common/src/s_serv.rs`, extending the existing `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Fifth `s_serv.c` sub‑phase.**
  - **Guard + RED→GREEN.** A single plain `#ifndef PORT_SERV_P5` guard around the contiguous C region (s_serv.c:3599‑3781, all three fns): `dump_map`/`dump_map_sid` are file‑`static` with **no remaining C caller** (only `m_map` calls them, and it ports here too) → private Rust `unsafe fn`s (no `cref_` oracle, like `m_list`/`can_join`); `m_map`'s decl resolves via the parse.rs `msgtab` imports. `nm target/debug/ircd | grep ' T m_map$'` → defined from Rust; `cargo build` 0 warnings.
  - **Module‑private `BUF` (the shared `buf[BUFSIZE]`).** `dump_map`/`dump_map_sid` accumulate the output line in the s_serv.c TU‑wide `static char buf[BUFSIZE]` via raw pointer arithmetic — `pbuf` indexes the current nesting offset (`pbuf + 4` per level), each leaf flushes the **whole** `buf` with `015 RPL_MAP`, and the tree‑char cleanup walks backwards (`pbuf[-2]`/`pbuf[-3]`). `m_map` fills+flushes `buf` entirely in‑call (no cross‑call aliasing with the still‑C users of `buf` — m_stats/report_*/send_server_burst), so a module‑private `static mut BUF: [c_char; BUFSIZE]` + a `buf_base()` helper is faithful (cf. P5aa/P5cc). Pointer ops use `.add()`/`.sub()`/`.offset_from()`; the snprintf `size` arg keeps C's `int`→`size_t` conversion via `size as usize` (negative→huge, faithful UB).
  - **Callees, all already resolved.** C externs — `sendto_one` (variadic P8 trampoline, local block fmt `*mut c_char`), plus `snprintf`/`strcat`/`strlen` (libc, added to the local extern block, faithful to the C). Rust — `match_` (P1), `replies[]` (P3 `reply()`). Globals — `me` (`addr_of_mut!(me)` for `&me`, the tree root), `timeofday`. New inline helpers `is_bursting`=`!(flags & FLAGS_EOB)` (struct_def.h:222) and `map_name`=`IsMasked(root) ? maskedby->name : root->name`; reused `is_masked`/`my_connect`/`bad_to`/`me_name` (P5ii/P5jj).
  - **Faithfulness notes.** `me` is `SetEOB`'d at boot (ircd.c:732) → `IsBursting(&me)` false → `dump_map_sid(&me)` always takes the non‑bursting `"%s %d %s %s"` branch (no wall‑clock `"bursting %ds"` trailer). `dump_map`'s `prevserver` carries the last unmasked server across masked‑subtree boundaries via a `*mut *mut aClient` out‑param + a recursion‑local `prev` (`addr_of_mut!(prev)`), byte‑for‑byte the C `aClient **`. The `%ds` literal (snprintf) is `%d` followed by a literal `s`.
  - **Classification: handler cluster, no L1.** `MAP {m_map, m_map, m_map, m_nop, m_unreg}` (msgtab col 1 client‑reachable + col 2 server‑reachable, min‑params 0 → **L2**). `m_map` has **no `hunt_server` forward** (it always dumps from `&me`), but `dump_map`/`dump_map_sid` format **remote‑server fields** (names, SID, version, usercount) only reachable with a linked peer → **L2‑S2S**. **No L1** — pure wire handlers with no socket‑free data op, terminating in `sendto_one` (cf. P5ii/P5jj/`m_list`/`m_names`).
  - **`format!` per user request — N/A.** Every wire line goes straight to the C variadic `sendto_one`; `dump_map_sid` builds its per‑server token into `buf` via libc `snprintf` (faithful, not a Rust string), `dump_map` via libc `strcat`. Nothing assembled with `format!`.
  - **L2 + L2‑S2S are the gates.** `golden_s_serv_map` (L2): a lone registered client drives `MAP` → `018 RPL_MAPSTART` + a single `015` (`irc.test`) + `017 RPL_MAPEND`, then `MAP s` → `018` + a single `015` with the local server's usercount/SID/version — ref‑C == Rust byte‑identical. `golden_s2s_s_serv_map` (L2‑S2S): the multi‑server tree walk a lone server can't produce — bare `MAP` before vs after the peer links (the positive/inverse pair: the lone server sees only `:irc.test 015 alice :irc.test`, then after the link adds `:irc.test 015 alice : \`- peer.test`), then `MAP s` after the link adds `: \`- peer.test 0 001B 0211030000` (the only way to exercise `dump_map_sid`'s remote `serv->sid`/`verstr`/`usercnt` formatting; the peer is sent an `EOB` first so `IsBursting(peer)` is false). `cargo build` 0 warnings; both touched golden binaries + the s_serv golden regression suite green.

- **2026‑06‑04 — P5nn (s_serv.c TRACE cluster — `m_trace`/`m_etrace`/`trace_one`/`count_servers_users`) merged.** The TRACE handler (s_serv.c:2745) + the extended‑TRACE handler `m_etrace` (s_serv.c:2862) + the per‑client renderer `trace_one` (s_serv.c:2656) + the count helper `count_servers_users` (s_serv.c:1653) ported into `ircd-common/src/s_serv.rs`, extending the existing `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Sixth `s_serv.c` sub‑phase.** Plan: `docs/superpowers/plans/2026-06-04-p5nn-s_serv-trace.md`.
  - **Guard + RED→GREEN.** One contiguous `#ifndef PORT_SERV_P5` guard around `trace_one`/`m_trace`/`m_etrace` (s_serv.c:2664‑2923, comment blocks included); `m_sidtrace` (the next fn, `#ifdef ENABLE_SIDTRACE`) left untouched. `trace_one` is file‑`static` with **no remaining C caller** (only `m_trace`×2 call it, both port here) → a **private Rust `unsafe fn`** (no `cref_` oracle, cf. `m_list`/`can_join`/`dump_map`). `m_trace`/`m_etrace`'s decls resolve via the parse.rs `msgtab` imports. RED confirmed exactly `{m_trace, m_etrace, count_servers_users}` undefined; `nm target/debug/ircd | grep ' T (m_trace|m_etrace|count_servers_users)$'` → all three defined from Rust; `cargo build` 0 warnings.
  - **`count_servers_users` extern‑prototype switch.** The `static void count_servers_users(...)` **forward decl** (s_serv.c:47) gives the function **internal linkage** despite its non‑`static` definition, so GCC inlined it into both call sites → **no emitted symbol** (absent from `nm`). It is still called by the C `report_myservers` (s_serv.c:1632, stays C) **and** by the now‑Rust `trace_one`, so it gets the **P5u/P5x extern‑prototype switch**: the forward decl flips `static`→`extern` under the guard, its body (1653‑1681) is guarded out, and the Rust `#[no_mangle] pub extern "C" fn count_servers_users` resolves the C remnant's call at link. **HUB off** → only the `#else` istat branch is ported: `*servers = is_serv‑1`, `*users = is_user[0]+is_user[1]‑is_myclnt` (the `cptr` arg unused); the `u_long` fields are `wrapping_*`‑combined then `as c_int` (faithful to C's `u_long`→`int`, avoids a debug overflow panic in the nounwind extern fn).
  - **Callees, all already resolved.** C externs (bindgen) — `get_client_name`/`get_client_class`/`get_client_ip`/`find_matching_client`/`find_sid`/`find_person`/`match_`; the variadic `sendto_one` (local block, fmt `*mut c_char`). Rust — `is_allowed` (P5o), `m_nopriv` (P4), `trace_one`/`count_servers_users` (this port). Globals — `local[]`/`highest_fd` (incomplete‑array via the `local_base()` send.rs helper), `me`, `timeofday`, `istat`, `replies` (P3 `reply()`), `IRC_VERSION`. New inline macro helpers `is_client`/`is_person`/`is_unknown`/`is_an_oper`/`send_wallops`/`my_client`; reused `is_server`/`is_me`/`my_connect`/`bad_to`/`me_name`/`dbuf_length`.
  - **Faithfulness notes.** `trace_one`'s status `switch` ported as a `match (*acptr).status as c_int` (status is `c_short`) over the nine `STAT_*` arms incl. the STAT_ME no‑op and the `default` RPL_TRACENEWTYPE; the STAT_SERVER case keeps both `serv->user`/`!serv->user` branches verbatim (the `*serv->by ? by : "*"` first‑char test, the masked‑vs‑real server fields). `m_trace`'s passthru emits the volatile `200 RPL_TRACELINK` (link‑uptime `timeofday‑from->firsttime`, two sendQ `DBufLength`s) ported faithfully but **only diffed peer‑side** in S2S (the deterministic signal is the forwarded `:%s TRACE :%s`). `m_etrace` is gated to my opers with ACL_TRACE; **XLINE off** → the user2/user3 columns are the `"-","-"` literals; the `serv->user->{username,host}`/`acptr->user->{username,host}` are `[c_char;N]` arrays passed via `.as_ptr()`. Never reads an `aClient`/`aServer` by value (raw‑pointer invariant). **ENABLE_SIDTRACE off** → `m_sidtrace` not compiled, not ported.
  - **Classification: handler cluster, no L1.** `TRACE {m_trace, m_trace, m_trace, m_trace, m_unreg}` (any registered client, col 1 → **L2**); `ETRACE {m_nop, m_nopriv, m_etrace, m_nop, m_unreg}` (only STAT_OPER, col 2, reaches `m_etrace`; a plain client hits `m_nopriv`/481). `m_trace`'s passthru + `trace_one`'s STAT_SERVER case format **remote‑server fields** → **L2‑S2S**; `m_etrace` walks only local persons (no S2S path of its own). **No L1** — pure wire handlers terminating in `sendto_one`; `count_servers_users` *is* a data op but has **no `cref_` oracle** (internal linkage in the oracle archive too) → L2‑S2S‑covered via the `206` servers/users it feeds (cf. P5jj `check_link`).
  - **`format!` per user request — N/A.** Every wire line goes straight to the C variadic `sendto_one(replies[…], …)`; no ASCII/numeric reply string is assembled in Rust. `get_client_name`/`get_client_ip` return their own C buffers.
  - **L2 + L2‑S2S are the gates.** `golden_s_serv_trace` (L2): bare `TRACE` from a lone plain client → `205 RPL_TRACEUSER` (self) + `262 RPL_TRACEEND`; `OPER alice secret`+`ETRACE` via the new `trace_oper.conf` (O‑line `t`/ACL_TRACE flag) → `381` + `709 RPL_ETRACEFULL` (self) + `759 RPL_ETRACEEND` — byte‑identical ref‑C == Rust. (Symbolic `RPL_ETRACEFULL`=708 but the dumped `replies[708]` carries the wire numeric 709; both builds share the P3 table → bytes match.) `golden_s2s_s_serv_trace` (L2‑S2S): bare `TRACE` after `Peer::link()` → `206 RPL_TRACESERVER` for the peer (the `trace_one` STAT_SERVER + `count_servers_users` path with the remote `serv->version`/`by`/`user` fields), diffed client‑side; `TRACE peer.test` → the `IsServer` passthru forwards the command, diffed peer‑side. `cargo build` 0 warnings; the two touched golden binaries green; no new canonicalizer masks (the 206/205/262/709/759 numerics carry no volatile token).
