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
158 lines
5.9 KiB
Markdown
158 lines
5.9 KiB
Markdown
# 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
|
|
|
|
1. **Self-review via "Oracle" agent** — catches real issues pre-merge
|
|
2. **Local CI mirroring** — GitHub Actions billing broken
|
|
3. **PR stacking** — need better branch management workflow
|
|
4. **Follow-up fix pattern** — PRs stay focused
|
|
|
|
---
|
|
|
|
## 3. Test Cases for Known Issues
|
|
|
|
### iOS Audio Session Lifecycle
|
|
|
|
```dart
|
|
// 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
|
|
|
|
```rust
|
|
// 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
|
|
|
|
```dart
|
|
// 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
|
|
|
|
```bash
|
|
# 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*
|