slice-1: WebRTC media loopback — the media-core proof #1
Reference in New Issue
Block a user
Delete Branch "slice-1-webrtc-loopback"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements spearhead step 1 of the Rutster build: a browser talks WebRTC to the core; the core terminates DTLS-SRTP, decodes Opus → canonical 16-bit PCM @ 24 kHz mono, echoes the PCM back to the browser.
What lands
[workspace.dependencies]pinning;rust-toolchain.tomlpinned to 1.85 (edition 2024 floor, mandated by uuid 1.x → getrandom 0.4.x).rutster-media— the media core:str0m 0.21sans-IO WebRTC + Opus⇄PCM boundary.PcmFrame(canonical 480-sample 24 kHz mono),AudioSource/AudioSinktrait seam (pre-paves the step-2 tap),EchoAudioPipeslice-1 wiring,OpusDecoder/OpusEncoderwith hot-path match-and-continue (no?on the 20 ms loop, nounwrap).rutster-call-model— theChannel/ChannelId/ChannelStateembryo (signaling-state only; media stays internal to rutster-media as a leaf concern).rutster-signaling-sip,rutster-tap,rutster-spend) locking ADR-0002 boundaries without anticipating code — each ships a//!doc naming its spearhead step.rutsterbinary — axum 0.7 signaling on0.0.0.0:8080plaintext (dev-loop posture),DashMap<ChannelId, Arc<Mutex<RtcSession>>>session store, four routes (POST /v1/sessions,POST /v1/sessions/:id/offer,DELETE /v1/sessions/:id,GET /), single tokio poll task driving all sessions, graceful shutdown via Ctrl-C / SIGTERM, browser test client served viainclude_str!.cargo-deny+ CI — gates on fmt, clippy -D warnings, test --all, deny check; matrix stable + 1.85;deny.tomlallows permissive Rust-ecosystem licenses + our own GPL-3.0 (workaround for cargo-deny 0.18.x parser bug on the SPDX form on the pinned toolchain — well-documented inline, revert at MSRV ≥ 1.88).LEARNING.md— 10 concept-to-file pointers (floor was 5);fuzz/README.mdpre-paves the step-5 harness layout.Process
Built via subagent-driven-development: 7 tasks, fresh implementer + reviewer pair per task, controller applied two cross-task plan corrections (toolchain bump 1.80→1.85, deny.toml parser workaround), final whole-branch review Approved.
Gate status (spec §6.5 done checklist)
cargo test --all— 18 tests across the workspacecargo fmt --check— cleancargo clippy -- -D warnings— cleancargo deny check— 3/4 subcommands clean locally on cargo-deny 0.18.3 (licenses, bans, sources);advisoriesfails locally on CVSS-4.0 entries the older parser can't read, but CI's 0.19+ action parses them fineDELETEroute, and the Closing→Closed transition are in place; the README §6.5 manual checklist covers verificationLEARNING.mdindexes 10 "to learn X, read Y" pointersDeviations
accept_offer()produces the SDP answer natively (DTLS fingerprint + ICE creds + Opus codec) — replaced the spec §3.7 sketch's "50-line SDP munger". str0m evolved since the spec was written.opuscrate 0.3.1 links system libopus via FFI (audiopus_sys) — amends spec §6.3's "no external deps beyond Rust" with PORT_PLAN §7's "Core (FFI)" rationale.libopus-devis the one system dep; documented in README + installed in CI.rcgen/timedeps needed lock-downgrade for rust 1.85 compat (the action's bundled cargo-deny 0.19+ parses fine).will block until MSRV lifts past 1.88flags in deny.toml —RUSTSEC-2026-0009ignore (time 0.3.41; fix needs rustc 1.88),thiserrorskip entries (workspace bump to v2 clears them),wildcards = warn(path deps lackversion =field).Plan:
docs/superpowers/plans/2026-06-28-slice-1-webrtc-loopback.md. Spec:docs/superpowers/specs/2026-06-28-slice-1-webrtc-loopback-design.md.Out-of-scope (per spec §1.2)
Slice 1 pre-paves the tap seam but does NOT ship the tap (step 2), the brain (step 3), barge-in/VAD (step 4), PSTN trunk (step 5), or spend cap (step 6). Dedicated timing thread deferred to step 4 (the tokio poll-path is a documented
DEV-DEVIATIONcomment inloop_driver.rs). No TLS on the HTTP surface, no authn/authz, no trickle ICE.cargo-deny 0.18.3 (the latest that installs on rust 1.85) can't parse the SPDX 'GPL-3.0-or-later' suffix — 'expected a <bare-gnu-license>'. CI uses cargo-deny-action@v1 (bundles 0.19+) which parses it correctly. Switching to bare 'GPL-3.0' lets local 'cargo deny check' work on the pinned toolchain. ADR-0004's GPL-3.0-or-later stance is unchanged; this is a parser workaround flagged for revert when the MSRV lifts past 1.88 (where cargo-deny 0.19.x installs natively). Three of four 'cargo deny check' subcommands now pass locally: - licenses ok - bans ok - sources ok - advisories: fails locally only because the advisory-db contains CVSS 4.0 entries (anchor-lang RUSTSEC-2026-0146) that cargo-deny 0.18.3's parser rejects. Unfixable on the rust 1.85 toolchain; CI's 0.19+ parses fine. Surfaced by Task 7's done-checklist run; not a Task 7 code change.