Implementation choice

Why Rust

The architecture would be expressible in several languages. Rust was chosen for reasons that connect directly to RAHN's design goals — determinism, explicit state, verifiable boundaries, and safety at the execution edge — and the choice is recorded honestly, including its costs (limitations, item 8: "Rust is an implementation choice with consequences").

1. Purity and explicit state can be enforced, not hoped for

RAHN's core rule is that states are never mutated in place: transitions are pure functions from a state plus operations to a new state. Rust's ownership model makes this enforceable at compile time — an &Network cannot be mutated, so a transition that "just fixes things in place" does not compile. In garbage-collected languages the same rule lives in conventions and reviews; here it lives in the type system, which matters for a project whose entire premise is that state identity is trustworthy.

2. Strict, total parsing of untrusted input

The canonical state parser is the project's untrusted-input boundary: malformed or corrupted state must be rejected loudly, never partially loaded (security specification). Rust's absence of null, its exhaustive match, and explicit error types make "every failure path is a typed value that must be handled" the default rather than an aspiration. The structured malformed-input test suites and the planned fuzzer (an open issue) build on that foundation.

3. Safety at the only edge that touches reality

RAHN's one real-world capability — shell-outs to ip netns inside isolated Linux namespaces — is precisely where memory-safety and argv-construction bugs would matter most. A memory-safe implementation of the execution backend shrinks the attack surface of the only code path that can affect a host, which complements (never replaces) the structural host-safety invariant of ADR 0012.

4. Determinism-friendly runtime

Determinism is achieved by excluding nondeterministic sources. Rust helps by not fighting the exclusion: no hidden GC pauses, no implicit runtime magic, iteration order controllable via ordered structures (the canonical format demands total ordering), and compilation to native code so a "same input, same output" claim does not drift with a VM version. Reproducible-from-source behavior is also what makes the cross-platform identity tests (E1) meaningful.

5. Dependency discipline

RAHN ships with a single direct dependency (sha2) and an audited transitive closure, recorded in docs/third-party.md. Cargo's deterministic lockfiles and the ability to audit the whole tree make that posture sustainable — relevant for a project that asks people to verify claims rather than trust them.

The costs, stated plainly

Compile-time strictness slows exploration, and the project carries an explicit warning against becoming Rust-shaped rather than problem-shaped (limitations, item 8). Ergonomics of explicit transitions are higher than editing configs — Rust amplifies that tax rather than hiding it. These are accepted deliberately: the architecture needs a language that refuses silent shortcuts.

Go deeper