Proof of concept mechanical port of ircnet/ircd to Rust as part of a bit about C being insecure for network services
0

Configure Feed

Select the types of activity you want to include in your feed.

ircd.rs / docs / claude-memory / leveva-s2s-notify-propagation.md
32 kB

name: leveva-s2s-notify-propagation description: "leveva P11 — the S2S-notify-propagation parity area (closing the IRCv3 "single-server-local" divergences); AWAY (122) + INVITE (123) + MONITOR live (124) + REDACT (125) + S2S-capability-foundation (126) + REDACT→ENCAP (127) + msgid (130) + server-time (134) + bot/oper inbound tags (135) done; slices 128/129 went elsewhere (auto-connect / live-join NJOIN); the account infra LANDED (139 SU identity / 140 account-notify / 141 account-tag / 142 extended-join — all single-server-local) + @account tag on REMOTE inbound-relayed messages (156, the slice-135 derive-from-mirror pattern via registry.record_of) — the S2S-notify-propagation area is now COMPLETE; certfp-live turned out already done (slice-86 local_introduce reuses unick_intro). Also records the 2026-06-13 server-SID-source MODE fix (source_mask SID→name). LATE ADDENDUM 2026-06-15 — slice 177 closed the metadata single-server-local divergence (draft/metadata-2 SET/CLEAR was local-only): now broadcasts :<sid> ENCAP * METADATA <target> <key> [:<value>] (modelled on SU), s2s/metadata.rs propagate/apply_encap_metadata, inbound reuses command::metadata::notify_subscribers (made pub(crate), actor Option). LATE ADDENDUM 2 (2026-06-15, ultracode workflow, slices 178-180): WALLOPS S2S (178, first-class verb, s2s/wallops.rs) + KILL S2S (179, remote-kill route + inbound eject/teardown, s2s/kill.rs) + S2S server-link traffic metrics (180); also flagged a pre-existing SASL chunking proptest flake — see [[leveva-sasl-chunking-proptest-flake]]" metadata: node_type: memory type: project originSessionId: b18f506a-8817-4004-8ec9-3e26fdf57052#

After the IRCv3 cap queue, the native-oracle differential matrix, and the testing-plan §4 fuzzing gaps were all exhausted (slices ≤121), the user picked S2S notify propagation as the next P11 area (2026-06-12): close the recurring "single-server-local" divergence carried by many IRCv3 behavior caps — they notify only LOCAL co-members and don't propagate to remote co-members over S2S.

Slice 122 DONE — AWAY propagation. AWAY is now a network-propagated command via the faithful first-class :<uid> AWAY [:message] carrier (NOT ENCAP — AWAY is a real RFC 2812 / IRCnet verb the oracle relays directly via m_away sendto_serv_butone; setname/chghost use ENCAP only because the oracle has no verb for them). New leveva/src/s2s/away.rs mirrors s2s/setname.rs: local_away (outbound broadcast) + inbound_away (a new s2s::dispatch "AWAY" arm: toggle the remote user's +a mirror bit + registry.set_away, away-notify local capable co-members + ext-monitor, onward-relay split-horizon). Burst carries existing away: s2s/burst.rs::unick_intro appends :<uid> AWAY :<msg> after an away user's UNICK. Maintainer add-on: the issuer gets its own :nick MODE nick :±a echo on an actual +a/-a flip (slice-72 self-MODE shape) after the 306/305 — but NOT on a message-only change (AWAY :new while already away re-notifies/re-propagates, no MODE). leveva-native, no differential.

Slice 123 DONE — INVITE propagation. INVITE is now a network-broadcast command (the first-class :<inviter-uid> INVITE <target-uid> :<channel> carrier, NOT ENCAP — INVITE is a real verb the oracle relays). New leveva/src/s2s/invite.rs clones s2s/away.rs: local_invite (outbound broadcast) + inbound_invite (a new s2s::dispatch "INVITE" arm: direct relay + a one-shot bypass token to a local target — recorded iff the remote inviter is_op, the oracle add_invite guard, via a new Channels::note_invite — invite-notify local capable ops, onward-relay split-horizon). command/invite.rs now shares s2s::invite::notify_channel_ops, propagates via local_invite (Invited + courtesy arms), and gates its direct relay() deliver on is_local_uid (a remote target is reached only by its home server, never a stray client-format line over the link). Divergence: the oracle relays INVITE point-to-point toward the target's server; leveva broadcasts to all peers so a remote invite-notify op is reached — leveva-native, no differential.

Slice 124 DONE — MONITOR live S2S propagation. Unlike AWAY/INVITE this is NOT a new propagated command — MONITOR is client-local (IRCnet has no WATCH/MONITOR, so no oracle differential; leveva-native). The 730/731 push (slice 70) fired only on LOCAL events; the fix hooks 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 → zero new state): s2s/unick.rs clean-claim → 730 (collision arm pushes nothing — first claimant already notified); s2s/squit.rs::quit_remote_user731 (ONE body, funnelled by both a single relayed QUIT and a whole-server SQUIT; an unmirrored NJOIN-only ghost has no registry nick → nothing); s2s/relay.rs::inbound_nick731(old)+730(new), capturing old-nick/user/host BEFORE the rename (the command/nick.rs shape); s2s/save.rs::handle_save731 for the nick a SAVE vacates (no 730 — the new identity is a bare UID, not monitorable). Gate = 7 seam units + golden_s2s_monitor + monitor_s2s_proptest (presence-model/panic-freedom). The proptest model must NOT drive a re-UNICK-while-online (that hits the collision-rename path and corrupts the mirror nick) — only genuine offline→online introductions are real UNICKs.

Slice 125 DONE — REDACT (message-redaction) propagation. Slice 68's REDACT delivery was single-server-local (a channel REDACT reached only local cap members; a remote nick target was DROPPED via Some(_) => Vec::new()). Now a propagated command via 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). New leveva/src/s2s/redact.rs: local_redact_channel (outbound broadcast for a channel target, clone of relay::local_channel_message) + route_redact_to_remote (a remote nick → the target's uplink, clone of relay::route_message_to_remote; made relay::uplink_of pub(super)) + inbound_redact (new s2s::dispatch "REDACT" arm: deliver the client-form line to local message_redaction members/nick — NO re-gate of channel send eligibility, the originating server already validated can_send, exactly like inbound PRIVMSG/TAGMSG — then onward-relay split-horizon; redact_wire builds the two-leading-param line relay_wire can't). command/redact.rs broadcasts via local_redact_channel after the local fan-out + routes the remote-nick arm via route_redact_to_remote (replacing the dropped arm); the remote recipient's cap is gated by its home server. Gate = 7 s2s units + golden_s2s_redact (both directions) + redact_s2s_proptest (cap-delivery/onward-relay/panic-freedom). NOTE: REDACT is BOTH a client and an S2S verb now (like PRIVMSG/AWAY/INVITE) — adding the S2S dispatch arm does NOT violate the slice-119 client-port-rejects-S2S-verbs rule, which only governs S2S-ONLY verbs (UNICK/NJOIN/SAVE/EOB/…).

Slice 126 DONE — S2S capability negotiation (the tag-gating FOUNDATION). The maintainer required this BEFORE the remaining tag work. It closes a latent bug: slices 58–66 attached client-only (@+…) tags to S2S lines for EVERY peer unconditionally → a tag-blind peer mis-parses the leading @. leveva now announces caps with a named-token CAPAB verb as the first burst line, ENCAP-wrapped: :<sid> ENCAP * CAPAB :message-tags. CRITICAL LESSON (verified): a bare unknown server command is FATAL in IRCnet 2.11 — sending :sid CAPAB … to the ircd-common oracle makes it reply SQUIT+ERROR :Closing Link; ENCAP is routed to m_nop and tolerated, so the link survives. So any leveva-extension S2S verb must ride ENCAP (this is why slice 127 re-does REDACT as ENCAP). CAPAB is link-local (interpreted, never relayed onward). See [[leveva-s2s-peer-caps]] for the full mechanism (s2s/caps.rs PeerCaps, PeerLink.caps, PeerLinks egress tag-filter, forward::inbound_encap CAPAB arm). leveva-native, no oracle differential for the tags; the burst's extra ENCAP * CAPAB line is a documented divergence s2s_skeleton_differential excludes.

Slice 127 DONE — REDACT → ENCAP (reworked 125's carrier). Slice 126 proved a bare unknown server command is FATAL in IRCnet 2.11 (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 unchangedlocal_redact_channel (broadcast for a channel) + route_redact_to_remote (point-to-point to the target's uplink) keep the same routing, only the wire builder changed (encap_redact_wire egress; client_redact_wire = the bare client-form line a local cap client receives). s2s/redact.rs inbound_redactapply_encap_redact (delivers locally, does NOT relay — the caller forward::inbound_encap onward-relays the ENCAP verbatim); a Some("REDACT") arm added to inbound_encap next to CHGHOST/CERTFP/SETNAME; the top-level "REDACT" s2s::dispatch arm REMOVED (REDACT stays a client command, reached over S2S only via ENCAP; not in the slice-119 S2S-only reject set so client ports unaffected). Note the ENCAP params are SHIFTED: params() == ["*", "REDACT", target, msgid, …] (target at index 2, msgid at 3). Gate = s2s/redact.rs/forward.rs units (encap_redact_is_applied_and_still_relayed) + golden_s2s_redact (snapshot regenerated to the ENCAP egress; alice still sees bare client-form) + 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). (AWAY 122 + INVITE 123 stay first-class — REAL IRCnet verbs the oracle relays.)

NOTE: slice 128 went to outgoing auto-connect ([[leveva-outgoing-autoconnect]]) and slice 129 went to live-join NJOIN propagation ([[leveva-live-join-njoin]]), so msgid landed as slice 130 (not 129).

Slice 130 DONE — msgid S2S propagation. The IRCv3 message-ids @msgid tag was single-server-local (slice 66 stamped it only for LOCAL recipients). Now it is network-stable: the introducing server mints one id per message event (the existing per-target msgid_cell) and carries the SAME id on the S2S wire; a relaying server carries the inbound @msgid through to its local message-tags clients and onward-relays verbatim, NEVER re-minting (the spec's introducing-server-assigns model — an absent or ill-formed (!msgid::is_valid) inbound id is delivered without one, avoiding two ids for one event). Mechanism: relay_wire() gained a msgid: Option<&str> that prepends a msgid SERVER tag ahead of the client-only (+) tags (wire order @msgid;+client); local_channel_message/route_message_to_remote/local_tagmsg/route_tagmsg_to_remote took a msgid arg, fed the shared cell by command/message+command/tagmsg only when !ctx.peers.is_empty(); inbound_message/inbound_tagmsg read+validate @msgid and deliver it to local cap recipients. Gated on slice 126's CAPAB egress — the msgid is a server tag, byte-stripped (with the + tags) for a tag-blind peer. leveva-native (no oracle differential). Gate = relay/message/tagmsg units incl. the per-event network invariant (local consumer's id == the id on the wire) + inverses (no inbound id ⇒ none minted; ill-formed dropped; non-cap member never sees one; egress strips for a tag-blind peer) + golden_s2s_msgid (both directions, exact id propagated inbound; canonicalize already masks msgid=<MSGID>) + msgid_s2s_proptest (propagate-iff-valid / egress / panic-freedom). PREP commit first: fixed pre-existing v0.0.2-bump LINK_VERSION (021- prefix) staleness in one handshake unit + 3 S2S golden snapshots (cargo test -p leveva was red on HEAD) — see [[leveva-link-version-021-staleness]].

Slice 134 DONE — server-time S2S propagation. The direct msgid twin for the IRCv3 @time tag (slice 62 stamped it only for LOCAL recipients). Now network-stable: the introducing server stamps @time on the S2S relay wire (the same now it gives local recipients); relay::relay_wire gained a time: Option<&str> carried as the FIRST server tag (@time;msgid;+client); the four outbound relay fns + command/message.rs + command/tagmsg.rs thread s2s_time = (!peers.is_empty()).then(|| now.clone()). Gated on slice-126 CAPAB egress (stripped for a tag-blind peer). Inbound (inbound_message/ inbound_tagmsg) switched from two-precomputed-wires (plain/tagged) to a per-recipient render(caps) closure so server-time is gated INDEPENDENTLY of message-tags: a server-time recipient gets the carried @time verbatim if well-formed (new clock::is_valid_server_time), ELSE a synthesized server_time_now() fallback (server-time is NOT optional for a negotiating client, unlike the optional msgid — this is the one documented divergence). New fanout helpers fanout_local_render/fanout_local_tagmsg_render replaced fanout_local_tagged/fanout_local_tagmsg. leveva-native, no differential. Gate = clock/relay units (8 new) + golden_s2s_server_time (both dirs) + server_time_s2s_proptest

  • golden_s2s_msgid snapshot regen (outbound now @time=<TS>;msgid=<MSGID>). The inbound two-wire→render refactor is the reusable pattern for the remaining bot/oper/account follow-ons.

Slice 135 DONE — bot/oper inbound-message tags. The IRCv3 bot (slice 64) + draft/oper (slice 67) tags, stamped only at the LOCAL plane, are now derived on the S2S inbound relay from the remote sender's mirrored umodesBot (+B) + Oper (+o) are both in [[leveva-s2s-notify-propagation]]'s SEND_UMODES, so they're network-global (RemoteUser.umodes, seeded by UNICK burst + UMODE propagation). No carried wire tag, no burst change — the receiving server re-derives from its own ctx.net.user() mirror (the faithful model: these tags derive from sender MODES, not assigned per-message like msgid/@time). Hung on slice-134's per-recipient render seam in BOTH inbound_message + inbound_tagmsg: read sender_umodes = Uid::try_from(prefix) → ctx.net.user → umodes once, then in render() stamp draft/oper iff sender_is_oper && caps.oper_tag (independent of message-tags), bot iff sender_is_bot && caps.message_tags (rides message-tags). Order @time;draft/oper;msgid;bot;+client. Remote oper is always +o (+O=LocalOp is local-only, never propagates → check Oper.bit() only). Gate = 8 relay units + golden_s2s_bot_oper (peer bursts +B bot + +o oper) + bot_oper_s2s_proptest (the 2×2 derivation gates). leveva-native, no differential.

Slice 156 DONE — @account tag on remote (inbound-relayed) messages. The last S2S-notify follow-on. The account-tag @account (slice 141, single-server-local) is now derived on the S2S inbound render(caps) seam in BOTH inbound_message + inbound_tagmsg, exactly the slice-135 bot/oper pattern: read sender_account = Uid::try_from(prefix) → ctx.registry.record_of → r.account ONCE outside the per-target loop (the account SoT is the registry record, populated for remote users via ENCAP * SU slice 139 — confirmed record_of works since UNICK claims remote users into the registry; NO RemoteUser mirror field needed), then in render() stamp account iff caps.account_tag && sender_account.is_some() — its OWN cap, independent of message-tags (placed after draft/oper, before the message_tags block). Derived, never on the wire, never relayed (each server re-derives from its mirror). New inbound order time;draft/oper;account;msgid;bot;+client. Gate = 5 relay.rs units + remote_account_tag_proptest (iff-gate × cap matrix × signed-in?, value fidelity, never-wedge). leveva-native, no differential. The S2S-notify-propagation area is now COMPLETE.

Remaining (the area's backlog): — none. (Was: @account remote tag, now done as 156.)

  • certfp live post-burst (78)ACTUALLY DONE (this line was stale): slice 86's live UNICK introduction (relay::local_introduce) reuses burst::unick_intro, which already appends the :<uid> ENCAP * CERTFP line, so a TLS user registering after the link is up propagates its certfp. No work remained.

S2S server-source bug (fixed 2026-06-13, commit ded29694, NOT a notify-propagation slice): a server-sourced channel MODE (auto-reop from a +R reop list, a server MODE) prefixes the source server's SID. relay::source_mask only resolved a UID prefix → nick!user@host and fell through to the raw token otherwise, so relay::after_mode delivered the line to local clients with the raw SID as the actor (ServerMode/#chan [+oo a b] by 8OPH). Fix: source_mask now resolves a SID prefix to the server name (our own SID → ctx.name; a known remote SID → its net.server mirror name), matching the local enforce_reop's prefix(&ctx.name). The onward S2S relay still carries the SID-prefixed wire (correct for the link). Invariant: any server-sourced line fanned to local clients must translate SID→name via source_mask.

Pattern for the next one: clone the s2s/setname.rs/s2s/away.rs shape — outbound local_* broadcast + an inbound_*/apply_encap_* that updates the mirror/registry, notifies local cap-havers, and onward-relays; carry state in the burst if it isn't already on UNICK. Gate = s2s/command units + a golden_s2s_* both-directions boot test + an inbound-lockstep proptest. See [[leveva-slice-recording]], [[leveva-next-step-s2s-completeness]].

Slice 177 DONE — METADATA SET/CLEAR S2S propagation (late addendum, 2026-06-15). draft/metadata-2 (slices 163/167/169) was the last single-server-local IRCv3 divergence: SET/CLEAR mutated the local MetadataStore + notified only local subscribers (command/metadata.rs:38 listed "S2S propagation … out of scope"). Now network-wide via the ENCAP plane, modelled on [[iauth-subsumed-into-leveva]]'s neighbour SU (slice 139): carrier :<sid> ENCAP * METADATA <target> <key> [:<value>] (target = UID for users so a later GET-by-nick resolves, channel name re-folded; value absent = removal; CLEAR → one removal line per key; server-prefixed). New leveva/src/s2s/metadata.rs: propagate (outbound, broadcast(None,…), no-op if no peers) called from command/metadata.rs set_cmd/clear_cmd after the store mutation; apply_encap_metadata wired into forward::inbound_encap Some("METADATA"), gates key_valid + value_valid, applies set/remove, reuses command::metadata::notify_subscribers (refactored to pub(crate) + actor: Option<&Uid>None for the remote actor). Onward ENCAP relay unchanged (split-horizon → multi-hop converges). Divergences: leveva-native no differential; MAX_KEYS NOT re-enforced inbound (per-hop cap would desync which keys exist; origin already enforced); no registration metadata burst (learns from link time on, like SU's "no burst re-assertion"). Fuzzed end-to-end through propagate → inbound_encap (leveva/tests/metadata_s2s_proptest.rs).

Slices 178-180 DONE — classic-message S2S propagation (2026-06-15, ultracode workflow). Three more single-server-local gaps closed in one parallel-spec → sequential-TDD workflow, all modelled on the s2s/away.rs shape (local_* outbound broadcast + inbound_* apply/relay):

  • 178 WALLOPS (feat 9a2a2ede). Was local-+w-only ("no S2S yet"). New s2s/wallops.rs: local_wallops broadcasts :<oper-uid> WALLOPS :<text> to peers (called from command/wallops.rs after the local fan); inbound_wallops resolves the source UID→mask (registry record else net mirror), fans :<nick!user@host> WALLOPS :<text> to LOCAL +w users only (is_local_uid gate — remote +w reached by their home server), then onward-relays split-horizon. First-class verb (real IRCnet m_wallops), not ENCAP. Dispatch arm "WALLOPS".
  • 179 KILL (feat 6392535e). Was single-server. New s2s/kill.rs: route_kill_to_remote (a local oper KILLing a remote user → routes :<killer> KILL <victim-uid> :<path> to the victim's uplink via relay::uplink_of, does NOT eject locally); inbound_kill (a peer's :<src> KILL <victim> :<reason> → a LOCAL victim is eject_uid'd so its serve loop's Session::release fans the QUIT; a FURTHER-remote victim torn down via squit::quit_one_remote_user; unknown = no-op-but-relayed; onward split-horizon). Network-kill QUIT reason Killed by <display> (<reason>) (vs local Local Kill by …); killer display via relay::source_mask (SID→name). First-class verb. Divergences: no FLAGS_KILLED/SCH_KILL server-notice mask (normal QUIT fires); eject is async.
  • 180 metrics (feat 747d9765). metrics.rs:63 follow-on. Four per-ServerContext prometheus IntCounters leveva_s2s_traffic_{sent,recv}_{bytes,messages}_total incremented in main::serve_linked_peer read/write sites (pipelined pending-drain skipped to avoid double-count); surfaced via two extra STATS t 249 :Traffic s2s … lines. Pure local plumbing, no wire change. Two golden snapshots (golden_metrics, golden_stats_traffic) regenerated (the s2s digit self-masks to s<N>s under the :Traffic canonicalizer). All three: TDD (RED first), a leveva/tests/*_s2s_proptest.rs fuzz file each, cargo build/ clippy/test -p leveva all-green. Verify phase also fixed a stale REDACT doc comment (docs 9d35bf45 — slice 127 already shipped the relay). Final: 2348 tests pass, 0 warnings.

Slice 182 DONE — SANICK S2S propagation (2026-06-15). The SA* oper-override family (SANICK/SAJOIN/SAPART, slices 151-153) was local-target only: a remote target got a NOTICE citing "the KILL-local scope" — but slice 179 closed that KILL gap, so the rationale was stale. This continues the 178-180 oper-command arc for the rename case. New leveva/src/s2s/sanick.rs, server-prefixed ENCAP (extension verb — slice-126 rule, modelled on SU/METADATA not the first-class AWAY/WALLOPS/KILL): propagate broadcasts :<our-sid> ENCAP * SANICK <uid> <newnick> to all peers (from command/sanick.rs remote branch, replacing the NOTICE); only the target's home server acts in apply_encap_sanick (wired into forward::inbound_encap Some("SANICK")) — runs the SAME local path try_rename → command::nick::apply_local_nick_change → force_nick_uid, whose :<oldmask> NICK <new> relay then carries the rename network-wide as an ordinary NICK change (transit/other servers no-op the ENCAP, update mirror from the NICK). command/mod.rs made mod nickpub(crate) so s2s can reach apply_local_nick_change. Network-wide nick collision → 433 at the command path (case-only onto target's own nick is NOT a collision); success = no numeric (like KILL). Divergences: leveva-native no differential; collision finally resolved at home server (race → silent no-op); transparent (looks like a self-rename). Fuzzed via propagate → apply_encap_sanick home-server round-trip proptest. Follow-on closed in slice 183. Gate: 1790 lib + all golden/integration green, clippy clean, workspace 0 warnings.

Slice 183 DONE — SAJOIN/SAPART S2S propagation (2026-06-15). The named follow-on to 182; closes the SA* family's last "local-target only" deferral. Structurally simpler than SANICK — no feed-the-line-back-in: the home server's existing force_join/force_part already relay the resulting :<sid> NJOIN / :<uid> PART to all peers (join_one / s2s::relay::local_part), so the inbound apply just runs the local force machinery and the network converges from that relay (every other server no-ops the ENCAP, like SANICK's NICK relay). New leveva/src/s2s/sajoin.rs + s2s/sapart.rs, server-prefixed ENCAP :<our-sid> ENCAP * SAJOIN <uid> <chans> / SAPART <uid> <chans> [:reason]. propagate from each command's remote branch (replacing the NOTICE; no numeric on success). apply_encap_sajoin/apply_encap_sapart (wired into forward::inbound_encap Some("SAJOIN")/Some("SAPART")): only the home server acts (uid local) — SAJOIN validates each channel name defensively (skip a malformed token, never create a bad channel), SAPART discards the home-side 403/442 error (oper is remote). command/mod.rs opened mod join/mod partpub(crate) so s2s reaches force_join/registered_view/force_part (same pattern 182 used for nick). Divergences: remote SAPART gives no 403/442 (membership lives on home server); single-uplink no-op; transparent (ordinary NJOIN/PART). Fuzzed via propagate → apply round-trips (joins/parts the local target across an arbitrary channel set). SA family now S2S-complete* (SAMODE rides ordinary MODE relay). Gate: 2373 tests pass (lib + all golden/integration), clippy clean, workspace 0 warnings.

Slice 188 — services-account netburst re-assertion#

s2s::burst::unick_intro (shared by the link-time burst + live relay::local_introduce) now bursts a logged-in user's services account as a following :<our-sid> ENCAP * SU <uid> :<account> right after the UNICK (after CERTFP/AWAY). Closed the "burst-re-assertion follow-on" named in s2s/su.rs/s2s/metadata.rs: a user who logged in via ENCAP * SU before a link came up previously showed logged-out on a freshly-linked peer (wrong WHOIS 330/WHOX %a/account-notify). Server-authoritative → prefix is our SID (matches the live carrier); receiver applies via su::apply_encap_su. No spurious account-notify (introduced-but-not-yet-NJOIN'd → zero local co-members). Live-introduce correct for free (just-registered user has account == None). Metadata burst re-assertion was the remaining follow-on here — now closed by slice 189 (below).

Slice 189 — metadata netburst re-assertion#

s2s::burst::build_burst now bursts pre-existing draft/metadata-2 keys: a metadata section after the user/channel sections + before EOB emits one :<our-sid> ENCAP * METADATA <target> <key> :<value> line per stored key, via new MetadataStore::snapshot (deterministic, sorted by wire token) + MetaTarget::wire_token (user→UID, channel→folded name). Closes the slice-177 "No registration metadata burst" deferral — the metadata analogue of slice 188's account burst. Server-authoritative (our SID prefix, matching live propagate); the full store is bursted since the peer links to us alone. Receiver applies via apply_encap_metadata (notifies local capable+subscribed members only). This was the last named netburst re-assertion follow-on — account (188) + metadata (189) are both closed. Fuzzed via metadata_burst_round_trips_an_arbitrary _store (exactly-one-line-per-key + exact store round-trip + empty-store inverse, 3000 cases).

Slice 280 — RESV/UNRESV S2S propagation (ENCAP * RESV/UNRESV)#

Closes the S2S RESV propagation follow-on named verbatim in slices 272/273 + resv.rs's module doc — an operator RESV/UNRESV was purely single-server. New s2s/resv.rs (modelled on [[leveva-knock]]/s2s/metadata.rs): propagate_resv/propagate_unresv broadcast :<our-sid> ENCAP * RESV <mask> :<reason> / :<our-sid> ENCAP * UNRESV <mask> to every peer (no-op peerless); apply_encap_resv/apply_encap_unresv apply inbound. Kind is NOT on the wire — inbound re-derives channel-vs-nick from the mask prefix via resv::is_channel_target (same as the local command). forward.rs gained Some("RESV")/Some("UNRESV") arms (applies + onward-relays verbatim, split-horizon). command/resv.rs calls propagate after the param/privilege gates (a 461/481 propagates nothing; UNRESV propagates unconditionally — network may hold it elsewhere). Burst re-assertion s2s/burst.rs::resv_burst re-asserts runtime (conf == false) reservations to a freshly-linked peer (after metadata_burst, before EOB) via new ResvStore::runtime_entries(). Config-vs-runtime boundary: only operator-laid (conf == false) reservations propagate; config resv {} blocks stay per-server local policy (each server seeds its own; inbound-applied lands as conf == false so REHASH never drops a network-learned one) — matches charybdis (config RESVs not clustered). Fuzz: 2 in-crate proptests (apply total/consistent

  • kind-matches-prefix; junk never panics + UNRESV targeted). Remaining slice-272 follow-ons: timed RESV <time> + reaping an already-present holder.

Slice 281 — KLINE/UNKLINE S2S propagation (ENCAP * KLINE/UNKLINE)#

The K-line analogue of slice 280. A TKLINE/UNTKLINE (leveva's temporary K-line family — there is NO separate permanent KLINE command) was single-server. New s2s/kline.rs (modelled on s2s/resv.rs): propagate_kline/propagate_unkline broadcast :<sid> ENCAP * KLINE <duration> <user> <host> :<reason> / :<sid> ENCAP * UNKLINE <user> <host> (no-op peerless); apply_encap_kline/apply_encap_unkline apply inbound. Duration not absolute expiry on the wire — each server computes expires = now + duration against its own clock (no skew); the live command propagates the clamped secs, s2s/burst.rs::kline_burst re-asserts the remaining time (expires - now, active bans only — expired burst nothing), inbound re-clamps [0, TKLINE_MAXTIME]. <user> <host> ride as two params (no @-resplit). Inbound apply reaps LOCAL clients (network ban reaps everywhere; a remote user is reaped by its own server) — this fixed a latent over-reap in the local TKLINE command by routing both through one command/tkline.rs::reap_matching helper now carrying the slice-278 is_local_uid guard (+ kline-exempt skip). UNKLINE does not un-kill (lifts the gate only), propagates unconditionally. TKLINE_MAXTIME + now_secs() promoted to pub/pub(crate) in kline.rs. forward.rs gained KLINE/UNKLINE arms. Fuzz: 2 in-crate proptests (apply total/consistent; junk never panics + UNKLINE targeted).

Slice 282 — SQLite persistence for K-lines + reservations#

TKLINE bans + RESV reservations (lost on restart) now persist to the same database {} SQLite file that backs chat-history ([[leveva-chathistory]]). Each KlineStore/ResvStore gains db: Option<Mutex<Connection>> (manual Debug; new()/default() = in-memory only, every persist path a no-op — used by all tests + when no database {}): open(path) creates a kline/resv table (WAL, COLLATE NOCASE PK so a case-differing re-add upserts not duplicates) + loads existing rows; add/remove/prune write through after the Vec mutation (Vec stays hot-path authority). K-lines drop expires <= now rows on load + prune. Resvs persist only runtime (conf == false) — add persists, seed_config does NOT (config resv {} re-derives from ircd.kdl; loaded rows land conf == false so REHASH never drops them); boot order open (load runtime) → seed_config. server.rs::from_config opens each store against cfg.database.path (log + fall back to new() on error). Inbound S2S apply_encap_kline/apply_encap_resv persist what a server learns (all via add). Errors log, never fatal. examples/+dist/ircd.kdl database {} comment extended. Fuzz: 1 proptest per store (the_persisted_set_matches_after_reopen — file-backed add/remove reloads to the in-memory set, 24 cases, unique temp DB + WAL/SHM cleanup). NO new config key — the existing database {} block transparently gained this.