# P7 — I/O core + event loop + glue (per-cluster progress)

One-line summary per cluster. Full entries: [`docs/progress-log/p7.md`](docs/progress-log/p7.md).
Phase row + plan: [`PLAN.md`](PLAN.md) P7; plans under `docs/superpowers/plans/`.

- **P7a DONE: `common/bsd.c` (socket write leaf)** — ported `deliver_it` (the bottom of the send path: `send()` + WOULDBLOCK→0/`FLAGS_BLOCKED` + `sendB` accumulation + `-errno`) and the re-arming `dummy` signal stub to `ircd-common/src/bsd.rs`; both portable → **`bsd.o` dropped outright** (no `_link.o`). L1 differential (5 cases, full FLAGS_BLOCKED set/clear/untouched matrix) zero-diff vs `cref_`; L2 = existing golden suite (deliver_it is the universal write path) stays byte-identical; no S2S/no new L2 (utility TU).
- **P7b DONE: `common/packet.c` (inbound packet reassembler)** — ported `dopacket` (the only exported symbol; ZIP_LINKS/DEBUGMODE off → just the plain `while (length>0 && ch2)` line-reassembly loop: CR-or-LF framing, `receiveB`/`receiveM` counter accumulation on me/cptr/acpt with the `acpt==&me` guard, `cptr->count` partial-line carry, BUFSIZE-1 overflow cap, and the parse→FLUSH_BUFFER/IsDead→exit_client/IsServer+UNKCMD return handling) to `ircd-common/src/packet.rs`; all callees already Rust → **`packet.o` dropped outright** (no `_link.o`). L1 differential (8 cases: single LF/CR, skipped extra CR-LF, two-lines-one-buffer, partial→continuation round-trip, acpt==&me vs distinct-acpt, 600-byte overflow truncation) zero-diff vs `cref_`; serialized on a `GLOBALS_LOCK` (shared `me`/`cref_me`). L2 = existing golden suite (universal read path) stays byte-identical (`golden_registration` confirmed); no S2S/no new L2 (utility TU, no IsServer-remote-field formatting).
- **P7c DONE: `ircd.c` tune-file pair (`ircd_writetune`/`ircd_readtune`)** — ported the tune-file persistence pair (the 7 sizing globals `ww_size`/`lk_size`/`_HASHSIZE`/`_CHANNELHASHSIZE`/`_SIDSIZE`/`poolsize`/`_UIDSIZE` serialized one-decimal-per-line via `sprintf`, parsed back via `sscanf`, the `USE_HOSTHASH`/`USE_IPHASH` mirrors `_HOSTNAMEHASHSIZE`/`_IPHASHSIZE` = `_HASHSIZE`, the `BOOT_BADTUNE` silent-return-vs-`exit(1)` branch, and the `lk_size = max(lk_size, ww_size)` clamp) to `ircd-common/src/ircd.rs`. First partial port of the central `ircd.c` → `ircd_link.o` second-compile (`-DPORT_IRCD_TUNE_P7c`, carrying ircd.o's IRCD*_PATH/IAUTH machine-path defines so the surviving C is byte-identical); `c_ircd_main`/`me`/signals/`restart`/`server_reboot`/the tune callers stay C. L1 differential (`ircd_tune_diff.rs`, 9 cases: writetune byte-identical files incl. lk<ww + zero/INT_MAX/u32-max edges, readtune global round-trip incl. clamp + hash mirrors + missing-file + BOOT_BADTUNE silent return, write→read round-trip) zero-diff vs `cref_`, serialized on a `GLOBALS_LOCK`. No new L2 (utility TU, not a `msgtab` handler; `ircd_readtune` exercised at boot by the existing golden suite — `golden_registration` stays byte-identical); no S2S (no remote-field formatting). The `exit(1)` arm is untested-by-design (would kill the test process).
- **P7d DONE: `s_bsd.c` socket/file utility leaves** — first (partial) port of the central I/O TU `s_bsd.c`; ported the three pure libc-wrapper leaves that touch none of the event-loop data globals: `get_sockerr` (`getsockopt(SO_ERROR)`-or-saved-`errno`), `set_non_blocking` (`fcntl F_GETFL`→`F_SETFL|O_NONBLOCK`; failure path calls the still-C `report_error`), and `write_pidfile` (truncate+create `IRCDPID_PATH`, `sprintf("%5d\n", getpid())`) to `ircd-common/src/s_bsd.rs`. Partial port via `s_bsd_link.o` (`-DPORT_S_BSD_LEAF_P7d`, carrying s_bsd.o's `IRCDPID_PATH`/`IAUTH_PATH`/`IAUTH` machine-path defines); the event loop + `local[]`/`highest_fd`/`timeofday`/`FdAry` + listeners + `add_connection`/`read_message`/`report_error`/`get_my_name`/`add_local_domain`/`start_iauth` stay C. `IRCDPID_PATH` (a command-line define, absent from bindgen) exposed to Rust via the P6m make-`--eval`+`rustc-env` pattern → `ircd_sys::PID_PATH`. L1 differential (`s_bsd_leaves_diff.rs`, 4 cases: get_sockerr fd<0 errno-passthrough + valid-fd/no-error, set_non_blocking O_NONBLOCK-set-with-untouched-fd-inverse, write_pidfile identical-behavior) zero-diff vs `cref_`, serialized on `GLOBALS_LOCK`. No new L2 (utility TU; `write_pidfile` hit at boot, `set_non_blocking`/`get_sockerr` on every connect — covered by the existing golden boot/connect path, `golden_registration` byte-identical); no S2S (no remote-field formatting). Untested-by-design: get_sockerr's `err!=0` branch + set_non_blocking's fcntl-failure→report_error branch (need a pending-error socket / bad fd); write_pidfile's byte rendering is pinned only where `IRCDPID_PATH` is writable (its dir is absent in the sandbox → both worlds no-op identically).
- **P7e DONE: `s_bsd.c` name-resolution leaf (`add_local_domain`)** — ported the next-easiest s_bsd.c leaf after the P7d socket/file trio: `add_local_domain` (strip one trailing `.` + `size++`; if the name is unqualified, lazily `ircd_res_init()` when `!(options & RES_INIT)`, then append `"." + ircd_res.defdname` iff `defdname[0]` and `strlen(defdname)+2 <= size`) to `ircd-common/src/s_bsd.rs`. Touches none of the event-loop globals — its only dependency is the resolver state (`ircd_res`/`ircd_res_init`), already Rust since P6. Partial port via the existing `s_bsd_link.o` seam with a new guard `-DPORT_S_BSD_LEAF_P7e` (added alongside `-DPORT_S_BSD_LEAF_P7d`); `get_my_name` (its only in-TU caller, needs `gethostname`/`gethostbyname`/`mysk`) stays C. RED confirmed the undefined symbol referenced by the now-Rust `s_conf.rs` + still-C `s_bsd.c` (`get_my_name`/`connect_server`); after GREEN `nm` shows `add_local_domain` as `T` from Rust. L1 differential (`add_local_domain_diff.rs`, 6 cases: trailing-dot-strip/no-append, unqualified-append, the size-guard boundary len+1-vs-len+2 inverse, empty-defdname-no-append, the `size++`-enables-append faithfulness check, and the init-trigger branch via `$LOCALDOMAIN` for determinism — both worlds run their P6-verified-equivalent `ircd_res_init`) zero-diff vs `cref_add_local_domain`, isolated worlds (Rust reads the real `ircd_res`, oracle reads `cref_ircd_res`), serialized on `GLOBALS_LOCK`. No new L2 (callee TU, not a `msgtab` handler; runs at boot via `s_conf.c` read_conf + on `connect_server` — `golden_registration` byte-identical); no S2S (no remote-field formatting).
- **P7f DONE: `s_bsd.c` delayed-close leaf (`delay_close`)** — ported the `DELAY_CLOSE`-gated (=15) `delay_close` (s_bsd.c:3359): a private static time-sorted linked list of fds awaiting a delayed `close()`, swept per call (expired entries, or — under fd pressure when `is_delayclosewait > (MAXCLIENTS-is_localc)>>1` — the oldest quarter; `fd==-2` from `m_close` forces close-all), then `fd>=0` is queued at `timeofday+15` (with `set_non_blocking`+`shutdown(SHUT_RD)`); returns the head entry's scheduled time or 0. Faithful: the unsigned `int-u_long` threshold (wraps), the `time<now || tmpdel-- >0` short-circuit (tmpdel only decrements when not expired), the 46-byte (43 chars+`\r\n`+NUL) "Too rapid connections" error sent to the *new* fd. Same `s_bsd_link.o` seam, new guard `-DPORT_S_BSD_DELAY_CLOSE_P7f`; reads the still-C `istat` (ircd.c) + `timeofday` (s_bsd.c) globals, calls the Rust `set_non_blocking` (P7d) + `MyMalloc` (P2). L1 differential (`delay_close_diff.rs`, 6 cases: queue-one + inverse time-eviction, unexpired-stays early-break, `fd==-2` close-all drain, overflow drop-oldest-quarter, chronological-head ordering) zero-diff vs `cref_delay_close`, isolated worlds (real `istat`/`timeofday` vs `cref_*`), serialized on `GLOBALS_LOCK` (incl. a `reset()` to drain the persistent static lists between tests). No new L2 (callee, not a `msgtab` handler — hit by the io_loop `delay_close(-1)`/`m_close`/connection-close paths; `golden_registration` byte-identical); no S2S (no remote-field formatting).
- **P7g DONE: `s_bsd.c` fd-teardown leaf (`close_client_fd`)** — ported the descriptor-teardown leaf `close_client_fd` (s_bsd.c:1270): closes `authfd` then `fd` (flushing its sendQ first via the Rust `flush_connections`, removing it from `fdas`/`fdall` via the Rust `del_fd` + clearing `local[fd]`), then drains `sendQ`/`recvQ` (`DBufClear`→`dbuf_delete`) and zeroes `passwd`. Config-resolved: `SO_LINGER` defined (the linger blocks compile, fired only when `exitc==EXITC_PING`), `ZIP_LINKS` off (`zip_free` omitted). All real callees already Rust (`flush_connections` P3, `del_fd` P2, `dbuf_delete` P1); only `report_error` stays C (already an `extern "C"` decl since P7d; fires solely on a `setsockopt(SO_LINGER)` failure). Same `s_bsd_link.o` seam, new guard `-DPORT_S_BSD_CLOSE_FD_P7g`; reads the still-C `local[]`/`fdas`/`fdall` globals. L1 differential (`close_client_fd_diff.rs`, 6 cases: client both-fds, server + listener `IsServer||IsListener` fdas+fdall arm, fd<0 only-authfd-closed, both-fds<0 no-op, and the inverse-of-insert recvQ-drain + passwd-zero) zero-diff vs `cref_close_client_fd`, isolated worlds (real `local`/`fdas`/`fdall` + Rust `flush_connections`/`del_fd` vs `cref_*`), serialized on `GLOBALS_LOCK`; inverse invariants checked (fd actually closed via EBADF, `local[fd]==NULL`, array slot freed). `exitc=0` everywhere → the `SO_LINGER`/`report_error` branches untested-by-design; the sendQ flush-then-clear (live socket I/O) is L2. No new L2 (callee, not a `msgtab` handler — hit on every disconnect via `close_connection`/`exit_client`; `golden_registration` incl. quit/reuse byte-identical); no S2S (no remote-field formatting).
- **P7h DONE: `s_bsd.c` connection-teardown leaf (`close_connection`)** — ported the bookkeeping layer directly above the P7g `close_client_fd`: `close_connection` (s_bsd.c:1341) bumps the per-class `ircstp` stats (`is_sv`/`is_cl`/`is_ni` + byte/time accumulators), drops outstanding DNS queries (`del_queries`), reschedules server reconnect (`find_conf_exact`→`nextconnect` with the `HANGONGOODLINK`/`HANGONRETRYDELAY` clamp), schedules a hang-on retry for an aborted handshake/connect, notifies iauth (`sendto_iauth "%d D"`) + decrements the P-line acceptor's `clients` refcount (recursing into `close_connection(acpt)` when the acceptor itself goes illegal), tears the descriptors down via the Rust `close_client_fd`, unlinks an illegal listener from `ListenerLL`, then `det_confs_butmask(cptr,0)` + `cptr->from = NULL`. Config-resolved: `USE_IAUTH` ON → the `sendto_iauth` block compiles; DEBUGMODE off. All callees already resolvable (`del_queries`/`find_conf_exact`/`det_confs_butmask` Rust since P6; `sendto_iauth` the variadic C trampoline; `close_client_fd` Rust P7g). Same `s_bsd_link.o` seam, new guard `-DPORT_S_BSD_CLOSE_CONN_P7h`; reads the still-C `ircstp`/`nextconnect`/`ListenerLL`/`timeofday`/`me` globals. L1 differential (`close_connection_diff.rs`, 6 cases: server/client/unknown stats accounting, handshake+connecting `nextconnect = now+30`, P-line acceptor refcount 5→4, illegal-listener `ListenerLL` unlink with the inverse — node gone, head intact, `from` NULL, confs detached) zero-diff vs `cref_close_connection`, isolated worlds (real `ircstp`/`nextconnect`/`ListenerLL`/`local`/`fdas`/`fdall`/`me`/`istat` vs `cref_*`), serialized on `GLOBALS_LOCK`; `me.fd`/`adfd` pinned to -1 (inner `flush_connections` else-branch + `sendto_iauth` no-op). No new L2 (callee, not a `msgtab` handler — hit on every disconnect via `exit_client`; `golden_registration` incl. quit/reuse byte-identical); no S2S (formats no remote-user fields). Untested-by-design: the recursive `close_connection(acpt)` (needs a fully-illegal acceptor conf) + the `find_conf_exact` reconnect-reschedule arm (NULL with no conf loaded) + the `sendto_iauth` wire emission (L2, variadic trampoline).
- **P7i DONE: `s_bsd.c` listener-list teardown leaf (`close_listeners`)** — ported the layer directly above P7g/P7h: `close_listeners` (s_bsd.c:427) walks the `ListenerLL` doubly-linked list and tears down every listener whose conf has gone illegal (`IsIllegal(aconf)`) — `clients>0` → the Rust `close_client_fd` (fd torn, node stays in the list), `clients≤0` → the Rust `close_connection` (fd torn + node unlinked + confs detached + `from` cleared); legal listeners untouched; the `bcptr = acptr->next` save handles the in-loop unlink. UNIXPORT off (config.h:339) → the `IsUnixSocket`/`unlink` block vanishes; both callees already Rust (P7g/P7h) → no new externs (reuses the existing `conf_is_illegal` helper). Same `s_bsd_link.o` seam, new guard `-DPORT_S_BSD_CLOSE_LISTENERS_P7i`; the only caller is the now-Rust `s_conf.rs` rehash (`s_conf.c:1315`). L1 differential (`close_listeners_diff.rs`, 5 cases: illegal-clients=0 unlinked, illegal-clients>0 stays-linked inverse, legal untouched (fd still open via fcntl), mixed 3-node middle-removed with the two legals relinked, all-illegal drains the list) zero-diff vs `cref_close_listeners`, isolated worlds, serialized on `GLOBALS_LOCK`. No new L2 (callee, not a `msgtab` handler — hit by rehash; `golden_registration` byte-identical); no S2S (no remote-field formatting).
- **P7j DONE: `s_bsd.c` listener-reactivation leaf (`activate_delayed_listeners`)** — ported the counterpart to P7i's `close_listeners`: `activate_delayed_listeners` (s_bsd.c:526) walks the `ListenerLL` list and, for every listener flagged `FLAGS_LISTENINACTIVE`, calls `listen(fd, LISTENQUEUE=128)`, clears the inactive bit, and counts it; if any were reactivated it emits one `sendto_flag(SCH_NOTICE, "%d listeners activated", cnt)` notice. No `#ifdef`s (DEBUGMODE off → no `Debug`); `listen()`'s return is ignored exactly as C. Same `s_bsd_link.o` seam, new guard `-DPORT_S_BSD_ACTIVATE_DELAYED_P7j`; no new still-C externs (`sendto_flag` is the existing variadic trampoline via `ircd_sys::bindings`, safe in L1 — short-circuits on NULL `svc_ptr`; `LISTENQUEUE` reproduced as a const since it's absent from bindgen). RED confirmed the undefined symbol referenced by the now-Rust `s_serv.rs` (`m_set`/burst) + `s_misc.rs` (`check_split`); after GREEN `nm` shows it `T` from Rust. L1 differential (`activate_delayed_listeners_diff.rs`, 5 cases: single-inactive→activated (inactive bit clear + socket actually listening via `SO_ACCEPTCONN`), single-active untouched (inverse), mixed `[active,inactive,active]` only-middle, empty no-op, all-inactive) zero-diff vs `cref_activate_delayed_listeners`, isolated worlds over real TCP-socket fds, serialized on `GLOBALS_LOCK`; inverse invariant — listeners never removed, already-active nodes untouched. No new L2 (callee, not a `msgtab` handler — hit by server-burst/rehash; `golden_registration` byte-identical); no S2S (formats only an integer count, no remote-user fields).
=== p7.md tail ===
    confirmed `delay_close` undefined — referenced by `s_serv.rs` (`m_close`, now
    Rust), `ircd.c:1176` (io_loop, still C), and `s_bsd.c:1661` (still C); after GREEN
    `nm target/debug/ircd` shows `delay_close` as `T` (from Rust).
  - **Classification** — utility/callee TU (not a `msgtab` handler). Called from the
    io_loop (`delay_close(-1)`), `m_close` (`delay_close(-2)`), and the
    connection-close / listener-accept paths.
  - **L1** (`ircd-testkit/tests/delay_close_diff.rs`) — 6 cases, isolated worlds (the
    Rust port reads/mutates the real `istat`/`timeofday`; the `cref_` oracle uses
    `cref_istat`/`cref_timeofday`), serialized on `GLOBALS_LOCK`. Because the static
    lists persist across `#[test]`s, each test `reset()`s first (drains both via
    `delay_close(-2)`, then zeroes the counters). Honouring the inverse-invariant
    rule: (1) queue one fd → return `now+15`, counters `(1,1)`; (2) time eviction
    (inverse of 1) — advance past the time, sweep with `fd<0` → entry gone, return 0,
    `wait 1→0`; (3) unexpired entry stays (the time-sorted early `break`); (4)
    `fd==-2` close-all drains 2 unexpired entries; (5) overflow — `is_localc=43` →
    threshold 1, 4 queued then a 5th → `tmpdel=4>>2=1` evicts the oldest while adding
    (net `wait` 4, `close` 5); (6) chronological head — head stays the oldest entry's
    time until it is evicted. socketpair fds so `close`/`shutdown`/`send` succeed
    identically; the same fd value drives both worlds. Zero-diff on return value +
    `(is_delayclose, is_delayclosewait)` for every call.
  - **L2** — no new test. `delay_close` runs from the io_loop / connection-close
    paths; the existing `ircd-golden` boot path covers it (`golden_registration`
    byte-identical). No client command reaches it deterministically under the locked
    config (it needs rapid-connect refusal).
  - **S2S** — none. No `IsServer` branch, no remote-user field formatting.

- **2026-06-06 — P7g (`s_bsd.c` fd-teardown leaf `close_client_fd`) merged.** The next `s_bsd.c` leaf after P7d (socket/file trio), P7e (`add_local_domain`), P7f (`delay_close`). Ported `close_client_fd` (s_bsd.c:1270) to `ircd-common/src/s_bsd.rs`.
  - **Cluster choice.** Picked because its effect is pure post-state on the `aClient` + the fd arrays (L1-testable by inspection, like `delay_close`), and all its real callees are already Rust: `flush_connections` (send.rs, P3), `del_fd` (list.rs, P2), `dbuf_delete` (dbuf.rs, P1). The only C dependency is `report_error`, already declared `extern "C"` in `s_bsd.rs` since P7d.
  - **Guard / seam.** Same `s_bsd_link.o` partial-compile; added `-DPORT_S_BSD_CLOSE_FD_P7g` to the recipe in `ircd-sys/build.rs` and wrapped the C body in `#ifndef PORT_S_BSD_CLOSE_FD_P7g`. RED confirmed the undefined `close_client_fd` referenced by the still-C `close_connection`/`add_connection_refuse`; after GREEN `nm` shows it `T` from Rust. The cref oracle keeps the full unguarded `s_bsd.o`.
  - **Config-resolved body.** `SO_LINGER` defined → the two linger blocks compile (only taken when `exitc==EXITC_PING`; on a nonzero `setsockopt` return they call the still-C `report_error`). `ZIP_LINKS` OFF → the `zip_free` call inside the `IsServer||IsListener` arm is omitted. Faithful: `SETSOCKOPT(...,&sockling,sockling)` = `setsockopt(...,&sockling,sizeof(struct linger))`; `DBufClear(d)` = `dbuf_delete(d, d->length)`; `bzero(passwd, sizeof)` = `memset(passwd,0,21)`; the `IsServer||IsListener` / `IsClient` arms are mutually exclusive (`if/else if`) but `del_fd(&fdall)` + `local[fd]=NULL` + `close` + the drains run unconditionally for any `fd>=0`. The linger struct is fully initialized (`l_onoff=0,l_linger=0`, per the 2014 Kurt Roeckx fix).
  - **Classification.** Callee TU (no `msgtab` entry) — reached from `close_connection` / `exit_client` / the listener-accept refuse paths.
  - **L1.** `close_client_fd_diff.rs`, 6 cases, isolated worlds (Rust reads/mutates the real `local`/`fdas`/`fdall` + calls Rust `flush_connections`/`del_fd`; oracle uses `cref_local`/`cref_fdas`/`cref_fdall` + `cref_*`), `me.fd`/`cref_me.fd` pinned to -1 so `flush_connections` takes the `else if fd>=0` branch. Cases: client both-fds; server + listener (the fdas+fdall arm, via `FLAGS_LISTEN` for the listener); fd<0 (only authfd closed, fd>=0 block skipped, queues/passwd untouched); both-fds<0 no-op; and the inverse-of-insert recvQ-drain + passwd-zero. Each asserts equal post-state + the inverse invariants (fd actually closed → second `close()` returns EBADF, `local[fd]==NULL`, array slot freed, `fdas`/`fdall.highest` agree, queues drained). Serialized on `GLOBALS_LOCK` (shared `local`/fd-arrays/`me`). Zero-diff vs `cref_close_client_fd`.
  - **Untested-by-design.** `exitc=0` in every case → the `SO_LINGER`/`report_error` failure branches are not exercised (they need a socket whose `setsockopt` fails). The `sendQ` flush-then-clear path (live socket I/O through `send_queued`) is L2, not L1 — queuing `sendQ` on a synthetic client crashes the live send path; only `recvQ` (never flushed) is used for the `DBufClear` drain check.
  - **L2 / S2S.** No new L2: hit on every disconnect; `golden_registration` (incl. `register_quit_reuse_releases_nick`) stays byte-identical. No S2S: formats no remote-user fields.

- **2026-06-06 — P7h (`s_bsd.c` connection-teardown leaf `close_connection`) merged.** The next `s_bsd.c` leaf after P7d (socket/file trio), P7e (`add_local_domain`), P7f (`delay_close`), P7g (`close_client_fd`). Ported `close_connection` (s_bsd.c:1341) to `ircd-common/src/s_bsd.rs` — the disconnect-bookkeeping layer directly above the P7g fd-teardown leaf.
  - **Cluster choice.** Picked as the natural next layer up from P7g: `close_connection` *calls* `close_client_fd`, and all its other callees are already resolvable — `del_queries`/`find_conf_exact`/`det_confs_butmask` are Rust (P6), `sendto_iauth` is the variadic C trampoline (declaring + calling a variadic is stable), `close_client_fd` is the Rust P7g symbol. Its whole effect is post-state on the `aClient` + the process globals → L1-testable by inspection.
  - **Guard / seam.** Same `s_bsd_link.o` partial-compile; added `-DPORT_S_BSD_CLOSE_CONN_P7h` to the recipe in `ircd-sys/build.rs` (alongside the P7d/P7e/P7f/P7g guards) and wrapped the C body (s_bsd.c:1341-1453) in `#ifndef PORT_S_BSD_CLOSE_CONN_P7h`. RED confirmed `close_connection` undefined — referenced by the now-Rust `s_misc.rs` (`exit_client`) and the still-C `s_bsd.c:458`; after GREEN `nm target/debug/ircd` shows it `T` from Rust. The cref oracle keeps the full unguarded `s_bsd.o`.
  - **Config-resolved body.** `USE_IAUTH` ON → the `sendto_iauth("%d D", cptr->fd)` notify block (gated `!IsListener && !IsConnecting`) compiles. DEBUGMODE off → the `Debug()` lines vanish. No other `#ifdef`'d branches. Macros reproduced inline: `IsHandshake`/`IsConnecting` (`status == STAT_HANDSHAKE`/`STAT_CONNECTING`), `IsIllegal(aconf)` (`status & CONF_ILLEGAL`), `ConfConFreq(aconf)` (`aconf->class->conFreq`, int→time_t), `CFLAG` (`CONF_CONNECT_SERVER|CONF_ZCONNECT_SERVER` = 40); `HANGONRETRYDELAY`=30/`HANGONGOODLINK`=900 (config.h.dist:656-657, object-like config macros absent from bindgen → Rust consts). Reuses the P7g `is_server`/`is_client`/`is_listener` helpers. The reconnect-reschedule arm short-circuits on `IsServer` (so `find_conf_exact` is only called for a server) exactly as C.
  - **Classification.** Callee/utility TU (no `msgtab` entry) — reached from `exit_client` (s_misc.c) and the listener/acceptor cleanup paths.
  - **L1.** `close_connection_diff.rs`, 6 cases, isolated worlds (Rust reads/mutates the real `ircstp`/`nextconnect`/`ListenerLL`/`local`/`fdas`/`fdall`/`me`/`istat` + calls Rust `close_client_fd`/`del_queries`/`det_confs_butmask`; oracle uses `cref_*`), serialized on `GLOBALS_LOCK`. `me.fd`/`cref_me.fd` pinned to -1 (inner `flush_connections` else-branch); `adfd`/`cref_adfd` pinned to -1 (`sendto_iauth` no-op, no live iauth pipe); `firsttime`/`since` pinned to constants for deterministic `timeofday - firsttime` deltas. Cases: (1) server → `is_sv`/`is_sbs`/`is_sbr`/`is_sti`; (2) client → `is_cl`/`is_cbs`/`is_cbr`/`is_cti` (inverse: server/ni untouched); (3) unknown → only `is_ni`; (4) handshake + connecting, `nextconnect==0` → `nextconnect = now + 30`; (5) P-line acceptor refcount 5→4 (inverse: closed client fd torn down); (6) illegal listener (`CONF_ILLEGAL`, `clients<=0`) unlinked from a 2-node `ListenerLL` — inverse invariants: head.next NULL, `ListenerLL` head intact, target fd -1, `from` NULL, `confs` detached. Zero-diff vs `cref_close_connection`. **Fixture note:** case 6's `det_confs_butmask`→`detach_conf` decrements the unsigned `istat.is_conflink` once per detached link; seeded `is_conflink=1` in both worlds (the real `attach_conf` would have incremented it) — without it the decrement underflows (C wraps silently, Rust debug-overflow panics, surfacing the unrealistic fixture).
  - **Untested-by-design.** The recursive `close_connection(cptr->acpt)` when the acceptor itself becomes illegal (needs a fully-illegal acceptor conf — case 5 covers the non-recursive refcount arm). The `find_conf_exact` reconnect-reschedule arm (returns NULL with no conf loaded → both worlds skip it identically). The `sendto_iauth` wire emission (L2, variadic trampoline, like the rest of the sendto_* family).
  - **L2 / S2S.** No new L2: hit on every disconnect; `golden_registration` (incl. `register_quit_reuse_releases_nick`) stays byte-identical. No S2S: formats no remote-user fields (the `IsServer` branch touches only local stats counters + reconnect scheduling, not wire output).

- **2026-06-06 — P7i (`s_bsd.c` listener-list teardown leaf `close_listeners`) merged.** The next `s_bsd.c` leaf after P7d (socket/file trio), P7e (`add_local_domain`), P7f (`delay_close`), P7g (`close_client_fd`), P7h (`close_connection`). Ported `close_listeners` (s_bsd.c:427) to `ircd-common/src/s_bsd.rs` — the listener-GC layer directly above the P7g/P7h teardown leaves.
  - **Cluster choice.** The cleanest remaining s_bsd leaf: it is a pure walk over the `ListenerLL` global dispatching to two already-Rust callees (`close_client_fd` P7g, `close_connection` P7h) — no socket syscalls of its own, effect fully observable as `ListenerLL` + per-node `aClient` post-state. The other remaining s_bsd symbols are the event-loop core (`read_message`/`add_connection`), listener *construction* (`inetport`/`add_listener`/`open_listener` — real `socket`/`bind`/`listen`), sender-only (`report_error`), real-DNS (`get_my_name`), or `static` (no `cref_` oracle: `set_sock_opts`/`check_init`).
  - **Guard / seam.** Same `s_bsd_link.o` partial-compile; added `-DPORT_S_BSD_CLOSE_LISTENERS_P7i` to the recipe in `ircd-sys/build.rs` (alongside the P7d/P7e/P7f/P7g/P7h guards) and wrapped the C body (s_bsd.c:427-462) in `#ifndef PORT_S_BSD_CLOSE_LISTENERS_P7i`. RED confirmed `close_listeners` undefined — referenced only by the now-Rust `s_conf.rs` rehash (`s_conf.c:1315`); after GREEN `nm target/debug/ircd` shows it `T` from Rust. The cref oracle keeps the full unguarded `s_bsd.o`.
  - **Config-resolved body.** UNIXPORT off (`cbuild/config.h:339 #undef UNIXPORT`; `nm cbuild/s_bsd.o` has no `unixport`) → the entire `#ifdef UNIXPORT` `IsUnixSocket`/`sprintf(unixpath)`/`unlink` block is not compiled. Resolved body: `for (acptr = ListenerLL; acptr; acptr = bcptr) { aconf = acptr->confs->value.aconf; bcptr = acptr->next; if (IsIllegal(aconf)) { if (aconf->clients > 0) close_client_fd(acptr); else close_connection(acptr); } }`. The `bcptr = acptr->next` is read *before* the teardown because `close_connection` may unlink `acptr` (the P7h `ListenerLL`-unlink arm). `IsIllegal` reuses the existing `conf_is_illegal` helper (`aconf->status & CONF_ILLEGAL`). No new externs — both callees are Rust in the same module.
  - **Classification.** Callee/utility TU (no `msgtab` entry) — the rehash listener garbage-collector, called from `s_conf.c` `rehash`.
  - **L1.** `close_listeners_diff.rs`, 5 cases, isolated worlds (Rust reads/mutates the real `ListenerLL`/`local`/`fdas`/`fdall`/`me`/`ircstp`/`istat` + calls the Rust `close_client_fd`/`close_connection`; oracle uses `cref_*`), serialized on `GLOBALS_LOCK`. `me.fd`/`adfd` pinned to -1 (inner `flush_connections` else-branch + `sendto_iauth` no-op); listeners built with status `STAT_ME` + flags `FLAGS_LISTEN` + `from = self` + a one-element confs `Link` + a live pipe fd registered in `local`/`fdas`/`fdall`; `istat.is_conflink` seeded per `close_connection`-bound node (its `det_confs_butmask` decrements the unsigned counter once per detached link — underflow else). Each case builds an identical `ListenerLL` on both worlds, runs `close_listeners`, and compares the structural walk (surviving node count + per-node `(fd_torn, from_null, confs_null)` — pointers differ across worlds so the comparison is on observable facts) plus inverse invariants. Cases: (1) illegal clients=0 → `close_connection` → unlinked (`ListenerLL` drained, fd -1, `from` NULL, confs detached); (2) illegal clients>0 → `close_client_fd` → fd torn BUT node stays linked + `from == self` + confs NOT detached (inverse of 1); (3) legal → fully untouched (fd still a valid descriptor via `fcntl(F_GETFD)`, still linked); (4) mixed `[legal] -> [illegal,c=0] -> [legal]` → middle removed, the two legals relinked head↔next with intact fds; (5) all-illegal-c=0 → list fully drained. Zero-diff vs `cref_close_listeners`.
  - **L2 / S2S.** No new L2: `close_listeners` is the rehash listener-GC, exercised at boot/rehash by the existing golden suite (`golden_registration` byte-identical). No S2S: it formats no remote-user wire fields (its only side effects are the descriptor teardowns + `ListenerLL` mutation).

- **2026-06-06 — P7j (`s_bsd.c` listener-reactivation leaf `activate_delayed_listeners`) merged.** The next `s_bsd.c` leaf after P7d–P7i; the reactivation counterpart to P7i's `close_listeners` teardown. Ported `activate_delayed_listeners` (s_bsd.c:526) to `ircd-common/src/s_bsd.rs`.
  - **Cluster choice.** The cleanest remaining s_bsd leaf: a pure walk over `ListenerLL` flipping one flag bit (`FLAGS_LISTENINACTIVE`) + a `listen()` syscall + a counter, the natural pair to P7i. Its whole effect is per-node `flags`/listen-state post-state → L1-testable by list inspection. The other remaining s_bsd symbols are the event-loop core (`read_message`/`add_connection`), listener *construction* (`inetport`/`add_listener`/`open_listener`/`reopen_listeners` — real `socket`/`bind`/`listen`), sender-only (`report_error`), process setup (`daemonize`/`init_sys`/`start_iauth`), real-DNS (`get_my_name`), or `static` (no `cref_` oracle: `set_sock_opts`/`check_init`/`check_clones`).
  - **Guard / seam.** Same `s_bsd_link.o` partial-compile; added `-DPORT_S_BSD_ACTIVATE_DELAYED_P7j` to the recipe in `ircd-sys/build.rs` (alongside the P7d–P7i guards) and wrapped the C body (s_bsd.c:526-545) in `#ifndef PORT_S_BSD_ACTIVATE_DELAYED_P7j`. RED confirmed `activate_delayed_listeners` undefined — referenced by the now-Rust `s_serv.rs:739` (`m_set` burst path) and `s_misc.rs:1153` (`check_split`); after GREEN `nm target/debug/ircd` shows it `T` from Rust. The cref oracle keeps the full unguarded `s_bsd.o` → `cref_activate_delayed_listeners`.
  - **Config-resolved body.** No `#ifdef`s in this function; DEBUGMODE off → no `Debug` line. `IsListenerInactive(x)` = `(x)->flags & FLAGS_LISTENINACTIVE` (0x8000000, bindgen const); `ClearListenerInactive(x)` = `(x)->flags &= ~FLAGS_LISTENINACTIVE`; `flags` is a `c_long` field so the mask is `as c_long`. `LISTENQUEUE` (config.h:622 = 128) is a config `#define` absent from bindgen → reproduced as a `const c_int`. `listen()`'s return is ignored exactly as C → the observable post-state (inactive bit cleared, node kept) is identical regardless of the fd. `sendto_flag(SCH_NOTICE, ...)` is the existing variadic C trampoline (`ircd_sys::bindings::sendto_flag` + `ServerChannels_SCH_NOTICE`); no new extern. It is safe in L1 because it short-circuits when `svchans[chan].svc_ptr == NULL` (the default un-`setup_svchans`'d state) → no-op in both worlds.
  - **Classification.** Callee/utility TU (no `msgtab` entry) — reached from the server-burst / TS-adjust path (`s_serv.c`) and `s_misc.c` `check_split`. Formats **no remote-user fields** (only an integer count) → no S2S even though a server path reaches it.
  - **L1.** `activate_delayed_listeners_diff.rs`, 5 cases, isolated worlds (Rust reads/mutates the real `ListenerLL`/`me`; oracle uses `cref_*`), serialized on `GLOBALS_LOCK`. `me.fd`/`adfd` pinned to -1 (defensive). Each `new_listener(inactive)` builds an `aClient` (status `STAT_ME`, flags `FLAGS_LISTEN` [+`FLAGS_LISTENINACTIVE`]) over a **real TCP socket** so `listen()` genuinely succeeds (asserted via `getsockopt SO_ACCEPTCONN`). Each case builds an identical `ListenerLL` on both worlds, runs the function, and compares the per-node `(still_inactive, accepting)` vector + node count (listeners are never removed). Cases: (1) single inactive → activated (bit clear + `SO_ACCEPTCONN==1`); (2) single active → untouched (inverse — flag stays clear, not re-listened, stays in list); (3) mixed `[active,inactive,active]` → only middle activated, all 3 kept, order preserved; (4) empty → no-op (cnt=0, `sendto_flag` not fired, no crash); (5) all-inactive (3 nodes) → all activated. Zero-diff vs `cref_activate_delayed_listeners`.
  - **Untested-by-design.** The `sendto_flag` wire emission (cnt>0) is the variadic-trampoline path; with NULL `svc_ptr` it is a no-op (L2 territory, like the rest of the `sendto_*` family). `listen()`'s failure path is unreachable-by-observation (return ignored).
  - **L2 / S2S.** No new L2: hit by server-burst/rehash; `golden_registration` (incl. `register_quit_reuse_releases_nick`) stays byte-identical. No S2S: formats no remote-user wire fields.
