Add validate_nickname() to ProtocolClient::connect() and bridge
connect(). Trim whitespace, reject empty, truncate to 30 chars.
Re-export validate_nickname from protocol and core.
Design documents for event replay, audio processing test, audio
loopback test, and protocol probe tools. iOS audio session test
plan with 28 scenarios and 3-phase automation approach.
p256 PR draft ready for ReSpeak/tsclientlib submission.
Performance benchmarks document with tsclientlib baselines and
Chanora current metrics. Web client assessed as infeasible without
UDP proxy infrastructure.
tsdeclarations eval: direct codegen redundant (already via tsproto),
but permission ID generation and error code enum have high value.
Permission mapping: 253 TS3 permissions identified, 7 P1 for chat/moderation.
Encoding verification: tsclientlib uses strict UTF-8, UCS-2 is edge case.
Extract BetaHome (2374 lines) to screens/home_screen.dart and
LiveDiagnosticsDialog (97 lines) to screens/diagnostics_dialog.dart.
main.dart reduced from 2910 to 255 lines. No behavioral changes.
Add validate_and_truncate(), validate_nickname(), validate_message(),
validate_poke_message(), validate_channel_name() with length limits.
Wire to send_text_message in adapter. 14 new validation tests.
Implement FloodTracker with server-configurable thresholds from
YaTQA §5.1 model: 0.5s tick interval, point costs per operation,
NearLimit/CommandBlocked/IpBlocked risk levels. Defaults from
TeaSpeak (tick_reduce=25, command_block=150, ip_block=300).
Mark TODO-059 (auto-reconnect) and TODO-062 (DNS chain) as verified
complete with evidence. Revise TODO-063 from implementation to
verification task (tsclientlib handles encoding). Create protocol
implementation traps doc with 13 traps from YaTQA/ReSpeak/TeaSpeak.
Split monolithic engine.rs (3,244 lines) into focused modules:
mod.rs (1,106), capture.rs (515), render.rs (176), lifecycle.rs (1,149).
Capture and render are desktop-only (cfg-gated). No behavioral changes.
All public API paths preserved.
Add purpose, architecture, and public API summary to each crate
README following chanora_resolver pattern. Update verification master
plan with new evidence sources and entry/exit criteria.
Add Android multi-ABI build (arm64-v8a, armeabi-v7a, x86_64) with
cargo-ndk. Add Windows and macOS cargo-check jobs. Add xcodebuild
archive verification to iOS release build. Make clippy a blocking
PR gate by removing continue-on-error.
Extract PttCapability event construction helper in events.rs.
Extract ensure_dir() helper in chanora_storage. Add TODO(refactor)
annotations for patterns requiring shared crate or API changes.
Deduplicate audio processing toggle UI from voice_compact.dart and
voice_settings.dart into shared AudioProcessingPanel widget in
voice_settings_controls.dart. Centralize platform detection getters
in voice_platform.dart.
pick_client_version() now returns correct version per platform via
cfg(target_os). keyring_load() on unsupported platforms returns
StorageError instead of silently returning Ok(None).
Add docs/superpowers/README.md as index for plans and specs.
Add docs/references/flutter-upstream-bugs.md tracking 4 known
Flutter framework workarounds.
Remove unused AudioFrame10ms/20ms structs, disable_failed_vad_backend(),
and ServerState dead accessors (replace_from_snapshot, channel_count,
client_count). Update tests to use .channels().count()/.clients().count().
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
Root cause: OSStatus 561145187 (!rec) - AVAudioSession was not in
.playAndRecord mode when VoiceProcessingIO tried to start.
Two changes:
1. Activate session BEFORE rust.connect() so it's ready when auto-join runs
2. Defensive activation in Connected handler as backup
This fixes both the !rec error and the subsequent 'voice_in already taken'
error that occurred after auto-join consumed voice_in on failure.
* fix(ios): preserve Silero VAD symbols in Flutter Debug builds
Flutter Debug builds split user code into a sibling Chanora.debug.dylib
alongside a minimal launcher executable; the six @_cdecl symbols
chanora_silero_vad_* land in the dylib, not the main binary. Two
problems were hiding behind that:
1. Debug.xcconfig only carried -exported_symbol flags, missing the
load-bearing -u force-undefined flags Release.xcconfig already had.
Without -u, the linker dropped the Swift @_cdecl symbols (no Swift
caller exists) before -exported_symbol could re-export them, so the
dylib shipped without the VAD entry points.
2. verify_silero_exports.sh inspected only ${EXECUTABLE_PATH}, which in
Debug builds is the launcher stub. Even with the symbols correctly
landing in the debug dylib, the script falsely reported them missing.
Mirror Release.xcconfig's -u + -exported_symbol pair in Debug.xcconfig
and teach the verify script to prefer Chanora.debug.dylib when it sits
next to the launcher. Release builds are unaffected (single fat binary
remains the inspected target).
* build(flutter): regenerate FRB bindings for file transfer API
Run flutter_rust_bridge_codegen against the post-PR-#40 chanora_bridge
to emit typed Dart bindings for initCache, downloadAvatar, downloadIcon,
clearFileCache, and fileCacheSize. Replaces the dynamic-cast +
NoSuchMethodError-swallowing shims that lib/src/rust/api.dart shipped
as a pre-regen safety net.
Functional change: downloadAvatar/downloadIcon now return Uint8List?
(was List<int>?) directly through the typed dispatch table. Existing
consumers stay source-compatible because Uint8List extends List<int>;
no call sites needed updates.
* fix(ios): set ITSAppUsesNonExemptEncryption to false
App uses only standard/exempt encryption (HTTPS, system-provided crypto);
declaring exempt status removes the App Store export-compliance prompt
at every TestFlight/release upload.
- Add iOS to voiceActivityTransmitAvailable — iOS has CoreML Silero
VAD pipeline (AppleCoreMlVadWorker) but was excluded by DEC-030
gating that predated the CoreML integration
- Inline deleted VadWorkerPolicy in android_voice_unit.rs — PR #37
removed the enum from vad/mod.rs but missed updating Android
Remove SonoraExperimental variant from BridgeIosVoiceProcessingMode
and collapse all match arms in the bridge config builder. Regenerate
flutter_rust_bridge bindings and update Podfile.lock.