# Linux P0 acceptance — human-must test cases (v1.0.0-rc.8) This document captures the human-side verification pass for the Linux P0 ship of Chanora. The officially-tested environment is **GNOME on Wayland** (DEC-025); on every other Linux environment (X11, sway, KDE, etc.) the desktop PTT layer cleanly downgrades to `FocusedPttBackend` and the rest of the app continues to function. Automated tests (`cargo check`, `cargo test --workspace --lib`, the `#[ignore]`-gated `linux_portal_smoke.rs`, and the cross- platform `ptt_privacy` integration test) sign off the mechanical side. This checklist signs off the user-experience side. A failure on any row blocks promotion of the Linux build from rc.8. Source: this checklist mirrors `windows-p0-acceptance.md`. The auto-test sign-off lives in this document's "Auto-test sign-off" section. SDD references: SDD-081 (trait), SDD-086 (Linux GNOME Wayland portal backend), SDD-094..097 (v1 audio + PTT lifecycle), DEC-025 (target environment), DEC-027 (diagnostic privacy invariant). ## 0. Pre-flight | # | Step | Expected | |---|---|---| | 0.1 | Log in to the GNOME on Wayland session at the physical console of `100.74.219.114` (user `edison`). Verify `echo $XDG_SESSION_TYPE` prints `wayland` and `echo $XDG_CURRENT_DESKTOP` contains `GNOME`. | Wayland GNOME session active. SSH/`tty` sessions are **not** sufficient; on those `try_select()` correctly returns `None` and the rest of this checklist is skipped from row TC-3 onward. | | 0.2 | Confirm `xdg-desktop-portal` and `xdg-desktop-portal-gnome` are installed: `pacman -Q xdg-desktop-portal xdg-desktop-portal-gnome` | Both packages present. (On the Arch verification host these are `1.20.4-1` and `50.0-1` respectively.) | | 0.3 | Wipe stale install: `rm -rf ~/.local/share/app.chanora/ ~/.config/app.chanora/` | First-launch from clean state. | | 0.4 | Build: `cd ~/chanora && cargo build --release -p chanora_bridge`. Then build the Flutter Linux bundle: `cd apps/chanora_flutter && flutter build linux --release` and copy `target/release/libchanora_bridge.so` next to the runner if the build glue did not auto-bundle it. | Build succeeds, runner binary at `apps/chanora_flutter/build/linux/x64/release/bundle/chanora_flutter` exists, bridge `.so` is in `bundle/lib/` or alongside the runner. | | 0.5 | Launch the runner from a GNOME-Wayland terminal (so the process inherits the right `DBUS_SESSION_BUS_ADDRESS` + `WAYLAND_DISPLAY`). | Window opens, no crash. | | 0.6 | Open About / version label | Shows **`v1.0.0-rc.8`**. | | 0.7 | Open `~/.local/share/app.chanora/chanora_flutter/logs/chanora.log` | Contains `bridge initialised`, `log file path …`, `identity store initialised`, `bookmark store initialised`. File <1 MB. The descriptor line for the PTT backend should mention `backend_id = "gnome-wayland-portal"` (or `"focused"` if not on GNOME Wayland). | ## 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 | 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); depth indent visible up to 6 levels | | 1.4 | Disconnect, reconnect with the same nickname | Server-visible UID is the same as previous session (identity persisted via `~/.local/share/app.chanora/identity.dek`) | | 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.** Voice Bar is visible at the bottom. | | 2.2 | Double-click a voice channel | Client moves into that channel; voice bar shows the channel name; `voice_join` log line appears with no error | | 2.3 | Double-click a different voice channel | Client moves; no audio glitch; `voice_join` repeats cleanly | | 2.4 | Double-click the same channel again quickly (concurrency) | Either: no-op move, or single clean move; no duplicate audio engine spawn (engine is single-instance) | ## TC-3: PTT press / release (SDD-083, SDD-086, SDD-096) — GNOME-Wayland only | # | Step | Expected | |---|---|---| | 3.1 | Open Voice settings (gear icon), select **Push to talk** | Bind-key row + Release-tail slider become visible | | 3.2 | Click "Bind key" | GNOME's **system** portal dialog appears asking you to pick a shortcut. (Chanora itself never reads raw keys — this is the portal's own UI.) | | 3.3 | Pick a key (e.g. Right Ctrl), accept | Dialog closes. VoiceBar's capability badge transitions from `L0` to `L2 GlobalHoldToTalk` (or `L3` for a mouse side-button). Bound-key label shows the portal's translated description. | | 3.4 | With another window focused, hold the bound key | Mic indicator turns "Mic on"; `transmit_active` true in stats | | 3.5 | Release the key | After the configured release-tail, indicator returns to "Mic off" | | 3.6 | Switch focus several times while pressing the key | PTT still fires from another window — this is the portal's "global" guarantee | ## TC-4: Release tail (SDD-097) | # | Step | Expected | |---|---|---| | 4.1 | Set release-tail to 0 ms in Voice settings | Slider updates immediately | | 4.2 | Tap PTT key briefly | Mic on/off transition is sharp (no tail) | | 4.3 | Set release-tail to 500 ms | Slider updates immediately | | 4.4 | Tap PTT key briefly | Mic stays "on" for ~500 ms after release before flipping to off | ## TC-5: Continuous mode (SDD-094) | # | Step | Expected | |---|---|---| | 5.1 | Switch transmit mode to **Continuous** | Bind-key + release-tail rows disappear; capability badge greys out. | | 5.2 | Talk into mic | "Mic on" stays solid; no self-disable bug. | | 5.3 | Switch back to PTT | Previously bound key still works without re-binding (binding persisted in `audio_meta.json`). | ## TC-6: Mic mute (SDD-097) | # | Step | Expected | |---|---|---| | 6.1 | Press mic-mute toggle in Voice Bar | Mic icon shows muted state; selector hard-mute engaged. | | 6.2 | Press PTT (still muted) | No "Sending audio while muted" spam in log. Mic indicator does not flip on. | | 6.3 | Un-mute | PTT resumes working normally. | ## TC-7: Speaker mute | # | Step | Expected | |---|---|---| | 7.1 | Press speaker-mute toggle | Other clients in channel are silenced locally; server still sees you in channel. | ## TC-8: Binding persistence across restart | # | Step | Expected | |---|---|---| | 8.1 | With a working PTT binding, quit Chanora | `audio_meta.json` next to `identity.dek` shows the new `ptt_*` fields. | | 8.2 | Relaunch | Binding restored without re-running the portal dialog. Hold key — mic flips on. | ## TC-9: Binding before voice-join | # | Step | Expected | |---|---|---| | 9.1 | Connect to server, do **not** join a voice channel yet. Open Voice settings, bind a PTT key. | Portal dialog appears; binding succeeds. | | 9.2 | Now double-click a voice channel | Voice engine starts with the existing binding active immediately. | ## TC-10: No-permission channel rejection (typed `ServerRejected` propagation) | # | Step | Expected | |---|---|---| | 10.1 | Try to join a channel you lack permissions on | Red SnackBar with a human message derived from the TS3 error code (e.g. `permissions_client_insufficient` → "You do not have permission to join this channel."). Move does not silently fail. | ## TC-11: Reconnect | # | Step | Expected | |---|---|---| | 11.1 | Yank the wifi or run `nmcli con down …` for 10 s, then reconnect | UI shows red "Connection lost" banner, then recovers. Transient `os error 111` blips are logged but **not** shown as a banner. | ## TC-12: Diagnostic export + privacy (DEC-027, SAD-077, SDD-090) | # | Step | Expected | |---|---|---| | 12.1 | Open Diagnostics, export a bundle | Bundle contains tracing records with allow-listed fields only: `backend_id`, `bound_input_class`, `capability_level`, `host_id`, `timeout_secs`, `error`, `event`, `message`, `target`, `level`. **No `platform_key`, no `trigger_description`, no raw key codes.** | | 12.2 | Grep the bundle for the human-readable PTT key label | No hit. | ## TC-13: PTT bind dialog labels | # | Step | Expected | |---|---|---| | 13.1 | Open Voice settings; the Bind-key row's display reads the portal's translated description (e.g. "Ctrl+Right Shift") | The translated string never appears in `chanora.log`. | ## TC-14: Capability badge gating | # | Step | Expected | |---|---|---| | 14.1 | On a non-GNOME-Wayland session (e.g. SSH-only `tty`, X11, sway), the badge displays `L0Focused` and explains it is information-only. The Bind-key UI is hidden in PTT mode if the backend is `focused`. | Verified manually by logging into the matching environment. | ## TC-15: Indicator label | # | 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. | Layer | Result on Arch host `100.74.219.114` | |---|---| | `cargo check --workspace --release` | clean (`Finished `release` profile [optimized] target(s) in 30.99s`) | | `cargo test --workspace --lib` | **78 passed / 0 failed / 1 ignored** (sums across all 7 workspace crates: `chanora_audio` 32, `chanora_bridge` 0, `chanora_core` 13, `chanora_diagnostics` 12, `chanora_protocol` 8 + 1 ignored, `chanora_state` 1, `chanora_storage` 12) | | `cargo test -p chanora_audio --test linux_portal_smoke -- --ignored` | **1 passed / 0 failed**; log line `GlobalShortcuts portal reachable, version = 1`. Run with `DBUS_SESSION_BUS_ADDRESS=unix:path=$XDG_RUNTIME_DIR/bus` + `XDG_SESSION_TYPE=wayland` + `XDG_CURRENT_DESKTOP=GNOME` exported. | | `cargo test -p chanora_audio --test ptt_privacy` | **1 passed / 0 failed** — DEC-027 invariant holds. | The Linux host runs fewer tests than the Korean Win 11 host (which reports 126 / 0 / 1) because 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` are Windows-only by construction. The Linux equivalent — the GNOME portal flow — is exercised by the `linux_portal_smoke` ignored integration test and the inline unit tests in `crates/chanora_audio/src/ptt_backends/linux.rs` (counted within the `chanora_audio` 32 above). ## Sign-off form ``` chanora v1.0.0-rc.8 — Linux P0 acceptance Host: Arch Linux GNOME Wayland (100.74.219.114) Tester: ______________________ Date: ______________________ Build: apps/chanora_flutter/build/linux/x64/release/bundle/chanora_flutter @ ______________________ libchanora_bridge.so @ ______________________ TC-1 Connect + identity persistence [ pass / fail ] notes: TC-2 Voice channel join [ pass / fail ] notes: TC-3 PTT press / release (GNOME-Wayland) [ 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: [ Linux rc.8 PASS / Linux rc.8 FAIL ] Sign: ______________________ ``` ## Known gaps (not blockers) - **X11, sway, KDE, other Wayland compositors**: officially out of scope for v1.0.0-rc.8 per DEC-025. The desktop PTT layer falls back to `FocusedPttBackend` (L0Focused capability) on these. Voice + identity + connect paths still work. - **Flutter build glue**: the Linux bundle currently requires manually copying `libchanora_bridge.so` next to the runner or into `bundle/lib/`. Auto-bundling is a P1 carryover. - **VAD** (`TransmitMode::VoiceActivity`) is intentionally disabled in P0 (DEC-030) on Linux as on Windows. - **macOS / iOS / Android** P0 acceptance is NOT covered here.