# Chanora Codebase Analysis Report **Date:** 2026-06-11 **Branch:** `docs/codebase-analysis-v2` **Scope:** Full codebase analysis — functions, tests, documentation, dead code, duplication, architecture, external research --- ## Table of Contents 1. [Executive Summary](#1-executive-summary) 2. [Function Inventory](#2-function-inventory) 3. [Test Coverage](#3-test-coverage) 4. [Documentation Coverage](#4-documentation-coverage) 5. [Dead Code Analysis](#5-dead-code-analysis) 6. [Useless/Redundant Code](#6-uselessredundant-code) 7. [Duplicated Code](#7-duplicated-code) 8. [Document Link Coverage](#8-document-link-coverage) 9. [Git History & Issue Patterns](#9-git-history--issue-patterns) 10. [PR Analysis](#10-pr-analysis) 11. [API Gap Analysis](#11-api-gap-analysis) 12. [Crate Architecture Analysis](#12-crate-architecture-analysis) 13. [Document Staleness Analysis](#13-document-staleness-analysis) 14. [Test Environment Requirements](#14-test-environment-requirements) 15. [External Research](#15-external-research) 16. [Recommendations](#16-recommendations) --- ## 1. Executive Summary ### Key Metrics | Metric | Value | |--------|-------| | **Total Rust public functions** | ~428 | | **Total Flutter/Dart functions** | ~586 | | **Rust test count** | 359 | | **Flutter test count** | 221 | | **Total test count** | 580 | | **Overall test coverage** | 75% of modules | | **Documentation coverage (Rust)** | 30% of functions have doc comments | | **Documentation coverage (Flutter)** | 58% of classes documented | | **Dead code items** | ~20 (5 definitely dead, 11 likely dead, 4 conditionally dead) | | **Duplicated code patterns** | 10 major patterns | | **Broken doc links** | 6 (all from missing LICENSE files) | | **Orphaned docs** | 14 files | | **Stale documents** | 5/8 major docs need updates | | **PRs analyzed** | 42 (34 merged, 8 closed) | | **Issues documented in history** | 45 significant issues | ### Critical Findings 1. **iOS audio is the #1 problem area** — 15+ issues, AVAudioSession lifecycle is the most recurring root cause 2. **chanora_audio has 168 public functions but only 24% documented** — largest crate, most complex 3. **chanora_bridge has 0 tests** — the Flutter-Rust boundary is completely untested 4. **53 SysRS requirements (SysRS-258–310) lack SysDes allocation** — breaks traceability 5. **Several features exist without requirements** — poke, file transfer, hard-mute, cache 6. **engine.rs is 3,244 lines** — monolithic, needs splitting 7. **main.dart is 2,910 lines** — monolithic, needs splitting 8. **~39 production `unwrap()` calls in engine.rs** — crash risk on poisoned mutex --- ## 2. Function Inventory ### Summary by Component | Component | Type | Total `pub fn` | Documented | Coverage | |---|---|---|---|---| | **chanora_core** | Rust lib | 68 | 65 | 96% | | **chanora_audio** | Rust crate | 168 | ~40 | 24% | | **chanora_bridge** | Rust crate | 65 | ~10 | 15% | | **chanora_protocol** | Rust crate | 35 | 33 | 94% | | **chanora_state** | Rust crate | 16 | ~8 | 50% | | **chanora_storage** | Rust crate | 20 | ~12 | 60% | | **chanora_cache** | Rust crate | 7 | 7 | 100% | | **chanora_resolver** | Rust crate | 15 | ~8 | 50% | | **chanora_diagnostics** | Rust crate | 27 | ~15 | 50% | | **chanora_prefetch** | Rust crate | 7 | 4 | 57% | | **Flutter app** | Dart | ~586 | ~5 | <1% | ### Potentially Unused Functions Functions defined but never called from outside their module: | Crate | Function | File:Line | |---|---|---| | chanora_core | `ChanoraSession::protocol_events_snapshot()` | lib.rs:788 | | chanora_audio | `AudioEngine::capture_active()` | engine.rs:1621 | | chanora_audio | `AudioEngine::frames_sent()` | engine.rs:1626 | | chanora_audio | `AudioEngine::frames_received()` | engine.rs:1631 | | chanora_audio | `HpfProcessor::process_sample()` | dsp/hpf.rs:63 | | chanora_audio | `CoreMlWorker::reset_state()` | apple_coreml.rs:140 | | chanora_audio | `PttCapabilityLevel::is_global()` | ptt.rs:72 | | chanora_bridge | `handle_media_services_reset_with_route()` | api.rs:696 | | chanora_bridge | `handle_interruption_began()` | api.rs:703 | | chanora_state | `ServerState::replace_from_snapshot()` | lib.rs:114 | | chanora_state | `ServerState::channel_count()` | lib.rs:148 | | chanora_state | `ServerState::client_count()` | lib.rs:153 | | chanora_storage | `BookmarkStore::upsert_or_add()` | lib.rs:891 | | chanora_resolver | `normalize_args()` | lib.rs:778 | | chanora_resolver | `validate_args()` | lib.rs:785 | --- ## 3. Test Coverage ### Summary by Component | Component | Source Modules | Modules w/ Tests | Coverage % | Test Count | |---|---|---|---|---| | **chanora_audio** | 43 | 35 | 81% | 221 | | **chanora_bridge** | 5 | 0 | **0%** | 0 | | **chanora_cache** | 1 | 1 | 100% | 7 | | **chanora_diagnostics** | 1 | 1 | 100% | 19 | | **chanora_prefetch** | 1 | 1 | 100% | 6 | | **chanora_protocol** | 4 | 2 | 50% | 23 | | **chanora_resolver** | 1 | 1 | 100% | 14 | | **chanora_state** | 2 | 2 | 100% | 27 | | **chanora_storage** | 1 | 1 | 100% | 15 | | **chanora_core** | 5 | 4 | 80% | 27 | | **Flutter (services)** | 24 | 22 | 92% | 124 | | **Flutter (widgets)** | 25 | 14 | 56% | 97 | | **TOTAL** | **113** | **85** | **75%** | **580** | ### Critical Untested Areas | Component | Module | Risk | |---|---|---| | **chanora_bridge** | All 5 modules | **High** — FFI boundary, zero tests | | **Flutter widgets** | `voice_bar`, `voice_settings`, `connect_widgets` | **High** — core UI | | **chanora_protocol** | `dto` module | **Medium** — serialization bugs | | **chanora_core** | `events` module | **Medium** — event system | --- ## 4. Documentation Coverage ### Doc Comment Coverage (Rust) | Crate | Functions | With Doc Comments | Coverage | |---|---|---|---| | chanora_core | 68 | 65 | 96% | | chanora_audio | 168 | ~40 | 24% | | chanora_bridge | 65 | ~10 | 15% | | chanora_protocol | 35 | 33 | 94% | | chanora_cache | 7 | 7 | 100% | | chanora_state | 16 | ~8 | 50% | | chanora_storage | 20 | ~12 | 60% | | chanora_resolver | 15 | ~8 | 50% | | chanora_diagnostics | 27 | ~15 | 50% | | chanora_prefetch | 7 | 4 | 57% | ### Missing README Files | Directory | Status | |---|---| | crates/chanora_audio/ | **MISSING** | | crates/chanora_bridge/ | **MISSING** | | crates/chanora_cache/ | **MISSING** | | crates/chanora_diagnostics/ | **MISSING** | | crates/chanora_prefetch/ | **MISSING** | | crates/chanora_protocol/ | **MISSING** | | crates/chanora_state/ | **MISSING** | | crates/chanora_storage/ | **MISSING** | | core/chanora_core/ | **MISSING** | Only `crates/chanora_resolver/README.md` exists. --- ## 5. Dead Code Analysis ### Definitely Dead (safe to remove) | Item | File:Line | Evidence | |------|-----------|----------| | `AudioFrame10ms` struct | frame.rs:21 | Never referenced outside tests | | `AudioFrame20ms` struct | frame.rs:28 | Never referenced outside tests | | `AudioFrame10ms::dbfs()` | frame.rs:58 | Never called anywhere | | `disable_failed_vad_backend()` | audio_processing.rs:216 | Only called in tests | | `import 'package:share_plus/share_plus.dart'` | main.dart:55 | `Share` class never used | ### Likely Dead (no production callers) | Item | File:Line | |------|-----------| | `AudioEngine::output_muted()` | engine.rs:1707 | | `AudioEngine::output_gain()` | engine.rs:1720 | | `AudioEngine::capture_active()` | engine.rs:1621 | | `AudioEngine::transmit_gate()` | engine.rs:1614 | | `AudioEngine::set_transmit_active()` | engine.rs:1601 | | `AudioEngine::android_diagnostics()` | engine.rs:1694 | | `TransmitModeSelector::gate()` | transmit_selector.rs:253 | | `TransmitModeSelector::in_channel()` | transmit_selector.rs:198 | | `TransmitModeSelector::ptt_held()` | transmit_selector.rs:226 | | `ReleaseTailTimer::cancel()` | release_tail.rs:133 | | `ReleaseTailTimer::arm()` | release_tail.rs:70 | ### `#[allow(dead_code)]` Annotated Items | Item | Status | |------|--------| | `AudioCommand::RemoveClient` | TODO: "Wire to client disconnect path" | | `android_render_ring` module | Conditionally dead (non-Android) | | `audio_event_queue` module | Conditionally dead (non-Android) | | `capture_accumulator` module | Conditionally dead (non-Android) | --- ## 6. Useless/Redundant Code ### TODO/FIXME/HACK Inventory (12 entries, 14 occurrences) | File | Line | Content | |------|------|---------| | engine.rs | 2348 | TODO: realtime-audio callback concern | | mobile_voice_backend.rs | 16 | TODO(SDD-117): back-fill IosVoiceUnit | | audio_event_queue.rs | 27 | TODO: Wire to client disconnect path | | audio_lifecycle_service.dart | 151,156 | TODO: macosDefaultDeviceChanged (×2) | | poke_notification_service.dart | 33-168 | TODO(event-sounds) (×10) | ### Risky Code | Risk | Location | Count | |------|----------|-------| | Production `unwrap()` | engine.rs | ~39 | | `unsafe impl Send/Sync` | Various | 8 | | `unimplemented!("")` in FRB | frb_generated.rs | 23 | ### Complexity Warnings | File | Lines | Risk | |------|-------|------| | engine.rs | 3,244 | **High** — monolithic audio engine | | main.dart | 2,910 | **High** — monolithic Flutter entry | | adapter.rs | 2,504 | Medium | | api.rs | 2,432 | Medium | --- ## 7. Duplicated Code ### Major Patterns | # | Pattern | Files | Lines Saved | Priority | |---|---------|-------|-------------|----------| | 1 | AudioProcessingConfig 4× construction | 1 Dart | ~50 | High | | 2 | Audio processing toggle UI duplication | 2 Dart | ~150 | High | | 3 | `.map_err(format!)` boilerplate | 5 Rust | ~85 closures | Medium | | 4 | PttCapability event construction | 1 Rust | ~15 | Medium | | 5 | DnsFailed/ServerRejected error mirroring | 2 Rust | ~20 | Medium | | 6 | Platform detection scatter | 6 Dart | ~35 checks | Medium | | 7 | Host normalization `trim().to_lowercase()` | 3 Rust | ~5 sites | Low | | 8 | `create_dir_all` pattern | 2 Rust | ~3 sites | Low | | 9 | `Io(String)` error variant | 3 Rust | ~10 | Low | | 10 | StateEvent ↔ Delta mirror | 1 Rust | ~5 | Low | --- ## 8. Document Link Coverage | Metric | Value | |--------|-------| | Total links checked | 38 | | Valid links | 32 | | Broken links | 6 | | Health rate | 84.2% | | Orphaned docs | 14 / 65 (21.5%) | ### Broken Links All 6 broken links stem from missing `LICENSE-APACHE` and `LICENSE-MIT` files at project root. ### Orphaned Documentation (14 files) Mostly in `docs/superpowers/plans/` and `docs/superpowers/specs/` — not linked from any index document. --- ## 9. Git History & Issue Patterns ### Issue Categories (45 significant issues) | Category | Count | Severity | |----------|-------|----------| | iOS audio (AVAudioSession/VPIO) | 15+ | Most problematic | | Realtime thread safety (Mutex) | 5+ | Cross-platform | | Build toolchain (Xcode Archive) | 4+ | CI-blocking | | Platform-specific build | 5+ | Cross-compilation | | Flutter framework bugs | 3+ | Workarounds needed | | Protocol failures | 3+ | Silent failures | ### Key Patterns 1. **iOS AVAudioSession has 7+ interacting configuration dimensions** — each fix reveals the next layer 2. **Realtime audio callbacks must NEVER use `Mutex::lock()`** — always `try_lock()` with silence fallback 3. **Always verify with `xcodebuild archive`** — not just `flutter build` 4. **Every protocol command should surface errors to UI** — fire-and-forget hides failures --- ## 10. PR Analysis ### PR Summary (42 total) | Type | Count | Merged | |------|-------|--------| | Features | 15 | 7 | | Bug fixes | 15 | 12 | | Refactoring | 4 | 3 | | Documentation | 1 | 1 | | Build/Chore | 4 | 4 | | Performance | 1 | 1 | ### Most Active Areas | Area | PR Count | |------|----------| | iOS Audio | 10+ | | macOS Audio | 5 | | Voice/VAD | 6 | | Flutter UI | 8 | | Protocol/State | 5 | ### Development Patterns - **Self-review via "Oracle" agent** — effective quality gate - **Local CI mirroring** — GitHub Actions billing broken - **PR stacking complexity** — need better branch management - **Follow-up fix pattern** — PRs stay focused --- ## 11. API Gap Analysis ### Requirements with NO or Minimal Implementation | Requirement | ID | Status | |---|---|---| | UI settings persistence | SysRS-143, SRS-087 | **Missing** | | Per-user mute persistence | SysRS-145, SRS-088 | **Missing** | | Event replay tool | SysRS-171, SRS-098 | **Missing** | | Audio loopback test tool | SysRS-073, SRS-083 | **Missing** | SRS-083 covers both loopback and processing test tools | | Audio processing test tool | SysRS-074, SRS-083 | **Missing** | SRS-083 shared with SysRS-073 | | Protocol probe tool | SysRS-128, SRS-123 | **Missing** | | Notification permission | SysRS-166, SRS-109 | **Missing** | | Recent server management | SysRS-141, SRS-085 | **Partial** | | Per-user volume persistence | SysRS-144, SRS-088 | **Partial** | | Input validation | SysRS-157, SRS-094 | **Partial** | ### Missing Bridge Functions | Capability | Gap | |---|---| | `is_hard_muted()` | Missing read for hard-mute state | | `get_output_gain()` | Missing gain read-back | | `get_client_volume()` | Missing per-client volume read | | `connection_state()` | UI must derive from events only | | `reconnect()` | No manual trigger | ### Hardcoded Implementations | Location | Issue | |---|---| | `adapter.rs:141` | `pick_client_version()` returns Windows version for ALL platforms | | `api.rs:350-356` | `log_file_path()` Android returns `None` | | `chanora_storage` | `keyring_load()` on Android returns `Ok(None)` always | --- ## 12. Crate Architecture Analysis ### Current Dependency Graph ``` chanora_bridge └─ chanora_core ├─ chanora_audio ────── chanora_protocol ───── chanora_resolver ├─ chanora_state ────── chanora_protocol ├─ chanora_storage (standalone) ├─ chanora_cache (standalone) ├─ chanora_diagnostics (standalone) └─ chanora_prefetch ── chanora_resolver ``` **No circular dependencies.** Max depth: 3 levels. ### Crate Size | Crate | Source Lines | Files | |-------|-------------|-------| | **chanora_audio** | **18,895** | 26 | | chanora_bridge | 7,579 | 5 | | chanora_protocol | 3,372 | 4 | | chanora_core | 2,716 | 5 | | chanora_state | 1,870 | 2 | | chanora_resolver | 1,434 | 1 | | chanora_storage | 1,332 | 1 | | chanora_diagnostics | 1,118 | 1 | | chanora_cache | 359 | 1 | | chanora_prefetch | 312 | 1 | ### chanora_audio Split Recommendation **Option A — Extract platform backends (recommended):** | New Crate | Contents | Lines | |---|---|---| | `chanora_audio` (core) | engine, frame types, transmit, VAD, DSP, PTT trait | ~8,000 | | `chanora_audio_android` | android_voice_unit, render_ring, event_queue, Oboe | ~3,200 | | `chanora_audio_apple` | ios_voice_unit, coreaudio-rs | ~1,400 | | `chanora_audio_desktop` | cpal, sdl_output, Windows/Linux PTT | ~3,500 | **Rationale:** Platform backends are 100% cfg-gated. Splitting removes heavy platform dependencies from core. ### Common Code Extraction **Not justified at this time.** Patterns are too small for a `chanora_common` crate. --- ## 13. Document Staleness Analysis ### Freshness Scores | Document | Score | Status | |---|---|---| | docs/sysrs.md | 8/10 | Mostly current | | docs/srs.md | 7/10 | Missing newer requirements | | docs/sysdes.md | 6/10 | Missing 53 SysRS allocations | | docs/architecture/sdd.md | 5/10 | Missing many modules | | docs/architecture/sad.md | 5/10 | Missing components | | docs/verification/verification-master-plan.md | 6/10 | Stale evidence source | | docs/governance/traceability-matrix.md | 5/10 | SRS ID mismatches | | docs/implementation-status-2026-05-28.md | 3/10 | 14 days stale | ### Critical Staleness Issues 1. **53 SysRS requirements (SysRS-258–310) lack SysDes allocation** — breaks traceability 2. **Multiple features without requirements** — poke, file transfer, hard-mute, cache 3. **SRS numbering mismatches** in traceability matrix 4. **Implementation status 14 days stale** — missing v0.3.0 features --- ## 14. Test Environment Requirements ### Current CI Coverage | Platform | CI Status | |----------|-----------| | Ubuntu (Rust + Flutter) | ✅ Automated | | macOS (iOS unsigned build) | ✅ Automated | | Android | ❌ Not in CI | | Windows | ❌ Not in CI | | macOS (native) | ❌ Not in CI | | Linux (non-Ubuntu) | ❌ Not in CI | ### Physical Devices Needed | Device | Purpose | Est. Cost | |---|---|---| | iPhone 14+ | iOS audio, CoreML VAD | $600-800 | | Android phone (arm64) | Android audio, Oboe | $200-400 | | Windows PC | Windows PTT, audio | $500-800 | | Linux PC | GNOME/Wayland, PipeWire | $500-800 | | Audio peripherals | USB/BT headset testing | $100 | | **Total** | | **$2,400-4,200** | ### Implementation Roadmap | Phase | Timeline | Focus | |-------|----------|-------| | Foundation | Weeks 1-4 | Android/Windows/macOS CI builds | | Device Integration | Weeks 5-8 | Physical devices, audio loopback | | Full Automation | Weeks 9-12 | E2E tests, audio quality, Firebase | --- ## 15. External Research ### TeaSpeak - **Status:** Effectively unmaintained since ~2022 - **Architecture:** Closed-source server, TypeScript web client, C++ music bot - **Lesson for Chanora:** Open-source client + formal engineering process is the right approach - **Market validation:** TeaSpeak's abandonment creates opportunity for Chanora ### ReSpeak - **Status:** Active, 16 repositories, tsclientlib is the core library - **Chanora dependency:** Uses `tsclientlib` (forked) for protocol implementation - **Key repos:** `tsclientlib` (protocol), `tsdeclarations` (protocol spec), `quicklz` (compression) - **Recommendation:** Continue using tsclientlib, consider upstreaming p256 fix ### yat.qa (YaTQA) - **What it is:** Windows GUI tool for TeamSpeak 3 ServerQuery management (NOT a testing/QA site) - **Relevance:** Low — management tool, not testing framework - **Useful resources:** Unofficial ServerQuery docs, server error codes, permission IDs, anti-flood mechanics --- ## 16. Recommendations ### P0 — Critical (do immediately) 1. **Add `chanora_bridge` tests** — 0/5 modules tested, FFI boundary is highest risk 2. **Replace `Mutex::lock().unwrap()` in engine.rs** — ~39 calls, crash risk 3. **Update implementation-status document** — 14 days stale, primary evidence source 4. **Allocate SysRS-258–310 in SysDes** — breaks traceability chain 5. **Fix traceability matrix SRS numbering** — IDs don't match actual SRS ### P1 — High Priority (next sprint) 6. **Add Android/Windows/macOS CI builds** — currently only Ubuntu 7. **Add missing bridge functions** — `get_hard_mute()`, `get_connection_state()`, `reconnect()` 8. **Add README files to all 8 crates + core** 9. **Split engine.rs** (3,244 lines) into smaller modules 10. **Add requirements for implemented features** — poke, file transfer, hard-mute, cache ### P2 — Medium Priority 11. **Extract platform backends from chanora_audio** — compile-time benefit 12. **Add doc comments to chanora_audio** (24% → 80% target) 13. **Fix `pick_client_version()` hardcoded to Windows** 14. **Implement per-user volume/mute persistence** 15. **Add UI settings store** ### P3 — Low Priority 16. **Clean up dead code** (25+ items) 17. **Deduplicate code patterns** (10 major patterns) 18. **Fix broken doc links** (create LICENSE files) 19. **Link orphaned documentation** 20. **Add protocol probe tool** --- *Generated by codebase analysis agents on 2026-06-11*