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
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.