Files
chanora/docs/verification/ios-p0-acceptance.md
T

8.8 KiB

iOS P0 acceptance — human-must test cases (v1.0.0-rc.8)

This document captures the human-side verification pass for the iOS P0 ship of Chanora. The officially-tested environment is iOS 17 or later on a physical iPhone signed with the developer's personal team (DEC-025). Simulator support is best-effort — microphone capture is simulated by the host's mic but global PTT behaviour cannot be exercised in the simulator.

Automated tests (cargo check, cargo test --workspace --lib) sign off the mechanical side. This checklist signs off the user- experience side. A failure on any row blocks promotion of the iOS build from rc.8.

Source: this checklist mirrors the macOS, Linux, and Windows acceptance documents. Auto-test sign-off lives in this document's "Auto-test sign-off" section. SDD references: SDD-094..097, SDD-098..104 (v1 audio + PTT lifecycle), DEC-025 (target environment), DEC-027 (diagnostic privacy invariant), SRS-197 (iOS audio routing contract), SRS-198 (honest capability advertising under runtime permission state).

iOS does NOT have a global PTT capability comparable to Windows / macOS / Linux desktops. The desktop PTT backend ladder (SDD-081..088) collapses to FocusedPttBackend on iOS and the capability badge always advertises L0Focused. PTT works only while Chanora itself is the foreground app. This is intentional per DEC-025 — Apple's iOS sandbox model has no path to a session-level event tap analogue.

0. Pre-flight

# Step Expected
0.1 Open apps/chanora_flutter/ios/Runner.xcworkspace in Xcode once. In Runner target → Signing & Capabilities → set your personal team (free Apple ID team is sufficient for the P0 device pass). Set a unique bundle identifier (e.g. your.name.chanoraFlutter) — the default com.example.chanoraFlutter may already be claimed in the App Store registry. Xcode shows "Provisioning Profile: Xcode Managed Profile" with no errors.
0.2 Connect a physical iPhone via USB and trust the development Mac. On the iPhone: Settings → General → VPN & Device Management → developer-cert → Trust. iPhone appears in Xcode's device picker.
0.3 Build the bridge for the device: cd ~/chanora && rustup target add aarch64-apple-ios && cargo build --release --target aarch64-apple-ios -p chanora_bridge. target/aarch64-apple-ios/release/libchanora_bridge.a is produced.
0.4 Build the Flutter app: cd apps/chanora_flutter && flutter build ios --release. build/ios/iphoneos/Runner.app exists.
0.5 Install + launch on the iPhone: in Xcode pick the device + Runner scheme → Run. App launches on phone.
0.6 On first launch the iPhone prompts for Microphone access — Allow. Prompt text matches NSMicrophoneUsageDescription from ios/Runner/Info.plist.
0.7 About / version label inside Chanora Shows v1.0.0-rc.8.

TC-1: Connect + identity persistence (DEC-006, SRS-201)

# Step Expected
1.1 Enter a reachable TS3 server address, a nickname, blank password Connect button enabled
1.2 Tap Connect Server snapshot appears
1.3 Quit (background) + relaunch with the same nickname Server-visible UID is the same (identity persisted in the app-private support directory as identity.tskey)

TC-2: Voice channel join (SRS-204, SDD-094)

# Step Expected
2.1 Tap a voice channel Join works; voice bar shows the channel name. Mic capture starts (the iOS status bar may show a red microphone indicator).
2.2 Tap a different voice channel Smooth move; no audio dropout.

TC-3: PTT press / release (Focused only — iOS limitation, SDD-103)

# Step Expected
3.1 Open Voice settings (gear icon), select Push to talk The capability badge clearly states L0 Focused with explanatory text noting iOS does not permit global hotkeys.
3.2 Bind a key — the only "bound" key on iOS is the on-screen PTT button in the Voice Bar "Bound key" UI is replaced by an on-screen Push-to-Talk button.
3.3 Touch and hold the PTT button Mic indicator turns "Mic on" while held; releases on touch-up.

TC-4: Release tail (SDD-096)

# Step Expected
4.1 Set release-tail to 0 ms; tap-and-release the PTT button Sharp on/off transition.
4.2 Set release-tail to 500 ms; tap-and-release Mic stays on for ~500 ms after release.

TC-5: Continuous mode

# Step Expected
5.1 Switch to Continuous mode PTT button disappears; mic stays open while in the voice channel.

TC-6: Mic mute

# Step Expected
6.1 Mute mic via the Voice Bar Mic icon shows muted state; touching the PTT button does not unmute it.

TC-7: Speaker mute

# Step Expected
7.1 Speaker mute Other clients silenced locally.

TC-8: Background audio (UIBackgroundModes = audio, SDD-102)

# Step Expected
8.1 While connected + in a voice channel + in Continuous mode, swipe Chanora to the background. The iOS red microphone indicator stays on; voice continues to be received and sent.
8.2 Return to Chanora Session intact; no reconnect cycle.
8.3 Lock the iPhone for 30 s, then unlock Session still intact (provided you stayed in the channel and on cellular/wifi network).

TC-9: AVAudioSession routing (SDD-098, SDD-100, SDD-101)

# Step Expected
9.1 With voice connected, place an iPhone phone call to yourself (or have someone call). Chanora's audio session yields to the phone call (iOS owns the audio focus).
9.2 End the phone call Chanora resumes audio without manual reconnect.
9.3 Connect AirPods / Bluetooth headset; talk on Chanora Audio routes to the headset (.allowBluetoothHFP + .allowBluetoothA2DP are set in AppDelegate.swift).

TC-10: Reconnect

# Step Expected
10.1 Toggle Airplane Mode on for 10 s, then off Connection-lost banner appears, then recovers.

TC-11: Diagnostic export + privacy (DEC-027)

# Step Expected
11.1 Export a diagnostic bundle Allow-listed fields only; no raw key labels, no audio bytes.

TC-12: Capability badge labels (SDD-103)

# Step Expected
12.1 Capability badge Shows L0Focused with explanation that iOS does not expose global hotkeys.

Auto-test sign-off

These rows do not require human interaction.

Layer Result
cargo check --workspace on macOS host clean
cargo test --workspace --lib on macOS host unchanged (iOS-specific Rust code is #[cfg(target_os = "ios")]-gated and not exercised in host tests)
cargo build --release --target aarch64-apple-ios -p chanora_bridge clean — produces libchanora_bridge.a
flutter build ios --release clean — produces Runner.app
AppDelegate.swift registers AVAudioSession.routeChangeNotification and AVAudioSession.interruptionNotification observers (SDD-100, SDD-101) Log lines chanora_flutter: route change reason=… and chanora_flutter: audio interruption began/ended in device console.

Sign-off form

chanora v1.0.0-rc.8 — iOS P0 acceptance
Device:     ______________________ (model + iOS version)
Tester:     ______________________
Date:       ______________________

TC-1  Connect + identity persistence       [ pass / fail ]  notes:
TC-2  Voice channel join                   [ pass / fail ]  notes:
TC-3  PTT press / release (Focused)        [ pass / fail ]  notes:
TC-4  Release tail                          [ pass / fail ]  notes:
TC-5  Continuous mode                       [ pass / fail ]  notes:
TC-6  Mic mute                              [ pass / fail ]  notes:
TC-7  Speaker mute                          [ pass / fail ]  notes:
TC-8  Background audio                      [ pass / fail ]  notes:
TC-9  AVAudioSession routing                [ pass / fail ]  notes:
TC-10 Reconnect                             [ pass / fail ]  notes:
TC-11 Diagnostic export + privacy           [ pass / fail ]  notes:
TC-12 Capability badge label                [ pass / fail ]  notes:

Overall result:   [ iOS rc.8 PASS / iOS rc.8 FAIL ]
Sign:             ______________________

Known gaps (not blockers)

  • TestFlight + App Store distribution: requires the paid $99/yr Apple Developer Program (the personal team is sufficient for sideloaded device testing but not for TestFlight). P1 follow-up.
  • Simulator audio: cpal-via-CoreAudio inside the iOS simulator routes to the Mac's audio devices and is fine for smoke-testing the UI, but real microphone capture / AEC behaviour cannot be assessed there. Test on a physical iPhone.
  • VAD (TransmitMode::VoiceActivity) is intentionally disabled in P0 (DEC-030).
  • iPad layout: this checklist targets iPhone. The wide-mode (≥ 840 dp) UI works on iPad but is not signed off here.