From 0b6ea1107720120347f29001b78aa807c650eee1 Mon Sep 17 00:00:00 2001 From: EdisonJwa Date: Sat, 16 May 2026 02:11:21 +0800 Subject: [PATCH] =?UTF-8?q?docs(verification):=20windows-p0-acceptance.md?= =?UTF-8?q?=20=E2=80=94=20human-side=20rc.8=20sign-off?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Captures the 15 TC rows the lead walks through on the Korean Win 11 host before tagging v1.0.0-rc.8, plus the auto-test sign-off matrix (Linux + Windows cargo + flutter analyze + validator + windows-smoke). Each TC row maps to a spec requirement (DEC / SRS / SDD) or to a regression the rc.7 review found. Failures block the tag. Known gaps recorded at the bottom: macOS / iOS / Android P0 are separate documents; VAD (DEC-030) and missed-key-up watchdog redesign (DEC-031) are P1; real RMS level meter is P1. --- docs/verification/windows-p0-acceptance.md | 246 +++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 docs/verification/windows-p0-acceptance.md diff --git a/docs/verification/windows-p0-acceptance.md b/docs/verification/windows-p0-acceptance.md new file mode 100644 index 0000000..0a3b6f8 --- /dev/null +++ b/docs/verification/windows-p0-acceptance.md @@ -0,0 +1,246 @@ +# 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 | 124 / 0 / 2 | +| `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.