commit 42fac0e37b6acfbe8b37efc1a5d7d050805beb5e
Author: Xe Iaso <me@xeiaso.net>
Date:   Fri Jun 12 19:39:33 2026 -0400

    docs(leveva): record P11 slice 129 (live-join NJOIN propagation)
    
    Plan file + p11.md entry (incl. the empirical oracle-wire investigation) +
    PLAN.md row bump to 129 slices; msgid S2S propagation follow-on moves to 130.

 PLAN.md                                            |  2 +-
 docs/progress-log/p11.md                           | 83 ++++++++++++++++++++++
 .../2026-06-12-p11-slice129-live-join-njoin.md     | 79 ++++++++++++++++++++
 3 files changed, 163 insertions(+), 1 deletion(-)
=== slice 129 plan file content head ===
commit 42fac0e37b6acfbe8b37efc1a5d7d050805beb5e
Author: Xe Iaso <me@xeiaso.net>
Date:   Fri Jun 12 19:39:33 2026 -0400

    docs(leveva): record P11 slice 129 (live-join NJOIN propagation)
    
    Plan file + p11.md entry (incl. the empirical oracle-wire investigation) +
    PLAN.md row bump to 129 slices; msgid S2S propagation follow-on moves to 130.

diff --git a/PLAN.md b/PLAN.md
index b221bdca..e45dba99 100644
--- a/PLAN.md
+++ b/PLAN.md
@@ -90,7 +90,7 @@ The leverage point: every `foo.c` already ships `foo_ext.h` (its public `extern`
 | **P8 — Delete the C + retire the oracle harness ✅ DONE** (per-sub-phase: [`PLAN-P8-progress.md`](PLAN-P8-progress.md) + [`docs/progress-log/p8.md`](docs/progress-log/p8.md)) | remaining C (the ~25 variadic sender trampolines + residual data globals) + `ircd-sys` C build + `ircd-golden` (L2) + `ircd-testkit`/`cref_*` archives (L1) + the frozen reference‑C tree | With all C _logic_ already Rust (P7 exit), delete the last C: replace the variadic sender trampolines with a non‑variadic Rust sender API at every call site (faithful `wire!`/`reply_one!`/`format!` first; leveva typed messages adopted alongside the IRC senders), drop the residual data globals via the data‑symbol seam (bindgen `extern` decls resolve to `#[no_mangle]` Rust defs at link), then drop **all** C compilation from `ircd-sys` (no more `cc::Build`), retire the differential harness (`cref_*`/L1 `ircd-testkit`/`ircd-golden` L2 can no longer be built once the oracle is gone), and **migrate the load‑bearing tests into `ircd-common`** as self‑contained Rust tests (own fixtures, no `cref_` oracle). **Progress (P8a–P8r — full entries in the progress logs):** **every variadic sender trampoline is now Rust** (P8a–P8m, incl. the keystones `sendto_one`/`sendto_flag`/`esendto_*`), and the five data‑global `.o`s are dropped outright (`s_auth.o` iauth globals P8n, `send.o` P8o, `s_bsd.o` `local[]`/`highest_fd`/… P8p, `ircd.o` `me`/`client`/timers/… P8q). **P8r dropped the last C‑logic TU `support.o`** — `dgets`/`make_isupport` ported to Rust + the `ipv6string`/`minus_one` data globals defined as `#[no_mangle]` statics (`snprintf_append` is dead in Rust — WHOX is field‑by‑field — so it died with the `.o`; `irc_sprintf` is deleted not ported, in P11). **Every ircd C TU is now Rust:** the link set holds only the generated `version.o` + the L1 harness's `ctruth.o`. **P8s migrated all 115 L1 `cref_` differentials into self‑contained `ircd-common` `insta` snapshot tests** (drive only the Rust port via `link_anchor()`, no oracle; soundness via the capture chain) — the suite is green + 0 warnings. **P8t ported the last *generated* C TU `version.c` to Rust** (`ircd-common/src/version.rs`): the data globals `generation`/`creation`/`pass_version`/`infotext`/`isupport` are now `#[no_mangle]` statics via the data‑symbol seam — `generation`/`creation` sourced from crate metadata at build time (`CARGO_PKG_VERSION` + an `ircd-common/build.rs` UTC build stamp), `pass_version`/`infotext` copied verbatim. `version.c.SH` generation + the `version.o` compile/archive are gone from `ircd-sys/build.rs`; `libircd_c.a` now holds **only** the L1 harness `ctruth.o`. (`creation` is now genuinely build‑time volatile, so the golden canonicalizer masks RPL_CREATED 003, matching the existing 371 Birth‑Date rule.) **P8u (FINAL) retired the oracle.** Ran the differential suite a last time green — L1 `ircd-testkit` all pass; L2 `ircd-golden` 86 pass + only the documented reference‑C‑garbage `s_serv_stats` flake (where Rust is the *correct* side) — then **dropped all C compilation** from `ircd-sys/build.rs`: the `make` object build, the `cref_*`/`ctruth.o`/`res.o` recompiles, the `libircd_c.a` archive, and the whole‑archive link + `-lz`/`-lm`/`-lcrypt` (none needed by Rust — `pow` resolves from glibc 2.29+). `build.rs` now only runs `configure` + bindgen over the C *headers* (the struct view `ircd-common` still uses until P9–P12) and expands the install‑path Makefile vars. `ircd-testkit` (L1) + `ircd-golden` (L2) are `exclude`d from the workspace (mothballed, git‑recoverable); the `ctruth.c`/`layout.rs` drift‑net is deleted. **The workspace is now 100% Rust — zero C TUs compiled.** **P8v (literal end of C) deleted the C *source tree* itself + retired `ircd-sys`:** froze the generated `bindings.rs` into a committed `ircd-common/src/bindings.rs` (a self‑alias `extern crate self as ircd_sys;` keeps every `ircd_sys::bindings::*` path resolving, zero src churn) + the install‑path consts as literals, then deleted `ircd-sys`, the mothballed `ircd-testkit`/`ircd-golden` oracle crates, the `iauth-rs` C‑iauth differential, and **all** C source (`common/ ircd/ iauth/ support/ contrib/ cbuild/ configure .clang-format* clangformat.yml`). `ircd-rs` calls `ircd_common::ircd::c_ircd_main` directly. **Not one line of C remains in the repo.** | **MET. Final differential run green; oracle mothballed; `cargo build --workspace` 0 warnings links pure Rust; `cargo test --workspace` 695 pass / 0 fail (P8v; was 698 before deleting the C‑oracle tests); the `ircd-common` snapshot tests carry the reference‑C correctness forward. C source tree deleted — repo is 100% Rust at the file level.** |
 | **P9 — std‑library cleanup ❌ RETIRED (2026‑06‑08)**     | — (was: whole Rust tree)                                                                                                                                                   | **Skipped by decision — superseded by the `leveva` greenfield.** P9 assumed an *in‑place* idiomatic transformation of the mechanical port (`MyMalloc`/`MyFree`→`Box`/`Vec`, `dbuf` freelist→owned, raw `libc`→`std`/`nix`, `[c_char;N]`→`[u8;N]`). Because the idiomatic end‑state is now a separate greenfield crate (`leveva`), `ircd-common` is throwaway code (the oracle, deleted at parity), so polishing it earns nothing. Nothing was implemented; the row is kept for provenance. | n/a — retired. |
 | **P10 — `leveva` greenfield foundations 🔶 IN PROGRESS** ([`docs/progress-log/p10.md`](docs/progress-log/p10.md)) | new `leveva` crate (lib) + `leveva-integration` differential tests                                                                                                        | The idiomatic‑Rust product, built from scratch (not transformed from the port). **Done so far:** RFC 1459 case‑folding (`casemap`); typed identifier strings (`IrcStr`/`IrcString` + `Nick`/`ChanName`/`Uid`/`Sid`/`Cid`/`ServerName`/`UserName`/`HostName` validating newtypes via `ident_newtype!`); `Message`/`MessageBuilder`; the full `Numeric` reply/error enum (184 codes, discriminant = wire code); a generic safe `patricia` trie; glob `matching`; `mode`; KDL `config` (model/parse/password/privilege); `rustls`/`tokio` `tls` endpoint with hot reload; `ident`. The async boot path (`main.rs`) binds listeners + watches certs but currently drops accepted connections — no protocol layer yet. Idiomatic Rust allowed everywhere; pulls real crates (tokio/rustls/kdl/nom/clap). | `cargo test -p leveva` green + clippy clean per module; `leveva-integration` pins each greenfield reimplementation against `ircd-common` (the oracle) within their shared domain (documented divergences asserted explicitly). |
-| **P11 — `leveva` protocol layer → feature parity 🔶 IN PROGRESS** ([`docs/progress-log/p11.md`](docs/progress-log/p11.md)) | `leveva` (client/server state machine + handlers) | The bulk of the remaining work: the connection + registration state machine, the post‑registration command handlers (JOIN/PRIVMSG/MODE/KICK/TOPIC/WHO/WHOIS/…), channels + channel/user modes, the S2S link/burst protocol (UID‑based: UNICK/NJOIN/SAVE/EOB), and `leveva-iauth` (native async auth — dnsbl/socks/webproxy/pipe/ident). Each slice is built idiomatically (owned per‑connection state, typed identifiers end‑to‑end, `Result`/`thiserror`, `format!`/typed builders — **no** `sprintf`/global `buf`), unit‑tested + boot‑golden + proptest‑fuzzed, and **differentially pinned against `ircd-common`** (or `iauth-rs` for auth) wherever a pure oracle entry point exists — structural skeleton + documented divergences, since leveva emits a clean modern burst rather than a byte copy. **Done: 128 slices** — full per‑slice detail (scope, mechanism, divergences, gate) lives in [`docs/progress-log/p11.md`](docs/progress-log/p11.md); the standing **testing plan** is at [`docs/superpowers/specs/2026-06-10-leveva-testing-plan.md`](docs/superpowers/specs/2026-06-10-leveva-testing-plan.md). The slices span the full client command surface (registration, channels + channel/user modes, WHO/WHOIS/WHOX, OPER/STATS), the UID‑based S2S link/burst/netsplit protocol (+ keepalive, live introduction, NJOIN chunking), `leveva-iauth` (dnsbl/socks/webproxy/pipe/ident), config live‑rehash (MOTD, opers/classes, allows/I‑lines incl. CIDR masks, admin/connect/options), a channel‑mode rework (oper‑only‑join `+O`), CertFP, an ongoing **IRCv3 track** (cap‑notify, multi‑prefix, message‑tags + delivery plane, away/invite/echo/server‑time/userhost‑in‑names, MONITOR + extended‑monitor, chghost/setname, ip‑cloaking, standard‑replies, message‑redaction, no‑implicit‑names, draft/pre‑away, utf8only, WebSocket transport), and the **native cross‑daemon command‑skeleton differential** harness (slices 92–95: an in‑process `ircd-common` oracle diffed against leveva for MODE, JOIN/PART/KICK, the read‑only WHOIS/WHO/NAMES/LIST/TOPIC query cluster, and PRIVMSG/NOTICE delivery — the last of which *closed* a divergence by making leveva emit the oracle's min‑params `461` instead of RFC `411`/`412`). Slices 96–99 then closed four more differential divergences by converging leveva to the oracle/RFC: 96 = `JOIN 0` part‑all (RFC 2812 §3.2.1); 97 = WHOIS `317 RPL_WHOISIDLE` (per‑connection idle/signon, `IDLE_FROM_MSG`); 98 = `MODE +l` no‑arg → `461`; 99 = welcome‑burst `253 RPL_LUSERUNKNOWN` via a live half‑open gauge (252 stays dormant until an oper count lands); 100 = WHOWAS/USERHOST/ISON native‑oracle skeleton differential + proptest fuzzing (full agreement; bare‑WHOWAS 431‑vs‑461 kept documented as leveva‑RFC‑correct); 101 = server‑info cluster (VERSION/TIME/ADMIN/INFO/LUSERS/USERS/MOTD) native skeleton differential + fuzzing, **closing** the `hunt_server` `<target>` → `402 ERR_NOSUCHSERVER` gap (unknown target server now 402s instead of being ignored; remote‑peer forward deferred), with VERSION‑005/INFO‑length/LUSERS‑mask kept as documented leveva‑native divergences. 102 = S2S burst + netsplit native‑oracle **verb‑skeleton** differential + fuzzing — a *link‑accepting* in‑process oracle (`Prot::Off`, own test binary/world/fixture) diffed against a leveva subprocess; a new `verb_skeleton` extractor (inverts `numeric_codes`); both daemons burst the identical `[PASS, SERVER, UNICK, EOB]` + discrete `EOBACK`, and both relay a `QUIT` on peer SQUIT (401‑unreachable inverse) — full agreement (the no‑oper‑split‑WALLOPS omission is the lone leveva‑native/RFC‑correct divergence). Slices 103–107 (a parallel workflow batch) extended the skeleton differential to the remaining client clusters: 103 = AWAY/INVITE/`+i`‑join (agreement; prefix‑less‑INVITE `403` documented); 104 = NICK errors/collision (agreement; bare‑NICK `431`‑vs‑`461` + reject‑vs‑truncate documented); 105 = registration errors, **closing** too‑short USER/PASS → `461` (oracle min‑params parity, not the old unconditional `462`); 106 = SUMMON, **closing** gap #2 (→ `411`/`445`/`402`, `ERR_SUMMONDISABLED`); 107 = LINKS/MAP/TRACE, **closing** `LINKS <remote>` unknown server → `402` (`hunt_server` parity). 108 = OPER + privileged‑command gate (OPER/KILL/WALLOPS/CONNECT/SQUIT/DIE/RESTART/REHASH) native skeleton differential + fuzzing, **closing** two leveva ordering bugs — a non‑oper bare `CONNECT`/`SQUIT` now `481` (privilege gated first, the oracle's `m_nopriv` routing) instead of `461`; the non‑oper `WALLOPS` `481`‑vs‑oracle‑silent kept as a documented leveva‑RFC‑correct divergence. 109 = STATS query‑cluster native skeleton differential + fuzzing (characterization, no leveva bug) — agreement on `u`/`o`/`c`/`k`/`f`/`a`/`p`/`?`/unrecognized + the `y`/`i` config‑block families (seeding the leveva test world one class+allow to mirror the fixture) + the slice‑101 `STATS <q> <bad‑target>` → `402` guard; four documented divergences (bare `STATS` `461`‑vs‑`219` RFC‑query‑optional, `l`/`L`/`P`/`t` state‑absent per‑link/listener/tstats lines, `m`/`z` count‑dependent 212/249 families). 110 = **info‑query S2S forward** (first slice to CLOSE a *forwarding* bug): the `hunt_server` remote half of `command/hunt.rs` (deferred at slice 101) now forwards `VERSION`/`TIME`/`ADMIN`/`INFO`/`STATS`/`LUSERS`/`MOTD`/`USERS` with a `<target>` naming a linked peer over S2S (`Hunt::Remote { uplink }` + a UID‑prefixed verbatim forward) and routes the answering server's numeric replies back to the originating client (a new `relay::inbound_numeric` + a 3‑digit `s2s::dispatch` arm) — per THE STANDING RULE, the oracle forwards these so leveva must too; the originating side only (the answering side is a follow‑on). Native‑oracle skeleton differential: full agreement on all 8 verbs (both `hunt_server` target indices) forwarding + reply‑back, with unknown‑target‑402 and own‑name‑local both‑direction inverses, + fuzzing (random forwardable verb generalizes; arbitrary peer numeric never wedges leveva). The **answering side** is closed too (same day): `s2s::query::inbound_query` answers a query a peer forwards on behalf of a remote client (us→answer back / further‑remote→forward onward / unknown→402), via a **shared** `command::query_answer` (the same fn the client dispatch uses — its 8 cluster arms collapsed into one); answer‑side differential agrees on TIME/ADMIN/MOTD/USERS/STATS/LUSERS, VERSION = the documented `005`‑superset divergence. 111 = **S2S inbound live‑relay** native skeleton differential + fuzzing (characterization, no leveva bug) — the last undiffed S2S surface: a linked peer bursts a remote op into a channel with a local co‑member, then injects `PRIVMSG`/`NOTICE`/`TOPIC`/`MODE`/`KICK`/`PART`; both daemons relay the identical `[PRIVMSG,NOTICE,TOPIC,MODE,KICK,PART]` verb skeleton to the co‑member (a local `relayed()` extractor over the client relay vocabulary), with the KICK‑removes‑only‑victim and PART‑removes‑actor inverses asserted mid‑sequence. With the differential matrix complete (111 = last undiffed surface), 112 turns to the testing‑plan §4 fuzzing gaps: **nick‑collision resolution** fuzzing (the S2S `handle_unick`/`handle_save` first‑claimant‑wins policy) pinned against an independent first‑claimant model + freed‑slot/double‑collision inverses — a proptest, not a differential, since the policy deliberately diverges from the oracle's nick‑timestamp arbitration. 113 closes the §4 `post_registration` gap: **pre-/post-registration gating** fuzzing (the `Session::dispatch`→`Registration::apply` gate — exempt set `{NICK,USER,PASS,CAP,QUIT}`; every other verb `451`s before registration and never after) against a trivial `registered = saw-NICK && saw-USER` model + the before/after gate-flip inverse — and the `arbitrary_command_bytes` property **found a real bug**: the `feed` framer split only on `\n`, so an embedded bare CR survived into the parsed command and was reflected into a malformed `421`; fixed by framing on CR-or-LF (classic `dbuf_getmsg`). Also fixed a stochastically-surfaced family of five stale hunt_server `<target>`→`402` proptests (slice 101/107/109 fallout). 114 closes the §4 `VERSION` gap: **VERSION fuzzing** — a leveva-native `version_proptest` (4 properties) covering the one server-info surface the oracle differential can't touch (VERSION's `005` ISUPPORT superset is excluded from the strict-agree domain as a documented divergence): local target (absent/empty/own-name-glob) → `351`+all-`005`, present non-matching target → lone `402` (with the never-leak inverses), the `local_xor_402` round-trip completeness invariant against the `matches(target, SERVER)` model (exercising wildcard globs), and `arbitrary_version_bytes` panic-freedom. A separate prep commit fixed pre-existing v0.0.2-bump breakage (`cargo test -p leveva` was red on HEAD): the version string is now masked bump-proof in the golden `canonicalize()` (`leveva-<VER>`) across 13 snapshots, and 3 lib unit tests interpolate `crate::server::VERSION` instead of a literal. 115 closes the §4 native-iauth gap: **iauth registration-seam fuzzing** — a leveva-native `iauth_seam_proptest` (5 properties) drives a real auth-enabled `Session` (`iauth { ident }`, so finalize defers to the verdict) over the `resolve_auth`→`finalize_registration` seam with random verdicts × random arrival order (verdict before/after NICK+USER, before/after `CAP END`), model-locked to the deny gate (465+ERROR+close, no welcome) and the `~` username rule, with the headline being **byte-identical wire output regardless of verdict arrival order** + the both-gates-commute invariant + arbitrary-bytes panic-freedom/mutual-exclusion. With this the §4 "concrete fuzzing gaps" list is effectively exhausted (only the deferred prometheus golden + the optional nightly cargo-fuzz tier remain). 116 closes the last non-nightly §4 gap (the prometheus-output golden) by giving `Counters::encode_text()` a **real consumer**: a new top-level `metrics { port; bind? }` config block that, when set, stands up an axum `GET /metrics` HTTP endpoint (reusing the WebSocket-transport axum dep) serving the prometheus text exposition — pinned by a boot golden (register a client, raw-HTTP scrape `/metrics`, snapshot the canonicalized body) and a 3-property `metrics_endpoint_proptest` fuzzing the exposition (clean-label model round-trip + raw-gauge semantics, an adversarial-label escaping-agnostic conservation invariant since a hostile verb becomes a prometheus label, and a live-Session exposed-label-set round-trip). 117 closes the §4 "features fuzzed but never boot-tested" tail for the **client keepalive** plane (heartbeat + ping): a `golden_keepalive` boot golden (reusing the 2s-`ping-freq` `s2s_fastping.kdl`) drives the real binary over a live socket — client `PING`→`PONG` echo, server-initiated `PING` of an idle client, ping-timeout `ERROR :Closing Link: (Ping timeout)` + socket close, and the inverse (a client that answers the keepalive is never dropped) — the client-plane twin of the existing `golden_s2s_keepalive`; plus a Session-layer `keepalive_proptest` fuzzing `Session::check_ping`/`record_activity` over random schedules to pin the wire+state contract (only `PING`/`ERROR` lines, no timeout without a prior ping, idempotent close, active-never-dropped, `freq==0` disables) — the layer the pure-core `heartbeat_proptest` never reached. 118 lands the §4 "cargo-fuzz tier over `Message::parse` + the full `Session::feed` byte path" as its verifiable structured-fuzz analogue (the libfuzzer tier needs a nightly toolchain) — `feed_framing_proptest` drives arbitrary bytes through the framer in arbitrary chunk boundaries (never-panic/well-formed-output, chunk-boundary reassembly invariance, the 512/8191 limit edges) and **found+fixed a real unbounded-`self.buf` DoS**: the raw-TCP serve loop fed 4 KB chunks straight into an uncapped accumulation buffer, so a client that never sent a CR/LF grew it without bound — now bounded at `MAX_INBOUND_LINE` (tag budget + body = 8703) with a `417 ERR_INPUTTOOLONG` + skip-to-terminator resync, faithful in spirit to `dbuf_getmsg`'s bounded line buffer; pinned by `golden_recvq` (20 KB unterminated blob → `417` + resync to a normal registration through the assembled daemon). With this the §4 concrete fuzzing gaps are exhausted (only the optional nightly cargo-fuzz tier remains). 119 locks the maintainer's **hard rule** (*leveva MUST NOT support S2S commands on client connections; ENCAP MUST return invalid command on client ports*): the S2S-only verb set `{ENCAP,UNICK,NJOIN,SAVE,EOB,EOBACK,SERVER,SMASK,SDIE}` (verbs `s2s::dispatch` handles that aren't also client commands) is a plain unknown command on a client port — `421` post-registration / `451` pre-registration, **never interpreted** — a deliberate divergence from the oracle's status-column routing (`ENCAP`→`m_nop`/`HAZH`→`m_hash`/`DNS`→`m_dns`) that **overrides THE STANDING RULE** for S2S verbs (leveva routes client/server by the listener `server-only` flag, never by handshake content); a regression-lock + **security fuzz** slice (no production change — the behavior already held) with a unit trio (incl. the forged `:victim ENCAP * CHGHOST` host-spoof → `421`, host untouched), a `golden_s2s_reject` boot golden (all 9 verbs `421` + `WHOIS` proving the host stayed `127.0.0.1` and the session resynced), and a 4-property `s2s_client_reject_proptest` pinning the headline invariant — an S2S verb (arbitrary args, forged prefix, dangerous CHGHOST/UNICK/NJOIN/SAVE payloads) yields exactly one rejection numeric and **zero state mutation** (no registry/server/user/channel growth, no host/realname/nick change), never wedging the session. 120 enforces the maintainer's directive (*leveva MUST reject invalid UTF-8 in client frames; leveva is UTF-8 only; ensure it at the message-parsing level — that transitively proves everything else*): the `UTF8ONLY` gate (slice 76) moves from the framing layer (`Session::feed`'s hand-rolled `str::from_utf8`) into the parser as `Message::parse_bytes(&[u8])` → `ParseError::InvalidUtf8` — the single byte→`Message` boundary, so every consumer of a parsed `Message` (handlers, relay plane, S2S) is *transitively* UTF-8-safe (a `Message`'s fields are `String`, so `parse_bytes` Ok ⟹ input was valid UTF-8 is the whole proof); `feed` now just translates the parse error to the `INVALID_UTF8` `FAIL` (client-frame wire output byte-identical, `golden_utf8only`/`utf8only_proptest` unaffected — both client transports already funnel through `feed`); a leveva-native hardening slice (no differential — the C oracle is byte-agnostic), pinned by 3 message unit tests + a 3-property `parse_utf8_proptest` whose headline is *`parse_bytes` admits a line iff it is valid UTF-8* (+ the inverse byte-entry≡str-entry and the transitive `to_wire`-is-UTF-8 wire proof); S2S/handshake reader paths keep `from_utf8_lossy` by deliberate scope (trusted peer, separate trust domain). 121 enforces the maintainer's directive (*leveva MUST support IRC lines whose non-tag portion can be up to 2048 **graphemes**, not just 512 bytes; advertise `LINELEN=2048` in ISUPPORT*): a new `LINELEN=2048` (graphemes, UAX #29 — not bytes, so a 2048-char multi-byte line is fully supported) replaces the old 510-byte `to_wire` body cut with a grapheme-cluster truncation (`unicode-segmentation`, never splits a cluster), the framer ceiling `MAX_INBOUND_LINE` rises to `MAX_TAG_DATA_LEN + MAX_BODY_BYTES` (8191 + 2048×64 = 139263) so the longer lines are accepted before the `417` recvQ guard, and ISUPPORT advertises the new `LINELEN` token (`MAX_MESSAGE_LEN`/`MAX_CONTENT_LEN` stay as the RFC floor / chunker budget — `ison`/`monitor`/`s2s::burst` keep packing to 510 B, no S2S drift); a leveva-native slice (no oracle differential — the C oracle truncates at 512 B and advertises no `LINELEN`), pinned by message/isupport/session units (incl. the 50 KB-line-accepted + still-417-past-the-raised-ceiling inverses) and the **fuzzing** `linelen_proptest` (headline: `to_wire` body == full body truncated to `LINELEN` graphemes, + the within-budget byte-identical round-trip + the never-split-a-grapheme prefix invariant over arbitrary Unicode). 122 begins the S2S-notify-propagation parity area (closing the IRCv3-track "single-server-local" divergences): **AWAY propagation** — AWAY becomes a network-propagated command (the faithful first-class `:<uid> AWAY [:msg]` carrier, NOT `ENCAP`, matching the oracle's `m_away` `sendto_serv_butone`) via a new `s2s/away.rs` (`local_away` outbound broadcast + `inbound_away` dispatch arm: toggle the remote user's `+a` mirror bit + `registry.set_away`, away-notify local capable co-members, onward-relay split-horizon) plus a burst `:<uid> AWAY :<msg>` line after an away user's UNICK; and the maintainer-requested **self umode echo** — on an actual `+a`/`-a` flip the issuer also gets `:nick MODE nick :±a` after the 306/305 (a message-only `AWAY :new` re-notifies/re-propagates but emits no MODE). leveva-native (no differential — the oracle emits neither away-notify nor the self-MODE echo); gate = s2s/command/burst units + `golden_s2s_away` (both directions) + the `away_s2s_proptest` inbound-lockstep/panic-freedom fuzzing + the `away_proptest` MODE-echo update. 123 continues the area with **INVITE propagation**: INVITE becomes a network-broadcast command (the first-class `:<inviter-uid> INVITE <target-uid> :<channel>` carrier — the oracle propagates point-to-point toward the target, leveva broadcasts to all peers so a remote `invite-notify` op is reached, a documented native divergence) via a new `s2s/invite.rs` (`local_invite` outbound + `inbound_invite` dispatch arm: direct relay + a one-shot bypass token — recorded iff the remote inviter `is_op`, the oracle `add_invite` guard, via a new `Channels::note_invite` — to a local target, invite-notify local capable ops, onward-relay split-horizon); `command/invite.rs` now shares `s2s::invite::notify_channel_ops`, propagates via `local_invite`, and gates its direct relay on `is_local_uid` (a remote target is reached only by its home server, no stray link line); gate = s2s/command units + `golden_s2s_invite` (both directions) + the `invite_s2s_proptest` token-policy/panic-freedom fuzzing. 124 continues the area with **MONITOR live S2S propagation**: the IRCv3 `MONITOR` `730`/`731` push (slice 70) fired only on local online/offline events, so a remote user coming online/quitting/renaming/netsplitting behind a peer never notified a local watcher — unlike AWAY/INVITE this is **not** a propagated command (IRCnet has no `WATCH`/`MONITOR`, so no oracle differential; leveva-native) but a hook of the four existing remote-transition S2S seams to the same `monitor::notify_online`/`notify_offline` fan-out the local seams use (the `Monitors` reverse index is already network-wide, so zero new state): `s2s/unick.rs` clean-claim → `730` (the collision arm registers under the UID and pushes nothing — the colliding nick's first claimant already notified), `s2s/squit.rs::quit_remote_user` → `731` (one body, funnelled by both a single relayed `QUIT` and a whole-server `SQUIT`; an unmirrored `NJOIN`-only ghost with no registry nick pushes nothing), `s2s/relay.rs::inbound_nick` → `731`(old)+`730`(new) (the local `command/nick.rs` shape), and `s2s/save.rs::handle_save` → `731` for the nick a `SAVE` vacates (no `730` — the new identity is a bare UID, not a monitorable nick); gate = 7 seam units + `golden_s2s_monitor` (online/rename/offline pushes) + the `monitor_s2s_proptest` presence-model/panic-freedom fuzzing. 125 continues the area with **REDACT (`message-redaction`) S2S propagation**: the IRCv3 message-redaction `REDACT` relay (slice 68) was single-server-local (a channel REDACT reached only local cap members; a remote nick target was dropped), so a member of the channel on another server — or a remote nick recipient — never saw the redaction; the fix makes REDACT a propagated command (the first-class `:<sender-uid> REDACT <target> <msgid> [:reason]` carrier — the spec relay model, not `ENCAP`; like MONITOR this is leveva-native, the C oracle has no `message-redaction` so **no differential**) via a new `s2s/redact.rs` (`local_redact_channel` outbound broadcast for a channel target + `route_redact_to_remote` for a remote nick + an `inbound_redact` dispatch arm: deliver the client-form line to local `draft/message-redaction`-capable members/nick, no re-gate of the channel send eligibility — the originating server already validated `can_send`, exactly as inbound PRIVMSG/TAGMSG — then onward-relay split-horizon); `command/redact.rs` now broadcasts a channel REDACT via `local_redact_channel` after the local fan-out and routes a remote-nick REDACT via `route_redact_to_remote` (replacing the old dropped `Some(_) => Vec::new()` arm), the remote recipient's cap gated by *its* home server; gate = 7 s2s units + `golden_s2s_redact` (both directions) + the `redact_s2s_proptest` cap-delivery/onward-relay/panic-freedom fuzzing. 126 is the **S2S capability-negotiation foundation** the maintainer required before the remaining tag work — it closes a latent bug: slices 58–66 attached client-only (`@+…`) tags to S2S lines for *every* peer unconditionally, so a tag-blind peer would mis-parse the leading `@`. leveva now announces capabilities with a named-token **`CAPAB`** verb carried as the first burst line `:<sid> ENCAP * CAPAB :message-tags` — it **rides `ENCAP`** because a *bare* unknown server command is fatal in IRCnet 2.11 (verified: the `ircd-common` oracle replies `SQUIT`+`ERROR :Closing Link`; `ENCAP` is routed to `m_nop` and tolerated, so the link survives), and is **link-local** (interpreted, never relayed onward). Capabilities are recorded per-link (`PeerCaps` on `PeerLink` + the `PeerLinks` routing table, set from the inbound `CAPAB` via `forward::inbound_encap`'s new arm). Tag emission is gated at a single **egress** point: callers always build the tagged wire and `PeerLinks::broadcast`/`route` strip the leading `@tags` for a non-tag peer (a byte cut, no-op when untagged), while `broadcast_tag_only`/`route_tag_only` send a tag-only `TAGMSG` only to tag peers (a non-tag peer is skipped). leveva-native (no oracle differential for the tags); the burst's extra `ENCAP * CAPAB` line is a documented divergence the `s2s_skeleton_differential` excludes before asserting burst-skeleton agreement; gate = `s2s/caps.rs`/`burst`/`links`/`relay` units + `golden_s2s_caps` (a tag-blind peer's tagged PRIVMSG arrives stripped, its TAGMSG not at all, end-to-end) + `caps_s2s_proptest` (the never-leak invariant) + `s2s_oracle_link` (bare-CAPAB-SQUITs vs ENCAP-CAPAB-tolerated against the real oracle). 127 **reworks slice 125's REDACT carrier from a first-class verb to `ENCAP`** — slice 126 proved a *bare* unknown server command is fatal in IRCnet 2.11 (the oracle SQUITs), so a first-class `:uid REDACT …` is either dropped by a non-implementing peer or kills a strict link; leveva now carries it as `:<uid> ENCAP * REDACT <target> <msgid> [:reason]` exactly like CHGHOST/CERTFP/SETNAME (delivery semantics unchanged: channel broadcast + remote-nick point-to-point route, the bare client-form REDACT delivered to local cap members/nick). `inbound_redact`→`apply_encap_redact` (delivers locally, the caller `forward::inbound_encap` onward-relays the ENCAP verbatim); the top-level `"REDACT"` S2S dispatch arm is removed (REDACT stays a client command, reached over S2S only via the `ENCAP` arm). Still leveva-native (no oracle differential). Gate: `s2s/redact.rs`/`forward.rs` units (incl. `encap_redact_is_applied_and_still_relayed`) + `golden_s2s_redact` (snapshot regenerated to the ENCAP egress) + `redact_s2s_proptest` with the **new headline P4** `outbound_redact_always_rides_encap` (every emitted wire is `ENCAP`-wrapped — leveva never puts a bare `REDACT` server command on the wire). 128 = **outgoing auto-connect** for `connect{}` blocks — the idiomatic counterpart of `try_connections`: a pure `autoconnect::AutoConnect::due` (master switch + per-block `autoconnect`/`port`/class `connect-freq`/already-linked/per-block-cooldown ladder, `connect-freq` doubling as the retry interval, `saturating_add` cooldown) driven by a `main` ticker (spawned only when `options.auto-connect`; immediate-first-tick boot dial; live-rehash-aware) that queues each due peer on the same `link::request` plane `CONNECT` uses; leveva-native (divergences: all-eligible-not-one-best, no deferral NOTICE, master not live-rehashable), gated by 10 unit + `autoconnect_proptest` (eligibility-model + cooldown + i64::MAX panic-freedom) + `golden_autoconnect` (unattended boot dial, no client/CONNECT). **Follow-on (same area): msgid S2S propagation (gated on slice 126's egress).** |  Per‑slice: leveva boots and serves the slice; leveva golden snapshot + proptest green; the `leveva-integration` differential agrees with `ircd-common` on the shared skeleton with divergences asserted. Across the eventual matrix: registration, channels, WHO/WHOIS/WHOX, OPER/STATS, server burst, netsplit, rehash, restart; iauth end‑to‑end. |
+| **P11 — `leveva` protocol layer → feature parity 🔶 IN PROGRESS** ([`docs/progress-log/p11.md`](docs/progress-log/p11.md)) | `leveva` (client/server state machine + handlers) | The bulk of the remaining work: the connection + registration state machine, the post‑registration command handlers (JOIN/PRIVMSG/MODE/KICK/TOPIC/WHO/WHOIS/…), channels + channel/user modes, the S2S link/burst protocol (UID‑based: UNICK/NJOIN/SAVE/EOB), and `leveva-iauth` (native async auth — dnsbl/socks/webproxy/pipe/ident). Each slice is built idiomatically (owned per‑connection state, typed identifiers end‑to‑end, `Result`/`thiserror`, `format!`/typed builders — **no** `sprintf`/global `buf`), unit‑tested + boot‑golden + proptest‑fuzzed, and **differentially pinned against `ircd-common`** (or `iauth-rs` for auth) wherever a pure oracle entry point exists — structural skeleton + documented divergences, since leveva emits a clean modern burst rather than a byte copy. **Done: 129 slices** — full per‑slice detail (scope, mechanism, divergences, gate) lives in [`docs/progress-log/p11.md`](docs/progress-log/p11.md); the standing **testing plan** is at [`docs/superpowers/specs/2026-06-10-leveva-testing-plan.md`](docs/superpowers/specs/2026-06-10-leveva-testing-plan.md). The slices span the full client command surface (registration, channels + channel/user modes, WHO/WHOIS/WHOX, OPER/STATS), the UID‑based S2S link/burst/netsplit protocol (+ keepalive, live introduction, NJOIN chunking), `leveva-iauth` (dnsbl/socks/webproxy/pipe/ident), config live‑rehash (MOTD, opers/classes, allows/I‑lines incl. CIDR masks, admin/connect/options), a channel‑mode rework (oper‑only‑join `+O`), CertFP, an ongoing **IRCv3 track** (cap‑notify, multi‑prefix, message‑tags + delivery plane, away/invite/echo/server‑time/userhost‑in‑names, MONITOR + extended‑monitor, chghost/setname, ip‑cloaking, standard‑replies, message‑redaction, no‑implicit‑names, draft/pre‑away, utf8only, WebSocket transport), and the **native cross‑daemon command‑skeleton differential** harness (slices 92–95: an in‑process `ircd-common` oracle diffed against leveva for MODE, JOIN/PART/KICK, the read‑only WHOIS/WHO/NAMES/LIST/TOPIC query cluster, and PRIVMSG/NOTICE delivery — the last of which *closed* a divergence by making leveva emit the oracle's min‑params `461` instead of RFC `411`/`412`). Slices 96–99 then closed four more differential divergences by converging leveva to the oracle/RFC: 96 = `JOIN 0` part‑all (RFC 2812 §3.2.1); 97 = WHOIS `317 RPL_WHOISIDLE` (per‑connection idle/signon, `IDLE_FROM_MSG`); 98 = `MODE +l` no‑arg → `461`; 99 = welcome‑burst `253 RPL_LUSERUNKNOWN` via a live half‑open gauge (252 stays dormant until an oper count lands); 100 = WHOWAS/USERHOST/ISON native‑oracle skeleton differential + proptest fuzzing (full agreement; bare‑WHOWAS 431‑vs‑461 kept documented as leveva‑RFC‑correct); 101 = server‑info cluster (VERSION/TIME/ADMIN/INFO/LUSERS/USERS/MOTD) native skeleton differential + fuzzing, **closing** the `hunt_server` `<target>` → `402 ERR_NOSUCHSERVER` gap (unknown target server now 402s instead of being ignored; remote‑peer forward deferred), with VERSION‑005/INFO‑length/LUSERS‑mask kept as documented leveva‑native divergences. 102 = S2S burst + netsplit native‑oracle **verb‑skeleton** differential + fuzzing — a *link‑accepting* in‑process oracle (`Prot::Off`, own test binary/world/fixture) diffed against a leveva subprocess; a new `verb_skeleton` extractor (inverts `numeric_codes`); both daemons burst the identical `[PASS, SERVER, UNICK, EOB]` + discrete `EOBACK`, and both relay a `QUIT` on peer SQUIT (401‑unreachable inverse) — full agreement (the no‑oper‑split‑WALLOPS omission is the lone leveva‑native/RFC‑correct divergence). Slices 103–107 (a parallel workflow batch) extended the skeleton differential to the remaining client clusters: 103 = AWAY/INVITE/`+i`‑join (agreement; prefix‑less‑INVITE `403` documented); 104 = NICK errors/collision (agreement; bare‑NICK `431`‑vs‑`461` + reject‑vs‑truncate documented); 105 = registration errors, **closing** too‑short USER/PASS → `461` (oracle min‑params parity, not the old unconditional `462`); 106 = SUMMON, **closing** gap #2 (→ `411`/`445`/`402`, `ERR_SUMMONDISABLED`); 107 = LINKS/MAP/TRACE, **closing** `LINKS <remote>` unknown server → `402` (`hunt_server` parity). 108 = OPER + privileged‑command gate (OPER/KILL/WALLOPS/CONNECT/SQUIT/DIE/RESTART/REHASH) native skeleton differential + fuzzing, **closing** two leveva ordering bugs — a non‑oper bare `CONNECT`/`SQUIT` now `481` (privilege gated first, the oracle's `m_nopriv` routing) instead of `461`; the non‑oper `WALLOPS` `481`‑vs‑oracle‑silent kept as a documented leveva‑RFC‑correct divergence. 109 = STATS query‑cluster native skeleton differential + fuzzing (characterization, no leveva bug) — agreement on `u`/`o`/`c`/`k`/`f`/`a`/`p`/`?`/unrecognized + the `y`/`i` config‑block families (seeding the leveva test world one class+allow to mirror the fixture) + the slice‑101 `STATS <q> <bad‑target>` → `402` guard; four documented divergences (bare `STATS` `461`‑vs‑`219` RFC‑query‑optional, `l`/`L`/`P`/`t` state‑absent per‑link/listener/tstats lines, `m`/`z` count‑dependent 212/249 families). 110 = **info‑query S2S forward** (first slice to CLOSE a *forwarding* bug): the `hunt_server` remote half of `command/hunt.rs` (deferred at slice 101) now forwards `VERSION`/`TIME`/`ADMIN`/`INFO`/`STATS`/`LUSERS`/`MOTD`/`USERS` with a `<target>` naming a linked peer over S2S (`Hunt::Remote { uplink }` + a UID‑prefixed verbatim forward) and routes the answering server's numeric replies back to the originating client (a new `relay::inbound_numeric` + a 3‑digit `s2s::dispatch` arm) — per THE STANDING RULE, the oracle forwards these so leveva must too; the originating side only (the answering side is a follow‑on). Native‑oracle skeleton differential: full agreement on all 8 verbs (both `hunt_server` target indices) forwarding + reply‑back, with unknown‑target‑402 and own‑name‑local both‑direction inverses, + fuzzing (random forwardable verb generalizes; arbitrary peer numeric never wedges leveva). The **answering side** is closed too (same day): `s2s::query::inbound_query` answers a query a peer forwards on behalf of a remote client (us→answer back / further‑remote→forward onward / unknown→402), via a **shared** `command::query_answer` (the same fn the client dispatch uses — its 8 cluster arms collapsed into one); answer‑side differential agrees on TIME/ADMIN/MOTD/USERS/STATS/LUSERS, VERSION = the documented `005`‑superset divergence. 111 = **S2S inbound live‑relay** native skeleton differential + fuzzing (characterization, no leveva bug) — the last undiffed S2S surface: a linked peer bursts a remote op into a channel with a local co‑member, then injects `PRIVMSG`/`NOTICE`/`TOPIC`/`MODE`/`KICK`/`PART`; both daemons relay the identical `[PRIVMSG,NOTICE,TOPIC,MODE,KICK,PART]` verb skeleton to the co‑member (a local `relayed()` extractor over the client relay vocabulary), with the KICK‑removes‑only‑victim and PART‑removes‑actor inverses asserted mid‑sequence. With the differential matrix complete (111 = last undiffed surface), 112 turns to the testing‑plan §4 fuzzing gaps: **nick‑collision resolution** fuzzing (the S2S `handle_unick`/`handle_save` first‑claimant‑wins policy) pinned against an independent first‑claimant model + freed‑slot/double‑collision inverses — a proptest, not a differential, since the policy deliberately diverges from the oracle's nick‑timestamp arbitration. 113 closes the §4 `post_registration` gap: **pre-/post-registration gating** fuzzing (the `Session::dispatch`→`Registration::apply` gate — exempt set `{NICK,USER,PASS,CAP,QUIT}`; every other verb `451`s before registration and never after) against a trivial `registered = saw-NICK && saw-USER` model + the before/after gate-flip inverse — and the `arbitrary_command_bytes` property **found a real bug**: the `feed` framer split only on `\n`, so an embedded bare CR survived into the parsed command and was reflected into a malformed `421`; fixed by framing on CR-or-LF (classic `dbuf_getmsg`). Also fixed a stochastically-surfaced family of five stale hunt_server `<target>`→`402` proptests (slice 101/107/109 fallout). 114 closes the §4 `VERSION` gap: **VERSION fuzzing** — a leveva-native `version_proptest` (4 properties) covering the one server-info surface the oracle differential can't touch (VERSION's `005` ISUPPORT superset is excluded from the strict-agree domain as a documented divergence): local target (absent/empty/own-name-glob) → `351`+all-`005`, present non-matching target → lone `402` (with the never-leak inverses), the `local_xor_402` round-trip completeness invariant against the `matches(target, SERVER)` model (exercising wildcard globs), and `arbitrary_version_bytes` panic-freedom. A separate prep commit fixed pre-existing v0.0.2-bump breakage (`cargo test -p leveva` was red on HEAD): the version string is now masked bump-proof in the golden `canonicalize()` (`leveva-<VER>`) across 13 snapshots, and 3 lib unit tests interpolate `crate::server::VERSION` instead of a literal. 115 closes the §4 native-iauth gap: **iauth registration-seam fuzzing** — a leveva-native `iauth_seam_proptest` (5 properties) drives a real auth-enabled `Session` (`iauth { ident }`, so finalize defers to the verdict) over the `resolve_auth`→`finalize_registration` seam with random verdicts × random arrival order (verdict before/after NICK+USER, before/after `CAP END`), model-locked to the deny gate (465+ERROR+close, no welcome) and the `~` username rule, with the headline being **byte-identical wire output regardless of verdict arrival order** + the both-gates-commute invariant + arbitrary-bytes panic-freedom/mutual-exclusion. With this the §4 "concrete fuzzing gaps" list is effectively exhausted (only the deferred prometheus golden + the optional nightly cargo-fuzz tier remain). 116 closes the last non-nightly §4 gap (the prometheus-output golden) by giving `Counters::encode_text()` a **real consumer**: a new top-level `metrics { port; bind? }` config block that, when set, stands up an axum `GET /metrics` HTTP endpoint (reusing the WebSocket-transport axum dep) serving the prometheus text exposition — pinned by a boot golden (register a client, raw-HTTP scrape `/metrics`, snapshot the canonicalized body) and a 3-property `metrics_endpoint_proptest` fuzzing the exposition (clean-label model round-trip + raw-gauge semantics, an adversarial-label escaping-agnostic conservation invariant since a hostile verb becomes a prometheus label, and a live-Session exposed-label-set round-trip). 117 closes the §4 "features fuzzed but never boot-tested" tail for the **client keepalive** plane (heartbeat + ping): a `golden_keepalive` boot golden (reusing the 2s-`ping-freq` `s2s_fastping.kdl`) drives the real binary over a live socket — client `PING`→`PONG` echo, server-initiated `PING` of an idle client, ping-timeout `ERROR :Closing Link: (Ping timeout)` + socket close, and the inverse (a client that answers the keepalive is never dropped) — the client-plane twin of the existing `golden_s2s_keepalive`; plus a Session-layer `keepalive_proptest` fuzzing `Session::check_ping`/`record_activity` over random schedules to pin the wire+state contract (only `PING`/`ERROR` lines, no timeout without a prior ping, idempotent close, active-never-dropped, `freq==0` disables) — the layer the pure-core `heartbeat_proptest` never reached. 118 lands the §4 "cargo-fuzz tier over `Message::parse` + the full `Session::feed` byte path" as its verifiable structured-fuzz analogue (the libfuzzer tier needs a nightly toolchain) — `feed_framing_proptest` drives arbitrary bytes through the framer in arbitrary chunk boundaries (never-panic/well-formed-output, chunk-boundary reassembly invariance, the 512/8191 limit edges) and **found+fixed a real unbounded-`self.buf` DoS**: the raw-TCP serve loop fed 4 KB chunks straight into an uncapped accumulation buffer, so a client that never sent a CR/LF grew it without bound — now bounded at `MAX_INBOUND_LINE` (tag budget + body = 8703) with a `417 ERR_INPUTTOOLONG` + skip-to-terminator resync, faithful in spirit to `dbuf_getmsg`'s bounded line buffer; pinned by `golden_recvq` (20 KB unterminated blob → `417` + resync to a normal registration through the assembled daemon). With this the §4 concrete fuzzing gaps are exhausted (only the optional nightly cargo-fuzz tier remains). 119 locks the maintainer's **hard rule** (*leveva MUST NOT support S2S commands on client connections; ENCAP MUST return invalid command on client ports*): the S2S-only verb set `{ENCAP,UNICK,NJOIN,SAVE,EOB,EOBACK,SERVER,SMASK,SDIE}` (verbs `s2s::dispatch` handles that aren't also client commands) is a plain unknown command on a client port — `421` post-registration / `451` pre-registration, **never interpreted** — a deliberate divergence from the oracle's status-column routing (`ENCAP`→`m_nop`/`HAZH`→`m_hash`/`DNS`→`m_dns`) that **overrides THE STANDING RULE** for S2S verbs (leveva routes client/server by the listener `server-only` flag, never by handshake content); a regression-lock + **security fuzz** slice (no production change — the behavior already held) with a unit trio (incl. the forged `:victim ENCAP * CHGHOST` host-spoof → `421`, host untouched), a `golden_s2s_reject` boot golden (all 9 verbs `421` + `WHOIS` proving the host stayed `127.0.0.1` and the session resynced), and a 4-property `s2s_client_reject_proptest` pinning the headline invariant — an S2S verb (arbitrary args, forged prefix, dangerous CHGHOST/UNICK/NJOIN/SAVE payloads) yields exactly one rejection numeric and **zero state mutation** (no registry/server/user/channel growth, no host/realname/nick change), never wedging the session. 120 enforces the maintainer's directive (*leveva MUST reject invalid UTF-8 in client frames; leveva is UTF-8 only; ensure it at the message-parsing level — that transitively proves everything else*): the `UTF8ONLY` gate (slice 76) moves from the framing layer (`Session::feed`'s hand-rolled `str::from_utf8`) into the parser as `Message::parse_bytes(&[u8])` → `ParseError::InvalidUtf8` — the single byte→`Message` boundary, so every consumer of a parsed `Message` (handlers, relay plane, S2S) is *transitively* UTF-8-safe (a `Message`'s fields are `String`, so `parse_bytes` Ok ⟹ input was valid UTF-8 is the whole proof); `feed` now just translates the parse error to the `INVALID_UTF8` `FAIL` (client-frame wire output byte-identical, `golden_utf8only`/`utf8only_proptest` unaffected — both client transports already funnel through `feed`); a leveva-native hardening slice (no differential — the C oracle is byte-agnostic), pinned by 3 message unit tests + a 3-property `parse_utf8_proptest` whose headline is *`parse_bytes` admits a line iff it is valid UTF-8* (+ the inverse byte-entry≡str-entry and the transitive `to_wire`-is-UTF-8 wire proof); S2S/handshake reader paths keep `from_utf8_lossy` by deliberate scope (trusted peer, separate trust domain). 121 enforces the maintainer's directive (*leveva MUST support IRC lines whose non-tag portion can be up to 2048 **graphemes**, not just 512 bytes; advertise `LINELEN=2048` in ISUPPORT*): a new `LINELEN=2048` (graphemes, UAX #29 — not bytes, so a 2048-char multi-byte line is fully supported) replaces the old 510-byte `to_wire` body cut with a grapheme-cluster truncation (`unicode-segmentation`, never splits a cluster), the framer ceiling `MAX_INBOUND_LINE` rises to `MAX_TAG_DATA_LEN + MAX_BODY_BYTES` (8191 + 2048×64 = 139263) so the longer lines are accepted before the `417` recvQ guard, and ISUPPORT advertises the new `LINELEN` token (`MAX_MESSAGE_LEN`/`MAX_CONTENT_LEN` stay as the RFC floor / chunker budget — `ison`/`monitor`/`s2s::burst` keep packing to 510 B, no S2S drift); a leveva-native slice (no oracle differential — the C oracle truncates at 512 B and advertises no `LINELEN`), pinned by message/isupport/session units (incl. the 50 KB-line-accepted + still-417-past-the-raised-ceiling inverses) and the **fuzzing** `linelen_proptest` (headline: `to_wire` body == full body truncated to `LINELEN` graphemes, + the within-budget byte-identical round-trip + the never-split-a-grapheme prefix invariant over arbitrary Unicode). 122 begins the S2S-notify-propagation parity area (closing the IRCv3-track "single-server-local" divergences): **AWAY propagation** — AWAY becomes a network-propagated command (the faithful first-class `:<uid> AWAY [:msg]` carrier, NOT `ENCAP`, matching the oracle's `m_away` `sendto_serv_butone`) via a new `s2s/away.rs` (`local_away` outbound broadcast + `inbound_away` dispatch arm: toggle the remote user's `+a` mirror bit + `registry.set_away`, away-notify local capable co-members, onward-relay split-horizon) plus a burst `:<uid> AWAY :<msg>` line after an away user's UNICK; and the maintainer-requested **self umode echo** — on an actual `+a`/`-a` flip the issuer also gets `:nick MODE nick :±a` after the 306/305 (a message-only `AWAY :new` re-notifies/re-propagates but emits no MODE). leveva-native (no differential — the oracle emits neither away-notify nor the self-MODE echo); gate = s2s/command/burst units + `golden_s2s_away` (both directions) + the `away_s2s_proptest` inbound-lockstep/panic-freedom fuzzing + the `away_proptest` MODE-echo update. 123 continues the area with **INVITE propagation**: INVITE becomes a network-broadcast command (the first-class `:<inviter-uid> INVITE <target-uid> :<channel>` carrier — the oracle propagates point-to-point toward the target, leveva broadcasts to all peers so a remote `invite-notify` op is reached, a documented native divergence) via a new `s2s/invite.rs` (`local_invite` outbound + `inbound_invite` dispatch arm: direct relay + a one-shot bypass token — recorded iff the remote inviter `is_op`, the oracle `add_invite` guard, via a new `Channels::note_invite` — to a local target, invite-notify local capable ops, onward-relay split-horizon); `command/invite.rs` now shares `s2s::invite::notify_channel_ops`, propagates via `local_invite`, and gates its direct relay on `is_local_uid` (a remote target is reached only by its home server, no stray link line); gate = s2s/command units + `golden_s2s_invite` (both directions) + the `invite_s2s_proptest` token-policy/panic-freedom fuzzing. 124 continues the area with **MONITOR live S2S propagation**: the IRCv3 `MONITOR` `730`/`731` push (slice 70) fired only on local online/offline events, so a remote user coming online/quitting/renaming/netsplitting behind a peer never notified a local watcher — unlike AWAY/INVITE this is **not** a propagated command (IRCnet has no `WATCH`/`MONITOR`, so no oracle differential; leveva-native) but a hook of the four existing remote-transition S2S seams to the same `monitor::notify_online`/`notify_offline` fan-out the local seams use (the `Monitors` reverse index is already network-wide, so zero new state): `s2s/unick.rs` clean-claim → `730` (the collision arm registers under the UID and pushes nothing — the colliding nick's first claimant already notified), `s2s/squit.rs::quit_remote_user` → `731` (one body, funnelled by both a single relayed `QUIT` and a whole-server `SQUIT`; an unmirrored `NJOIN`-only ghost with no registry nick pushes nothing), `s2s/relay.rs::inbound_nick` → `731`(old)+`730`(new) (the local `command/nick.rs` shape), and `s2s/save.rs::handle_save` → `731` for the nick a `SAVE` vacates (no `730` — the new identity is a bare UID, not a monitorable nick); gate = 7 seam units + `golden_s2s_monitor` (online/rename/offline pushes) + the `monitor_s2s_proptest` presence-model/panic-freedom fuzzing. 125 continues the area with **REDACT (`message-redaction`) S2S propagation**: the IRCv3 message-redaction `REDACT` relay (slice 68) was single-server-local (a channel REDACT reached only local cap members; a remote nick target was dropped), so a member of the channel on another server — or a remote nick recipient — never saw the redaction; the fix makes REDACT a propagated command (the first-class `:<sender-uid> REDACT <target> <msgid> [:reason]` carrier — the spec relay model, not `ENCAP`; like MONITOR this is leveva-native, the C oracle has no `message-redaction` so **no differential**) via a new `s2s/redact.rs` (`local_redact_channel` outbound broadcast for a channel target + `route_redact_to_remote` for a remote nick + an `inbound_redact` dispatch arm: deliver the client-form line to local `draft/message-redaction`-capable members/nick, no re-gate of the channel send eligibility — the originating server already validated `can_send`, exactly as inbound PRIVMSG/TAGMSG — then onward-relay split-horizon); `command/redact.rs` now broadcasts a channel REDACT via `local_redact_channel` after the local fan-out and routes a remote-nick REDACT via `route_redact_to_remote` (replacing the old dropped `Some(_) => Vec::new()` arm), the remote recipient's cap gated by *its* home server; gate = 7 s2s units + `golden_s2s_redact` (both directions) + the `redact_s2s_proptest` cap-delivery/onward-relay/panic-freedom fuzzing. 126 is the **S2S capability-negotiation foundation** the maintainer required before the remaining tag work — it closes a latent bug: slices 58–66 attached client-only (`@+…`) tags to S2S lines for *every* peer unconditionally, so a tag-blind peer would mis-parse the leading `@`. leveva now announces capabilities with a named-token **`CAPAB`** verb carried as the first burst line `:<sid> ENCAP * CAPAB :message-tags` — it **rides `ENCAP`** because a *bare* unknown server command is fatal in IRCnet 2.11 (verified: the `ircd-common` oracle replies `SQUIT`+`ERROR :Closing Link`; `ENCAP` is routed to `m_nop` and tolerated, so the link survives), and is **link-local** (interpreted, never relayed onward). Capabilities are recorded per-link (`PeerCaps` on `PeerLink` + the `PeerLinks` routing table, set from the inbound `CAPAB` via `forward::inbound_encap`'s new arm). Tag emission is gated at a single **egress** point: callers always build the tagged wire and `PeerLinks::broadcast`/`route` strip the leading `@tags` for a non-tag peer (a byte cut, no-op when untagged), while `broadcast_tag_only`/`route_tag_only` send a tag-only `TAGMSG` only to tag peers (a non-tag peer is skipped). leveva-native (no oracle differential for the tags); the burst's extra `ENCAP * CAPAB` line is a documented divergence the `s2s_skeleton_differential` excludes before asserting burst-skeleton agreement; gate = `s2s/caps.rs`/`burst`/`links`/`relay` units + `golden_s2s_caps` (a tag-blind peer's tagged PRIVMSG arrives stripped, its TAGMSG not at all, end-to-end) + `caps_s2s_proptest` (the never-leak invariant) + `s2s_oracle_link` (bare-CAPAB-SQUITs vs ENCAP-CAPAB-tolerated against the real oracle). 127 **reworks slice 125's REDACT carrier from a first-class verb to `ENCAP`** — slice 126 proved a *bare* unknown server command is fatal in IRCnet 2.11 (the oracle SQUITs), so a first-class `:uid REDACT …` is either dropped by a non-implementing peer or kills a strict link; leveva now carries it as `:<uid> ENCAP * REDACT <target> <msgid> [:reason]` exactly like CHGHOST/CERTFP/SETNAME (delivery semantics unchanged: channel broadcast + remote-nick point-to-point route, the bare client-form REDACT delivered to local cap members/nick). `inbound_redact`→`apply_encap_redact` (delivers locally, the caller `forward::inbound_encap` onward-relays the ENCAP verbatim); the top-level `"REDACT"` S2S dispatch arm is removed (REDACT stays a client command, reached over S2S only via the `ENCAP` arm). Still leveva-native (no oracle differential). Gate: `s2s/redact.rs`/`forward.rs` units (incl. `encap_redact_is_applied_and_still_relayed`) + `golden_s2s_redact` (snapshot regenerated to the ENCAP egress) + `redact_s2s_proptest` with the **new headline P4** `outbound_redact_always_rides_encap` (every emitted wire is `ENCAP`-wrapped — leveva never puts a bare `REDACT` server command on the wire). 128 = **outgoing auto-connect** for `connect{}` blocks — the idiomatic counterpart of `try_connections`: a pure `autoconnect::AutoConnect::due` (master switch + per-block `autoconnect`/`port`/class `connect-freq`/already-linked/per-block-cooldown ladder, `connect-freq` doubling as the retry interval, `saturating_add` cooldown) driven by a `main` ticker (spawned only when `options.auto-connect`; immediate-first-tick boot dial; live-rehash-aware) that queues each due peer on the same `link::request` plane `CONNECT` uses; leveva-native (divergences: all-eligible-not-one-best, no deferral NOTICE, master not live-rehashable), gated by 10 unit + `autoconnect_proptest` (eligibility-model + cooldown + i64::MAX panic-freedom) + `golden_autoconnect` (unattended boot dial, no client/CONNECT). 129 = **faithful live-join propagation** — `relay::local_join` now emits `:<sid> NJOIN <chan> :<prefix><uid>` (not the oracle-dropped `:<uid> JOIN`), carrying the chanop `@` prefix atomically, and inbound `handle_njoin` gained live (post-burst) fanout (client JOIN + synthetic `+o`/`+v` MODE to local members, split-horizon onward-relay) — closing two maintainer-reported interop bugs (UIDs-not-nicks + chanop-not-synchronized), verified by spawning the oracle and reading its wire. **Follow-on: msgid S2S propagation (slice 130, gated on slice 126's egress).** |  Per‑slice: leveva boots and serves the slice; leveva golden snapshot + proptest green; the `leveva-integration` differential agrees with `ircd-common` on the shared skeleton with divergences asserted. Across the eventual matrix: registration, channels, WHO/WHOIS/WHOX, OPER/STATS, server burst, netsplit, rehash, restart; iauth end‑to‑end. |
 | **P12 — Retire the mechanical port; `leveva` is the product** | delete `ircd-common`/`ircd-rs` + C‑era `iauth-rs` scaffolding; workspace = `leveva` | Once `leveva` is at parity (P11 green across the matrix), run the differential suite a final time, then **delete the mechanical port** (`ircd-common`, `ircd-rs`) and fold/replace `iauth-rs` with leveva‑native auth. The `leveva-integration` oracle tests retire with their oracle; the load‑bearing characterizations carry forward as self‑contained `leveva` tests. Workspace becomes just `leveva` (+ any sub‑crates it wants). This is the literal end of the strangler — same lifecycle the C tree had at P8. | Final differential run green; `ircd-common`/`ircd-rs` deleted; `cargo test -p leveva` carries the behavioral guarantees forward; minimal `unsafe`; clean clippy. |
 
 ---
diff --git a/docs/progress-log/p11.md b/docs/progress-log/p11.md
index 450ef1b2..57c6618b 100644
--- a/docs/progress-log/p11.md
+++ b/docs/progress-log/p11.md
@@ -7233,3 +7233,86 @@ background ticker periodically dials every opted-in, unlinked peer.
 **Gate:** `cargo test -p leveva` (unit + `autoconnect_proptest` + `golden_autoconnect` +
 unbroken `golden_connect`/`connect_proptest`) green; `cargo clippy -p leveva --tests` clean;
 `cargo build --workspace` 0 warnings.
+
+## 2026-06-12 — P11 slice 129: faithful live-join S2S propagation (`NJOIN`, not `JOIN`)
+
+A maintainer-reported interop bug, two symptoms, one root cause: joining a channel the new
+daemon created showed members as **UIDs, not nicks** on the old ircd, and the joiner's
+**chanop status was not synchronized** across the link.
+
+### Investigation (empirical, against the in-process `ircd-common` oracle)
+
+A scratch test booted the link-accepting oracle (`Prot::Off`), linked a peer, EOBed it, and
+read what the oracle emits when a **local** user joins a channel:
+
+- The oracle propagates a live local join as `:<sid> NJOIN <chan> :<prefix><uid>` — the op
+  status (`@`/`@@`) rides the member token. Confirmed wire: `:000B NJOIN #investigate
+  :000BAAAAA` (a plain join of an existing channel); a creating join carries `@`.
+- leveva instead emitted `:<uid> JOIN <chan>` (`relay::local_join`). Fed to the oracle, that
+  line is **silently dropped** — IRCnet 2.11's `m_join` treats a non-`0` server-sourced JOIN
+  as an error and ignores it (`channel.rs:2590`); the member never appears and a later local
+  joiner gets `437`. The `@`/`@@` prefix was never conveyed.
+- The correct `:<sid> NJOIN #chan :@<uid>` form, fed to the oracle, resolves the nick **and**
+  the op (`bob NAMES #correct` → `:bob @sasha`).
+
+So leveva used the wrong verb. `NJOIN` is the only join-propagation verb IRCnet 2.11 honours
+(besides `JOIN 0` part-all) and it carries the chanop prefix atomically — fixing the verb
+fixes both symptoms.
+
+### Mechanism (both directions of the seam — they must change together)
+
+leveva↔leveva used the invented `:<uid> JOIN` form both ways; switching only outbound would
+break it (the receiver's `handle_njoin` was burst-silent). So:
