# Windows P0 acceptance — human-must test cases (v1.0.0-rc.8) This document captures the human-side verification pass for the Windows P0 ship of Chanora. Automated tests (cargo + flutter analyze + windows-smoke.cmd) sign off the mechanical side; this checklist signs off the user-experience side. A failure on any row blocks the rc.8 tag. Source: this checklist supersedes the inline plan in the conversation that produced the v1.0.0-rc.8 baseline. The auto-test sign-off lives in this document's "Auto-test sign-off" section. ## 0. Pre-flight | # | Step | Expected | |---|---|---| | 0.1 | RDP into `100.84.219.45` as `admin` / `jkorisno1` | Desktop visible | | 0.2 | Wipe stale install: delete `%LOCALAPPDATA%\app.chanora\` and `%APPDATA%\app.chanora\` if they exist | First-launch from clean state | | 0.3 | Launch `C:\Users\admin\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\chanora_flutter.exe` | Window opens, no crash | | 0.4 | Open About / version label | Shows **`v1.0.0-rc.8`** (not rc.1) | | 0.5 | Open `C:\Users\admin\AppData\Local\app.chanora\chanora_flutter\logs\chanora.log` | Contains `bridge initialised`, `log file path …`, `identity store initialised`, `bookmark store initialised`. File size <1 MB. | ## TC-1: Connect + identity persistence (DEC-006, SRS-201) | # | Step | Expected | |---|---|---| | 1.1 | Enter `cn.teamspeak.app` (or your own test server), nickname, blank password | "Connect" button enabled | | 1.2 | Click Connect | Server snapshot appears: channel tree on left, client list visible | | 1.3 | Note the connected server name + the channel tree | Tree is sorted (parents above children); no duplicate roots | | 1.4 | Disconnect, reconnect with the same nickname | Server-visible UID is the same as previous session (identity persisted) | | 1.5 | Disconnect | Returns to connect form, no error | ## TC-2: Voice channel join (SRS-204, SDD-094) | # | Step | Expected | |---|---|---| | 2.1 | After connecting, observe the UI | **No "Start audio" button anywhere** | | 2.2 | Click a non-default voice channel in the tree | Voice Bar widget appears at top | | 2.3 | Voice Bar shows: channel-name pill on left, speaker-mute + mic-mute on right, mode badge ("PTT"), capability badge — expected `L2GlobalHoldToTalk (raw-input)` or `L3GlobalWithMouseButtons (raw-input)` after a successful Raw Input register | All five visible; capability NOT `L0Focused` on this Win 11 host | | 2.4 | Tap a different voice channel | Voice Bar's channel-name pill updates to the new channel; other clients see us move | | 2.5 | There is **no** "Leave voice" button | TS3 model: you are always in *some* channel | ## TC-3: PTT mode press / release (SDD-088, SDD-096, SAD-083) | # | Step | Expected | |---|---|---| | 3.1 | In a voice channel, click the gear "Voice settings" | Dialog opens with three mode radio rows (PTT selected, Voice activity disabled "Coming soon"), bind-key button, release-tail slider at 200 ms | | 3.2 | Click "Bind PTT key", press Space, observe Captured value, click Save | "Captured: **Space**" (not blank); after Save the Voice Bar's PTT line reads **"PTT: Space"** + release tail value | | 3.3 | Press and hold Space, watch the stats line | Within ~100 ms: **"Mic on"** appears; level meter goes active | | 3.4 | Release Space | After ~200 ms: **"Mic off"** appears; level meter returns to idle | | 3.5 | Repeat 3.3–3.4 ten times rapidly | Each press toggles Mic on/off; no stuck-on state | | 3.6 | Hold Space for 60 seconds continuously while saying something | **Mic stays on the entire time** (watchdog is disabled per DEC-031; no mid-sentence cut-off) | | 3.7 | Alt-tab to another application, press Space (no mouse focus on chanora) | Mic on toggles even though chanora is not focused (verifies L2/L3 global path); other clients hear you | ## TC-4: Release tail (SDD-096, SRS-206) | # | Step | Expected | |---|---|---| | 4.1 | Open Voice settings, slide release tail to 0 ms, save | Slider shows "0 ms" | | 4.2 | Hold Space briefly then release | "Mic off" appears within ~100 ms of release | | 4.3 | Set release tail to 500 ms, save | Slider shows "500 ms" | | 4.4 | Hold Space briefly then release | "Mic on" persists for ~500 ms after release, then "Mic off" | | 4.5 | Set release tail back to 200 ms | Slider shows "200 ms" | ## TC-5: Continuous mode (SAD-083, SRS-205, regression: DEC-031) | # | Step | Expected | |---|---|---| | 5.1 | Open Voice settings → select "Continuous" radio → Save | Mode badge reads "Continuous"; **no "PTT: …" line**; **no release-tail line**; **no capability badge** (all PTT-only surfaces hidden) | | 5.2 | Observe the stats line | "Mic on" immediately and **stays on** indefinitely | | 5.3 | Wait 60 seconds continuously | **Mic stays on** the whole time (the old bug — watchdog disabling Continuous after 30 s — must not reproduce) | | 5.4 | Switch back to PTT mode | Mode badge reads "PTT: Space"; PTT-only lines reappear; Mic off (no key held) | ## TC-6: Mic mute toggle (SRS-207, regression: log spam) | # | Step | Expected | |---|---|---| | 6.1 | In Continuous mode, click the mic-mute icon | Icon toggles to crossed-out; Mic shows off immediately | | 6.2 | Have a second client check our status | Other client sees a microphone-off icon next to your nickname | | 6.3 | Wait 30 seconds while muted, then check log file size | `chanora.log` stays <500 KB (no "Sending audio while muted" flood) | | 6.4 | Click mic-mute again to unmute | Icon clears; Mic returns to on | | 6.5 | In PTT mode with key held, click mic-mute | Mic immediately goes off mid-press; key release is ignored as long as muted | | 6.6 | Unmute, key still held | Mic returns to on | ## TC-7: Speaker mute (server-broadcast) | # | Step | Expected | |---|---|---| | 7.1 | Have a second client talk to you | You hear them | | 7.2 | Click speaker-mute (headset icon) | Icon toggles; their voice is silent | | 7.3 | Other client checks our status | They see a headset-off icon next to our nickname | | 7.4 | Click speaker-mute again | Voice returns | ## TC-8: Binding persistence across restart (SDD-095) | # | Step | Expected | |---|---|---| | 8.1 | Bind PTT to F10 → Save | Voice Bar shows "PTT: F10" | | 8.2 | Close the app entirely | Window dismissed | | 8.3 | Relaunch | Connect form appears | | 8.4 | Connect + join a voice channel | Voice Bar shows **"PTT: F10"** (binding survived restart) | | 8.5 | Press F10 | Mic on | ## TC-9: Binding before voice-join (SDD-094 follow-up) | # | Step | Expected | |---|---|---| | 9.1 | Wipe storage again (steps 0.2) | Clean state | | 9.2 | Launch, connect, but do not join a voice channel yet | Channel tree visible | | 9.3 | Open Voice settings, bind a key, Save | No `audio not started` error | | 9.4 | Join a voice channel | Voice Bar reflects the binding | ## TC-10: No-permission channel rejection (issue 3 from rc.7 review) | # | Step | Expected | |---|---|---| | 10.1 | Identify a channel where your account lacks join permission | Server tree shows it as locked or similar | | 10.2 | Tap it | After ~1.5 s, **red error banner** appears: "channel move rejected by server (no permission, wrong password, or channel full)" | | 10.3 | Voice Bar's channel-name pill does **not** update | We did NOT join the channel locally | | 10.4 | Other clients confirm we are NOT in the requested channel | Server-side reality matches the error banner | ## TC-11: Reconnect (real disconnect, not transient blip) | # | Step | Expected | |---|---|---| | 11.1 | Connect, join a voice channel | Voice Bar visible | | 11.2 | Force a hard disconnect (server-side kick, firewall block, or `nm-cli con down` on Linux RDP host) | UI shows red "Connection lost" banner with a spinning indicator and reconnect attempt counter | | 11.3 | Restore network | Reconnect succeeds; voice channel rejoined automatically; banner disappears | ## TC-12: Diagnostic export + privacy (DEC-027) | # | Step | Expected | |---|---|---| | 12.1 | Trigger a settings change (e.g. toggle mode) | Activity in log | | 12.2 | Trigger the diagnostic export (if a button exists) or copy `%LOCALAPPDATA%\app.chanora\chanora_flutter\logs\chanora.log` | Multi-line text | | 12.3 | Read it — privacy invariant | Contains `capability_level`, `backend_id`, `bound_input_class` (`keyboard` / `mouse-side-button`); **does NOT** contain any `vk`, `scan_code`, `keysym`, the actual key label, or any timing sequence of presses | | 12.4 | File size at end of session | <5 MB (rotation: previous session is at `chanora.log.1`; the one before at `chanora.log.2`) | ## TC-13: PTT bind dialog labels (regression) | # | Step | Expected | |---|---|---| | 13.1 | Open binding dialog | Initial state: "Captured: " is blank or shows a placeholder | | 13.2 | Press Space | "Captured: **Space**" (not blank — the rc.7 regression) | | 13.3 | Press Enter | "Captured: Enter" | | 13.4 | Press Tab | "Captured: Tab" | | 13.5 | Press A | "Captured: A" | | 13.6 | Press F12 | "Captured: F12" | | 13.7 | Press Shift alone | Captured field unchanged (modifier-only press ignored) | | 13.8 | Press a mouse side button (Mouse4 / Back) | "Captured: mouse-side-button:8" | ## TC-14: Capability badge gating | # | Step | Expected | |---|---|---| | 14.1 | In PTT mode | Capability badge visible (`L2GlobalHoldToTalk (raw-input)` or similar) | | 14.2 | Switch to Continuous mode | **Capability badge disappears** (no info-icon, no level label) | | 14.3 | Switch to "Voice activity (coming soon)" | Cannot select (disabled); confirms the radio row is non-interactive | ## TC-15: Indicator label (regression) | # | Step | Expected | |---|---|---| | 15.1 | In any mode, look at the stats line | Reads "Mic on" / "Mic off" (mode-neutral); **not** "PTT on" / "PTT off" | ## Auto-test sign-off These rows do not require human interaction. The values are filled in from CI / local invocation. | Layer | Result on Linux | Result on Korean Win 11 | |---|---|---| | `cargo check --workspace` | clean | clean | | `cargo test --workspace --lib` | 80 / 0 / 3 | 126 / 0 / 1 | | `flutter analyze` | clean (6 pre-existing Radio.groupValue infos) | n/a | | `python3 tools/validate_docs.py` | strict layered sourcing OK; pre-existing 35-filename warning | n/a | | `tools/windows-smoke.cmd` | n/a | exit 0 | The Windows host runs 44 more tests than Linux because of the `#[cfg(target_os = "windows")]`-gated PTT-backend, dispatcher, and full-chain tests in `crates/chanora_audio/src/ptt_backends/windows.rs` and `core/chanora_core/src/ptt.rs::windows_full_chain_tests`. ## Sign-off form ``` chanora v1.0.0-rc.8 — Windows P0 acceptance Host: Korean Win 11 (HP LAPTOP-37KAQO05, ko-KR locale) Tester: ______________________ Date: ______________________ Build: chanora_flutter.exe @ ______________________ chanora_bridge.dll @ ______________________ data\app.so @ ______________________ TC-1 Connect + identity persistence [ pass / fail ] notes: TC-2 Voice channel join [ pass / fail ] notes: TC-3 PTT press / release [ 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 Binding persistence across restart [ pass / fail ] notes: TC-9 Binding before voice-join [ pass / fail ] notes: TC-10 No-permission channel rejection [ pass / fail ] notes: TC-11 Reconnect [ pass / fail ] notes: TC-12 Diagnostic export + privacy [ pass / fail ] notes: TC-13 PTT bind dialog labels [ pass / fail ] notes: TC-14 Capability badge gating [ pass / fail ] notes: TC-15 Indicator label [ pass / fail ] notes: Overall result: [ rc.8 PASS / rc.8 FAIL ] Sign: ______________________ ``` ## Known gaps (not blockers) - **macOS / iOS / Linux** P0 acceptance is NOT covered here; this document is Windows-only. Tagging rc.8 ships Linux from a separate pass and remains Windows-gated for macOS / iOS / Android. - **VAD** (`TransmitMode::VoiceActivity`) is intentionally disabled per DEC-030 (deferred to P1). UI shows it as a "Coming soon" radio row. - **Missed-key-up watchdog** is disabled on P0 per DEC-031 (long PTT speech would have been cut off at 30 s). P1 reintroduces a redesigned variant. - **Audio level meter** is binary (`pttActive` only). Real RMS meter is a P1 follow-up.