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.

P12 — Retire the mechanical port; leveva is the product#

The literal end of the strangler fig. The C tree was strangled by the faithful mechanical port (P8); the faithful port was strangled by the greenfield leveva (P10–P11); P12 deletes the faithful port now that leveva is at parity.

Plan: docs/superpowers/plans/2026-06-13-p12-retire-mechanical-port.md.

  • 2026‑06‑13 — P12 (retire the mechanical port) merged. The user chose "begin the P12 deletion" over adding more IRCv3 caps — parity is sufficient (the full client surface, S2S, the IRCv3 account-extensions trio, and the parity-matrix fuzzing pass through slice 143 are all done).

    • The gate (final differential run). cargo test -p leveva-integration — the last run of the oracle differential suite — passed green (exit 0, every *_differential.rs + *_proptest.rs binary ok, including the slow topology/stats/s2s proptests). leveva and the mechanical-port oracle (ircd-common/iauth-rs) agree across the entire shared skeleton one final time. This is the PLAN.md P12 entry condition ("run the differential suite a final time, then delete").

    • Pre-condition verified before deleting. leveva and leveva-iauth have no dependency on the mechanical port — neither a Cargo path dep nor a use ircd_common/use iauth_rs import; every textual match across both crates is a comment. So the deletion is clean (no dangling references). The behavioral guarantees were already carried outside the oracle by leveva's own self-contained 212-file suite (boot-golden + per-slice proptest); the leveva-integration tests were purely the oracle differential pin layer (assert leveva ⇔ ircd-common on a shared skeleton), a guarantee that is meaningless once the oracle is gone, and every leveva-only invariant inside them (parse panic-freedom, CRLF framing) is duplicated by leveva's own proptests (feed_framing_proptest, the per-slice *_proptest.rs). Nothing to salvage — they retire with their oracle.

    • Deleted. git rm -r ircd-common ircd-rs iauth-rs leveva-integration. iauth-rs was the C-iauth differential oracle, long since subsumed by the native in-process leveva-iauth (see the iauth-subsumed-into-leveva note). Workspace Cargo.toml members reduced to ["leveva", "leveva-iauth"]; the explanatory comment rewritten to record the completed strangler.

    • Deployment rigging (user ask). Removed the mechanical port's deployment artifacts: docker/Dockerfile.ircd; the ircd target + its slot in the default group of docker-bake.hcl (leaving the leveva target); and the entire docs/k8s/example-network/ (its whole purpose was demonstrating the now-impossible leveva↔ircd S2S link — README topology, ircd.yaml, cfg/ircd.conf, the mixed kustomization.yaml).

    • Docs (user ask). Rewrote README.md from "experimental mechanical port" to what the project actually is now: a finished strangler fig whose product is leveva, an idiomatic async-Rust IRC daemon — with build/run instructions, the workspace table, and the history preserved as a pointer to PLAN.md + git. Also fixed the stale present-tense references to the deleted ircd-* crates in leveva/src/lib.rs (module doc), leveva/Cargo.toml, and leveva-iauth/Cargo.toml comments.

    • Gate (exit). cargo build --workspace 0 warnings; cargo clippy --workspace --tests clean; cargo test -p leveva -p leveva-iauth green. The workspace is now leveva + leveva-iauth. Everything deleted — the C source tree (gone at P8v), the mechanical port, the oracles — remains recoverable from git history; the P8 final byte-identical reference-C run is the provenance anchor.

    • The strangler is complete. There is no more mechanical port and no oracle; leveva stands alone as the product, its own test suite carrying the behavioral guarantees forward.


  • 2026-06-21 — post-P12 refactor: leveva-casemap leaf crate extracted (+ proptest fuzz). Continuing the leaf-crate carve-out begun by the leveva-message/leveva-patricia extraction, the RFC 1459 case-folding module moved out of the monolith into its own workspace crate. This is not a migration slice — the strangler is finished; it is standalone refactoring of the finished product.

    • Why casemap. It is the lowest leaf in the string cluster: it imports only core::cmp::Ordering + core::hash::Hasher and has zero intra-crate coupling, while string/ident/matching/channel/registry/whowas all depend on it. That made it the cleanest next extraction (the string/ident/matching/cidr siblings still touch each other / typed ids, so they stay put for now).

    • Mechanism (identical to message/patricia). New leveva-casemap crate (publish = false, std-only lib, proptest dev-dep); leveva/src/casemap.rs deleted; leveva/src/lib.rs now does pub use leveva_casemap as casemap; (a doc'd re-export beside the message/patricia ones). Every crate::casemap::* (~40 source + test files) and leveva::casemap::* path is unchanged — zero consumer churn.

    • Fuzzing (user ask). Stable toolchain only (rustc 1.96, no nightly, no cargo-fuzz), so proptest is the runnable fuzz tier — same choice leveva-message made. Added 7 proptest! invariants fed arbitrary bytes / arbitrary (incl. non-ASCII) strings, all consistency/inverse properties rather than happy-path echoes: fold ⇔ eq_ignore_case (both directions), cmp==Equal ⇔ eq, cmp antisymmetry, hash agrees with eq (prefix-free 0xff marker exercised), fold idempotent + UTF-8-safe + byte-length-preserving, high bytes (≥0x80) identity, and to_upper∘to_lower identity on the uppercase domain over the full byte range.

    • Gate. cargo build --workspace 0 warnings; cargo clippy --workspace --tests clean; cargo test -p leveva-casemap 13 green (6 unit + 7 fuzz); full leveva suite green. Plan: docs/superpowers/plans/2026-06-21-extract-leveva-casemap.md. Workspace members are now leveva + leveva-iauth + leveva-casemap + leveva-message + leveva-patricia.


  • 2026-06-21 — post-P12 refactor: leveva-string leaf crate extracted (+ proptest fuzz). The next leaf-crate carve-out after leveva-casemap (which followed leveva-message/leveva-patricia). The casemapping-aware string types moved out of the monolith into their own workspace crate. Still not a migration slice — the strangler is finished; this is standalone refactoring of the finished product.

    • Why string (the architectural #2). With casemap now its own crate, string depends on exactly one intra-crate module — crate::casemap, already the extracted leveva-casemap — and otherwise only core/std. That makes it the cleanest next leaf: leveva-string depends on leveva-casemap and nothing else in the workspace, while ident/channel/registry/whowas depend on it (via the re-exported IrcStr/IrcString/IrcStringBuilder/IrcError names). No cycle — leveva-message uses neither, and leveva-casemap depends only on core.

    • Mechanism (identical to message/patricia/casemap). New leveva-string crate (publish = false, std lib, one lib dep leveva-casemap, proptest dev-dep); leveva/src/string.rs deleted; leveva/src/lib.rs now does pub use leveva_string as string; (a doc'd re-export beside the others) and the existing pub use string::{IrcError, IrcStr, IrcString, IrcStringBuilder}; then re-exports straight out of the new crate. The body moved verbatim except use crate::casemap;use leveva_casemap as casemap; and the two doctests' use leveva::…;use leveva_string::…;. Every crate::string::* / leveva::string::* path and the four flat re-exports are unchanged — zero consumer churn (the full build of every dependent crate confirms it).

    • Fuzzing (user ask). Stable toolchain → proptest, matching casemap/message. Added 6 proptest! invariants fed arbitrary (incl. non-ASCII) strings, all consistency/inverse properties: eq lifts casemap (the wrapper adds no equality of its own), Ord consistent-with-Eq + antisymmetric, Hash agrees with Eq (the HashMap-key contract for nick/channel tables), Borrow<IrcStr> round-trip (insert under one casing, find by a case-different borrowed key), validation soundness (accept iff no NUL/CR/LF, FromStr agrees, storage byte-identical on success), and builder ≡ try_from (build is a deferred validate, rejects iff a piece carried a framing byte).

    • Other crates that can still move out (the user's question). Surveyed by intra-crate dep surface: cloak (zero intra-crate deps — a perfect standalone leaf, the strongest next candidate); uid (only crate::ident, extractable once ident is a crate); matching+cidr are a coupled pair (mutually referential) so not a clean single leaf yet; msgid pulls cap/clock/ident, not a leaf.

    • Gate. cargo build --workspace 0 warnings; cargo clippy --workspace --tests clean; cargo test -p leveva-string 13 green (7 unit + 6 fuzz) + 2 doctests; full leveva suite green. Plan: docs/superpowers/plans/2026-06-21-extract-leveva-string.md. Workspace members are now leveva + leveva-iauth + leveva-casemap + leveva-message + leveva-patricia + leveva-string.

  • 2026-06-21 — refactor: extract leveva-cidr leaf crate (+ proptest fuzzing). Continues the post-P12 leaf-crate carve-out after casemap/string/message/patricia. Standalone feature work — no oracle, no differential.

    • Why / a correction. cidr is a pure leaf — every function depends only on std::net::IpAddr. The earlier leveva-string survey filed matching+cidr as "a coupled pair (mutually referential), not a clean single leaf yet"; that was wrong. cidr.rs's only references to crate::matching/crate::connlimit are in doc comments, not code. The real edge is one-way: matchingcidr (matching.rs:176 calls crate::cidr::cidr_match), with connlimit/websocket also calling in, while cidr calls nothing intra-crate. So cidr extracts cleanly on its own — and unblocks matching, whose only remaining intra-crate deps are now the two already-extracted crates casemap + cidr.

    • Mechanism (identical to casemap/string/message/patricia). git mv leveva/src/cidr.rs → leveva-cidr/src/lib.rs; new leveva-cidr crate (publish = false, std lib, no lib deps, proptest dev-dep); leveva/src/lib.rs now does pub use leveva_cidr as cidr; (a doc'd re-export beside the others). Body moved verbatim except the doctest's use leveva::cidr::cidr_match;use leveva_cidr::cidr_match; and two cross-crate intra-doc links repointed to plain text. All four call sites use fully-qualified crate::cidr::* (parse_cidr/contains/network_base/cidr_match), so zero consumer churn — the full leveva build + the matching/connlimit/websocket tests confirm it.

    • Fuzzing (user ask). Stable toolchain → proptest, matching casemap/string. Added 10 proptest! invariants over the full v4/v6 address space (u32::ANY/u128::ANY) and arbitrary in-range prefixes, all consistency/inverse properties: parse_cidr round-trips (+ out-of-range prefix always rejected), contains reflexive through network_base, network_base idempotent, contains prefix-monotone (membership at p ⇒ membership at every wider q ≤ p), /0 universal + full-length exact, family mismatch never contains, and cidr_match ≡ parse + contains.

    • Other crates that can still move out (the user's question). cidr cleared and matching now unblocked: matching (498 LoC) is now a clean leaf (deps casemap + cidr, both crates; pulls nom) — the natural next extraction, the C match.c cluster; cloak (zero intra-crate deps — a perfect standalone leaf, independent of the matching cluster); uid (only crate::ident, extractable once ident is a crate); msgid pulls cap/clock/ident, not a leaf.

    • Gate. cargo build -p leveva 0 warnings; cargo test -p leveva-cidr 18 green (8 unit + 10 fuzz) + 1 doctest; leveva cidr-consumer tests (matching/connlimit/websocket, 54) green. Plan: docs/superpowers/plans/2026-06-21-extract-leveva-cidr.md. Workspace members are now leveva + leveva-iauth + leveva-casemap + leveva-cidr + leveva-message

      • leveva-patricia + leveva-string.
  • 2026-06-22 — leveva-cloak leaf crate extracted (+ proptest fuzzing). Continues the leaf-crate carve-out (after casemap / string / message / patricia / cidr). Plan: docs/superpowers/plans/2026-06-22-extract-leveva-cloak.md.

    • Why / leaf-nesscloak is the cleanest remaining leaf: zero intra-workspace deps (only std::net::IpAddr), exactly as the cidr survey predicted ("strongest next pick"). Its only crate::-references are doc comments; the code edges all run into it (command::mode::apply_cloak_change mode.rs:916 + session.rs:1786 call crate::cloak::cloak). No cycle — leveva-cloak depends on nothing in the workspace.
    • Mechanismgit mv leveva/src/cloak.rs → leveva-cloak/src/lib.rs verbatim (no doctest, all intra-doc links resolve in-module, so zero body edits beyond the appended fuzz module); leveva/src/lib.rs swaps pub mod cloak; for pub use leveva_cloak as cloak;; both call sites use fully-qualified crate::cloak::cloak → zero consumer churn.
    • Fuzzing (the user ask) — 10 proptest invariants; the transform has no differential oracle (C 2.11 has no +x), so these are the gate. Determinism; the leading-colon wire-safety biconditional (+ :-prefixed-unchanged); length preservation for both cloak_ip/cloak_host; separator/dot byte-index invariance; IP-literal dispatch to cloak_ip; the g–z IP alphabet + first-two-octets-kept (v4) and hex/:/g–z (v6); and fnv_hash_32 == charybdis's shift-decomposition over arbitrary bytes. Fed arbitrary (incl. non-ASCII) strings + the full v4/v6 space.
    • Next extraction candidatesmatching (now a clean casemap+cidr leaf, pulls nom, the C match.c cluster); uid (blocked on ident); msgid (not a leaf).
    • Gatecargo build --workspace 0 warnings; cargo clippy --workspace --tests clean; cargo test -p leveva-cloak 18 (8 unit + 10 fuzz) green; the +x consumer tests in leveva (command::mode plus_x suite + session registers-cloaked, 8 incl. the s2s +s+x spy) green.
  • 2026-06-22 — leveva-matching leaf crate extracted (+ proptest fuzzing). Continues the post-P12 leaf carve-out after leveva-casemap/leveva-string/leveva-message/ leveva-patricia/leveva-cidr/leveva-cloak. The match.c cluster (IRC glob matcher + nick!user@host hostmasks, 498 LoC) was the survey-flagged "natural next pick": its only intra-crate edges were use crate::casemap; (casemap::to_lower) and crate::cidr::cidr_match — both already their own leaf crates — plus nom.

    • Mechanism (identical to the prior six): git mv leveva/src/matching.rs leveva-matching/src/lib.rs; new crate deps leveva-casemap + leveva-cidr + nom, dev-dep proptest. Five verbatim repoints only: use crate::casemap;use leveva_casemap as casemap;; crate::cidr::cidr_matchleveva_cidr::cidr_match; the module-header intra-doc link (crate::casemap)(leveva_casemap); two doctests use leveva::matching::…use leveva_matching::…. leveva/src/lib.rs swaps pub mod matching; for pub use leveva_matching as matching;, so the flat pub use matching::{collapse, matches, HostMask, Pattern}; re-export and all ~13 consumer modules (xline/kline/resv/webirc/metadata/registration + command/{oper,map,mask,hunt,dline,tkline}) keep their crate::matching::* paths.
    • No dependency cycle: leveva-matching{leveva-casemap, leveva-cidr, nom} (leaves that depend on nothing in-workspace); levevaleveva-matching. The code edges all run into matching.
    • Fuzzing (the user ask): stable-toolchain proptest, no differential oracle (leveva's matcher deliberately diverges from match.c's ASCII-only fold — RFC 1459 case-fold, #=any-digit), so the 13 proptest invariants ARE the gate. Fed arbitrary (incl. non-ASCII) strings + glob masks: totality/no-panic across every entry point, * is universal, ?^k ⇔ exact byte-length, case-insensitivity under leveva_casemap::fold of the name, compile==matches, collapse is matching-preserving + idempotent + non-growing, HostMask re-parses its own Display, matches_target==matches_parts, allow_host_matches decomposes into user-glob && host-component, and a glob host component falls back to matches.
    • Gate: cargo build --workspace (0 warnings) · cargo clippy --workspace --tests (clean) · cargo test -p leveva-matching (28 = 8 unit + collapse/escaping etc. unit + 13 fuzz, + 2 doctests) green · leveva matching-consumer tests (xline/kline/resv/webirc, 181) green.
    • What else can still move out: uid (≈230 LoC, only crate::ident) becomes a leaf once ident splits — ident is blocked by a single crate::command reference worth auditing, the next unlock. msgid pulls cap/clock/ident; clock is a small candidate leaf (audit pending).