Files
rutster/docs/ARCHITECTURE.md
adlee-was-taken 0370347642 ADR-0001: SIP strategy — native Rust core behind Kamailio + rtpengine
Record the SIP edge decision and align the docs:
- docs/adr/0001-sip-strategy.md: layered strategy (own Rust parser, rent the
  interop tail via a Kamailio + rtpengine SBC, grow native core behind the shield);
  pjproject FFI explicitly rejected for breaking the memory-safety thesis at the
  most exposed seam.
- PORT_PLAN §1 + open decisions: SIP row updated to the decided strategy.
- ARCHITECTURE: "biggest technical risk" now points at ADR-0001.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C2bfD7MkqEdfnMXxXBu456
2026-06-26 21:49:36 -04:00

2.8 KiB

Rutster Architecture

The reframe

Asterisk's power was: one process, load any .so, wire anything to anything in the dialplan. That composability is the thing to match — but it does not require a 1.2M-LOC monolith. Rutster delivers the same "build anything" through a different substrate:

  • a small hardened core (media + signaling glue + call model),
  • a WASM plugin runtime for safe, third-party-extensible logic,
  • declarative routing as data for the common path,
  • a programmable API (REST/gRPC + event stream) modeled on Asterisk's ARI.

More extensible than Asterisk, because extensions are safe to run from people you don't fully trust.

Three planes

Control plane (stateless-ish, horizontally scalable)

The ARI-style resource API (channels / bridges / endpoints / recordings / playbacks) over REST + gRPC + a WebSocket/SSE event stream. Registrar, routing, auth. This is where "the dialplan" disappears — replaced by declarative routing + external services reacting to call events (the Twilio / ARI-Stasis model). Asterisk's rest-api/api-docs/*.json is a reusable spec for the resource model.

Media plane (stateful, latency-pinned, scaled separately)

RTP/SRTP termination, mixing/bridging (softmix), transcoding, record/playback. A controllable media node driven over gRPC by the control plane. Built on the Rust WebRTC media ecosystem (str0m sans-IO design, webrtc-rs). The media datapath stays tight — do not over-decompose it across service hops; latency and failure modes compound.

App plane (your services + plugins, outside the core)

IVR, queues, voicemail, dialers, custom routing — driven via the API, deployed independently. WASM plugins for in-call logic that needs to run close to the core; microservices for stateful/business/billing logic.

Cross-cutting

  • Event bus (NATS / Redis Streams / Kafka) replaces Asterisk's internal Stasis bus for cross-service events; a lightweight in-core dispatcher handles intra-core.
  • State store replaces astdb + realtime/sorcery.
  • Security is load-bearing, not a row: memory-safe fuzzed parsers, TLS/SRTP mandatory, deny-by-default routing + toll-fraud engine, mTLS gRPC admin (no AMI), WASM tenant isolation, SBOM + KMS/Vault for secrets.
  • Observability: OpenTelemetry traces that follow a single call across signaling → media → app services.

Biggest technical risk

The SIP stackdecided in ADR-0001: own the Rust parser from day one (the security thesis depends on it), front the public edge with a proven Kamailio + rtpengine SBC to absorb the interop tail, and grow the native Rust transaction/dialog core behind that shield. No pjproject FFI. Everything else builds on the existing Rust media ecosystem.