# Cargo.toml — rutster workspace root. # Spec ref: slice-1 §2. The workspace pins shared dep versions here so # member crates can't drift (§2.1). Each member references with # `dep.workspace = true`. [workspace] resolver = "2" members = [ "crates/rutster", "crates/rutster-brain-realtime", "crates/rutster-call-model", "crates/rutster-media", "crates/rutster-sim", "crates/rutster-spend", "crates/rutster-tap", "crates/rutster-tap-echo", "crates/rutster-trunk", ] [workspace.package] license = "GPL-3.0-or-later" edition = "2024" repository = "https://git.adlee.work/alee/rutster" # Pinned versions for all member crates. References are `foo.workspace = true` # in the member manifest. Keeps the dep tree unified (§2.1). [workspace.dependencies] # str0m 0.21: sans-IO WebRTC. Frame API (Event::MediaData + Writer::write). str0m = "0.21" # opus 0.3.1: libopus FFI (system libopus required — see README). opus = "0.3" # axum 0.7: HTTP signaling surface. axum = { version = "0.7", features = ["macros"] } # tokio 1: runtime driving the str0m poll loop (slice-1 deviation per §3.4). tokio = { version = "1", features = ["full"] } # dashmap 6: in-process session store. dashmap = "6" # uuid 1: ChannelId newtype backing. uuid = { version = "1", features = ["v4"] } thiserror = "1" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } serde = { version = "1", features = ["derive"] } serde_json = "1" # tower: used by the binary crate's integration tests (ServiceExt::oneshot # on the axum Router). Axum re-exports parts of tower but the integration test # uses `tower::ServiceExt` directly, so it needs to be a workspace dep. tower = { version = "0.5", features = ["util"] } # tokio-tungstenite 0.24: WS client + server (slice-2 tap transport). tokio-tungstenite = { version = "0.24", features = ["connect"] } # futures-util 0.3: Sink/Stream traits for WebSocketStream. futures-util = "0.3" # url 2: tap URL parsing + host validation (spec §4.4). url = "2" # base64 0.22: PCM <-> base64 codec for the v1 wire format (spec §3). base64 = "0.22" # async-trait 0.1: async fns in trait objects (Tool trait, slice-3 spec §6.1). async-trait = "0.1" # http 1: Request/Response builders for the OpenAI WS handshake (slice-3 # spec §5.3). Task 9's main.rs builds the http::Request<...> the tungstenite # client sends before WS upgrade; `openai_client::openai_headers` produces # the header pairs the caller stuffs into it. http = "1" # reqwest 0.12: HTTP client for the green-zone Twilio REST call-control # client (slice-5 T6, feature-gated behind `twilio-live`). `rustls-tls` # (not native-tls/OpenSSL) keeps the TLS stack pure-Rust + consistent with # str0m's existing aws-lc-rs crypto provider (ADR-0001 "memory-safe by # construction"). `default-features = false` drops the default # native-tls/OpenSSL backend. `json` for the Calls.json response parsing. reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } # toml 0.8: TOML deserialization for the slice-4½ sim-crate's Scenario files # (crates/rutster-sim/scenarios/*.toml). The first consumer of `toml` in # the workspace; declared here so future members share the version pin. toml = "0.8" # ipnet 2: CIDR parsing for RUTSTER_TRUSTED_PROXIES (deploy slice A §5.3). # Already in Cargo.lock transitively (via reqwest) — this adds only the # direct edge; MIT/Apache-2.0, cargo-deny clean. ipnet = "2" # axum-server 0.8: in-process TLS listener for rustls Phase 1 (deploy spec §5.4). Consumes # rustls 0.23 + tokio-rustls 0.26 (already in Cargo.lock transitively via str0m → aws-lc-rs # at 0.23.41 / 0.26.4 — verified). The tls-rustls feature enables # axum_server::tls_rustls::{RustlsConfig, RustlsAcceptor}. MIT license — cargo-deny-clean. axum-server = { version = "0.8", features = ["tls-rustls"] } # rustls 0.23: TLS implementation consumed transitively by axum-server's tls-rustls # feature. Already in Cargo.lock at 0.23.41 via str0m → aws-lc-rs; this surfaces the # direct edge for the integration test's ClientConfig. Apache-2.0 / MIT / ISC, # cargo-deny clean. rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs", "ring"] } # tokio-rustls 0.26: tokio integration for rustls. Already in Cargo.lock at 0.26.4 # (transitive once Task 1's Cargo.lock resolves). Used by the serve_tls integration # test's TLS client handshake. tokio-rustls = { version = "0.26", default-features = false, features = ["aws-lc-rs", "ring"] } # redis 0.27: Valkey/Redis client for ValkeyEventSink (deploy spec §5.6). # BSD-3-Clause (verified via docs.rs/redis + crates.io API), cargo-deny clean against # the deny.toml allow list (line 88). Pinned to 0.27 (NOT 1.3.0) because redis 1.3.0 # requires Rust 1.88, conflicting with the workspace MSRV of 1.85 # (rust-toolchain.toml). redis 0.27.6 has MSRV 1.70, well within 1.85. # Features: # - aio: async API (ConnectionManager, AsyncCommands) # - streams: XADD MAXLEN ~ (the capped-stream primitive, StreamMaxlen::Approx) # - tokio-comp: tokio runtime adapter # Used only by crates/rutster/src/valkey_sink.rs. default-features = false deliberately DROPS # the redis crate's TLS feature — TLS to Valkey is the operator's network posture # (ADR-0005 sub-ms rule), not a rutster code path. redis = { version = "0.27", default-features = false, features = ["aio", "streams", "tokio-comp"] } # rcgen NOTE: rcgen 0.14.8 bumped MSRV to Rust 1.88, breaking the 1.85 # toolchain matrix. rcgen is a transitive dep via dimpl → str0m 0.21 → # rutster-media. Cargo.lock pins it to 0.14.7 (the minimum satisfying # dimpl's ^0.14.7 constraint) to keep the 1.85 MSRV safety net. If a # `cargo update` bumps it past 0.14.7, the 1.85 CI job will fail — re-pin # with `cargo update -p rcgen --precise 0.14.7`. When the project bumps # rust-toolchain.toml past 1.88, this pin can be dropped.