- **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.
- **P5xx DONE: `s_serv.c` operator CONNECT cluster** (`m_connect` — the oper command to force a server link) via the same `s_serv_link.o` partial port (`-DPORT_SERV_P5`). **Sixteenth `s_serv.c` sub-phase.** A `msgtab` handler row `CONNECT { m_nop, m_nopriv, m_connect, m_nop, m_unreg }` — col 2 (STAT_OPER) only: a plain client hits `m_nopriv` (481) at the parse table. Self-contained handler (no file-statics shared with other clusters; only a local port var), so dropped via a fresh `#ifndef PORT_SERV_P5` guard with no extern-prototype switch (every caller already resolves to the Rust def at link). Faithful port: `is_allowed(sptr, parc>3 ? ACL_CONNECTREMOTE : ACL_CONNECTLOCAL)` gate → `m_nopriv`; `BOOT_STANDALONE` short-circuit; `hunt_server` HUNTED_ISME routing; `find_name`/`find_mask` "already exists"; the two-pass `conf` walk (server names, then `user@host` hostnames via `index(host,'@')+1` — replicated with `strchr(...).wrapping_add(1)` to mirror C's NULL+1 when there is no `@`); port resolution (`atoi`/`abs`); the `!IsAnOper(cptr)` "Remote CONNECT … from …" ops notice; and the `connect_server` retval switch (0/-1/-2/default with `strerror`). `USE_SYSLOG`/`SYSLOG_CONNECT` off → the syslog line not compiled. New libc externs `abs`/`strerror`; the local `me_name()` binding renamed `myname` (can't shadow the static `me`). **Classification: handler cluster with a server-reachable path → L1 N/A (needs a live server/socket; no pure data op), L2 + L2-S2S the gates.** L2 `golden_s_serv_connect` (local opered client): new `connect_oper.conf` fixture (O-line flags `C` = ACL_CONNECT) → `CONNECT nosuch.invalid` → `NOTICE alice :Connect: Host nosuch.invalid not listed in ircd.conf` (no `connect_server` call); **inverse** via plain `oper.conf` (no flags) → handler-internal `is_allowed` reject → 481 — both byte-identical vs reference-C. L2-S2S `golden_s2s_s_serv_connect` (`boot_s2s` + `Peer`): a remote oper (`+o` → STAT_OPER) behind the peer issues a remote-form `CONNECT nosuch.invalid 0 irc.test` → reaches `m_connect` over the server link (`IsServer(cptr)` true) → the "not listed" reply routes back out the peer; **inverse** a plain remote client (col 1 → `m_nopriv` at parse) produces no such notice — both byte-identical. **The `!IsAnOper(cptr)` ops notice + `connect_server` tail run only once a real C-line matches (a live outbound socket) → no deterministic golden form; faithful C-call passthroughs covered by review.** Regression: `golden_s2s_link` / `golden_s2s_squit` / `golden_s_serv_maint` stay byte-identical; workspace builds 0 warnings.
- **P5yy DONE: `s_serv.c` `m_squit` handler** (the SQUIT command — remove a server from the network) via the `s_serv_link.o` partial port (`-DPORT_SERV_P5`). A **self-contained** cluster: its only module-local state is the function-local `static char comment2[TOPICLEN+1]` (private scratch → a module-private `static mut COMMENT2`, not ABI); it touches none of the server-introduction file-statics (`introduce_server`/`send_server`/`get_version`), so it ports cleanly without dragging in the big server cluster. Every callee is already Rust (`is_allowed` P5o, `exit_client` P5c, `find_sid`/`find_server`/`next_client` P2, `m_nopriv` P4, `replies[]` P3) or a C extern (`get_client_name`/`my_name_for_link`/`mycmp`, the variadic `sendto_one`/`sendto_ops_butone`/`sendto_flag` trampolines). Config-resolved: the `#if defined(USE_SYSLOG) && defined(SYSLOG_SQUIT)` line is out (`USE_SYSLOG` `#undef`); a local oper reaches `m_squit` (col 2) only because `OPER_SQUIT`+`OPER_SQUIT_REMOTE` are defined and the O-line carries flag letter `S` (→ ACL_SQUIT). L2 `golden_s_serv_squit` (local oper: `SQUIT irc.test` → "you cannot SQUIT me" notice + `SQUIT nosuch.invalid` → 402; inverse no-flag oper → handler-internal 481, no 402) + **S2S `golden_s2s_s_serv_squit`** (remote oper's `SQUIT nosuch.invalid` → 402 routed back out the peer link; inverse plain remote client → no 402, proving col-2 prefix-is-oper gating). The `exit_client` link-teardown tail stays faithful passthrough, covered by the existing `golden_s2s_squit` peer-EOF netsplit net.
- **P5zz DONE: `s_serv.c` oper-shutdown cluster** (`m_die` + `m_restart`) — the leaf oper shutdown/restart pair (analogue of P5rr's m_close/m_rehash) via the `s_serv_link.o` partial port (`-DPORT_SERV_P5`); plain `#ifndef` guards, no extern-switch. `m_die` uses a local `killer[]`; `m_restart`'s file-static `buf` was in-call scratch → a module-private `RESTARTBUF` (the still-C `check_version`/`m_server_estab` keep the C `buf`). Both re-gate `is_allowed(ACL_DIE/ACL_RESTART)` → `m_nopriv`/481. **L2 gate = the non-destructive reject** (`golden_s_serv_shutdown`: flag-less oper DIE/RESTART → 481 byte-identical); the notice-loop + terminal `s_die(0)`/`restart(buf)` are destructive → review-covered; **no S2S** (no `IsServer(cptr)` branch, no remote-user fields).
- **P5aaa DONE: `s_serv.c` ENCAP/SDIE server-broadcast stub cluster** (`m_encap` + `m_sdie`) via the `s_serv_link.o` partial port (`-DPORT_SERV_P5`) — two server-only leaf handlers (msgtab col 0) that rebuild + `sendto_serv_v(cptr, SV_UID, …)`-propagate a line to every *other* server (origin link excluded); plain `#ifndef` guards, no file-static. **No L1** (pure wire/broadcast, no socket-free data op), **L2-S2S the only gate** (`golden_s2s_encap`: a peer's `:001B ENCAP …`/`:001B SDIE` is NOT echoed back to its origin link + the link survives a follow-up routed PRIVMSG fence — byte-identical ref-C vs Rust). The forward-to-an-additional-server arm needs a 2nd direct peer link the harness lacks → review-covered.
- **P5bbb DONE: `s_serv.c` server‑introduction / link‑establishment / burst cluster** (`m_server` + `m_server_estab` + `m_smask` + `check_version`/`get_version` + `send_server`/`introduce_server`/`send_server_burst` + the `check_servername_errors[3][2]` table) — the **final `s_serv.c` sub‑phase**, so **`s_serv.o` is now dropped outright** (added to `PORTED`; the P5ii…P5aaa `s_serv_link.o` second‑compile + `‑DPORT_SERV_P5` removed; the cref oracle keeps the unguarded `s_serv.o`). **`s_serv.c` is now FULLY ported to Rust.** Config‑resolved (all OFF): USE_SERVICES (no `check_services_butone`), ZIP_LINKS (no `zip_init`/FLAGS_ZIP arms — `encr = cptr->passwd`), JAPANESE, CRYPT_LINK_PASSWORD, HUB (the `#ifndef HUB` leaf‑check IS compiled), USE_SYSLOG. `check_servername_errors` (kept C through P5qq to avoid a BSS‑symbol collision) is now a `#[no_mangle] pub static mut` (raw‑pointer table → the `replies[]`‑in‑s_err.rs pattern) since the C def is gone and `ircd.c:1056` reads it. **Classification: handler cluster, server‑reachable.** **L1** (`s_serv_version_diff`): `check_version` (transitively `get_version`) vs `cref_` on parallel `make_client`'d clients with empty conf — the `0210`‑beta `991199`/`991200` boundary, the `021x` fast‑path, else→`SV_OLD`, the in‑place `info` split, the `Z`→`FLAGS_ZIPRQ` flag (with a `P` flag so the faithful `BOOT_STRICTPROT` "Unsafe mode" exit isn't taken — `bootopt` defaults to `BOOT_PROT|BOOT_STRICTPROT`, ircd.c:47), and the `DefInfo` early‑return — the only gate on the version branches the fixed‑`PEER_VERSION` S2S harness can't reach. **L2‑S2S**: the **entire existing 37‑test `golden_s2s_*` suite is the regression gate** — every test's `Peer::link()` PASS/SERVER handshake drives `m_server`(local)→`check_version`→`m_server_estab`→`send_server_burst`→EOB, and `golden_s2s_reject` drives `m_server`'s reject path; all byte‑identical (the lone `golden_s2s_s_serv_stats` red is the documented pre‑existing reference‑C uninitialized‑sendq flake, not a regression). New **`golden_s2s_server`** covers the gap — `m_server`'s `IsServer(cptr)` remote‑server‑introduction branch (a peer `:001B SERVER sub.test 1 002C …` → remote `aServer` creation + `introduce_server`, observed via `LINKS`). The server‑removal inverse + `m_smask` + multi‑server `send_server`/`introduce_server` are review/`golden_s2s_squit`‑covered (the single‑peer harness can't host a fully‑formed sub‑server — SQUITting one **segfaults even reference‑C**).
- **P5ccc DONE: `s_user.c` `hunt_server` / `next_client` cluster (final s_user.c)** — the two network-routing callees (resolve a command's target-server arg → forward/handle-locally/402; find the next list client matching a wild mask) ported → **`s_user.o` dropped outright** (removed `s_user_link.o` second-compile + `-DPORT_USER_P5`; `s_user.c` now fully Rust, only `s_auth.c` left in C among P5 TUs). L1 `s_user_hunt_diff` (next_client exact/wildcard/continuation/inverse-NULL walk on parallel client lists+hash; hunt_server ISME/PASS/NOSUCH verdicts + parv[server] rewrite + forwarded-line/error sendQ bytes vs `cref_`) + **S2S `golden_s2s_hunt`** (VERSION → ISME 351 local / PASS `:src VERSION :peer.test` at peer / next_client `peer.*` wildcard forward / NOSUCH 402; the whole `golden_s2s_*` suite is the de-facto regression gate since it routes via hunt_server).
- **P5whowas DONE: `whowas.c` `m_whowas` handler (P2‑deferred → now ported, whowas.o dropped)** — the WHOWAS command handler (the last C remnant kept behind `whowas_link.o`/`-DPORT_WHOWAS_P2` since the P2 ring port) is ported into `ircd-common/whowas.rs` alongside the ring machinery → **`whowas.o` added to PORTED and dropped outright** (the P2c `whowas_link.o` second‑compile removed; the cref oracle keeps the full unguarded `whowas.o` for the L1 `whowas_diff`). Every callee already resolves: `canonize` (P5m), `hunt_server` (P5ccc), `strtoken`/`mycmp`/`myctime` (P1), `replies[]` (P3), `was`/`ww_index`/`ww_size` (P2, Rust‑owned), the C variadic `sendto_one` + libc `atoi`. Faithful: the do‑while ring walk from `(ww_index?ww_index:ww_size)-1`, the per‑token `up` reset, the `j>=max` early break, the `!MyConnect(sptr)` cap of 20, the NICKLEN truncation on the not‑found path. **Classification: handler cluster, server‑reachable** (formats `up->server` remote‑user field + `hunt_server` forward) → no L1 (pure wire handler; the ring is already L1'd by `whowas_diff`), **L2 + L2‑S2S the gates**. L2 `golden_whowas` (alice QUIT → bob WHOWAS alice → 314/312/369 found path + `max 1` early break + unknown‑nick 406 inverse; 312 ctime masked locally) + **S2S `golden_s2s_whowas`** (remote rmuser QUIT → local WHOWAS renders 312 with `peer.test`; `WHOWAS ghost 1 peer.test` → `hunt_server` forwards peer‑side). `golden_s_user_canonize` (the 406/369 dedup path) now drives the Rust `m_whowas` as a regression.
=== p5.md tail ===
  - **Classification** — handler cluster, both **server-only** (msgtab `ENCAP { m_encap, m_nop, m_nop, m_nop, m_nop }`, `SDIE { m_sdie, m_nop, m_nop, m_nop, m_unreg }` → col 0 only; a local client/oper hits `m_nop`). **No L1** (pure wire/broadcast handlers, no socket-free `cref_` data op), **no plain L2** (a local client can't present a STAT_SERVER prefix). **L2-S2S is the only gate.**
  - **L2-S2S** `golden_s2s_encap` — a peer's `:001B ENCAP *.test SOMECMD arg1 :trailing arg` then `:001B SDIE`; the **inverse** gate (`sendto_serv_v(cptr=peer, …)` excludes the origin link → the peer must NOT receive either command echoed back) + a follow-up `PRIVMSG bob` routing fence (proves both handlers returned 0/cleanly and the link survives). Byte-identical ref-C vs Rust on the peer transcript. **The forward-to-an-*additional*-server arm and `m_encap`'s SCH_ERROR over-length path are review-covered** — the single-peer harness has no second *direct* server link to receive the `butone` broadcast (SID `001B` is hardcoded to `fixtures/s2s.conf`), and the 512-capped reader can't deterministically overflow `BUFSIZE-2` in the rebuilt buffer. Regression: `golden_s2s_link`/`golden_s2s_squit`/`golden_s2s_eob` stay byte-identical; workspace builds 0 warnings.

- **2026‑06‑04 — P5bbb (s_serv.c server‑introduction / link‑establishment / burst — FINAL s_serv.c cluster) merged.** `s_serv.c` is now fully Rust; `s_serv.o` dropped outright.
  - **Cluster choice** — the connected component left in `s_serv_link.o`: `m_server` (the SERVER command), `m_server_estab` (the ~530‑line local‑link accept + full network burst), `m_smask` (masked‑server introduction), `check_version`/`get_version` (the PASS‑staged version classifier), and the burst emitters `send_server`/`introduce_server`/`send_server_burst` — plus the `check_servername_errors[3][2]` string table that P5qq deliberately kept C (a `#[no_mangle]` strong def would have collided with the C BSS symbol while `s_serv.o` was still linked).
  - **Drop mechanism** — every symbol `s_serv.c` defines now lives in `ircd-common/src/s_serv.rs`, so `s_serv.o` is added to `PORTED` and dropped from the link set outright (mirroring P5hh's channel.o drop): the P5ii…P5aaa `s_serv_link.o` second‑compile (`‑DPORT_SERV_P5`, which also carried `‑DIRCDMOTD_PATH` for the then‑still‑C `m_motd`) and the `s_serv.o`→`s_serv_link.o` link‑set mapping are removed; the cref oracle keeps the unguarded `s_serv.o` for differential testing.
  - **Config‑resolved bodies** — USE_SERVICES off (the `check_services_butone` arms in `m_server`/`m_server_estab` not compiled); ZIP_LINKS off (the `zip_init`/`FLAGS_ZIP`/connect‑burst‑stats arms gone; `encr = cptr->passwd` directly); JAPANESE off (no `FLAGS_JP`); CRYPT_LINK_PASSWORD off (no `crypt()` link‑password); `#ifndef HUB` IS compiled (a leaf refuses a second server link); USE_SYSLOG off. `check_servername_errors` is reproduced as a `#[no_mangle] pub static mut [[*const c_char; 2]; 3]` (a `static` of raw pointers isn't `Sync` → the `replies[]`‑in‑s_err.rs pattern) because `ircd.c:1056` reads `[i‑1][1]` for its fatal‑error message.
  - **Faithfulness notes** — the in‑place `cptr->info` split in `check_version` (`*id++ = '\0'` chains) ported via raw‑pointer writes; the `get_version` `0210`/`021`/else classification kept exact (`id` arg unused, retained for signature fidelity); `set_server`/`strncpyzt`/`str_eq`(StrEq)/`TIMESEC=60` helpers added; the `m_server_estab` EOB‑list builder (raw‑pointer `eobbuf` walk + `memcpy` of each `aServer.sid`) and the client/service UNICK/SERVICE burst loop (`for acptr=&me; acptr; acptr=acptr->prev`) ported faithfully; the dead `SV_OLD` (`==0`) remote‑too‑old branch kept including the C string‑concat typo `"%s is"`+`"too"`→`"%s istoo"`.
  - **Classification** — handler cluster, server‑reachable. **L1** is `s_serv_version_diff` (the only socket‑free data op with a `cref_` oracle: `check_version` + transitively `get_version`); the five statics + the three handlers terminate in sockets/exit cascade → no L1.
  - **L1** — `s_serv_version_diff.rs`: `check_version` vs `cref_check_version` on parallel `make_client`'d clients with an empty conf (so `find_two_masks`/`find_conf_flags` return 0 → the happy path, no `exit_client`). Corpus covers the `0210`‑beta `991199` (old) vs `991200` (ok) boundary, the `021x` fast‑path, else→`SV_OLD`, the in‑place `info` truncation, and the `Z`→`FLAGS_ZIPRQ` flag (with a `P` flag so the faithful `BOOT_STRICTPROT` "Unsafe mode" exit — `bootopt` defaults to `BOOT_PROT|BOOT_STRICTPROT` — isn't taken, keeping it a clean data op) + the `DefInfo` pointer‑identity early‑return. Zero diff. This is the *only* gate on the version branches: the live S2S harness only links with the fixed `PEER_VERSION` `0211030000` (one `get_version` branch).
  - **L2‑S2S** — the headline gate is the **whole existing 37‑test `golden_s2s_*` suite**: every test's `Peer::link()` PASS/SERVER handshake drives `m_server`(local IsUnknown→handshake)→`check_version`→`m_server_estab` (N/C conf + password validation, `det_confs_butmask`, hash/tree/`svrtop` registration, `add_fd`, the server/client/service/channel burst, the EOB list)→`send_server_burst`→EOB, so none can pass unless the handshake is byte‑exact; `golden_s2s_reject` drives `m_server`'s unauthorized‑link reject. All byte‑identical (the lone `golden_s2s_s_serv_stats` failure is the documented pre‑existing reference‑C uninitialized peer‑burst‑sendq flake — `…3544950458613235712kB sq` left vs Rust's correct `0kB sq` — not a regression). New **`golden_s2s_server.rs`** closes the gap the user‑only UNICK introduce can't: `m_server`'s `IsServer(cptr)` **remote‑server‑introduction** branch — a peer `:001B SERVER sub.test 1 002C 0211030000 :Sub Server` (the `H|*||peer.test|1|` hub line admits it at hop 1) → `make_client`/`make_server`, the L/H/Q‑line gating, the remote `aServer` creation, `add_server_to_tree` + SID/client‑hash registration, `introduce_server` — observed via `LINKS` (the new server's `up`/`sid`/`info` formatted by `m_links`), byte‑identical ref‑C vs Rust.
  - **S2S inverse / no‑path note** — the server‑removal inverse, `m_smask`, and the multi‑server `send_server`/`introduce_server` paths are **review/`golden_s2s_squit`‑covered**: the minimal single‑peer harness can only half‑form a sub‑server (the fake peer never completes a burst/EOB for it), and SQUITting such a sub‑server **segfaults even the reference‑C ircd** — so `remove_server_from_tree` stays covered byte‑for‑byte by `golden_s2s_squit.rs` (a peer‑EOF netsplit), and `send_server`'s SMASK/SERVER multi‑link output needs ≥2 concurrent peer links the harness lacks (mirrors the P5ss mass‑SID / P5qq multi‑server review‑coverage precedent).

- **2026-06-04 — P5ccc (`s_user.c` `hunt_server` / `next_client`, the final s_user.c cluster) merged.** `s_user.c` is now FULLY ported → `s_user.o` dropped outright; only `s_auth.c` remains C among the P5 TUs.
  - **Cluster choice** — the two routing callees left in `s_user_link.o` (`nm` showed only `hunt_server` + `next_client` still C): `next_client` (s_user.c:119) finds the next `client`-list entry matching a wild mask (exact-hash shortcut via `find_client` + wildcard `next->next` walk); `hunt_server` (s_user.c:155) resolves `parv[server]` (find_client→find_sid→find_server→find_service, each nulling a self-loop hit, then `collapse`+`next_client` wildcard walk), rewrites `parv[server]` to the matched server's real name, and `sendto_one`-forwards `command` (or 402s). Pure callees — **not** in `msgtab`; reached from m_who/m_whois (s_user), m_list/m_names (channel), m_version/m_info/m_links/m_stats/m_time/… (s_serv), m_whowas (whowas).
  - **Guard / Config** — both unguarded (always compiled, no `#ifdef`). Added `is_registered` (`status >= STAT_SERVER || == STAT_ME`) + `my_service` (`MyConnect && IsService`) inline helpers; imported `find_sid`/`find_service`/`client`. Faithful: the 9-slot `sendto_one(acptr, command, parv[0..8])` forward, the `IsService(sptr)` dist-vs-`acptr->serv->sid` reject arm, and the for-loop `continue`→increment semantics ported byte-for-byte.
  - **Build** — `s_user.o` added to `PORTED`; removed the `s_user.o → s_user_link.o` substitution in `link_objs()` and the `s_user_link.o` second-compile recipe (`-DPORT_USER_P5` + FNAME_USERLOG/CONNLOG/OPERLOG). The cref oracle keeps the full unguarded `s_user.o`.
  - **Classification** — utility/callee TUs (no `msgtab` row). L1 is the socket-free gate; L2-S2S covers the live `IsServer`/remote-link routing.
  - **L1** (`s_user_hunt_diff.rs`, zero-diff vs `cref_`) — `next_client`: parallel client lists (`add_client_to_list`) + client hash (`add_to_client_hash_table`) on each side's own globals (hash_diff pattern); exact-name hit, `alpha*` wildcard full enumeration, continuation past the first hit, and the **inverse** no-match→NULL. `hunt_server`: the send-free `HUNTED_ISME` fast-paths (parc≤server, BadPtr, match-ME), `HUNTED_PASS` (route to a directly-linked `peer.test` → return + parv[server] rewrite + the `:alice VERSION :peer.test\r\n` forwarded line buffered into the target sendQ, send_diff pattern), and `HUNTED_NOSUCH` (unknown target → 402 buffered to the source).
  - **S2S** (`golden_s2s_hunt.rs`, byte-identical) — VERSION drives all three verdicts: `VERSION` → ISME 351 local; `VERSION peer.test` → PASS `:<src> VERSION :peer.test` observed at the peer; `VERSION peer.*` → the `next_client` wildcard walk → same forward; `VERSION nosuch.server` → NOSUCH 402; inverse re-drive stays 402. The whole existing `golden_s2s_*` suite routes via `hunt_server` (info_links/lusers/motd/trace/who re-verified green), so it is the de-facto regression gate.
  - **Known flake** — `golden_s2s_s_serv_stats` still fails on the documented reference-C uninitialized peer-burst sendq garbage (`…kB sq`); pre-existing, not a regression. `s_user_umode_diff` fails to compile on clean HEAD too (bindgen `c_char` signedness rot) — unrelated to this cluster.
- **2026‑06‑04 — P5whowas (`whowas.c` `m_whowas`, whowas.o dropped) merged.** The P2‑deferred WHOWAS command handler ported → `whowas.c` fully Rust.
  - **Cluster choice** — `m_whowas` was the only C remnant of `whowas.o`, kept behind `whowas_link.o` (`-DPORT_WHOWAS_P2`) since the P2 ring port because its reply path needed the variadic `sendto_one` (P3) and routing callees `canonize` (P5m) / `hunt_server` (P5ccc), all now Rust. With those landed it ports cleanly; this is the natural next droppable command‑handler cluster after the three big P5 TUs (channel/s_serv/s_user) finished.
  - **Drop vs `_link.o`** — every symbol `whowas.o` defines is now Rust → **`whowas.o` added to `PORTED` and dropped outright** (the rename match arm `"whowas.o" => "whowas_link.o"` and the P2c second‑compile step removed from `ircd-sys/build.rs`). The cref oracle still compiles the full unguarded `whowas.o` (in `CREF_OBJS`, unaffected by `PORTED`), so `cref_add_history`/`cref_get_history`/… survive for the L1 `whowas_diff`.
  - **Config‑resolved body** — `parc<2`→431; `parc>2`→`atoi(parv[2])` max; `parc>3`→`hunt_server(...,":%s WHOWAS %s %s :%s",3,...)` forward; `canonize(parv[1])`; `!MyConnect(sptr)`→`max=MIN(max,20)`; the do‑while ring scan from `&was[(ww_index?ww_index:ww_size)-1]` decrementing with wrap, matching `mycmp(nick,ww_nick)` → 314 `RPL_WHOWASUSER` (`up->username`/`host`, `ww_info`) + 312 `RPL_WHOISSERVER` (`up->server`, `myctime(ww_logout)`); `j>=max` early break; not‑found → NICKLEN‑truncate + 406; trailing 369.
  - **Faithfulness notes** — `up` is declared once and reset to NULL only via the `else up=NULL` arm (so a found token leaves it set across the `if up.is_null()` check, then clears it for the next token) — ported literally. `p[-1]=','` token restore via `*p.sub(1)`. The helpers `me_name`/`reply`/`bad_to`/`my_connect` mirror s_user.rs.
  - **Classification** — handler cluster (msgtab WHOWAS row), server‑reachable: it formats `up->server` (a remote‑user field) and forwards via `hunt_server` → L2 + L2‑S2S required; no L1 (pure wire handler; the ring it reads is already L1‑covered by `whowas_diff`).
  - **L1** — none new; `whowas_diff` (P2) stays zero‑diff vs `cref_` (ring add/get/find/off/count) and now links against the dropped‑`whowas.o` build.
  - **L2** — `golden_whowas`: alice registers + QUITs (→ `add_history`), bob `WHOWAS alice` → 314/312/369 found path, `WHOWAS alice 1` exercises the `j>=max` break, `WHOWAS ghost` → 406 inverse; byte‑identical ref‑C vs Rust. 312's `myctime(ww_logout)` is wall‑clock volatile → masked locally (the shared `canonicalize` leaves 312 untouched for the stable‑server‑info WHOIS goldens). `golden_s_user_canonize` (406/369 dedup) is the regression.
  - **S2S** — `golden_s2s_whowas`: (1) a peer introduces+QUITs `rmuser` → local `WHOWAS rmuser` renders 312 with `peer.test` (the remote `up->server`, not `irc.test`); (2) `WHOWAS ghost 1 peer.test` → `hunt_server` matches parv[3] and forwards the command out the link, observed peer‑side. byte‑identical. The remote‑sender `max>20` cap is review‑covered (the single‑peer harness reply‑routing doesn't reach a remote sender passing max>20).
