Audit: - docs/AUDIT-2026-05-25.md: full protocol audit covering 8 findings (4 critical, 2 high, 5 medium, 4 low) with code references and fix effort estimates - vault/Audit/Tasks.md: Obsidian Tasks plugin file tracking all audit items with priorities, due dates, and per-step checklists Architecture docs updated for Wire format v2 and Wave 5/6 features: - ARCHITECTURE.md: adds wzp-video to dependency graph and project structure; wire format updated to v2 (16B header, 5B MiniHeader); relay concurrency section corrected (DashMap+RwLock is current, not a future optimization); test count 571→702; Android note - PROGRESS.md: Wave 5 and Wave 6 sections appended; test count 372→702; current status and open blockers as of 2026-05-25 - ROAD-TO-VIDEO.md: implementation status table inserted (✅/🟡/🔴/🔲 per phase); 6-step critical path to first video call - WZP-SPEC.md: MediaHeader updated to v2 (16B byte-aligned); MiniHeader updated to 5B with seq_delta; codec IDs 9-12 added (H.264/H.265/AV1); version negotiation section added Obsidian vault (vault/): - 114 files across Architecture/, PRDs/, Reports/, Android/, Reference/, Audit/ with YAML frontmatter - 00 - Home.md index note with wiki links - .obsidian/app.json config Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.9 KiB
4.9 KiB
tags, type
| tags | type | ||
|---|---|---|---|
|
reference |
Roadmap & Known Gaps
Current State Summary
The Android client can connect to a WZP relay, complete the crypto handshake, and exchange audio in real-time. Two phones on the same network can talk to each other through the relay.
What Works (April 2025)
- QUIC transport to relay with room-based SFU
- Full crypto handshake (X25519 ephemeral + Ed25519 signatures)
- Opus 24kbps encoding/decoding at 48kHz
- Lock-free audio I/O via Oboe (capture + playout)
- AEC (acoustic echo cancellation) with 100ms tail
- AGC (automatic gain control)
- RaptorQ FEC encoder/decoder (wired to pipeline)
- Adaptive jitter buffer (10-250 packets)
- UI with connect/disconnect, mute, speaker, live stats
- Random identity seed per app launch
Known Gaps
P0 — Must fix for usable calls
| Gap | Impact | Where to fix |
|---|---|---|
| Media encryption not applied | Audio sent in cleartext over QUIC | engine.rs — pass _session to send/recv, encrypt/decrypt payloads |
| FEC repair symbols not sent | No loss recovery — audio gaps on packet loss | engine.rs send task — call fec_encoder.generate_repair() and send repair packets |
| Quality reports not sent | Relay can't monitor quality, no adaptive switching | engine.rs — periodically attach QualityReport to MediaPacket header |
| CallService not started | Call dies when app is backgrounded | CallViewModel.startCall() — call CallService.start(context) |
P1 — Important for production
| Gap | Impact | Where to fix |
|---|---|---|
| Hardcoded relay address | Can't change server without rebuild | Add settings screen with SharedPreferences |
| No reconnection logic | Connection drop = call over | engine.rs network task — detect disconnect, retry with backoff |
| No adaptive quality switching | Stays on GOOD profile even in bad conditions | Wire AdaptiveQualityController to network path quality from QuinnTransport |
| Identity seed not persisted | New identity every launch | Save seed to Android Keystore or SharedPreferences |
| No Bluetooth audio routing | AudioRouteManager exists but not wired to UI |
Add Bluetooth button to InCallScreen, call AudioRouteManager methods |
| No ringtone/notification for incoming | Only outgoing calls supported | Need signaling for call setup (currently both sides initiate independently) |
P2 — Nice to have
| Gap | Impact | Where to fix |
|---|---|---|
| No android_logger | Rust tracing output lost on Android | Add android_logger crate, init in nativeInit() |
| Stats don't include network metrics | Loss/RTT/jitter always 0 | Feed QuinnTransport.path_quality() back to stats |
| No ProGuard/R8 minification | Release APK larger than necessary | Enable isMinifyEnabled = true in build.gradle.kts |
| Single ABI (arm64-v8a) | No support for older 32-bit devices or emulators | Add armeabi-v7a and x86_64 to cargo-ndk build |
| No call history | Can't see past calls | Add Room database for call log |
| No contact integration | Manual relay/room entry | Add contacts with fingerprint-based identity |
Architecture Evolution Plan
Phase 1: Make Calls Reliable (current → next)
[x] QUIC connection to relay
[x] Crypto handshake
[x] Audio encode/decode pipeline
[ ] Media encryption (ChaCha20-Poly1305)
[ ] FEC repair packet transmission
[ ] Foreground service for background calls
[ ] Reconnection on network change
Phase 2: Quality & Polish
[ ] Adaptive quality (GOOD → DEGRADED → CATASTROPHIC switching)
[ ] Quality reports in MediaPacket headers
[ ] Network path quality display (real RTT, loss, jitter)
[ ] Settings screen (relay, room, seed persistence)
[ ] Bluetooth/wired headset audio routing
[ ] Rust android_logger for debugging
Phase 3: Production Features
[ ] featherChat authentication
[ ] Persistent identity (Android Keystore)
[ ] Push notifications for incoming calls
[ ] Multi-party rooms (already supported by relay)
[ ] Call transfer
[ ] End-to-end encryption (bypass relay decryption)
Dependency Upgrade Path
quinn 0.11 → 0.12 (when released)
Quinn 0.12 will likely require rustls 0.24. Update both together:
Cargo.toml: bump quinn and rustls versions- Check
client_config()andserver_config()in wzp-transport for API changes - DATAGRAM API may change — check
send_datagram()/read_datagram()
Compose BOM 2024.01 → 2025.x
The LinearProgressIndicator progress parameter changed from Float to () -> Float in Material3 1.2+. If upgrading the BOM:
// Old (current):
LinearProgressIndicator(progress = level, ...)
// New (Material3 1.2+):
LinearProgressIndicator(progress = { level }, ...)
Kotlin 1.9 → 2.x
Kotlin 2.0 changed the Compose compiler plugin. Update kotlinCompilerExtensionVersion in composeOptions and the Kotlin Gradle plugin version together.