# Chanora Implementation Status — 2026-05-28 **Workspace version:** `v0.2.0-beta.1` **Flutter app version/build:** `0.3.0+100` **CHANGELOG latest:** `v0.3.0` **Build status:** Host Rust workspace evidence shows all 9 crates compile cleanly. This does not claim Android target success; Android target compile/install/smoke evidence remains blocked locally as noted below. --- ## P0 / MVP ### Done | Area | Evidence | |---|---| | App shell / startup | `main.dart` (2313 lines), `app_bootstrap.dart`, `RustLib.init()` wired | | Flutter UI | Full widget set: `connect_widgets`, `snapshot_view`, `chat_views`, `voice_bar`, `voice_compact`, `voice_settings`, `voice_settings_controls`, `client_info_sheet`, `input_dialogs`, `bbcode_text` | | Material 3 + design tokens | `chanora_tokens.dart`, `platform_capabilities.dart` | | Localization (en + zh-Hans) | `l10n/generated/app_localizations_en.dart` + `app_localizations_zh.dart`, `l10n.yaml` | | Flutter/Rust bridge | `chanora_bridge` crate (2152-line `api.rs`), generated `frb_generated.rs`, Dart side generated | | Protocol adapter | `chanora_protocol` — `tsclientlib` isolated behind `ProtocolClient`, typed DTOs, `ProtocolError` catalogue | | Connection lifecycle | `chanora_core` — supervisor task, exponential backoff reconnect (1s→60s), user-disconnect suppresses reconnect; branch `simplify-project-review` has started splitting the previous large `lib.rs` into focused internal Modules (`events.rs`, `network_diagnostics.rs`) while preserving public re-exports | | State sync reducer unit | `chanora_state` — `ConnectionState`, `channel_join`, snapshot/delta reducers, reconnect handling, deterministic ordering, malformed duplicate normalization, channel-delete/client cleanup, and reducer unit tests. Runtime core integration still uses snapshot/probe refresh paths and remains separate validation work. | | Audio subsystem | `chanora_audio` — Opus encode/decode, HPF/NS/AEC3/AGC2 DSP, PTT backends (Windows/macOS/Linux/focused), iOS VoiceProcessingIO, Android Oboe, jitter buffer via `tsclientlib::audio::AudioHandler`, mixer, mute/deaf gates, release-tail timer, and Windows/Linux desktop `VoiceActivity` through the capture VAD path. Mobile, macOS, and unverified-platform `VoiceActivity` remain deferred per DEC-030. | | Push-to-talk | Per-platform backends: Windows Raw Input + hook fallback, macOS Event Tap, Linux freedesktop portal, focused fallback; `PttCapabilityLevel` (L0–L3); missed-key-up watchdog | | Voice controls UI | `voice_bar`, `voice_compact`, `voice_haptics`, `voice_level_meter`, `voice_platform`, `ptt_capability_badge`, `talk_power_warning` | | Storage (non-secret) | `chanora_storage` — `BookmarkRepository` (SQLite/rusqlite bundled, schema v2), ChaCha20-Poly1305 encrypted passwords | | Storage (secrets) | `IdentityFileStore` with platform keyring (Linux Secret Service, macOS Keychain, Windows Credential Manager, iOS Keychain); file fallback with 0600 perms | | Diagnostics | `chanora_diagnostics` — `Redactor` (IP/host/email/token/path/secret scrubbing), `InMemoryLogSink`, `DiagnosticExport` JSON bundle, `KnownSecretRegistry`, panic hook | | Server address resolution | `chanora_resolver` — SRV/TSDNS/DNS fallback | | Server prefetch | `chanora_prefetch` crate + `prefetch_debouncer.dart` — invisible host-field prefetch, TTL cache, generation-safe | | Android platform | `android_voice_unit.rs`, `android_permissions_service.dart`, `MODE_IN_COMMUNICATION` routing, foreground service (`flutter_foreground_task`) | | iOS platform | `ios_voice_unit.rs`, `ios_raw_unit.rs`, `ios_permissions_service.dart`, `AVAudioSession` integration, `audio_session` package | | Permission UX | `permission_state_banner.dart`, pre-request explainers | | Bookmark UI | Save/connect/delete in `connect_widgets.dart` | | Channel join | Tap-to-join with optional password, `channel_join_error_mapper.dart`, `channel_spacer.dart` | | Chat | `chat_views.dart`, BBCode rendering (`bbcode_text.dart`) | | Audio settings UI | `voice_settings.dart`, `voice_settings_controls.dart`, `audio_processing_config_state.dart`, `audio_device_list_tile.dart`, `audio_output_tile.dart` | | Audio debug stats | `audio_debug_stats_panel.dart` | | TS3 server link | `ts3_server_link.dart` — `ts3server://` URI parsing | | UI preferences | `ui_preferences_service.dart`, `shared_preferences` | | Connection phase state | `connection_phase_state.dart` | | Snapshot state mapper | `snapshot_state_mapper.dart` | | Back intent (Android) | `back_intent_policy.dart`, `back_intent_service.dart` | | Audio lifecycle | `audio_lifecycle_service.dart` | | Link trust | `link_trust_service.dart` | | About dialog | Non-affiliation statement, dual-license declaration, NOTICE pointer | | CI | GitHub Actions on every push | | Workspace compiles | Host Rust workspace evidence shows all 9 crates build cleanly; Android target compilation remains blocked locally as noted below. | ### Partial / Scaffold Only | Area | Gap | |---|---| | Event replay tooling | Reducer tests cover the state-sync contract, but standalone replay-file tooling remains a P1 verification gap. | | Reducer runtime integration evidence | The standalone reducer is unit-tested, but `chanora_core` still refreshes UI state through snapshot/probe paths rather than folding all live protocol events through `chanora_state::reduce`. | | Mobile/macOS VoiceActivity | `assets/models/silero_vad.onnx` is bundled and used by the desktop VAD path where runtime evidence supports it; mobile, macOS, and unverified-platform `TransmitMode::VoiceActivity` remain disabled/deferred until a later baseline supplies backend enablement and verification evidence. | | macOS build | Source-buildable only; no public release artifact is approved. | | Windows build | Source-buildable only; no public release artifact is approved. | | iOS build | Source-buildable/unsigned validation only; no TestFlight/App Store release artifact is approved. | ### Not Done (P0 blockers remaining) | Item | Status | |---|---| | DEC-012 legal/trademark/OSS review | Explicitly open. Public release is blocked. | | Android Keystore-backed DEK | Deferred to v1.1. Android still uses file-fallback for the Data Encryption Key. | | Android target compile/install/smoke evidence | Blocked locally until the Android NDK compiler `aarch64-linux-android-clang` is available and `adb devices -l` shows an authorized device or emulator. | | iOS `AVAudioSession.Mode.voiceChat` | Implemented in `apps/chanora_flutter/ios/Runner/AppDelegate.swift` with call-scoped activation (idle `.ambient` baseline; VoIP `.playAndRecord` + `.voiceChat` + `.mixWithOthers` engaged only on `BridgeEvent::AudioStarted` via `chanora/ios_audio_session` MethodChannel). Release readiness still requires device audio validation and candidate evidence attachment. | | Candidate state-sync evidence attachment | Reducer tests exist and pass locally; release readiness still needs candidate CI/run IDs and runtime integration evidence attached before public release approval. | --- ## P1 / Beta ### Done (promoted from Beta work) | Area | Evidence | |---|---| | Diagnostics export UI | Diagnostics dialog in `main.dart`, `share_plus` for export | | Reconnect banner | Referenced in CHANGELOG v0.4 | | Identity persistence | `IdentityFileStore` shipped | | Audio loopback/processing test hooks | `compare_baseline.rs`, `emit_baseline.rs` examples; `ptt_privacy.rs`, `linux_portal_smoke.rs` tests | | Opus codec benchmarks | `benches/opus_codec.rs`, `benches/resampler.rs`, `benches/realtime_capture.rs` | | Audio processing backend abstraction | `processor/mod.rs` with `sonora`, `webrtc_apm`, `noop` backends | | Per-user mute | SRS-074 implemented in audio gate | | Protocol adapter isolation | SRS-053 trait boundary in place | ### Not Done (P1 backlog) | Item | Notes | |---|---| | Per-user volume (SRS-075) | Not yet wired to UI/storage | | Recent servers persistence (SRS-085) | Not confirmed in storage crate | | UI settings persistence (SRS-087) | Implemented for current P1 scope using `shared_preferences`: host, nickname, permission explanation flag, and theme mode (`system` / `light` / `dark`). SQLite-backed UI settings remain a future hardening option if multi-profile or transactional settings are introduced. | | Event replay tool (SRS-061, SRS-098) | No replay infrastructure found | | Network diagnostics (SRS-100) | Core tracks connect/disconnect counts and last-loss reasons in `network_diagnostics.rs`; export/integration evidence still needs release-candidate attachment | | Side navigation rail for medium layout (SRS-153) | Not confirmed | | Keyboard focus traversal (SRS-160) | Not confirmed | | Android audio focus / BT route changes (SRS-112) | Partial — `MODE_IN_COMMUNICATION` done; full focus/BT handling not confirmed | | Windows installer packaging (SRS-116) | Not in rc.1 artifacts | | Linux packaging (AppImage/Flatpak/deb/rpm) (SRS-118) | Not confirmed | | Android AAB release build pipeline (SDD-109) | Referenced but not confirmed as CI-automated | | iOS TestFlight/App Store build pipeline (SRS-120) | Deferred | | Light/dark theme toggle (SAD-043) | Not confirmed in UI | | Audio device hot-plug recovery (SRS-082) | Noted as follow-up work in `chanora_audio/src/lib.rs` | --- ## P2 / Production ### Not Done (all P2 items pending) | Item | Notes | |---|---| | DEC-012 legal sign-off | Hard blocker for public release | | macOS signed + notarized builds (SRS-117) | Requires macOS build host | | C4 architecture views in SAD (SAD-046) | Documentation artifact | | ADRs for significant decisions (SAD-047) | Documentation artifact | | Architecture glossary (SAD-055, SDD-063) | Documentation artifact | | Staged rollout plan | `staged-release-plan.md` referenced but not confirmed complete | | Bidirectional text (SRS-175) | Deferred | | Expanded layout persistent side panes (SRS-154) | Deferred | --- ## SOP (Standing Operating Procedures) ### In Place - Agent router + phase spec docs (in git history, currently untracked/renamed) - `phase_index.json` machine-readable requirement index - Conventional Commits style enforced - Privacy/security gates documented (`SOP_AGENT_OPERATIONS.md`) - Traceability chain: SysRS → SysDes → SRS → SAD → SDD - `SECURITY.md`, `CONTRIBUTING.md`, `NOTICE`, dual-license files present ### Needs Attention - The agent spec docs (`P0_MVP_AGENT_SPEC.md`, `P1_BETA_AGENT_SPEC.md`, etc.) are deleted from the working tree but still in git HEAD. The new `docs/srs.md`, `docs/sysdes.md`, `docs/sysrs.md` are untracked. Docs reorganization in progress — files need to be committed or deletions reverted. --- ## Summary ``` P0 / MVP: ~85% done. Core product works end-to-end (connect, voice, chat, bookmarks, storage, diagnostics). Main blockers: DEC-012 legal review (hard gate), Android Keystore DEK, iOS voiceChat evidence, and candidate evidence attachment. P1 / Beta: ~40% done. Audio processing backend, diagnostics export, and loopback tests are in. Per-user volume, event replay, network diagnostics, packaging pipelines, and several UI hardening items remain. P2 / Prod: ~5% done. Blocked on P0 legal gate. Documentation artifacts (C4 views, ADRs, glossary) and production signing pipelines not started. SOP: Docs in place but a working-tree reorganization is uncommitted. ```