- SendQ is byte-approximate (`Relaxed`, racy by one frame) — a ceiling, not an exact gate.
- The `DEFAULT_SENDQ` ceiling applies even to a class-less open server (unlike slice 136's conn
  caps, which no-op without a class) — a safety ceiling is always on.

### Tests (TDD; fuzzing mandated)
- **connstats unit (7)** — admit under/at/over limit (Send / Send / Overflow+latch+back-out);
  post-death Dropped (no accounting); `max == 0` never overflows; drain decrements + saturates;
  force-add bypasses the latch; **inverse** enqueue/drain round-trips to zero.
- **registry unit (4)** — deliver over a small `sendq_max` queues a terminal eject then drops;
  KILL eject + forced SAVE bypass the ceiling (delivered, accounted, no latch); `link_info().sendq`
  reflects live depth and **inverse** falls to 0 after the consumer drains; a `try_claim` (max 0)
  link is accounted but never killed under a 1000-frame flood.
- **`sendq_proptest.rs` (fuzz, 3 props)** — accumulator vs an independent model until overflow
  (verdict + depth + dead-latch lockstep; overflow ≤ 1); uncapped link tracks the model forever;
  registry ejects at the overflowing frame then drops, eject reason/body asserted.
- **No boot-golden** — the overrun kill is timing-dependent over a real socket; the `STATS l`
  live-sendq render is already covered by `golden_stats_traffic` (masked, `0` in the quiescent
  dump). The slice-145 `stats_traffic_proptest` "sendq 0" assertion still holds (quiescent links).
- **Fixture realism** — every test fixture's cosmetic `sendq 1000` (unenforceable; 1000 bytes
  can't hold a handful of lines) bumped to the shipped example's `512000`; the one `STATS Y`
  golden (`golden_stats__stats_queries`) refreshed. This surfaced + fixed
  `golden_s2s_mass_burst_drop` (a 300-user burst overran the old cosmetic cap).

**Plan:** [`docs/superpowers/plans/2026-06-13-p11-slice147-sendq-backpressure.md`](../superpowers/plans/2026-06-13-p11-slice147-sendq-backpressure.md)

**Gate:** `cargo test -p leveva` green (unit + `sendq_proptest` + existing goldens); `cargo clippy
--workspace --tests` clean; `cargo build --workspace` 0 warnings.

- **2026-06-13 — P11 slice 148 (SendQ follow-ons: bounded socket writes + server-link SendQ accounting) merged.** The two items slice 147 explicitly deferred.
  - **Why.** (1) Both serve loops (`serve_client`, `serve_linked_peer` in `main.rs`) wrote with a bare `stream.write_all(&bytes).await`. When the peer stops reading, TCP backpressure parks that write *inside* its `tokio::select!` branch body — so the whole task parks and the `ticker.tick()` keepalive branch can never fire. A *fully* wedged socket was therefore never reaped (the slice-147 SendQ eject rides the very mailbox the wedged write is blocking; the ping-timeout branch is unreachable): memory stayed bounded but the fd/task leaked until restart. (2) `serve_linked_peer`'s `mailbox_rx` was an *unbounded* channel fed by `PeerLinks::{route,broadcast,…}` with **no** SendQ accounting — the exact write-side DoS slice 147 fixed for clients, still open for peers.
  - **Part A — bounded socket writes (new `leveva::netio`).** `WRITE_TIMEOUT` (60 s) + `write_bounded`/`flush_bounded` wrap `write_all`/`flush` in `tokio::time::timeout`; a timeout returns `Err(TimedOut)` so the serve loop tears the connection down exactly like an I/O error — the wedged-socket prompt kill, the write-side analogue of the read idle/ping timeout. Both steady-state serve loops route every write/flush through them (the handshake one-shots are left to the existing `HANDSHAKE_IDLE` governor). Divergence: a timed-out `write_all` future is dropped mid-write → the peer may get a truncated final frame before the RST (correct — we are closing regardless).
  - **Part B — server-link SendQ accounting (mirrors slice 147's client path).** `PeerLink` gains `stats: Arc<ConnStats>` (born in `PeerLink::new` — signature unchanged, so ~15 handler/test call sites untouched); `serve_linked_peer` holds a clone and `sendq_drain`s each mailbox item it pops. `LinkEntry` gains `stats`/`sendq_max` + a private `enqueue` running the slice-147 policy (`Send` push wire / `Overflow` `sendq_force_add` + push one `ERROR :Closing Link: <sid> (Max SendQ exceeded)` eject → the serve loop writes it, breaks, `squit_subtree` tears the link down / `Dropped` skip); the four send methods (`route`/`route_tag_only`/`broadcast`/`broadcast_tag_only`) route through it, accounting the **egress** length (post tag-strip). `PeerLinks::link` (the convenience wrapper) stays, delegating to the new `link_with_stats(…, ConnStats::new(0), 0)` (account-only, never kill — correct for the test peers + the remote-user registry-routing path with no draining serve loop); `main.rs:serve_linked_peer` registers via `link_with_stats(link.stats.clone(), DEFAULT_SERVER_SENDQ)`. `DEFAULT_SERVER_SENDQ` = 8 MiB (matches `dist`'s `class "servers" { sendq 8000000 }`; far above the client 1 MiB because a peer legitimately queues a whole netburst — a client-sized ceiling would kill it, the `golden_s2s_mass_burst_drop` trap).
  - **Divergences (leveva-native — the oracle's server SendQ is the connect-block class).** The ceiling is the constant `DEFAULT_SERVER_SENDQ`, not resolved from the matched `connect`/`class` block (per-connect resolution is a follow-on; reusing `default_ping_freq`'s first-class pick would wrongly hand a server the 512 KB *users* ceiling). Frames delivered to a *remote user* via the registry (`deliver_uid` onto its `link.mailbox_tx`-backed entry) carry that user's own account-only `ConnStats` (`try_claim`, max 0), not the peer's — they still land on the peer's mailbox, which the loop drains with `saturating_sub`, so an un-admitted frame just floors the depth at 0 (no underflow); the dominant peer-bound traffic flows through `ctx.peers` and **is** accounted.
  - **Tests (TDD; fuzzing mandated).** Part A: 3 `netio` units (ready sink writes verbatim+Ok; wedged `Pending`-forever writer → `TimedOut` under `start_paused`; empty write is Ok) + `netio_proptest` (2 props: arbitrary payload through a ready sink conserves bytes; through a stalled writer always times out, never panics). Part B: 5 `links` units (route over-ceiling ejects once then drops; uncapped peer never ejects under a 1000-frame flood; draining keeps a peer under its ceiling; accounting uses the egress length after tag-strip; broadcast ejects an overrun peer while a healthy one keeps receiving) + `s2s_sendq_proptest` (2 model-lockstep props over `PeerLinks::route`: per-frame verdict + exact mailbox contents + single eject; uncapped tracks Σ len forever). Added `tokio` `test-util` as a dev-dep for `start_paused`. **No boot-golden** — both behaviors are real-time/socket-timing dependent (the 60 s write timeout; the overflow kill needs a non-draining real socket), as in slice 147.
  - **Gate:** `cargo test -p leveva` green (netio + links units + both proptests + every existing golden/s2s test); `cargo clippy --workspace --tests` clean; `cargo build --workspace` 0 warnings.
  - **Plan:** `docs/superpowers/plans/2026-06-13-p11-slice148-sendq-followons.md`.

- **2026-06-13 — P11 slice 149 (per-connect class resolution for server links) merged.** The slice-148 follow-on: a directly-linked peer now derives its SendQ ceiling **and** keepalive ping-freq from its matched `connect{}`-block class, not the constant `DEFAULT_SERVER_SENDQ` + the misleading `default_ping_freq` first-class pick.
  - **Why.** Slice 148 documented the SendQ ceiling as a constant follow-on. The keepalive had the *same* latent bug from the start: `serve_linked_peer` armed its ping ticker with `default_ping_freq(&classes)`, which returns the **first** class in file order — on a typical config that is `class "users"` (`ping-freq 75`), so a server link was pinged at the client rate instead of `class "servers"` (often `600`). Both are now resolved from the peer's class, mirroring the client's `allow → class` resolution in `Session::finalize_registration`.
  - **Mechanism.** Two pure helpers in `leveva/src/link.rs`: `server_link_class(peer, links, classes) -> Option<&Class>` (find the `connect{}` block whose name case-folds to the peer via `as_irc_str`, then its `class` in the class set — `None` for an open/unconfigured link) and `server_link_limits(peer, links, classes) -> (Duration, u64)` ((ping-freq, sendq) off that class, else `(DEFAULT_PING_FREQ, DEFAULT_SERVER_SENDQ)`; `sendq 0` floors to `DEFAULT_SERVER_SENDQ` — a draining mailbox always has a safety ceiling, the slice-147/148 invariant, mirroring the client's `.filter(|&s| s != 0)`; `ping_freq 0` is preserved verbatim, an exempt "never ping" class that `Heartbeat`/`tick_interval` already handle, matching `default_ping_freq`'s no-filter behavior). `main.rs::serve_linked_peer` resolves the live-or-boot links (`control::live_links()` else `ctx.stats_conf.links`, the same source `command::connect::find_link` re-resolves against), computes `(ping_freq, sendq_max)` once, and feeds them to the existing `link_with_stats(...)` registration and the keepalive `Heartbeat`/ticker.
  - **Divergences (leveva-native — no oracle).** Resolution happens once at link establishment (same lifetime as the client's `finalize_registration` class reads) — a REHASH'd class applies to *new* links, not an already-linked peer. `ping_freq 0` now keeps the link from ever timing out (faithful to an exempt class); previously such a link still got the first-class default.
  - **Tests (TDD; fuzzing mandated).** 5 `link.rs` units: case-folded block→class match; `None` for an unknown peer and for a block naming an undefined class (the inverse — fall back, never stale/first-in-file); limits use the matched class (not `users`, not the constant); no match → both defaults; `sendq 0` floored while `ping_freq 0` preserved. `leveva/tests/server_link_class_proptest.rs` (2 props, 512 cases): `server_link_limits` lockstep with an independent model over arbitrary `(connect blocks, classes, query)`, never panics, ceiling never `0`; a matched defined class's ping equals its `ping_freq` seconds exactly. **No boot-golden** — the values feed a real-time ticker + a socket-timing-dependent SendQ kill (same rationale slice 147/148 gave); the resolver is the testable unit. The existing two-daemon S2S goldens (incl. `golden_s2s_mass_burst_drop`, 300-user burst through `serve_linked_peer`) stay green.
  - **Gate:** `cargo test -p leveva` green (223 binaries, link units + new proptest + every existing golden/s2s); `cargo clippy --workspace --tests` clean; `cargo build --workspace` 0 warnings.
  - **Plan:** `docs/superpowers/plans/2026-06-13-p11-slice149-server-link-class-resolution.md`.

- **2026-06-13 — P11 slice 150 (enforce the network-wide `max-global-per-host` / `max-global-per-user-host` caps) merged.** The slice-136 deferral: a class can now cap how many connections one host / `user@host` holds **across the whole network**, not just locally.
  - **Why.** Slice 136 built `leveva::connlimit` and enforces the *local* caps (`max-links`, `max-local-per-host`, `max-local-per-user-host`, `cidr`) via the ticketed `ConnLimits` store, but explicitly deferred the two network-wide caps ("would need to count the `Network` mirror; modelled in `Class`, not acted on"). They were parsed (`config::parse` keys `max-global-per-host` / `max-global-per-user-host`), stored on `Class`/`ClassLimits`, and rendered in `STATS Y`, but **never enforced** — a class could set `max-global-per-host 1` and a host still open unlimited connections network-wide. This closes that, the capstone to the slices-145–149 connection-accounting arc.
  - **Key insight — the registry IS the network mirror.** Remote users introduced by the S2S burst (`s2s::unick` / `s2s::burst`) are `try_claim`ed into the **same** shared `Registry` as local clients. So a single scan of `Registry::by_uid` counting records whose `orighost` equals the new client's connect host yields the **true network-wide** count — no separate ticketed counter, nothing to reserve or release (the registry's own add-on-claim / remove-on-disconnect *is* the global accounting). This is the clean asymmetry vs the local caps: local caps need their own per-class ticket store (the registry can't say "how many in *this class* from this host"); global caps are a pure function of the registry's current contents.
  - **Mechanism.**
    - `connlimit.rs`: `ClassLimits` gains `max_global_per_host` / `max_global_per_user_host` (+ `from_class`); `is_unlimited()` stays **local-only** by design (it gates whether the *ticketed* accounting can be skipped — globals are enforced against the registry, not the ticket, so a class with only global caps still needs no local accounting; documented on the method). Two new `CapDenial` variants `TooManyGlobalFromHost` / `TooManyGlobalFromUserHost` with reasons `Too many global connections from your host` / `… from your user@host` (the "global" word distinguishes them from the slice-136 local per-host reasons in the closing-link `ERROR`). The pure decision `check_global_admission(lim, host_usage, user_host_usage) -> Result<(), CapDenial>` refuses when a non-zero global cap is already met (`usage >= limit`), host before user@host in declared priority — the new fuzz target.
    - `registry.rs`: `Registry::global_host_counts(user, host) -> (u32, u32)` — one lock acquisition, walk `by_uid`, count records whose `orighost == host` (per-host) and additionally `record.user == user` (per-user@host). Uses `orighost` (the real connect host, left intact by `+x` cloaking) so the basis matches the local per-host cap's pre-cloak host.
    - `session.rs finalize_registration`: a global pre-check **before** `try_claim` (so the new client is not yet in the registry → `usage` is the pre-insert count → `>= limit` semantics, consistent with the local caps; and **no nick to release** on denial — cleaner than the post-claim local block). Resolves the matched class's `ClassLimits`; if either global cap is non-zero, calls `global_host_counts` + `check_global_admission`; on denial emits the same bare `ERROR :Closing Link: <host> (<reason>)` (no numeric — class-full is not a ban) and sets `self.closing`. The local `try_admit` block below is untouched.
  - **Scope / divergences (leveva-native — no oracle).** Local client registrations only (server links / opers don't traverse `finalize_registration`; remote users are *counted*, never *gated* — their origin polices admissions). Cloaked remote hosts: a remote user's `orighost` is whatever its origin announced (possibly already `+x`-cloaked there), so a global per-host match is best-effort string equality against the new local client's real connect host — the oracle counts by resolved hostname network-wide, leveva's cloak plane makes this an approximation. Best-effort under concurrent registration: the global check is a registry scan, not an atomic check-and-reserve (the local caps reserve atomically under the `ConnLimits` lock), so two simultaneous same-host registrations can transiently overshoot by one — a soft ceiling, matching slice 136's framing of host/CIDR caps as approximate. Host/user compared by exact string equality (matches the local per-host `HashMap` key).
  - **Tests (TDD; fuzzing mandated).** `connlimit.rs` units (6): the `check_global_admission` truth table (each global cap full in isolation → right variant; host-before-user@host priority; all-unlimited admits; the freed-slot inverse re-admits; the reasons distinguish from the local variants). `registry.rs` unit: `global_host_counts` over the whole registry (zero on empty; counts local + S2S-mirrored sharing a host; the per-user@host sub-count only same-user; different host/user uncounted; the **inverse** — `release` drops both counts by exactly one). `session.rs` units (3): `max-global-per-host 1` refuses a second same-host connection (global-host `ERROR`, no nick, not counted, ticketed store untouched) while a different host registers + the release-frees-the-slot inverse; the per-user@host cap distinguishes user (same user@host refused, different user same host admitted); the uncapped path gates nobody. `tests/golden_global_caps.rs` (boot golden, real binary): a `max-global-per-host 2` class welcomes two loopback clients, refuses the third with `ERROR :Closing Link: 127.0.0.1 (Too many global connections from your host)`, and — the inverse — frees the network slot on disconnect so a fresh connection registers. `tests/global_caps_proptest.rs` (fuzz, 2 props): `check_global_admission` vs an independent boolean model (verdict + denial variant); the live registry counter driven through random `try_claim`/`release` interleavings cross-checked against a `HashMap` reference model (counts exact for every (host,user) pair, never negative, panic-free). Also threaded the two new fields through the existing `conn_limit_proptest.rs` `ClassLimits` literals (set 0 → no behavior change). **No snapshot churn** — global caps default `0`, every fixture unaffected.
  - **Gate:** `cargo test -p leveva` green (units + both proptests + every existing golden incl. `golden_conn_limits`); `cargo clippy -p leveva --tests` clean; `cargo build --workspace` 0 warnings.
  - **Plan:** `docs/superpowers/plans/2026-06-13-p11-slice150-global-per-host-caps.md`.

- **2026-06-13 — P11 slice 151 (`SAMODE`: oper channel-mode override) merged.** A new leveva-native operator command that acts like `MODE` but bypasses the channel-operator gate, so an IRC operator can override channel modes set by ordinary users.
  - **Why.** `MODE`'s channel path is op-gated (`Channels::apply_modes` → `ApplyOutcome::NeedOps` → `482` for a non-chanop). Operators had no way to fix a channel whose only chanop is absent/abusive (deop a runaway op, lift a wrongful `+b`, clear a forgotten `+k`/`+l`) without first being opped. `SAMODE` is the standard god-mode answer (UnrealIRCd/InspIRCd), here built leveva-native.
  - **Mechanism (one axis — only the op-gate moves).**
    - `channel.rs`: extracted the per-change application loop out of `apply_modes` into a private associated `Channel::apply_changes(chan, changes) -> (effective, not_members, key_set)` (a pure refactor — `apply_modes` now gates then calls it), then added the sibling `Channels::apply_modes_oper(name, changes) -> ApplyOutcome` that runs the **same** loop with **no** chanop gate. It never returns `NeedOps`; it still returns `NoSuchChannel` for an unknown channel and preserves the `441` (non-member `+o`/`+v` target) + `467` (key already set) outcomes — the override lifts only the op gate, not the structural facts.
    - `command/mode.rs`: the old `mode()` body became `mode_dispatch(client, msg, ctx, oper_override)`; `mode()` is the public `MODE` entry (override = false). New `samode()` gates on the oper bit (`Oper | LocalOp` → `481 ERR_NOPRIVILEGES`, mirroring `KILL`) then runs the identical body with override = true, selecting `apply_modes_oper` at the channel apply site. Everything else — parse, the `324`/list-query/`472`/`461` replies, the `:oper MODE #chan …` broadcast + member fan-out, the S2S `relay::local_channel_mode` propagation, and auto-reop — is shared verbatim.
    - `command/mod.rs`: `"SAMODE" => mode::samode(...)`. `help/SAMODE.md` + `"SAMODE"` registered in the `help.rs` `COMMANDS` list (both help invariants test-enforced).
  - **Scope / divergences (leveva-native — no oracle to pin against).** The override is **transparent**: the change is broadcast as a normal `:oper MODE #chan …` line, not a distinct `SAMODE` verb and no server-notice (leveva has no server-notice masks; "acts like `/MODE`" is the intent), so to every other client it is indistinguishable from a chanop's `MODE`. The oper receives the echo even when not a member (it is appended to the reply vector, not only fanned out to members). A user-mode target (`SAMODE <nick>`) passes straight through to the existing `umode` path — the override flag only governs the channel op-gate, so it behaves exactly as `MODE` (`221` self / `502` other). Gated on the bare oper bit (like `KILL`), not an `OperPrivilege` ACL — `SAMODE` is not an IRCnet ACL'd command.
  - **Tests (TDD; fuzzing mandated).** `command/mode.rs` units (5): the `481` gate + its inverse (a non-oper *chanop* still `481`, nothing changes); an oper non-member overrides `+m` (vs the boundary — the same non-member as a plain user is `482`); deop-then-reop a chanop (both directions reach member status); structural limits still bite under override (`+o` non-member → `441`, `+k` over a key → `467`, original key survives); bare `SAMODE #chan` passes through → `324`. `channel.rs` proptest `samode_override_equals_a_real_ops_mode` (256 cases): over an arbitrary subsequence of a representative candidate set (every `ModeChange` arm + no-op churn + a non-member `+o` + `+k`-over-key), `apply_modes_oper(chan, changes)` produces the **identical** `ApplyOutcome` (effective / `not_members` / `key_set`) and identical resulting channel state as `apply_modes(chan, op_actor, changes)` on an identical channel where the actor *is* an op — i.e. the override differs from `MODE` **only** in the gate, never in the applied effect — and never yields `NeedOps`; plus a unit pinning `apply_modes_oper` on a missing channel → `NoSuchChannel`. **No boot-golden** — the behavior is fully covered by the handler units + the data-layer parity proptest, and `SAMODE` emits a plain `MODE` line the existing mode goldens already characterize.
  - **Gate:** `cargo test -p leveva` green (1453 lib tests incl. the 6 new + every existing channel/mode/help test); `cargo clippy -p leveva --tests` clean; `cargo build -p leveva` 0 warnings.
  - **Plan:** `docs/superpowers/plans/2026-06-13-p11-slice151-samode.md`.

- **2026-06-13 — P11 slice 152 (`SANICK` + `SAJOIN`: the rest of the SA* oper-override family) merged.** The nick and channel companions to slice 151's `SAMODE`: `SANICK <nick> <newnick>` forcibly renames a local user; `SAJOIN <nick> <channel>{,…}` forcibly joins one to channels, bypassing `+i`/`+k`/`+l`/`+b`/`+O`. Both are IRC-operator only (→ `481`, like `KILL`), leveva-native (no oracle), and **local-target only** (a remote/mirrored target gets a `NOTICE` — leveva does not yet propagate a forced rename/join across a link, the scope `KILL`'s local branch keeps).
  - **Why.** With `SAMODE` overriding channel modes, the obvious gaps were the user-identity and forced-membership overrides standard on opered networks (UnrealIRCd/InspIRCd SA* set). They round out oper control of a local user without a KILL.
  - **Mechanism — reuse the canonical NICK/JOIN machinery so the SA* form genuinely *acts like* the real one.** The risk in a forced command is drift from the user-driven path, so both are built by extracting the side-effect core of the existing handler into a shared helper; `SANICK`/`SAJOIN` and `NICK`/`JOIN` are then the **same** code with two differences — who is gated, and where the user-facing replies go (the caller's socket for the self-driven form, the target's mailbox for the forced form).
    - `command/nick.rs`: extracted the post-rename block into `pub(crate) apply_local_nick_change(ctx, uid, old_nick, old_user, old_host, old_realname, new) -> Message` (WHOWAS file + co-member client-form `:<oldmask> NICK <new>` relay + peer relay + MONITOR offline/online; returns the `NICK` message). `nick_change` now calls it then sets `client.nick`.
    - `command/sanick.rs`: oper-gate (`481`); `461`/`401`/`432`/`433` exactly as `NICK`; resolve the target, capture its record, `try_rename` (the `433`/case-only decision stays the registry's), `apply_local_nick_change`, then push an `Envelope::ForceNick` so the target's **own** session adopts the new nick and writes the line (the renamed user is excluded from the co-member fan-out). The oper gets no numeric on success (like `KILL`).
    - `command/join.rs`: extracted the per-channel loop body into a private `join_one(ctx, joiner, target, key, bypass) -> Vec<Message>` — it performs the co-member JOIN fan-out, away-notify, S2S relay, default-modes and auto-reop side effects internally and **returns** the joiner-facing replies (JOIN echo, topic `332`/`333`, NAMES, reop `MODE`); `bypass` skips the `check_join` mode gate. `join()` now loops `join_one(..., false)`. Two thin `pub(crate)` entry points: `registered_view(&ClientRecord) -> Registered` (a synthetic joiner from the registry record — identity/modes/caps, empty privileges) and `force_join(ctx, joiner, target)` (`join_one(..., true)` delivering each returned reply to the joiner's own mailbox).
    - `command/sajoin.rs`: oper-gate (`481`); `461`/`401`; per comma-separated channel a bad name → `403` **to the oper**, else `force_join` the target. The oper gets no numeric on success.
    - `command/mod.rs`: `"SANICK"`/`"SAJOIN"` routes; `help/SANICK.md` + `help/SAJOIN.md` + both names in the `help.rs` `COMMANDS` list (both help invariants test-enforced).
  - **Scope / divergences (leveva-native — no oracle).** Local targets only; a remote target → a server `NOTICE` to the oper (no S2S forced-rename/join propagation yet — the `KILL`-local scope). The oper receives no success numeric (it observes the effect through any shared channel), matching `KILL`/`SANICK`/`SAJOIN`'s no-feedback model. `SANICK` preserves every `NICK` structural rule (a taken nick is `433`, never an invented slot); `SAJOIN` preserves `JOIN`'s already-member silent no-op. Both extractions are pure refactors — the existing `nick`/`join` suites are the regression guard.
  - **Tests (TDD).** `sanick.rs` (4): the `481` gate + inverse (target untouched); success renames the registry + files WHOWAS + force-renames the target's session (`ForceNick` envelope asserted) + a co-member sees the old-mask `NICK`; `461`/`401`/`432` operand+lookup errors; `433` onto a taken nick leaves both nicks on their UIDs. `sajoin.rs` (5): the `481` gate + inverse (joins nobody); success delivers the target its JOIN echo + NAMES on its mailbox and an existing member sees the JOIN; the override beats `+i`/`+k`/`+b` where the **same user's own JOIN is refused** (the inverse boundary); `461`/`401`/`403` errors land on the oper not the target; SAJOIN onto an already-held channel is a silent no-op (nothing delivered). The refactored `nick` (9) + `join` (25) + `help` (9) suites stay green. **No boot-golden** — the forced delivery is to a mailbox the handler units already assert; SA* emits the same `NICK`/`JOIN`/`MODE` lines the existing goldens characterize.
  - **Gate:** `cargo test -p leveva` green (1462 lib tests incl. the 9 new); `cargo clippy -p leveva --tests` clean; `cargo build -p leveva` 0 warnings.
  - **Plan:** `docs/superpowers/plans/2026-06-13-p11-slice152-sanick-sajoin.md`.

## 2026-06-14 — P11 slice 153: `SAPART` — the force-part companion to `SAJOIN`

`SAPART <nick> <channel>{,<channel>} [:reason]` — a leveva-native operator command that
forcibly parts a **local** user from one or more channels. The leave companion to slice 152's
`SAJOIN`, closing out the SA* oper-override family (`SAMODE` 151, `SANICK`+`SAJOIN` 152).

### Mechanism — reuse the canonical `PART` machinery (no drift)
Mirrors slice 152's SAJOIN approach: the side-effect core of `PART` is extracted so `SAPART`
*is* the real handler, differing only in **who is gated** and **where the replies go**.
- `command/part.rs`: extracted `part_one(ctx, parter, target, reason) -> Result<Message,
  PartError>` — runs `Channels::part`, fans the `PART` echo out to the channel's other local
  members, fires the S2S `local_part` relay, and **returns** the parter-facing echo (`Ok`) or a
  structured `PartError::{NoSuchChannel, NotOnChannel}` (`Err`). `part()` is now a thin loop
  over it (`Ok`→push echo, `Err`→`part_error_reply` addressed to the caller); a private
  `part_error_reply(ctx, to_nick, chan, err)` renders the `403`/`442` for whichever actor issued
  the command. Pure refactor — the existing `part` suite is the regression guard. New
  `pub(crate) force_part(ctx, parter, actor_nick, target, reason) -> Option<Message>`: on `Ok`
  delivers the echo to the **parted user's own mailbox** (`deliver_uid`); on `Err` returns the
  numeric addressed to `actor_nick` (the oper).
- `command/sapart.rs` (new): the oper gate (`481`), operand parse (`<nick> <channels>`, trailing
  = reason), `461`/`401`/remote-`NOTICE`/`record_of` resolution **identical to `sajoin`** (reuses
  `join::registered_view` for the synthetic target `Registered`), then per comma-separated
  channel `force_part`, collecting any error reply for the oper.
- `command/mod.rs`: `"SAPART" => sapart::sapart(...)` + `mod sapart;`. `help/SAPART.md` +
  `"SAPART"` in the `help.rs` `COMMANDS` list (both help invariants test-enforced).

### Divergences (leveva-native — no oracle)
Local targets only; a remote/mirrored target → a server `NOTICE` to the oper (no S2S forced-part
propagation — the `KILL`-local scope slices 151/152 kept). The oper gets no success numeric (like
`KILL`); only `481`/`461`/`401`/`403`/`442` come back. The leave is a transparent `:nick!user@host
PART …` line — no distinct `SAPART` verb, no server-notice (leveva has none) — indistinguishable
from the user's own `PART`. Gated on the bare oper bit, not an `OperPrivilege` ACL.

### Tests (TDD; inverse invariants + fuzzing)
`sapart.rs` units (6): the `481` gate **+ inverse** (a gated SAPART parts nobody); success forces a
local user out — the target's mailbox gets the `PART` echo (`bob!u@h`), a co-member sees it,
membership is gone, the oper gets no numeric; the reason rides to the `PART` trailing;
`461`/`401`/`403`/`442` all land on the **oper** not the target **+ inverse** (the target's other
memberships untouched, nothing delivered); a remote target → `NOTICE`, no state change; forcing the
last member out deletes the channel. Fuzz — `proptests::sapart_equals_the_targets_own_part` (256
cases): two identical worlds where a victim holds an arbitrary set of pool channels; in world A the
victim `PART`s an arbitrary subset itself, in world B an oper `SAPART`s the victim from the same
subset — asserts the **residual membership across every pool channel is identical**, the **channel
count (delete-on-empty) is identical**, and the **`PART` lines the victim sees are identical**
(world A: returned replies; world B: its mailbox) — i.e. SAPART differs from the target's own PART
only in the gate and reply routing, never in effect; never panics. **No boot-golden** — the forced
delivery is to a mailbox the units already assert, and `SAPART` emits the same `PART` line the
existing part goldens characterize.

**Plan:** [`docs/superpowers/plans/2026-06-14-p11-slice153-sapart.md`](../superpowers/plans/2026-06-14-p11-slice153-sapart.md)

**Gate:** `cargo test -p leveva` green (1469 lib tests incl. the 7 new + the refactored part/help
suites); `cargo clippy -p leveva --tests` clean; `cargo build --workspace` 0 warnings.
