Files
chanora/docs/governance/product-decision-register.md
T
EdisonJwa 5aa51c310f docs(p0): SysRS/SysDes/SRS/SAD/SDD/Verification + traceability for Android P0 reconciliation
Full P0 Android documentation chain:

- SysRS: API 24 → API 28 reconciliation per DEC-004 (SysRS-288);
  add SysRS-305 (Android in-call audio mode), SysRS-306
  (RECORD_AUDIO runtime timing).
- SysDes: SysDes-152 (in-call audio mode subsystem), SysDes-153
  (RECORD_AUDIO permission flow), SysDes-154 (Android voice audio
  backend), SysDes-155 (macOS runtime baseline).
- SRS: SRS-187 → API 28; add SRS-208 (in-call audio mode), SRS-209
  (RECORD_AUDIO + listen-only fallback), SRS-210..215 (Android voice
  audio backend latency/preset/AEC/usage/sharing/foreground service);
  retarget SysDes anchors from generic SysDes-135 to SysDes-152/153/154.
- SAD: SAD-063 refreshed (API 28); add SAD-084 (audio mode
  controller), SAD-085 (permission adapter with listen-only),
  SAD-086 (foreground service), SAD-087 (macOS runtime baseline);
  formalize cross-cutting + platform-specific allocation pattern
  in §24.1.
- SDD: expand SDD-028 (BackIntentService); refresh SDD-073 (build
  config); add SDD-105 (JNI bootstrap), SDD-106 (permission
  requester), SDD-107 (foreground service), SDD-108 (audio mode
  controller), SDD-109 (AAB pipeline), SDD-110 (PTT capability),
  SDD-111..116 (Android voice audio backend), SDD-118 (Android
  bridge build automation), SDD-119 (iOS/macOS bridge build
  automation back-fill).
- Verification: create android-p0-acceptance.md TC-1..TC-18; add
  SWE4-UV-040..052, SWE5-IV-016..026, SWE6-SV-018..030,
  SYS4-SIV-015 strengthened + SYS4-SIV-017/018.
- Governance: traceability matrix v0.9.9 with end-to-end chain
  closure; DEC-032 documents the temporary abiFilters reduction to
  arm64-v8a only and its restore-by gate.

Trace: full chain SysRS → SysDes → SRS → SAD → SDD → Code → Verification.
2026-05-18 12:48:28 +08:00

43 KiB
Raw Blame History

CHANORA_CFG_Product_Decision_Register_v0.9.7.0.0

Document type: Configuration / Product Decision Register
Version: 0.9.8
Status: Baseline Candidate
Language: English
Product: Chanora
Repo path: docs/governance/product-decision-register.md ---

1. Purpose

This document records key product, architecture, release, legal, and engineering decisions that affect Chanora scope, testing, architecture, app store eligibility, and release readiness.

A decision marked Proposed / Owner Confirmation Required is a recommended decision that should be confirmed by the owner before Final / Approved Baseline.

2. Decision Status Legend

Status Meaning
Proposed / Owner Confirmation Required Recommended decision; owner must confirm before Final.
Accepted Confirmed and part of baseline.
Deferred Not decided for this release; must not block scope if explicitly deferred.
Rejected Not selected.

3. Key Blocking Decisions

Decision ID Decision Recommended decision Status Owner Why it matters
DEC-001 Release type Internal Alpha first, then External Beta, then MVP Public / Store Release Accepted Product Owner Controls release gate, verification bar, legal/privacy requirements, and platform scope.
DEC-002 MVP platform scope MVP target remains Windows, macOS, Linux, Android, and iOS; first release may be staged by channel/platform Accepted Product Owner + Engineering Owner Controls verification matrix, build artifacts, store readiness, and support load.
DEC-003 Minimum iOS version iOS 13 minimum for Flutter support baseline; test latest iOS release separately Accepted Product Owner + iOS Owner Controls iOS compatibility, test devices, and app store eligibility.
DEC-004 Minimum Android version Android API 28 (Android 9.0) minimum, raised from the original recommendation of API 24 by explicit owner ruling on 2026-05-14. Rationale: simplifies the audio path (AAudio is unconditionally available from API 26+ and stable from API 28), narrows the TLS / privacy / scoped-storage compatibility surface, and matches typical 2026 Android baselines. The cpal-on-Oboe Android spike was built with minSdk = 24 and cargo-ndk -P 26; product code in apps/chanora_flutter must move minSdk to 28 and may simplify the AAudio-vs-OpenSL-ES fallback logic accordingly. Accepted Product Owner + Android Owner Controls Android device support, runtime permissions, and Play Store eligibility.
DEC-005 Android target SDK Target the Google Play-required API level on the upload date; current release gate uses API 35+ unless newer Google policy applies Accepted Android Owner + Release Manager Required for new apps and updates submitted to Google Play after the current policy date.
DEC-006 Multiple server connections in MVP Not in MVP; support one active server connection per client instance Accepted Product Owner + Software Architect Reduces state synchronization, audio routing, UI complexity, and verification scope.
DEC-007 AEC default state Enabled by default on platforms/audio backends where supported and stable Accepted Audio Owner + Product Owner Affects echo quality, CPU usage, platform behavior, and user experience.
DEC-008 AGC default state Enabled by default, with user setting to disable Accepted Audio Owner + Product Owner Affects perceived loudness consistency and may affect advanced user preference.
DEC-009 Noise suppression default state Enabled by default, with user setting to disable Accepted Audio Owner + Product Owner Improves typical voice quality but may affect voice naturalness and CPU usage.
DEC-010 High-pass filter default state Enabled by default Accepted Audio Owner Removes low-frequency rumble and usually improves speech capture.
DEC-011 Audio processing implementation path Use platform-native audio processing first where available; use Rust/WebRTC-style processing as controlled fallback or later architecture option Accepted Software Architect + Audio Owner Controls architecture, latency, CPU use, platform compatibility, and testing.
DEC-011.1 Audio crate choice cpal for desktop (empirically verified on Linux/PipeWire by poc/audio-capture-playback-spike on 2026-05-13) and for Android (cpal-on-Oboe, empirically verified on a Motorola Moto G Stylus 5G (2023) running Android 14 arm64-v8a by poc/audio-capture-playback-android-spike on 2026-05-13); iOS crate TBD pending an iOS spike that requires macOS + Xcode hardware Accepted (desktop + Android) / Deferred (iOS) Software Architect + Audio Owner Pins the desktop and Android audio dependencies; iOS remains an open risk surface.
DEC-012 Official SDK / trademark / licensing review Public/store release is blocked until legal confirms TeamSpeak non-affiliation wording, trademark usage, OSS licenses, and tsclientlib license posture Accepted (as a release gate) Legal / Compliance + Product Owner Public release risk and store metadata risk. Owner accepted the gate on 2026-05-14; the legal review itself is still to be performed and remains a public-release blocker.
DEC-013 Local database choice Use SQLite or equivalent embedded local database for non-secret local state; secrets remain in platform secure storage Accepted Software Architect + Storage Owner Controls storage schema, migrations, backup/delete policy, and portability.
DEC-013.1 SQLite crate rusqlite with the bundled feature (SQLite statically linked into the binary; no system libsqlite3 dependency); verified by poc/sqlite-storage-spike on 2026-05-13 Accepted Software Architect + Storage Owner Pins the embedded-DB dependency; locks reproducibility.
DEC-013.2 Linux secure-storage backend policy Prefer Secret Service (libsecret / gnome-keyring / kwallet / KeePassXC) on Linux; if the default collection is locked or D-Bus is unavailable, fall back to kernel keyutils with a clear user notice. Both backends are "equivalent" per SysRS-053 / SysRS-162; verified by poc/secure-storage-spike on 2026-05-13 Accepted Software Architect + Storage Owner + Security Reviewer Closes the SysRS-162 ambiguity surfaced by the secure-storage PoC.
DEC-014 Bridge choice Use a stable typed Flutter/Rust bridge with generated or schema-controlled DTOs; flutter_rust_bridge 2.x pinned (empirically verified at 2.12.0 by poc/flutter_rust_bridge_hello on 2026-05-13) Accepted Software Architect Controls API stability, maintainability, async event flow, and long-term code generation.
DEC-015 Product language for MVP English + Chinese (Simplified) for MVP, raised from the original recommendation of English-only by explicit owner ruling on 2026-05-14. Rationale: the demonstrated test-server population (verified live against cn.teamspeak.app) and broader TS3 audience include substantial Chinese-speaking users; shipping zh-Hans alongside en at MVP avoids a launch-window UX gap. Architecture remains i18n-ready so additional languages can be added later mechanically. Server-provided content is preserved verbatim and never translated (ADR-008 UTF-8 boundary, DEC-015 server-content rule retained). Accepted Product Owner Controls localization scope and release schedule.
DEC-016 Diagnostics upload policy No automatic upload for MVP; user-initiated local diagnostic export only Accepted Product Owner + Legal + Security Controls privacy policy, support workflow, and security review scope.
DEC-017 Crash reporting Disabled for MVP unless explicit opt-in provider and privacy policy are approved Accepted Product Owner + Legal + Security Avoids privacy/legal complexity before public release.
DEC-018 Public product name Chanora Accepted Product Owner Branding and legal identity. Trademark / registrability check remains under DEC-012 legal review before public release.
DEC-019 Public non-affiliation statement Use legal-approved wording; drafted text accepted as working copy: "Chanora is independent and is not affiliated with, endorsed by, sponsored by, or officially associated with TeamSpeak." Subject to final legal review under DEC-012 before public release. Accepted (drafted wording) Legal / Compliance Required for public release and store metadata.
DEC-021 Apple App Store submission SDK Use Xcode 26 or later and the iOS 26 / iPadOS 26 SDK or later for App Store submission on or after 2026-04-28, unless Apple publishes a newer applicable requirement before upload Accepted iOS Owner + Release Manager Controls App Store Connect upload eligibility and release pipeline.
DEC-020 License model Dual-licensed under Apache-2.0 OR MIT (recipient's choice), the standard Rust-ecosystem permissive license model. Accepted on 2026-05-14. Compatible with every direct dependency in the PoC tree (tsclientlib MIT-OR-Apache-2.0, flutter_rust_bridge MIT, cpal Apache-2.0, rusqlite MIT, keyring MIT-OR-Apache-2.0, etc.) and with the Flutter framework's BSD-3-Clause. The license texts ship as LICENSE-APACHE and LICENSE-MIT at the repository root; an aggregator LICENSE points to both. NOTICE enumerates current direct-dependency attributions. The full OSS legal review (transitive deps, license obligations, OSS notices) remains under DEC-012 and is still required before public release. Accepted Product Owner + Legal Business and OSS compliance decision. No longer a public-release blocker by itself; legal review under DEC-012 is the remaining gate.
DEC-022 Canonical implementation directory layout Accept the README's sketch as canonical: apps/chanora_flutter/, core/chanora_core/, crates/chanora_protocol/, crates/chanora_audio/, crates/chanora_state/, crates/chanora_storage/, crates/chanora_diagnostics/, crates/chanora_bridge/. Matches SAD §7.2 module decomposition Accepted Software Architect Unblocks product-crate scaffolding; was not formalised by any prior doc.
DEC-023 Windows desktop Global PTT priority P0 in MVP. Resolves PTT-OPEN-001 from gen2/chanora-desktop-ptt-review-summary-v0.9.2.md. The Windows backend ladder (Raw Input → low-level keyboard hook → Focused fallback) is mandatory for the first public release; release notes shall not claim Global PTT support on Windows until live measurement confirms a Global level from a non-fallback rung. Accepted Product Owner + Windows Platform Owner Sets the MVP commitment level for the most common desktop platform.
DEC-024 macOS desktop Global PTT priority P0 in MVP, with explicit permission UX flow. Resolves PTT-OPEN-002. The macOS backend shall request the Input Monitoring / Accessibility permission, accept user denial gracefully (continue at L0Focused without functional regression), and upgrade to Global asynchronously when the user grants the permission. Accepted Product Owner + macOS Platform Owner Forces the permission UX to ship with the rest of the macOS audio path rather than as a follow-up.
DEC-025 Officially-tested Linux environment for first public release GNOME on Wayland (only). Resolves PTT-OPEN-003. The Linux backend shall use the freedesktop org.freedesktop.portal.GlobalShortcuts interface on GNOME-on-Wayland and fall back to Focused PTT on every other Linux environment (X11, sway, KDE, untested compositors). Release notes shall not claim Global PTT support outside the tested compositor. Accepted Product Owner + Linux Platform Owner Bounds the verification matrix; honest claim on Linux.
DEC-026 Mouse side-button support in first desktop PTT release Supported on Windows and macOS; Linux follows whatever the GlobalShortcuts portal exposes. Resolves PTT-OPEN-004. The Raw Input backend (Windows) and the Event Tap backend (macOS) shall accept Mouse4 / Mouse5 bindings; the Linux portal binding accepts whatever the session exposes and the release notes shall not over-claim. Accepted Product Owner + UX Owner Common dedicated PTT input class; shipping in MVP avoids a follow-up.
DEC-027 PTT diagnostics privacy posture Capability and availability state only — no raw key codes ever leave the device. Resolves PTT-OPEN-005. The diagnostic export shall name only PttCapabilityLevel, backend_id, bound_input_class, and fallback_exercised; the user's actual key value (scan code, virtual key, keysym) shall never be logged, persisted, or exported. PttSanitizer enforces this at write time. Accepted Security Reviewer + Privacy Reviewer Closes a clear privacy risk that the gen2 review flagged; aligns with DEC-016.
DEC-028 Missed-key-up watchdog requirement P0. Resolves PTT-OPEN-006. The audio engine shall include a missed-key-up watchdog that clears transmit_active after a configured ceiling (default 30 s) when no key-up event arrives. The watchdog is a P0 release-gate item rather than an implementation-level concern because the failure mode (stuck transmission after the user has released the binding) is user-visible and reputation-relevant. Accepted Audio Owner + Software Architect Prevents stuck-PTT bug class regardless of platform-input quirks.
DEC-029 Flutter global-hotkey packages rejected for PTT Use the native Rust DesktopPttBackend trait + per-OS implementations (already specified in SDD-083 / SDD-084 / SDD-085); do not adopt hotkey_manager, super_hot_key, or any equivalent pub.dev package for PTT. Rationale: those packages wrap the OS RegisterHotKey / RegisterEventHotKey semantics — they consume the key (suppressing it from other applications), they do not deliver a key-up event, and they do not support mouse side-buttons. PTT requires the opposite primitive (observe, do not consume, deliver both up and down). Accepted Software Architect + Audio Owner Locks the v1 PTT capture path to the native backend; removes ambiguity for future maintainers tempted to "simplify" via a Flutter package.
DEC-030 Voice activity detection deferred to P1 TransmitMode::VoiceActivity ships as a reserved enum variant with no v1 implementation. The settings UI shows it as a disabled "coming soon" option. The actual implementation choice is deferred to a future baseline. Rationale: three viable backends were compared (RMS energy threshold — trivial but quality-poor; WebRTC VAD via the webrtc-vad crate — frozen-but-stable C++ BSD-3 dep, ~200 KB binary, industry baseline; Silero VAD via ONNX Runtime — best quality but ~816 MB binary uplift per platform plus an ONNX-runtime dependency surface). The v1 dependency-surface budget does not have room for the trade-off review required to pick correctly. Choosing too early risks either user-visible quality regression (RMS) or a forced ONNX adoption (Silero) before there is a comparable need for ML inference elsewhere (noise suppression, AEC). Accepted Audio Owner + Product Owner Locks v1 to PTT + Continuous; preserves the enum surface so a P1 increment is non-breaking.
DEC-031 Missed-key-up watchdog disabled on P0; redesign deferred to P1 The MissedKeyUpWatchdog is constructed and unit-tested but is NOT spawned by ChanoraSession::start_audio in the P0 baseline. Supersedes DEC-028 for the v1 ship. Rationale: the original 30 s ceiling cut real users off mid-sentence when speaking through PTT for longer than the timeout — Mumble and TeamSpeak do not ship a comparable watchdog, so the protection is stricter than industry baseline while imposing a real UX cost. The watchdog's purpose (catching OS-level key-up loss when the app loses focus / is minimised / hits App Nap) remains valid; the fixed-timeout shape is the wrong implementation. P1 will reintroduce a redesigned variant using one of: (a) raised ceiling (~5 min, owner-tunable) only, (b) active OS-level key-state polling via GetAsyncKeyState / CGEventSourceKeyState / XQueryKeymap so we detect the actual OS desync directly, (c) audio-activity (RMS-silence) fallback once the level meter lands, or (d) a combination. The Rust unit tests for MissedKeyUpWatchdog::spawn_on_signal remain in crates/chanora_audio/src/ptt.rs so the P1 re-enable is non-breaking. Accepted Audio Owner + Product Owner Eliminates a P0-class UX regression (long PTT speech cut off at 30 s) while preserving the implementation surface for P1.

4. Accepted MVP Defaults

The "Recommended" defaults below have all been confirmed by the owner; two were modified from the original recommendation (marked MODIFIED).

Area Accepted MVP default
Release sequence Internal Alpha → External Beta → MVP Public
MVP platforms Windows, macOS, Linux, Android, iOS (staged release allowed)
Active connections One active server connection
UI design system Material 3 + Chanora Design System
Product language MODIFIED — English + Chinese (Simplified) at MVP; i18n-ready architecture
Server content Preserve and display Unicode; do not translate
Diagnostics Local, user-initiated export only
Telemetry None
Crash reporting None unless later approved
Secret storage Platform secure storage
Non-secret local storage SQLite (rusqlite bundled)
Audio processing Platform-native first; fallback strategy documented
AEC Enabled by default where supported
AGC Enabled by default (user-toggleable)
Noise suppression Enabled by default (user-toggleable)
High-pass filter Enabled by default
Android minimum MODIFIED — API 28 (Android 9.0), raised from the original recommendation of API 24
Android target API 35 or newer per current Google Play policy on upload date
iOS minimum iOS 13
Apple App Store SDK gate Xcode 26+ / iOS 26 SDK+ for uploads on or after 2026-04-28
Audio crate cpal (desktop, Android); iOS deferred
Bridge Stable typed Flutter/Rust bridge; flutter_rust_bridge 2.x pinned
Implementation directory layout apps/chanora_flutter/, core/chanora_core/, crates/chanora_*
License Dual-licensed under Apache-2.0 OR MIT, recipient's choice (DEC-020)

5. Decision Impact Matrix

Decision Affects SysRS Affects SysDes Affects SRS Affects SAD Affects SDD Affects Verification Affects Release
Minimum iOS / Android versions Yes Yes Yes Yes Yes Yes Yes
Android target SDK No No Yes No No Yes Yes
Multiple active connections Yes Yes Yes Yes Yes Yes Yes
AEC/AGC/NS/HPF defaults Yes Yes Yes Yes Yes Yes Yes
Audio implementation path No if behavior unchanged Yes Possibly Yes Yes Yes Yes
SDK/trademark/legal review Yes No No No No Yes Yes
SQLite/equivalent choice Possibly Yes Yes Yes Yes Yes Yes
Bridge choice No if API behavior unchanged Yes Possibly Yes Yes Yes Yes
Apple App Store SDK gate Yes Yes Yes Yes Yes Yes Yes
Diagnostics upload policy Yes Yes Yes Yes Yes Yes Yes
Crash reporting Yes if included Yes if included Yes if included Yes if included Yes if included Yes Yes
Flutter hotkey packages rejected for PTT (DEC-029) No Yes Yes Yes Yes Yes No
VAD deferred to P1 (DEC-030) Yes Yes Yes Yes Yes Yes Yes

6. Decisions That Must Be Confirmed By You

All decisions in the register have been addressed by the owner. The remaining release-gating work (not decisions) is the legal review itself under DEC-012, which must complete before any public/store release but is not an open decision:

Priority Item Status
P0 DEC-012 legal/trademark/licensing review — perform the actual review work (non-affiliation wording final sign-off, trademark registrability check, transitive-dependency OSS obligations, tsclientlib license posture confirmation). Pending; gate Accepted.

7. Open Decision Log

Decision ID Owner Decision Status Date Notes
DEC-001 Product Owner Release type sequence Accepted 2026-05-14 Internal Alpha → External Beta → MVP Public.
DEC-002 Product Owner / Engineering MVP platform strategy Accepted 2026-05-14 All five platforms as target; staged release allowed.
DEC-003 Product Owner / iOS Owner Minimum iOS version Accepted 2026-05-14 iOS 13.
DEC-004 Product Owner / Android Owner Minimum Android version Accepted 2026-05-14 API 28 (modified from the recommendation of API 24).
DEC-005 Android Owner / Release Manager Android target SDK Accepted 2026-05-14 Google Play-required API on upload date (currently API 35+).
DEC-006 Product Owner / Software Architect Multiple server connections in MVP Accepted 2026-05-14 Single connection in MVP.
DEC-007 Audio Owner / Product Owner AEC default Accepted 2026-05-14 Enabled by default where supported.
DEC-008 Audio Owner / Product Owner AGC default Accepted 2026-05-14 Enabled by default with user toggle.
DEC-009 Audio Owner / Product Owner Noise suppression default Accepted 2026-05-14 Enabled by default with user toggle.
DEC-010 Audio Owner High-pass filter default Accepted 2026-05-14 Enabled by default.
DEC-011 Software Architect / Audio Owner Audio processing path Accepted 2026-05-14 Platform-native first; Rust/WebRTC-style fallback.
DEC-011.1 Software Architect / Audio Owner Audio crate (desktop / mobile) Accepted (desktop: cpal; Android: cpal-on-Oboe) / Deferred (iOS) 2026-05-13 Closed by poc/audio-capture-playback-spike (desktop) and poc/audio-capture-playback-android-spike (Android). iOS crate TBD pending iOS spike.
DEC-012 Legal / Compliance SDK/trademark/licensing review Accepted as a release gate 2026-05-14 Required before public/store release; legal review work still to be performed.
DEC-013 Software Architect / Storage Owner Local database Accepted 2026-05-14 SQLite or equivalent for non-secret state.
DEC-013.1 Software Architect / Storage Owner SQLite crate Accepted (rusqlite bundled) 2026-05-13 Closed by poc/sqlite-storage-spike 11/11.
DEC-013.2 Software Architect / Storage Owner / Security Reviewer Linux secure-storage backend policy Accepted (Secret Service preferred, keyutils fallback) 2026-05-13 Closed by poc/secure-storage-spike 6/6. Resolves SysRS-053 / SysRS-162 ambiguity.
DEC-014 Software Architect Bridge choice Accepted (flutter_rust_bridge 2.x pinned) 2026-05-13 Closed by poc/flutter_rust_bridge_hello 3/3.
DEC-015 Product Owner Product language for MVP Accepted 2026-05-14 English + Chinese (Simplified) (modified from the recommendation of English-only).
DEC-016 Product Owner / Legal / Security Diagnostics upload policy Accepted 2026-05-14 User-initiated local export only; no automatic upload.
DEC-017 Product Owner / Legal / Security Crash reporting Accepted 2026-05-14 Disabled for MVP.
DEC-018 Product Owner Public product name Accepted 2026-05-14 Chanora. Trademark check still required under DEC-012.
DEC-019 Legal / Compliance Public non-affiliation statement Accepted (drafted wording) 2026-05-14 Final legal sign-off still required under DEC-012.
DEC-020 Product Owner / Legal License model Accepted (Apache-2.0 OR MIT dual-license) 2026-05-14 Compatible with every direct dependency; texts ship as LICENSE-APACHE / LICENSE-MIT. Full OSS legal review remains under DEC-012.
DEC-021 iOS Owner / Release Manager Apple App Store SDK gate Accepted 2026-05-14 Xcode 26+ / iOS 26 SDK+ on or after 2026-04-28.
DEC-022 Software Architect Canonical implementation directory layout Accepted (README sketch) 2026-05-13 Closes the absence flagged during PoC review.
DEC-023 Product Owner / Windows Platform Owner Windows desktop Global PTT priority Accepted (P0 / MVP) 2026-05-15 Resolves PTT-OPEN-001 from the gen2 desktop-PTT review.
DEC-024 Product Owner / macOS Platform Owner macOS desktop Global PTT priority Accepted (P0 / MVP, permission-UX required) 2026-05-15 Resolves PTT-OPEN-002.
DEC-025 Product Owner / Linux Platform Owner Officially-tested Linux environment Accepted (GNOME on Wayland only) 2026-05-15 Resolves PTT-OPEN-003.
DEC-026 Product Owner / UX Owner Mouse side-button support Accepted (Windows + macOS; Linux portal-dependent) 2026-05-15 Resolves PTT-OPEN-004.
DEC-027 Security / Privacy Reviewer PTT diagnostics privacy posture Accepted (capability + availability only, no key codes) 2026-05-15 Resolves PTT-OPEN-005.
DEC-028 Audio Owner / Software Architect Missed-key-up watchdog Accepted (P0) 2026-05-15 Resolves PTT-OPEN-006.
DEC-029 Software Architect / Audio Owner Flutter global-hotkey packages rejected for PTT Accepted 2026-05-15 Native DesktopPttBackend is the v1 PTT capture path; pub.dev hotkey packages consume the key, drop key-up events, and skip mouse side-buttons.
DEC-030 Audio Owner / Product Owner Voice activity detection deferred to P1 Accepted (deferred to P1) 2026-05-15 TransmitMode::VoiceActivity reserved on the enum surface; UI shows "coming soon"; backend choice (RMS / WebRTC / Silero) deferred for dependency-surface review.
DEC-031 Audio Owner / Product Owner Missed-key-up watchdog disabled on P0; redesign deferred to P1 Accepted (supersedes DEC-028 for P0) 2026-05-16 Watchdog implementation + tests retained; not spawned by ChanoraSession::start_audio in v1. P1 chooses between raised ceiling / OS key-state polling / RMS-silence fallback.

8. Change History

Version Date Description
0.9.0 2026-05-14 Updated decision register with proposed decisions for mobile minimum versions, audio defaults, audio implementation path, legal review, local database, bridge choice, diagnostics policy, and MVP release scope.

Baseline Candidate 0.9.1 Update

Version Date Description
0.9.1 2026-05-14 Updated baseline after product decision closure: Apple App Store SDK gate uses Xcode 26+ and iOS 26 / iPadOS 26 SDK+ for App Store Connect upload on or after 2026-04-28, platform baselines and decision traceability propagated across the document set.

Baseline Candidate 0.9.2 Update

Version Date Description
0.9.2 2026-05-14 Corrected Apple App Store Connect upload gate to 2026-04-28 and checked full-package naming, references, and coverage.

Baseline Candidate 0.9.3 Update

Version Date Description
0.9.3 2026-05-14 Recorded owner-confirmed decisions surfaced during the initial PoC phase: DEC-014 Accepted (flutter_rust_bridge 2.x pinned); added DEC-011.1 Accepted for desktop (cpal) / Deferred for mobile; added DEC-013.1 Accepted (rusqlite bundled); added DEC-013.2 Accepted (Linux Secret Service preferred with keyutils fallback); added DEC-022 Accepted (canonical implementation directory layout per README sketch and SAD §7.2); DEC-020 explicitly Deferred and remains a public-release blocker. Evidence pointers: poc/flutter_rust_bridge_hello/VERIFICATION.md, poc/secure-storage-spike/VERIFICATION.md, poc/sqlite-storage-spike/VERIFICATION.md, poc/audio-capture-playback-spike/VERIFICATION.md.

Baseline Candidate 0.9.4 Update

Version Date Description
0.9.4 2026-05-14 Promoted DEC-011.1 mobile half from Deferred to Accepted (Android), keeping iOS Deferred. Evidence: poc/audio-capture-playback-android-spike/VERIFICATION.md records empirical playback (22,050 frames at 44.1 kHz mono out of the device speaker) and capture (42,624 frames written to a valid 85,292-byte RIFF/WAVE mono 16-bit PCM file) on a physical Motorola Moto G Stylus 5G (2023) running Android 14 arm64-v8a, verifying the full Rust → cpal → Oboe → AAudio → Android audio HAL path.

Baseline Candidate 0.9.5 Update

Version Date Description
0.9.5 2026-05-14 Owner confirmation pass on all previously-Proposed decisions. Accepted: DEC-001, DEC-002, DEC-003, DEC-005, DEC-006, DEC-007, DEC-008, DEC-009, DEC-010, DEC-011, DEC-012 (as a release gate), DEC-013, DEC-015, DEC-016, DEC-017, DEC-018, DEC-019 (drafted wording), DEC-021. Two decisions modified from their original recommendations: DEC-004 Android minimum raised from API 24 to API 28 (simpler audio path, narrower compatibility surface); DEC-015 product language expanded from English-only to English + Chinese (Simplified) for MVP (reflects the demonstrated TS3-compatible-server audience). DEC-020 license model remains Open / Deferred — the only public-release blocker outstanding. §4 renamed from "Recommended MVP Defaults" to "Accepted MVP Defaults" with MODIFIED rows annotated. §6 collapsed to the single remaining DEC-020 item. §7 dated and statused.

Baseline Candidate 0.9.6 Update

Version Date Description
0.9.6 2026-05-14 DEC-020 license model closed: Apache-2.0 OR MIT dual-license (standard Rust-ecosystem permissive model). The license is compatible with every direct dependency in the PoC tree (tsclientlib, flutter_rust_bridge, cpal, rusqlite, keyring, hound, etc.) and with the Flutter framework's BSD-3-Clause. License texts added as LICENSE-APACHE and LICENSE-MIT at the repository root; the existing LICENSE file now aggregates both with the dual-license declaration and the standard Apache-2.0 inbound-contribution clause. NOTICE populated with current direct-dependency attributions. README §License rewritten. §4 updated. §6 collapsed: there is no longer any open decision — DEC-012 legal review remains a pending work item, not a pending decision. With this change, every previously-Proposed or Open decision in the register has been resolved; the only outstanding release-gating activity is the DEC-012 legal review itself (which is sign-off work, not an architectural choice).

Baseline Candidate 0.9.7 Update

Version Date Description
0.9.7 2026-05-14 DEC-001 release-sequence progress recorded: Internal Alpha (v0.1.0-alpha.1, commit 3bb038c) completed on 2026-05-14; Internal Beta first build (v0.2.0-beta.1) reached the same day. Beta milestone adds voice in/out: crates/chanora_audio promoted from scaffold to a cpal-based capture + playback engine with audiopus Opus encoding and tsclientlib AudioHandler for decode + jitter buffer + mix; crates/chanora_protocol extended to forward inbound voice packets and accept outbound OutPackets via mpsc channels; core/chanora_core::ChanoraSession exposes start_audio, set_ptt, and audio_stats; crates/chanora_bridge adds matching DTOs; the Flutter UI gains a "Start audio" action and a hold-to-talk PTT button with live frame counters. Verified end-to-end against cn.teamspeak.app; capture runs in graceful playback-only mode on hosts with no usable microphone (e.g. the PipeWire auto_null source on the verification host). No decision rows change; this entry documents progress against DEC-001 only.
0.9.8 2026-05-15 DEC-001 release-sequence progress recorded for the polished Internal Beta and the External Beta milestones, plus the first MVP-public release candidate. v0.3.0-beta.1 ("Internal Beta polish") added the supervisor + reconnect-with-watchdog path (A.6), OS-connectivity-aware backoff (A.6.1), persistent identity at rest as a plain 0600 file (A.2), the redacted in-memory log sink + user-initiated diagnostic export per DEC-016 (A.3), the SnapshotChanged lifecycle event for UI auto-refresh (A.4), and the mobile_voice_preset config-surface plumb-through (A.5). v0.4.0-beta.2 ("External Beta") added the server-password input, channel join via tap, self mute (input + output), master output gain, SQLite-backed bookmark list, ChaCha20-Poly1305 encryption of the identity at rest with the DEK in a separate identity.dek file, Android AudioManager.setMode(MODE_IN_COMMUNICATION) routing engagement via JNI, and the .github/workflows/ci.yml pipeline. v1.0.0-rc.1 ("MVP Public release candidate") closes the v0.4 DEK-on-disk weakness on every keyring-reachable platform: chanora_storage::IdentityFileStore now stores the DEK in the OS keyring (Linux Secret Service via D-Bus / macOS Keychain / Windows Credential Manager / iOS Keychain via the keyring crate) and migrates pre-existing file-fallback installs into the keyring opportunistically; bookmark server passwords are ChaCha20-Poly1305-encrypted under the same per-install DEK and the legacy plain password TEXT column is upgraded into a new password_blob BLOB column on the next update(); SessionEvent::SnapshotChanged now fires on any tree mutation (the in-channel-move blind spot from A.4 is closed); the in-app About dialog surfaces DEC-018 / DEC-019 / DEC-020. New docs/governance/legal-review-readiness.md carries the DEC-012 handoff package (trademark check, non-affiliation wording, third-party license posture, cargo about deliverables, cargo deny lifelines); new docs/governance/staged-release-plan.md enumerates the DEC-002 platform staging (Linux + Android sideload GA on DEC-012 sign-off; Windows, macOS, iOS gate on per-platform signed-build availability). No decision rows change; DEC-012 remains the sole outstanding release gate.
0.9.9 2026-05-15 Recorded six new accepted decisions DEC-023 through DEC-028 closing the gen2 desktop-PTT review's open questions PTT-OPEN-001 through PTT-OPEN-006: Windows Global PTT is P0/MVP (DEC-023), macOS Global PTT is P0/MVP with permission UX (DEC-024), the officially-tested Linux environment is GNOME-on-Wayland only (DEC-025), mouse side buttons are supported on Windows + macOS and Linux follows the portal (DEC-026), PTT diagnostics carry capability/availability only with no raw key codes (DEC-027), and the missed-key-up watchdog is a P0 release-gate requirement (DEC-028). No prior decision rows are mutated.
0.9.10 2026-05-15 Code-side promotion: the Linux GNOME-Wayland backend (DEC-025) is now a live org.freedesktop.portal.GlobalShortcuts session — CreateSession + BindShortcuts + Activated / Deactivated signal subscription scoped to the session handle, owned by a dedicated tokio task per backend instance. The Flutter "Configure" button on Linux portal delegates to the portal's own system dialog (Q3a) rather than the in-app _PttBindingCaptureDialog. Descriptor transitions broadcast via a watch::Sender consumed by chanora_core::ChanoraSession::start_audio and forwarded to SessionEvent::PttCapability. Cancellation / failure path downgrades to L0Focused and re-emits. No decision rows mutate.
0.9.11 2026-05-15 Added DEC-029 and DEC-030 covering the v1 audio + PTT lifecycle redesign. DEC-029 rejects Flutter global-hotkey packages (hotkey_manager, super_hot_key, equivalents) for PTT — they consume the key, do not deliver key-up, and do not support mouse side-buttons; the native Rust DesktopPttBackend already specified in SDD-083 / SDD-084 / SDD-085 is the v1 capture path. DEC-030 defers Voice Activity Detection to P1: TransmitMode::VoiceActivity ships as a reserved enum variant with no v1 implementation pending a backend trade-off review (RMS vs WebRTC VAD vs Silero VAD differ by ~816 MB and an ONNX-runtime dependency surface). No prior decision rows mutate; §5 impact matrix and §7 open-decision log gain matching rows.
0.9.12 2026-05-16 Added DEC-031: missed-key-up watchdog is disabled on P0 (supersedes DEC-028 for the v1 ship). The 30 s default ceiling spec'd in DEC-028 was cutting real PTT users off mid-sentence whenever a single utterance crossed the timeout; the watchdog's intent (catching OS-level key-up loss) remains valid, but the fixed-timeout implementation is the wrong shape. The MissedKeyUpWatchdog Rust type and its unit tests remain in crates/chanora_audio/src/ptt.rs; only the ChanoraSession::start_audio spawn is removed. P1 will choose between a raised ceiling, OS key-state polling (GetAsyncKeyState / CGEventSourceKeyState / XQueryKeymap), an RMS-silence fallback paired with the audio level meter, or a combination. DEC-028 stays in the register as historical context.

Baseline Candidate 0.9.8 Update — DEC-032

DEC-032 — Temporary reduction of Android abiFilters to arm64-v8a only during P0 smoke-test cycle

Field Value
Decision ID DEC-032
Title Temporary reduction of Android abiFilters to arm64-v8a only during P0 smoke-test cycle.
Status Active (temporary deviation)
Owner Build/Toolchain
Restore-by P0 release gate (must be restored before any P0 release upload).
Date recorded 2026-05-18
Supersedes None (temporary deviation from SDD-073 item 4 and SDD-118 item 3; does NOT supersede them).

Context. SDD-073 item 4 and SDD-118 item 3 mandate the canonical three-ABI set {arm64-v8a, armeabi-v7a, x86_64} for the Android AAB. apps/chanora_flutter/android/app/build.gradle.kts:72-79 currently has abiFilters reduced to arm64-v8a only with a TODO(x86_64/armv7 follow-up) comment explaining the reduction.

Cause. The audiopus_sys + cmake-rs + NDK toolchain-file interaction does not propagate ANDROID_ABI as a CMake variable when invoked via the Gradle Exec task chain. armeabi-v7a and x86_64 builds fail because the inner CMake configure step does not see the correct -DANDROID_ABI=<abi> argument. arm64-v8a (the smoke-test emulator target) builds cleanly because it happens to be the default that cmake-rs emits when no ANDROID_ABI is propagated.

Scope. Smoke-test build only. The P0 release must restore the full three-ABI set before any release upload. Internal Beta / RC builds for the smoke-test emulator path may continue using the reduced set while the cmake-rs propagation fix is in flight.

Exit criteria (all four must be met to close DEC-032).

  1. audiopus_sys / cmake-rs ANDROID_ABI propagation gap resolved (research + builder-dispatch fix; root-cause whether upstream cmake-rs patch, a builder-side env override, or a Gradle-Exec level argument injection is the correct fix).
  2. All three ABIs (arm64-v8a, armeabi-v7a, x86_64) compile cleanly in CI for chanora_bridge cdylib.
  3. The abiFilters declaration in apps/chanora_flutter/android/app/build.gradle.kts is restored to the canonical three-ABI set, and the TODO(x86_64/armv7 follow-up) comment removed.
  4. The SDD-118 item 10 release-inspection assertion confirms that all three libchanora_bridge.so files and all three libc++_shared.so co-staged files (per SDD-118 item 6 extended, absorbed into the traceability matrix v0.9.9 addendum) are present in any release AAB.

Impact assessment.

  • arm64-v8a installs work on all 64-bit modern Android devices, including the smoke-test emulator and every device meeting the DEC-004 API 28 minimum on 64-bit hardware.
  • armeabi-v7a (32-bit ARM Android, ~1% of the 2026 active install base for app-stores that still permit 32-bit) installations are blocked until restoration. Affected users see Play Store filtering and cannot install the AAB.
  • x86_64 (some Android emulators outside the smoke-test loop, rare Chromebook deployments, some VMs) installations are blocked until restoration.
  • P0 release-gate cannot pass until the three-ABI set is restored: release-inspection assertion (SDD-118 item 10) would fail, and the canonical SDD-073 item 4 / SDD-118 item 3 contract would be violated.
  • No SDD edit is required: the deviation is governance-layer only and the SDD canonical intent is unchanged.

Cross-references.

  • SDD-073 item 4 (canonical Android ABI set).
  • SDD-118 item 3 (Gradle automation enforcing the three-ABI set); also item 6 (extended) for libc++_shared.so co-staging and item 10 for the release-inspection assertion that any future restoration must satisfy.
  • apps/chanora_flutter/android/app/build.gradle.kts:72-79 (in-source TODO comment marking the deviation site).
  • Audit task ses_1c7645e36ffeY007MaYPep4wqs (auditor New-D — origin of this DEC entry).
  • Traceability matrix v0.9.9 §D (governance cross-reference).
  • DEC-031 (separate temporary deviation, for MissedKeyUpWatchdog P0 disable) — listed only as precedent for the "Active (temporary deviation)" status pattern; no direct technical overlap.

§3 row (for canonical table consistency).

Decision ID Decision Recommended decision Status Owner Why it matters
DEC-032 Android abiFilters set during P0 smoke-test cycle Temporarily reduced to arm64-v8a only; restore to canonical three-ABI set {arm64-v8a, armeabi-v7a, x86_64} (per SDD-073 item 4 / SDD-118 item 3) before any P0 release upload Active (temporary deviation) Build/Toolchain Affects who can install the AAB (armv7 + x86_64 currently blocked); P0 release gate cannot pass until restored; documents the SDD-073 / SDD-118 deviation site so it is not silently shipped.

§5 row (impact matrix).

Decision Affects SysRS Affects SysDes Affects SRS Affects SAD Affects SDD Affects Verification Affects Release
abiFilters temporary reduction (DEC-032) No No No No No (canonical intent unchanged; SDD-073 item 4 / SDD-118 item 3 stand) Yes (release-inspection assertion path) Yes (release-gate blocker until restored)

§7 row (open decision log).

Decision ID Owner Decision Status Date Notes
DEC-032 Build/Toolchain Temporary reduction of Android abiFilters to arm64-v8a only during P0 smoke-test cycle Active (temporary deviation) 2026-05-18 Restore to canonical three-ABI set before any P0 release. Root cause: audiopus_sys + cmake-rs + NDK toolchain-file ANDROID_ABI propagation gap. Exit criteria (4 items) listed in DEC-032 detail entry. SDD-073 item 4 / SDD-118 item 3 unchanged.

Change history

Version Date Description
0.9.8 2026-05-18 Added DEC-032: temporary reduction of Android abiFilters to arm64-v8a only during the P0 smoke-test cycle. Status: Active (temporary deviation) from SDD-073 item 4 / SDD-118 item 3, which both remain unchanged. Restore-by gate: any P0 release upload must restore the canonical three-ABI set {arm64-v8a, armeabi-v7a, x86_64} and satisfy the SDD-118 item 10 release-inspection assertion (including the libc++_shared.so co-staging per SDD-118 item 6 extended). Root cause: audiopus_sys + cmake-rs + NDK toolchain-file ANDROID_ABI propagation gap. Owner: Build/Toolchain. Cross-references: SDD-073 item 4, SDD-118 item 3 (+ item 6 extended, item 10), apps/chanora_flutter/android/app/build.gradle.kts:72-79 (in-source TODO), audit task ses_1c7645e36ffeY007MaYPep4wqs, traceability matrix v0.9.9 addendum §D. No prior decision row mutates.