Add full codebase analysis report, issue history, test environment requirements, external research (TeaSpeak/ReSpeak/YaTQA), and offline protocol references (ReSpeak ts3protocol, TeaSpeak, YaTQA). Add master TODO list with 88 items across 11 categories. Add missing LICENSE files. Branch: docs/codebase-analysis-v2
5.9 KiB
5.9 KiB
Issue History Analysis
Date: 2026-06-11
Scope: All git history, PRs, and issue patterns
1. Issue Categories
iOS Audio (15+ issues) — Most Problematic Area
| Commit | Issue | Root Cause | Fix |
|---|---|---|---|
| #42 (OPEN) | AVAudioSession not activated before connect | Auto-join spawns VPIO before session in playAndRecord mode | Activate session BEFORE rust.connect |
| #41 | iOS Debug builds blocked | Debug.xcconfig missing -u flags; verify script checked wrong Mach-O |
Mirror Release xcconfig; check correct dylib |
| #38 | Audio session dead after "already in channel" | Server response 0x0302 treated as failure | Keep session active on already-in-channel |
| #33 | App kills other apps' audio while idle | Held .playAndRecord from launch |
Idle baseline now .ambient; escalate during calls |
| #28 | False underrun counters when muted | peak_i16 == 0 check didn't gate on muted state |
Gate underrun on !muted |
| #26 | Silero exports stripped in Xcode Archive | ld -dead_strip removed unreferenced symbols |
-exported_symbol whitelist in xcconfigs |
| #10 | Voice join stuck at "Connecting" | Audio startup blocking connect critical path | Move audio startup off connect path |
Pattern: iOS AVAudioSession has 7+ interacting configuration dimensions. Each fix reveals the next layer.
Realtime Thread Safety (5+ issues)
| Commit | Issue | Root Cause | Fix |
|---|---|---|---|
| #20 | Android audio output stutter | Mutex contention in audio callback | Oboe config tuning + lock-free callback |
| #27 | macOS audio event queue | Lock contention in render path | Lock-free ArrayQueue pattern |
| engine.rs:39 | ~39 unwrap() calls on Mutex |
Poisoned mutex will panic engine | Need try_lock() or parking_lot::Mutex |
Pattern: Realtime audio callbacks must NEVER use Mutex::lock() — always try_lock() with silence fallback.
Build Toolchain (4+ issues)
| Commit | Issue | Root Cause | Fix |
|---|---|---|---|
| #41 | iOS Debug builds fail | Debug.xcconfig diverged from Release | Mirror Release settings in Debug |
| #26 | Silero exports stripped | ld -dead_strip + install-time strip |
-exported_symbol whitelist + STRIP_STYLE = non-global |
| #37 | MSVC CRT mismatch | cmake linking wrong CRT | cmake-msvc-release-crt.cmd |
Pattern: Always verify with xcodebuild archive, not just flutter build.
Protocol Issues (3+ issues)
| Commit | Issue | Root Cause | Fix |
|---|---|---|---|
| #16 | Speaking state incorrect for non-self clients | Client profiles not refreshed before mapping | Refresh non-self profiles |
| #16 | Server-query clients missing | Missing protocol DTO fields | Add ping deviation through full stack |
| #5 | UI crashes on unexpected state transitions | Missing null/mounted guards | Guard deferred side effects |
Pattern: Every protocol command should surface errors to UI — fire-and-forget hides failures.
2. PR Development Patterns
PR Summary (42 total, 34 merged, 8 closed)
| Type | Count | Merged |
|---|---|---|
| Features | 14 | 10 |
| Bug fixes | 12 | 12 |
| Refactoring | 4 | 3 |
| Documentation | 1 | 1 |
| Build/Chore | 4 | 4 |
| Performance | 1 | 1 |
| Dependency | 1 | 0 |
| Closed (superseded) | 5 | 0 |
Most Active Areas
| Area | PR Count | Notes |
|---|---|---|
| iOS Audio | 10+ | Most recurring issues |
| macOS Audio | 5 | Lock-free architecture |
| Voice/VAD | 6 | CoreML, ONNX, WebRTC |
| Flutter UI | 8 | Event-driven, responsive |
| Protocol/State | 5 | State reducers, events |
Quality Patterns
- Self-review via "Oracle" agent — catches real issues pre-merge
- Local CI mirroring — GitHub Actions billing broken
- PR stacking — need better branch management workflow
- Follow-up fix pattern — PRs stay focused
3. Test Cases for Known Issues
iOS Audio Session Lifecycle
// Test: Session activates before connect
test('voice_join activates AVAudioSession before starting voice', () async {
// Verify session state transitions: ambient → playAndRecord → ambient
});
// Test: Already-in-channel response keeps session active
test('voice_join keeps session active on already-in-channel response', () async {
// Mock server response code 0x0302
// Verify session remains in playAndRecord state
});
// Test: Idle app doesn't kill other audio
test('app uses ambient mode when not in voice channel', () async {
// Verify session mode is .ambient + .mixWithOthers when idle
});
Realtime Thread Safety
// Test: Audio callback doesn't panic on poisoned mutex
#[test]
fn audio_callback_survives_poisoned_mutex() {
// Verify try_lock fallback produces silence, not panic
}
Protocol Error Surfacing
// Test: Server errors surface to UI
test('server error messages are forwarded as UI events', () async {
// Mock protocol error
// Verify UI receives error event
});
Build Verification
# Test: iOS Debug build succeeds
xcodebuild -workspace ios/Runner.xcworkspace -scheme Runner -configuration Debug build
# Test: iOS Archive build preserves Silero exports
xcodebuild archive -workspace ios/Runner.xcworkspace -scheme Runner
# Verify: nm -g archive.xcarchive/Products/Applications/Chanora.app/Chanora | grep silero
4. Root Cause Patterns
| Pattern | Frequency | Prevention |
|---|---|---|
| iOS AVAudioSession lifecycle | 8+ PRs | Document state machine, add integration tests |
| Mutex on realtime threads | 5+ issues | Use try_lock() or parking_lot::Mutex |
| Xcode Archive vs build divergence | 4+ issues | Always test with xcodebuild archive |
| Silent protocol failures | 3+ issues | Surface all errors to UI |
| Platform-specific build quirks | 5+ issues | CI on all target platforms |
Generated by git history analysis agents on 2026-06-11