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
- Executive Summary
- Function Inventory
- Test Coverage
- Documentation Coverage
- Dead Code Analysis
- Useless/Redundant Code
- Duplicated Code
- Document Link Coverage
- Git History & Issue Patterns
- PR Analysis
- API Gap Analysis
- Crate Architecture Analysis
- Document Staleness Analysis
- Test Environment Requirements
- External Research
- 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
- iOS audio is the #1 problem area — 15+ issues, AVAudioSession lifecycle is the most recurring root cause
- chanora_audio has 168 public functions but only 24% documented — largest crate, most complex
- chanora_bridge has 0 tests — the Flutter-Rust boundary is completely untested
- 53 SysRS requirements (SysRS-258–310) lack SysDes allocation — breaks traceability
- Several features exist without requirements — poke, file transfer, hard-mute, cache
- engine.rs is 3,244 lines — monolithic, needs splitting
- main.dart is 2,910 lines — monolithic, needs splitting
- ~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
| 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
- iOS AVAudioSession has 7+ interacting configuration dimensions — each fix reveals the next layer
- Realtime audio callbacks must NEVER use
Mutex::lock() — always try_lock() with silence fallback
- Always verify with
xcodebuild archive — not just flutter build
- 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 |
| Audio processing test tool |
SysRS-074, SRS-083 |
Missing |
| 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
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.
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
- 53 SysRS requirements (SysRS-258–310) lack SysDes allocation — breaks traceability
- Multiple features without requirements — poke, file transfer, hard-mute, cache
- SRS numbering mismatches in traceability matrix
- 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)
- Add
chanora_bridge tests — 0/5 modules tested, FFI boundary is highest risk
- Replace
Mutex::lock().unwrap() in engine.rs — ~39 calls, crash risk
- Update implementation-status document — 14 days stale, primary evidence source
- Allocate SysRS-258–310 in SysDes — breaks traceability chain
- Fix traceability matrix SRS numbering — IDs don't match actual SRS
P1 — High Priority (next sprint)
- Add Android/Windows/macOS CI builds — currently only Ubuntu
- Add missing bridge functions —
get_hard_mute(), get_connection_state(), reconnect()
- Add README files to all 8 crates + core
- Split engine.rs (3,244 lines) into smaller modules
- Add requirements for implemented features — poke, file transfer, hard-mute, cache
P2 — Medium Priority
- Extract platform backends from chanora_audio — compile-time benefit
- Add doc comments to chanora_audio (24% → 80% target)
- Fix
pick_client_version() hardcoded to Windows
- Implement per-user volume/mute persistence
- Add UI settings store
P3 — Low Priority
- Clean up dead code (25+ items)
- Deduplicate code patterns (10 major patterns)
- Fix broken doc links (create LICENSE files)
- Link orphaned documentation
- Add protocol probe tool
Generated by codebase analysis agents on 2026-06-11