- **P5j DONE: `s_user.c` OPER cluster** (`m_oper`) — same `s_user_link.o` partial port; reuses the Rust `send_umode_out`; new dedicated `oper.conf` fixture + `boot_conf` harness fn to L2‑test the auth paths (491/464/success).
- **P5k DONE: `s_user.c` QUIT/POST exit cluster** (`m_quit` + `m_post`) — same `s_user_link.o` partial port; both terminate in the already‑Rust `exit_client` (P5c); L2 covers QUIT (registered) + POST (unregistered http‑proxy alias).
- **P5l DONE: `s_user.c` PASS cluster** (`m_pass`) — same `s_user_link.o` partial port; registration‑time password/version‑staging handler (no wire output); L1 differential on `cptr->passwd`/`cptr->info` + L2 PASS‑then‑register banner byte‑identical.
- **P5m DONE: `s_user.c` canonize utility** (`canonize` — the comma‑list deduplicator) — same `s_user_link.o` partial port; a pure callee (no msgtab row) reached from m_mode/m_part/m_topic (channel.c) + m_whowas (whowas.c) + the WHO cluster; L1 differential is the gate, WHOWAS gives an L2 dedup regression gate.
- **P5n DONE: `s_user.c` do_nick_name utility** (`do_nick_name` — the nickname validator/canonicalizer) — same `s_user_link.o` partial port; a pure string callee (no msgtab row) reached from still‑C m_nick/m_user/register_user; L1 differential is the gate, the registration banner is the L2 regression gate (the nick is echoed in every reply).
- **P5o DONE: `s_user.c` is_allowed ACL gate** (`is_allowed` — the per‑client O‑line/service privilege check) — same `s_user_link.o` partial port; a pure callee (no msgtab row, no globals/hash — a pure function of `cptr`) reached from ported `parse.rs` (penalty) + still‑C m_kill/s_serv/s_conf/channel/res/hash/s_bsd; L1 differential (conf‑walk) is the gate, oper‑KILL grant(`K`→401)/deny(`T`→481) is the L2 branch‑selection gate.
- **P5p DONE: `s_user.c` KILL handler** (`m_kill` — the oper/server KILL command; gates on the Rust `is_allowed` (P5o), resolves the victim via Rust `find_uid`/`find_client`/`get_history`, terminates in the Rust `exit_client` (P5c)) — same `s_user_link.o` partial port; new multi‑client `golden_s_user_kill` L2 (oper alice KILLs registered bob → victim KILL notice + `exit_client` close byte‑identical).
- **P5q DONE: `s_user.c` register_user** (the central client‑registration routine — ident‑prefix username canonicalization, `check_client`/`find_kill` gating, the welcome banner [001…RPL_YOURID + LUSERS + MOTD], `send_umode`, the leaf‑server UNICK feed) — same `s_user_link.o` partial port; a utility/callee (no msgtab row) reached from still‑C `m_nick`/`m_user`/`m_unick`; the registration banner (the P0‑L2 anchor scenario) is the L2 gate.
- **P5r DONE: `s_user.c` m_user** (the USER registration handler — `make_user`/numeric `sip`, the `+/-`/RFC‑bit umode‑in‑USER parse, real‑name `info` capping, then the `register_user` (P5q) tail‑call) — same `s_user_link.o` partial port; a handler (msgtab `USER`=`[m_nop,m_reg,m_reg,m_nop,m_user]` → unregistered col only) reached on the registration path; the registration banner is the L2 gate (drives `make_user` + the "no flags" umode path).
- **P5s DONE: `s_user.c` NICK cluster** (`m_nick` + `m_unick` + `save_user` [static SAVE emitter] + `m_save` — the connected component sharing `save_user`) — same `s_user_link.o` partial port; `m_nick`'s `goto badparamcountkills`/`goto nickkilldone` control flow refactored into two faithful helper fns; L2 golden (`golden_s_user_nick`: local nick change echo, `432` erroneous nick, `433` nick‑in‑use) byte‑identical; `m_unick`/`m_save`/`save_user`'s SAVE emit are S2S‑only (no L2 path under `‑s`, covered by review). **Only `next_client`/`hunt_server` (hash‑dependent → S2S/L2) now remain in `s_user_link.o`.** **`s_auth.c` deferred to P7/P‑IAUTH** (no `m_*`; pure socket/ident/iauth‑pipe I/O, no L2 path under `‑s` boot).**
- **P5t DONE: `channel.c` leaf‑predicate foundation cluster** (`is_chan_op`/`has_voice`/`find_channel`/`clean_channelname` — the only truly‑leaf exports, no file‑static/shared‑buffer dep) via the new `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`); establishes the channel.c port mechanism. L1 differential (4 fns) + L2 `golden_channel` (JOIN #chan → 353 `@alice`/366). `can_send` deferred to the mode cluster (calls the static `match_modeid`). **P5‑S2S DONE: server‑link golden coverage** — the new `ircd-golden` `Peer` fake‑server (completes the IRCnet 2.11 `PASS`/`SERVER`→burst handshake) + `s2s.conf` fixture (C/N/H lines) close the `IsServer(cptr)` paths every cluster above deferred to "S2S/L2": 13 `golden_s2s_*` scenarios byte‑identical (ref‑C == Rust) — link+remote‑WHOIS, PRIVMSG routing (P5f), AWAY (P5g), umode propagation (P5h), QUIT propagation (P5k), server‑KILL (P5p), SQUIT/`exit_server` reap (P5c), remote NICK + SAVE (P5s), USERHOST/ISON (P5e), remote WHO (P5d), `register_user` leaf‑UNICK feed (P5q), SERVICE intro+SQUERY (P5a).
- **P5u DONE: `channel.c` invite cluster** (`m_invite` + the file‑statics `add_invite`/`list_length` + `check_channelmask` + `del_invite`) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). Second channel.c sub‑phase; first to hit the **static‑function‑with‑remaining‑C‑callers** case: `check_channelmask` (called by m_join/m_part/m_kick/m_topic/m_njoin/set_mode/send_channel_*) has its forward `static` prototype switched to `extern` under the guard so the C remnant resolves to the Rust def (linkage‑only, faithful). `del_invite` (exported) now resolves for s_misc.rs + free_channel/m_kick/m_njoin too. L1 `channel_invite_diff` (del_invite chain relink + istat deltas; the statics `add_invite`/`list_length`/`check_channelmask` have no oracle symbol → L2‑covered); L2 `golden_channel_invite` (4 scenarios: success 341 + relayed INVITE [fires add_invite live], 401, 442, 476 `check_channelmask`).
- **P5v DONE: `channel.c` can_send + match_modeid cluster** (`can_send` [exported send‑permission predicate] + `match_modeid` [file‑static ban/exception matcher, via the P5u extern‑prototype switch since `can_join`/`reop_channel` stay C]); resolves the already‑Rust `m_message`/who callers; also fixed a latent P5u `is_member` bug (the active `IsMember` macro walks the client's channel list via `find_channel_link`, not `chptr->members`). L1 `channel_can_send_diff` (8 cases vs `cref_can_send`) + L2 `golden_channel_can_send` (+m moderated / +n no‑external 404 rejects).
- **P5w DONE: `channel.c` `channel_modes` leaf** (the "simple" channel mode‑string serializer, channel.c:831 — writes `+`‑flags into `mbuf` and the `+l`/`+k` params into `pbuf`) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). Fourth channel.c sub‑phase; a **true leaf** (no file‑static — writes caller buffers; only `IsMember`/`IsServer` + libc `sprintf`/`strcat`), so a plain `#ifndef` guard drops the exported def and resolves the still‑C callers (`m_mode` query, `set_mode`, `send_channel_modes`) to the Rust def. L1 `channel_modes_diff` (17 cases vs `cref_channel_modes`: every bit + secret/private precedence + `+l`/`+k` params member/server vs suppressed) + L2 `golden_channel_modes` (`MODE #chan` query → `324 RPL_CHANNELMODEIS` byte‑identical, exercising both `+l` `sprintf` and `+k` `strcat`).
- **P5x DONE: `channel.c` membership cluster** (`add_user_to_channel` + `remove_user_from_channel` + `change_chan_flag` — the `members`/`clist`/`user->channel` list manipulators + `istat` counters) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). Fifth channel.c sub‑phase; touches **no** shared `buf`/`modebuf` static. The two file‑statics (`add_user_to_channel`/`change_chan_flag`) get `extern` forward decls under the guard (no existing forward decl); the still‑C `free_channel` is **kept C** via a linkage‑only `static`→`extern` switch (the Rust `remove_user_from_channel` calls it on the last‑user teardown). `remove_user_from_channel` already resolves for the Rust `s_misc.rs` exit cascade (P5c). L1 `channel_membership_diff` (the exported `remove_user_from_channel` vs `cref_`: members/clist relink + `user->channel` + `is_userc`/`is_chanusers` deltas; the statics are L2‑covered). L2 `golden_channel_part` (PART with a second member observing the relay + NAMES/WHO omitting the parted user → `remove_user_from_channel`; `MODE +o`→NAMES `@bob` → `change_chan_flag`) + the JOIN `golden_channel` regression covers `add_user_to_channel`; **S2S `golden_s2s_membership`** (remote NJOIN → `add_user_to_channel`, remote PART → `remove_user_from_channel`, observed by a local member).
- **P5y DONE: `channel.c` `m_topic` handler** (the TOPIC command — per‑channel query [331/332/333] or set [propagate + 482 reject]) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). The **cleanest channel.c handler**: every callee is already Rust (`canonize`/`strtoken`/`find_channel`/`check_channelmask`/`is_chan_op`) or a C variadic sender, and `m_topic` has **no file‑static of its own** → a plain `#ifndef` guard drops the C def and the `m_topic` decl parse.rs imports resolves to the Rust def (no extern‑prototype switch, no parse.rs/build.rs edit). `TOPIC_WHO_TIME` defined → the `topic_t`/`topic_nuh` blocks ported (`topic_nuh` = byte‑builder, not `format!`; 333's `topic_t` masked as wall‑clock volatile). L2 `golden_channel_topic` (lifecycle: query‑empty 331 → set → query 332/333 → change → re‑query reflects the new value; rejects 442/403/482) + **S2S `golden_s2s_topic`** (remote bob TOPIC → relay to local member + 333 with bob's `topic_nuh`; local alice TOPIC → `sendto_match_servs` UID‑sourced propagation to the peer).
- **P5z DONE: `channel.c` `m_list` handler** (the LIST command — channel listing: bare lists all visible channels [322 + LIST_ALIS_NOTE notice + 323], named/`!`‑mask forms) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). Like `m_topic` a **true leaf** (no file‑static of its own) → a plain `#ifndef` guard drops the C def; every callee is already Rust (`canonize`/`strtoken`/`find_channel`/`hash_find_channels`/`get_sendq`) or a C extern (`hunt_server`, the variadic `sendto_one` — whose ircd‑common extern decls were unified to `-> c_int` so `m_list`'s `rlen += sendto_one(…)` reply‑length throttle ports faithfully). L2 `golden_channel_list` (bare LIST shows two public channels + 323, a `+s` channel a non‑member can't see is absent [the inverse], named `LIST #pub`, `LIST #nonexistent` → only 323) + **S2S `golden_s2s_list`** (the `hunt_server` forwarding short‑circuit: `LIST #chan peer.test` → the peer receives the forwarded command, byte‑identical).
- **P5aa DONE: `channel.c` `m_part` handler** (the PART command — leave one/more channels: per‑channel `get_channel`/`check_channelmask`/`IsMember` gating, the comma‑batched server broadcast via the private scratch `buf`, member relay, then the now‑Rust `remove_user_from_channel`) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). Its only still‑C callee is the file‑static `get_channel` (extern‑prototype switch on both forward decl + definition, P5u/P5x mechanism — flag 0, no CREATE); every other callee is already Rust (`canonize`/`strtoken`/`check_channelmask`/`remove_user_from_channel`) or a C variadic sender (`sendto_serv_butone`/`sendto_match_servs`/`sendto_channel_butserv`); `get_channelmask` is the JAPANESE‑off macro `rindex(name,':')`=`strrchr`. The shared `static buf[BUFSIZE]` is pure scratch (init+flush in‑call) → a module‑private `static mut BUF` is faithful. L2: the existing `golden_channel_part` (local success + NAMES/WHO inverse) now drives the Rust m_part, **extended** with its own error numerics (403 NOSUCHCHANNEL / 442 NOTONCHANNEL); **S2S `golden_s2s_membership`** already covers the remote‑PART `IsServer(cptr)` / `sptr->user->uid` propagation branch.
- **P5bb DONE: `channel.c` `m_kick` handler + the file‑static `find_chasing`** (the KICK command — kick one/more users from one/more channels: `get_channel`/`check_channelmask`/`is_chan_op` gating, `find_chasing`/`find_uid` victim resolution, the comma‑batched `sendto_match_servs_v(SV_UID)` UID propagation, member relay via `sendto_channel_butserv`, then the now‑Rust `remove_user_from_channel`) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). `find_chasing` is the cluster's shared file‑static — also called by the still‑C `m_mode`/`set_mode`, so it gets the **P5u/P5x extern‑prototype switch** (its C body is guarded out and an `extern` forward decl added so the C remnant resolves to the Rust def); `check_string` (the other display static) is untouched (m_kick doesn't call it). Every other callee is already Rust (`get_channel` [C static, extern‑switched by P5aa]/`check_channelmask`/`is_chan_op`/`remove_user_from_channel`/`find_uid`/`find_client`/`get_history`/`mystrdup`) or a C variadic sender (`sendto_flag`/`sendto_match_servs_v` added to the extern block). L2 `golden_channel_kick` (chanop KICKs member → relay + NAMES inverse; error numerics 441 [find_chasing resolves a non‑member]/403/442/482) + **S2S `golden_s2s_kick`** (UID propagation `:<kicker‑uid> KICK #chan <victim‑uid>` to the peer; server‑sourced `:001B KICK` exercising the `IsServer(cptr)`+`find_uid` / `IsServer(sptr)` SID‑sender branches).
- **P5cc DONE: `channel.c` display cluster — `m_names` handler + the file‑static `names_channel`** (the NAMES command + the per‑channel `353 RPL_NAMREPLY`/`366 RPL_ENDOFNAMES` emitter) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). `names_channel` is still called by the C `m_join` (the JOIN echo) → **P5u/P5x extern‑prototype switch** (its `static` forward decl + body guarded out, an `extern` forward decl added so the C remnant resolves to the Rust def); `m_names` is a plain `#ifndef` guard (msgtab `NAMES`=`[m_nop,m_names,m_names,m_nop,m_unreg]` → its decl parse.rs imports resolves to Rust). Every callee is already Rust (`find_channel_link`/`find_channel`/`clean_channelname`/`strtoken`) or a C extern (`hunt_server`, the variadic `sendto_one`). Both share the module `BUF` (the C `buf[BUFSIZE]`): `names_channel` fills+flushes it in‑call and `m_names` only writes `buf` itself after all its `names_channel` calls → one `BUF` is faithful (the still‑C `m_join` keeps its own C `buf`; its `!`‑autocreate `name=buf` cross‑call aliasing is a documented residual that vanishes when m_join ports). No socket‑free data op (read‑only + wire) → **L2/L2‑S2S are the gates, no L1** (cf. m_list/m_topic). L2 `golden_channel_names` (`NAMES #pub` `= #pub :@alice bob` 353+366; secret‑channel member `@ #secret` marker; **inverse** — a non‑member's `NAMES #secret` yields only 366; bare `NAMES` all‑channels + `* * :` remaining‑users section) + JOIN‑echo regression via `golden_channel`; **S2S `golden_s2s_names`** (the `parc>2` `hunt_server` forwarding short‑circuit: `NAMES #chan peer.test` → the peer receives the forwarded command, byte‑identical).
- **P5dd DONE: `channel.c` JOIN cluster — `m_join` handler + the file‑static `can_join`** (the JOIN command + its access‑control predicate) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). `can_join` is file‑static and its only caller (`m_join`) ports here too → no C caller remains, so it is a **private Rust `unsafe fn`** (no `cref_can_join` oracle → L2‑tested via m_join's reject numerics); both its forward decl + body are plainly guarded out. `m_join` is a plain `#ifndef` guard (msgtab `JOIN`=`[m_nop,m_join,m_join,m_nop,m_unreg]` → client+server cols; its decl parse.rs imports resolves to Rust). Every callee is already Rust (`strtoken`/`check_channelmask`/`clean_channelname`/`find_channel`/`hash_find_channels`/`check_chid`/`get_chid`/`del_invite`/`add_user_to_channel`/`remove_user_from_channel`/`names_channel`/`exit_client`/`match_modeid`/`mycmp`) or a C extern (`get_channel` [extern‑switched by P5aa], the variadic senders `sendto_serv_v`/`sendto_channel_butone` added to the block). m_join's function‑`static jbuf[BUFSIZE]` → a module‑private `JBUF` (distinct from the shared `BUF` it uses as the `!`‑channel‑id `sprintf` scratch — resolving the P5cc‑documented `m_join`/`buf` residual). No socket‑free data op (membership via the already‑L1'd `add_user_to_channel`, then wire) → **L2/L2‑S2S are the gates, no L1** (cf. m_names/m_list). L2 `golden_channel_join` (`+k` wrong‑key 475 then keyed join, `+i` 473 then INVITE override, `+l 1` full 471, duplicate‑JOIN no‑op, `JOIN 0` part‑all + NAMES inverse) + the `golden_channel` JOIN/part/rejoin regression; **S2S `golden_s2s_join`** ((a) a local client's JOIN of a federated `#chan` propagates `:000A NJOIN #chan :000AAAAAA` to the peer [`sendto_serv_v` SV_UID, local SID + joiner UID]; (b) the `IsServer(cptr)` head — a peer‑sourced `:<uid> JOIN 0` relays the remote user's PART to a local co‑member). `m_njoin`/`reop_channel`/the mode cluster stay C.
- **P5ee DONE: `channel.c` `m_njoin` handler** (the server‑only NJOIN channel‑membership burst command) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). Twelfth channel.c sub‑phase; a **handler with no standalone client path** (msgtab `NJOIN`=`[m_njoin,m_nop,m_nop,m_nop,m_unreg]` → col 0 only, server‑reachable) → **L2‑S2S is its only gate** (no L2, no L1). Plain `#ifndef` guard (its decl parse.rs imports resolves to Rust; not anyone's static callee). Every callee already Rust (`check_channelmask`/`find_person`/`find_uid`/`add_user_to_channel`/`get_client_name`) or a C extern (`get_channel` [extern‑switched by P5aa, CREATE], the variadic senders). The shared `modebuf`/`parabuf` file‑statics (the synthetic‑MODE scratch) → module‑private `MODEBUF`/`PARABUF` (pure in‑call scratch — faithful, cf. P5aa's `BUF`); `uidbuf`/`mbuf` are C autos → Rust stack arrays. New `is_bursting` helper (`!(flags & FLAGS_EOB)`). L2‑S2S `golden_s2s_njoin` (the `@+` op+voice MODE‑burst the membership test doesn't cover: a peer NJOINs carol `@+` onto a #chan a local member is on → the relayed JOIN + the synthetic `:peer.test MODE #chan +ov carol carol` burst, exercising the `mbuf[1]` double‑param path) + the existing `golden_s2s_membership` (plain add/remove) now drives the Rust m_njoin as a regression; the other NJOIN‑driving goldens (join/kick/topic) stay byte‑identical.
- **P5ff DONE: `channel.c` mode‑id list layer** (`check_string` + `make_bei`/`free_bei` + `add_modeid`/`del_modeid` — the ban/exception/invite `+b`/`+e`/`+I` list‑item alloc + `mlist` add/del, the connected component over the file‑static `asterix` var) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). Thirteenth channel.c sub‑phase; all five are file‑`static` in C → the **P5u/P5x extern‑prototype switch** on each (the still‑C `set_mode` calls `check_string`/`make_bei`/`add_modeid`/`del_modeid`; `set_mode`+`free_channel` call `free_bei` — so each `static` forward decl flips to `extern` under the guard; `check_string` had none → a new `extern` decl added). `asterix` is **module‑private** in Rust (`static mut ASTERIX`): C never references it outside the now‑ported `check_string`/`make_bei`/`free_bei`, so the pointer identity stays self‑consistent (make_bei stores it, free_bei compares it, C only ever passes the resulting `aListItem`). Every callee already Rust (`collapse`/`mycmp` P1, `make_link`/`free_link` P2, `istat` P2 with `wrapping_add/sub` — cf. P5u add_invite) or libc (`MyMalloc`/`free`/`strncpy`/`isspace`). **No L1** — all five file‑statics → no `cref_` oracle (cf. P5v `match_modeid`/P5dd `can_join`); L2 byte‑identity through the still‑C `set_mode` is the faithfulness gate. L2 `golden_channel_ban` (local chanop `+b`/`+e`/`+I` add → make_bei split + add_modeid store, ban‑list query `367`/`348`/`346` reads the Rust‑built `mlist`, duplicate `+b` BanExact dedup, then `-b` → del_modeid + free_bei + **inverse** re‑query the ban is gone) + **S2S `golden_s2s_ban`** (a peer **server** sets `+b` → the **non‑MyClient** add_modeid arm — the pure list‑add that skips every `sendto_one`, reachable only over a link — then server `-b` → del_modeid; alice's query confirms the round‑trip).
- **P5gg DONE: `channel.c` mode core** (`m_mode` + `set_mode` + `send_mode_list` + `send_channel_modes` + `send_channel_members` — the MODE handler + the ~860‑line mode parser/applier + the server‑burst emitters; the connected component over the shared `modebuf`/`parabuf`/`uparabuf` statics, now module‑private since `m_njoin` [the only other user] is already Rust) via the existing `channel_link.o` partial port (`‑DPORT_CHANNEL_P5`). **Fourteenth (final large) channel.c sub‑phase.** All five take a plain `#ifndef` guard (no extern‑switch): `set_mode`/`send_mode_list` are file‑static with **no remaining C caller** (m_mode/send_channel_modes port here) → private Rust `unsafe fn`s; `send_channel_modes`/`send_channel_members` are exported and still called by the C `send_server_burst` → `#[no_mangle]` resolves s_serv's calls at link; `m_mode`'s decl resolves via the parse.rs imports. Faithful port of the full mode grammar (`+/-` with `o`/`v`/`O`/`k`/`b`/`e`/`I`/`R`/`l` + the simple‑flag table, the `opcnt` `chops` reconstruction, parseNUH via the Rust `make_bei`, the `k` key sanitizer, the `reop` scheduling). **Bug caught by the burst S2S test:** `aListItem.nick`/`user`/`host` are `*mut c_char` **pointers**, not arrays — the first port took `addr_of!` and printed pointer bytes; fixed to pass the pointers directly. L2 `golden_channel_mode_set` (chanop `+v`/`-v` member‑voice relay seen by a second member + NAMES `+bob`→`bob` inverse) + the regression suite already driving set_mode (`golden_channel_modes` simple/limit/key, `golden_channel_ban` `+b`/`+e`/`+I`, `golden_channel_part` `+o`→NAMES). **S2S `golden_s2s_mode`** (outbound: a local chanop's `+m`/`+l 5` → `sendto_match_servs_v(SV_UID)` UID‑sourced propagation to the peer; link burst: a peer **relink** replays #chan via `send_channel_members` NJOIN + `send_channel_modes` `+tnl`/`+b` — the only way to burst a populated `#` channel in the single‑peer harness, since a split local server can't pre‑create one) + `golden_s2s_ban`/`golden_s2s_membership` the inbound‑server‑MODE regression.
- **P5hh DONE: `channel.c` lifecycle group** (`get_channel`/`free_channel`/`reop_channel`/`setup_server_channels`/`collect_channel_garbage` + the `channel` global list head) — the **15th and final channel.c sub‑phase**, so **`channel.o` is now dropped outright** (added to `PORTED`; the P5t…P5gg `channel_link.o` second‑compile + its `-DPORT_CHANNEL_P5` substitution removed entirely; the cref oracle keeps the unguarded `channel.o`). `get_channel`/`free_channel` were file‑static (extern‑switched P5aa/P5x) and `reop_channel` purely file‑static (`collect_channel_garbage`'s only caller → private Rust `unsafe fn`); `setup_server_channels`/`collect_channel_garbage` are channel_ext.h exports called from `ircd.c` (boot / io_loop timer). **Classification: utility/callee TU** (no `msgtab` handler). **L1** (`channel_lifecycle_diff.rs`, the two exported entries have `cref_` oracles; the three statics are transitively covered): `setup_server_channels` create‑cluster (14 server channels under USE_IAUTH‑on/CLIENTS_CHANNEL‑off — chname/topic/mode/lone‑chanop walk identical) + the **inverse** (oracle'd `remove_user_from_channel` on `&ERRORS` → `free_channel` unlinks it from list+hash, the other 13 survive) + `collect_channel_garbage` (hand‑built `&dead` empty+expired vs `&live` → identical return `now+CHECKFREQ` + free/keep; pinned `timeofday` so free_channel's clock re‑check fires). **No new L2‑S2S** — none of the six has an `IsServer(cptr)` dispatch branch or formats remote‑user fields; `get_channel`/`free_channel` are already L2/S2S‑covered transitively by every JOIN/PART golden (`golden_channel*`, `golden_s2s_membership`), and `collect_channel_garbage`/`reop_channel` are timer‑driven (300 s, unreachable in a short golden — the `myrand` reop arm is review‑covered). **channel.c is now FULLY ported to Rust.**
- **P5ii DONE: `s_serv.c` informational query foundation cluster** (`m_version` + `m_time` + `m_admin` — the three leaf informational query handlers: each a `hunt_server` forward + a few `sendto_one(replies[…])` replies, with **no file‑static of its own**) — the **first `s_serv.c` sub‑phase**, establishing the `s_serv_link.o` partial port (`‑DPORT_SERV_P5`, carrying the per‑object `‑DIRCDMOTD_PATH` for the still‑C `m_motd`; mirrors `s_user_link.o`) for the last/largest P5 TU. Plain `#ifndef` guards (none is a file‑static or anyone's static callee). Every callee already resolves: `hunt_server`/`find_admin`/`sendto_one` (C externs), `replies` (P3), `date` (P5c), `serveropts` (P5b), `me`/`me.serv->sid`/`IRC_VERSION`. **Classification: handler cluster** (msgtab col 1, min‑params 0 → client‑reachable) with a **server‑reachable `hunt_server` forward** branch → L2 + L2‑S2S, **no L1** (pure wire handlers, no socket‑free data op — cf. `m_list`/`m_topic`/`m_names`). L2 `golden_s_serv_info` (local VERSION→351 / TIME→391 [localtime masked] / ADMIN→256‑259 via minimal.conf's `A` line) + **S2S `golden_s2s_s_serv_info`** (the `hunt_server` forwarding short‑circuit: `VERSION/TIME/ADMIN peer.test` → the peer receives the forwarded command, byte‑identical).
- **P5jj DONE: `s_serv.c` network‑info query cluster** (`m_info` + `m_links` + the file‑static `check_link`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). Second s_serv.c sub‑phase; **first s_serv.c extern‑prototype switch**: `check_link` (file‑static, still called by the C `m_stats`/`m_motd`) flips its forward decl `static`→`extern` under the guard so the C remnant resolves to the Rust def (P5u/P5x mechanism); `m_info`/`m_links` take plain `#ifndef` guards. Every callee already resolves (`hunt_server`/`sendto_one` C externs; `infotext`/`creation`/`generation` version.c externs; `myctime`/`collapse`/`match_`/`svrtop`/`ircstp` Rust; `CHREPLLEN`=8192 baked). **Classification: handler cluster, no L1** (pure wire handlers; `check_link`'s counter‑mutating load branches are file‑static → no `cref_` oracle + non‑deterministic over a loaded link → review‑covered, the return‑0 local path is L2‑covered). Two new canonicalizer masks for m_info's volatile `371` trailers (`:Birth Date:` build stamp + `:On‑line since` boot clock). L2 `golden_s_serv_info_links` (INFO `371`/`374` + bare LINKS `364`/`365`) + **S2S `golden_s2s_s_serv_info_links`** (INFO/LINKS `hunt_server` forwards to the peer + the bare‑LINKS tree walk before/after the link — the positive/inverse pair exercising `m_links`'s remote `up->name`/`sid`/`info` formatting).
- **P5kk DONE: `s_serv.c` informational stub cluster** (`m_users` + the file‑static `send_users` + `m_summon` + `m_help`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). Third s_serv.c sub‑phase; three leaf handlers with no file‑static of their own. Config‑resolved: `USERS_RFC1459` off → `m_users` forwards (`parc>1`) then calls `send_users` (`265`/`266`); `ENABLE_SUMMON` off → `m_summon` → `445`; `m_help` lists `msgtab[].cmd` as NOTICEs. **`send_users` is `static` in C but has a *remaining* C caller** (the still‑C `m_lusers`, s_serv.c:2386) → the **P5u/P5x extern‑prototype switch** on its forward decl (s_serv.c:52) so that caller resolves to the `#[no_mangle]` Rust def. **No L1** (pure wire handlers; `send_users` has no `cref_` oracle — GCC inlined it as `.isra.0`). L2 `golden_s_serv_stubs` (USERS `265`/`266` + SUMMON `445` + HELP NOTICE list anchored on the final `:ETRACE`) + **S2S `golden_s2s_s_serv_stubs`** (the `hunt_server` forwarding short‑circuit: `USERS peer.test` / `SUMMON nobody peer.test` → the peer receives the forwarded command; `m_help` has no forward path → not in the S2S scenario).
- **P5ll DONE: `s_serv.c` LUSERS handler** (`m_lusers`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). Fourth s_serv.c sub‑phase; a single leaf handler with no file‑static of its own (plain `#ifndef` guard) that **closes the P5kk `send_users` loop** — its `all`‑path tail `if (all) send_users(...)` already resolves to the Rust `send_users`. Config‑resolved (`USERS_RFC1459` off): bare/`*` `LUSERS` reads `istat` (the `all` path → 251/254/255 then 265/266 via `send_users`); `LUSERS <server>` resolves a remote `find_client`→`IsServer`→`usercnt[]`; `LUSERS <mask>` walks `svrtop`/`svctop` summing remote `usercnt[]`; `parc>2` forwards via `hunt_server`. New `is_server`/`is_me` one‑line status helpers. Faithfulness: `int` locals stay `c_int` (C's `u_long`→`int` truncation = `as c_int`), `istat.is_chan` passed straight to the `%d` variadic as `u_long` (byte‑identical, cf. `send_users`), and the **253 RPL_LUSERUNKNOWN uses `parv0` not `BadTo(parv0)`** quirk ported literally. **Classification: handler cluster, no L1** (pure wire handler, the lookups are read‑only counting terminating in `sendto_one`). L2 `golden_s_serv_lusers` (bare LUSERS → 251/254/255 + the `send_users` 265/266) + **S2S `golden_s2s_s_serv_lusers`** (two server‑reachable facets: the `svrtop` mask walk `LUSERS *.test` after a peer links — the 251 server count reflects the link + the `IsMe` 253 arm — diffed client‑side; and the `parc>2` `hunt_server` forward `LUSERS * peer.test` → the peer receives the forwarded command).
- **P5mm DONE: `s_serv.c` map‑display cluster** (`m_map` + the two recursive file‑statics `dump_map` [plain names] / `dump_map_sid` [names + usercount + SID + version]) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). Fifth s_serv.c sub‑phase; a handler + its two tree‑renderer statics, all under one plain `#ifndef` guard (the statics have no remaining C caller → private Rust `unsafe fn`s, no `cref_` oracle; `m_map`'s decl resolves via the parse.rs `msgtab` imports). The shared `buf[BUFSIZE]` → a module‑private `BUF` (filled+flushed in‑call → faithful, cf. P5aa/P5cc); the recursive tree walk over `serv->down`/`->right` accumulates the output line via raw pointer arithmetic (`pbuf + 4` per nesting, backward tree‑char cleanup), each leaf flushing the whole `buf` with `015 RPL_MAP`. `me` is `SetEOB`'d at boot → `dump_map_sid(&me)` always takes the deterministic non‑bursting branch. **Classification: handler cluster, no L1** (pure wire handlers; `m_map` has no `hunt_server` forward but `dump_map`/`dump_map_sid` format remote‑server fields → L2 + L2‑S2S). L2 `golden_s_serv_map` (`MAP` → 018/015/017 single‑server + `MAP s` → local usercount/SID/version) + **S2S `golden_s2s_s_serv_map`** (the multi‑server tree walk: bare `MAP` before/after the peer links — `: \`- peer.test` appears — then `MAP s` adds `: \`- peer.test 0 001B 0211030000`, the peer sent an `EOB` first so the non‑bursting branch is deterministic).
- **P5nn DONE: `s_serv.c` TRACE cluster** (`m_trace` + `m_etrace` + the file‑static `trace_one` + the internal‑linkage `count_servers_users`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). Sixth s_serv.c sub‑phase; a handler pair + their shared per‑client renderer. `trace_one` (file‑static, only callers `m_trace`×2 port here) → private Rust `unsafe fn`; `count_servers_users` (the `static` forward decl gives it internal linkage despite the non‑`static` def → GCC inlined it, no symbol) is still called by the C `report_myservers` → **extern‑prototype switch** (its forward decl flips `static`→`extern` under the guard so the C remnant resolves to the `#[no_mangle]` Rust def). HUB off → `count_servers_users` uses the `istat`‑only branch (`is_serv‑1`, `is_user[0]+is_user[1]‑is_myclnt`); XLINE off → `m_etrace`'s user2/user3 are the `"-","-"` literals; ENABLE_SIDTRACE off → `m_sidtrace` not compiled, not ported. The volatile `200 RPL_TRACELINK` uptime/sendQ ported faithfully but only diffed peer‑side (the forwarded command) in S2S. **Classification: handler cluster, 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), so it is L2‑S2S‑covered via the `206` servers/users it feeds (cf. P5jj `check_link`). L2 `golden_s_serv_trace` (bare TRACE → 205/262 plain client; OPER+ETRACE → 709/759 via new `trace_oper.conf` `t`/ACL_TRACE oper) + **S2S `golden_s2s_s_serv_trace`** (bare TRACE after a peer links → `206 RPL_TRACESERVER` from `trace_one`+`count_servers_users` with the remote `serv->version`/`by`/`user` fields; `TRACE peer.test` → the `IsServer` passthru forwards the command, diffed peer‑side).
- **P5oo DONE: `s_serv.c` STATS / reporting cluster** (`m_stats` + the five file‑static reporters `report_myservers`/`report_configured_links`/`report_ping`/`report_fd`/`report_listeners` + the `report_array[18][3]` table) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). Seventh s_serv.c sub‑phase; **completes the cluster‑map "Stats / reporting" component** (its siblings `trace_one`/`check_link`/`count_servers_users` already ported P5jj/P5nn). All five reporters are file‑`static` with `m_stats` as their only caller → **private Rust `unsafe fn`s** (no extern‑switch, no `cref_` oracle); `report_array` is a module‑private static reproduced **resolved to TKLINE‑on** (the two `CONF_T*KILL` rows present, the `*p`/`p+=3` row walk preserved); `m_stats` is a plain `#ifndef` guard (its decl resolves via the parse.rs `msgtab` imports). XLINE off → `report_x_lines` not compiled. Faithful: the full selector `switch`, the `IsServer(cptr)` check_link rate‑limit head, both `hunt_server` `parc==3`/`parc>=3` forms, the `report_configured_links` K/V/H/Q‑passwd‑shown + TKLINE `hold‑timeofday` + CLIENT/OPERATOR `iline`/`oline_flags` branches, the `STATS m` msgtab command‑frequency loop; `report_ping`/`report_fd` use the module `BUF`/`ipv6string` as in‑call scratch (cf. dump_map P5mm). **Classification: handler cluster, no L1** (pure wire reporters terminating in `sendto_one`; `report_array` is config‑gated data with no oracle). L2 `golden_s_serv_stats` (STATS i `215`/o `243` via `report_configured_links` over oper.conf's I/O lines, y `218` via `report_classes`, m `212` the msgtab loop — each closing `219`; volatile selectors l/L/P/f/F/?/u review/mask‑covered) + **S2S `golden_s2s_s_serv_stats`** (`report_myservers` — `STATS ?` after a peer links → `249 RPL_STATSDEBUG` with the peer name/`1S 0C`/byte counts/BURST/`%X` version, diffed in full bar the masked `(timeconnected)` real‑clock token; the `hunt_server` forward `STATS m peer.test` → the peer receives the forwarded command).
- **P5pp DONE: `s_serv.c` `m_motd` handler** (the MOTD command — `check_link` rate‑limit + `hunt_server` forward, then the `motd`‑list reply: 375/372 + the `localtime(&motd_mtime)` date line/376, or 422 when `motd==NULL`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). Eighth s_serv.c sub‑phase; a **leaf handler** with no file‑static of its own → a plain `#ifndef` guard (its decl resolves via the parse.rs `msgtab` imports). Every callee already resolves: `check_link` (Rust P5jj), `hunt_server`/`sendto_one` (C externs), `reply()` (P3), the `motd`/`motd_mtime` globals (bindgen statics), `localtime`/`tm` (libc). **Classification: handler cluster, no L1** (pure wire handler terminating in `sendto_one`). L2 `golden_s_serv_motd` (MOTD → `422 ERR_NOMOTD` under the no‑MOTD‑file test config — the realistic local path; the listing + date line are review‑covered, wall‑clock data from the file mtime) + **S2S `golden_s2s_s_serv_motd`** (the `hunt_server` forwarding short‑circuit: `MOTD peer.test` → the peer receives the forwarded command, byte‑identical).
- **P5qq DONE: `s_serv.c` server‑registration data‑structure cluster** (`find_server_string`/`find_server_num` [the `server_name[]` string‑interning pair], `add_server_to_tree`/`remove_server_from_tree` [the `aServer`‑tree pointer rewiring], `check_servername`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Ninth `s_serv.c` sub‑phase** — the first s_serv.c **utility/callee** cluster (no `msgtab` row; pure data ops, no socket/wire). The `server_name`/`server_max`/`server_num` file‑statics → module‑private Rust `static mut`; `check_servername_errors[3][2]` **stays C** (the s_serv_ext.h decl is a tentative definition under `EXTERN`‑empty → a Rust `#[no_mangle]` strong def would collide with the C BSS symbol, and `check_servername` never reads the table — only its callers index it; ported when `s_serv.o` is dropped). All five take a plain `#ifndef PORT_SERV_P5` guard (every caller stays C — `m_server`/`m_server_estab` s_serv.c, `exit_server` s_misc.c, boot ircd.c, `register_user` s_user.c — and resolves to the Rust defs at link). **Classification: utility/callee TU → L1 is the gate** (`s_serv_servtree_diff`: `server_name[]` interning round‑trip incl. the `MyRealloc`/`server_max+=50` growth boundary + the no‑duplicate‑slot re‑intern inverse; the `aServer`‑tree add/remove/re‑add with the leaf **and** head unlink inverses + the `servers` count; `check_servername` rc corpus + the exported error table — all zero‑diff vs `cref_`). **No new L2/S2S** — none has an `IsServer(cptr)` dispatch branch of its own (they are unconditional callees of the still‑C link handler); every symbol runs on the existing 13 `golden_s2s_*` peer‑link/SQUIT scenarios (link → `find_server_num`+`add_server_to_tree`+`check_servername`; remote users → `find_server_string`; SQUIT → `remove_server_from_tree`), which stay byte‑identical as the regression gate.
- **P5rr DONE: `s_serv.c` oper‑maintenance cluster** (`m_close` + `m_rehash`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Tenth `s_serv.c` sub‑phase** — two leaf oper handlers with no file‑static of their own (plain `#ifndef` guards; their `msgtab` decls resolve to the Rust defs at link). Config‑resolved: **DELAY_CLOSE on** → `m_close`’s trailing `is_delayclosewait`/`delay_close(-2)` block ported; **USE_SYSLOG off** → `m_rehash`’s `syslog()` line not compiled/ported. Faithful: the `for(i=highest_fd;i;i--)` walk never touches `local[0]`, `RPL_CLOSING` carries `acptr->status` as the `%d` arg, `exit_client(..,&me,..)` (P5c) closes each UNKNOWN/CONNECTING/HANDSHAKE fd, `m_rehash` returns `rehash(cptr,sptr, parc>1?parv[1][0]:0)` (C extern). **Classification: handler cluster** (dispatch col 2/STAT_OPER only — a non‑oper client hits the col‑1 `m_nopriv`/481 at the parse table), **no L1** (pure wire handlers terminating in `sendto_one`/`sendto_flag`, no socket‑free data op), **no S2S** (neither has an `IsServer(cptr)` dispatch branch nor formats remote‑user fields). L1: none. L2 `golden_s_serv_maint` (success via the new `maint_oper.conf` O‑line flags `lr`: REHASH → 382 RPL_REHASHING, CLOSE → 363 RPL_CLOSEEND; **inverse** via `oper.conf` no‑flags: the handler‑internal `is_allowed` reject → 481).
- **P5ss DONE: `s_serv.c` end‑of‑burst cluster** (`m_eob` + `m_eoback`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Eleventh `s_serv.c` sub‑phase** — the thematic end‑of‑burst pair: a linked server's `EOB` (burst complete) + the `EOBACK` ack. Both **server‑only** (`msgtab` col 0 — a local client/oper hits `m_nop`; `m_eob`'s first guard is `IsServer(sptr)`) with no file‑static of their own (`m_eob`'s `eobbuf[BUFSIZE]` is a function‑local stack scratch → a Rust `let mut` array, not a module static) → plain `#ifndef` guards; their `msgtab` decls resolve to the Rust defs at link. Every callee already resolves: `strtoken` (P1), `find_sid` (P4), `exit_client`/`check_split` (P5c), `istat` (P2), the C variadic `sendto_one`/`sendto_flag`/`sendto_serv_v(SV_UID)`; `SetEOB` is a new inline flag helper. Faithful: the `IsBursting(sptr)` branch (MyConnect → wall‑clock "after %d seconds" SCH_NOTICE / remote → un‑masked "End of burst" notice), `SetEOB`+`is_eobservers++`, the hopcount‑1 `:000A EOBACK` reply, the `parc<2` bare‑EOB `sendto_serv_v` propagation, the `parc≥2` mass‑SID `strtoken`/`find_sid` loop (unknown‑SID/wrong‑direction → `exit_client` link drop; the `eobbuf` comma‑SID builder + `eobmaxlen` flush via raw‑pointer walk + `memcpy`), then `check_split`; `m_eoback` clears `FLAGS_CBURST`+`byuid[0]`. **Classification: handler cluster, server‑reachable → L2‑S2S is the only gate** (no L1 — pure server‑protocol handlers with no socket‑free `cref_` oracle; no plain L2 — a local client can't present a STAT_SERVER prefix; cf. m_njoin P5ee). L2‑S2S `golden_s2s_eob` (a bursting peer's `EOB` → `:000A EOBACK` reply on the peer socket; **inverse** — a second EOB now finds `!IsBursting` → no reply, proving SetEOB changed state; `m_eoback` → link survives a follow‑up remote introduce+WHOIS) + `golden_s2s_s_serv_map` (which drives a peer EOB) the regression. The mass‑SID multi‑server loop is review‑covered (the single‑peer harness reaches only the directly‑linked bare‑EOB path).
- **P5tt DONE: `s_serv.c` `m_set` handler** (the SET oper command — read/change the runtime tunables POOLSIZE/ACONNECT/CACCEPT, echoing each value back as a NOTICE) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Twelfth `s_serv.c` sub‑phase** — a single leaf oper handler with no file‑static of its own (plain `#ifndef` guard; its `msgtab` decl resolves to the Rust def at link). Config‑resolved: `set_table[]` is unconditional (POOLSIZE/ACONNECT/CACCEPT); `TSET_SHOWALL` = `(int)~0` = ‑1 (bindgen drops the cast macro → baked as `const TSET_SHOWALL: c_int = -1`, all bits set so the no‑arg form's three `acmd & TSET_*` echoes all fire). Faithful: the C `switch`/`break`‑to‑bottom‑echo control flow refactored into a `set_finish` helper (the two "Illegal value" arms `break` out of the switch straight to the trailing `if(acmd)` echo block → ported as an early `return set_finish(...)`, acmd unchanged so the echo still fires); `poolsize > tmp` keeps the C signed→unsigned promotion (`tmp as c_uint`); `poolsize`/`tmp` passed to `%d` width‑matched (`as c_int`). **Classification: handler cluster** (dispatch col 2/STAT_OPER — a non‑oper client hits the col‑1 `m_nopriv`/481 at the parse table; the body re‑gates on `is_allowed(ACL_SET)`), **no L1** (pure wire handler terminating in `sendto_one`/`sendto_flag`, no socket‑free data op), **no S2S** (no `IsServer(cptr)` dispatch branch, no remote‑user fields — reads/writes local tunables only). L2 `golden_s_serv_set` (new `set_oper.conf` O‑line flag `e` = ACL_SET → no‑arg SET showall POOLSIZE/ACONNECT/CACCEPT echoes, `SET ACONNECT OFF` apply+echo, `SET BOGUS` → "Invalid option BOGUS" with **no** trailing echo [acmd stays 0, the inverse of a hit]; the `oper.conf` no‑flags **inverse** → handler‑internal is_allowed reject → 481).
- **P5uu DONE: `s_serv.c` `m_wallops` handler** (the WALLOPS broadcast — relay an operwall to every other server [origin link excluded] + emit the `!from!` framing to local `&WALLOPS` watchers via `sendto_flag(SCH_WALLOP)`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Thirteenth `s_serv.c` sub‑phase** — a leaf server‑only handler (msgtab `WALLOPS`=`[m_wallops, m_nop, m_nop, m_nop, m_unreg]` → col 0/STAT_SERVER only; a local client/oper hits `m_nop`) with no file‑static of its own → a plain `#ifndef` guard; its `msgtab` decl resolves to the Rust def at link. The whole body is `sendto_ops_butone(IsServer(cptr)?cptr:NULL, parv[0], "%s", parv[1])` (the C variadic imported from bindings, P8); USE_SERVICES off → the `check_services_butone` block not compiled (sptr/parc unused). **Classification: handler cluster, server‑reachable → L2‑S2S the only gate** (no L1 — pure wire handler terminating in the variadic; no plain L2 — a local client can't present a STAT_SERVER prefix). L2‑S2S `golden_s2s_wallops` (a peer `:001B WALLOPS` → a local `&WALLOPS` member receives `:irc.test NOTICE &WALLOPS :!peer.test! …`; **inverse 1** a non‑member gets nothing [PING‑fenced]; **inverse 2** the originating peer does *not* get its own WALLOPS echoed back [PRIVMSG‑to‑remote fenced] — proving the `IsServer(cptr)?cptr:NULL` origin‑link exclusion).
- **P5vv DONE: `s_serv.c` `m_error` handler** (the server‑protocol ERROR message — pass an error received over a server link on to local `&ERRORS` watchers via `sendto_flag(SCH_ERROR)`) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Fourteenth `s_serv.c` sub‑phase** — a leaf server‑only handler (msgtab `ERROR`=`[m_error, m_nop, m_nop, m_nop, m_unreg]` → col 0/STAT_SERVER only; a registered client hits `m_nop`, an unregistered connection `m_unreg`) with no file‑static of its own → a plain `#ifndef` guard; its `msgtab` decl resolves to the Rust def at link. Faithful: `para = (parc>1 && *parv[1]) ? parv[1] : "<>"`; the reachable server branch emits `:irc.test NOTICE &ERRORS :from %s -- %s` (cptr==sptr, `get_client_name(cptr,FALSE)`) / `from %s via %s -- %s` (the "via" form) via the C variadic `sendto_flag` (P8); returns 2 (not FLUSH_BUFFER → link survives). DEBUGMODE off → the `Debug()` line not compiled; the `IsPerson||IsUnknown||IsService → return 2` ignore guard ported for faithfulness but unreachable via the col‑0‑only dispatch. New private `is_service` helper. **Classification: handler cluster, server‑reachable → L2‑S2S the only gate** (no L1 — pure wire handler terminating in the variadic; no plain L2 — a local client can't present a STAT_SERVER prefix). L2‑S2S `golden_s2s_error` (a peer `:001B ERROR :the disk is full` → a local oper `&ERRORS` member receives `:irc.test NOTICE &ERRORS :from peer.test -- the disk is full`; **inverse** a non‑member gets nothing [PING‑fenced]). The boot‑created `&ERRORS` channel is +i (`can_join` admits only opers, channel.c:2091) → new `s2s_oper.conf` fixture (s2s.conf + an O‑line) and alice OPERs before subscribing; the `cptr != sptr` "via" form (needs a server introduced behind the peer) review‑covered.
- **P5ww DONE: `s_serv.c` server network‑registration cluster** (`register_server` + `unregister_server` — head‑insert / unlink a server's `aServer` on the global `svrtop` doubly‑linked list, called whenever a server (re)associates or loses its client struct) via the same `s_serv_link.o` partial port (`‑DPORT_SERV_P5`). **Fifteenth `s_serv.c` sub‑phase** — the first pure **utility/callee** s_serv.c cluster since P5qq (no `msgtab` row, no socket, no wire); two `EXTERN` intrusive‑list ops under one plain `#ifndef` guard (no extern‑prototype switch — every caller stays C and resolves to the Rust def: boot `ircd.c`, link estab `m_server`/`m_server_estab`, `exit_one_client`). Faithful raw‑pointer rewiring (head‑insert via `svrtop->prevs`/`cptr->serv->nexts`; splice‑out relink + `svrtop` advance, then clear `prevs`/`nexts`/`bcptr`). **Classification: utility/callee → L1 the gate, no new L2/S2S** (no `IsServer(cptr)` branch — unconditional callee of the still‑C link handler / exit cascade). L1 `s_serv_register_diff` (register A/B/C head‑insert → `[C,B,A]` + full `nexts`/`prevs` cross‑links; **inverses** unregister middle/head/sole node → relink + `nexts`/`prevs`/`bcptr` cleared, `svrtop` advance/empty; re‑register → clean `[C,A]` round‑trip — zero‑diff vs `cref_`). Regression: `golden_s2s_link` (register_server) / `golden_s2s_squit` (unregister_server) stay byte‑identical.
=== ls ===
docs/progress-log/p5.md
PLAN-P5-progress.md
