Hardware acceptance run on Void, niri, Dank Material Shell, RTX 2050 #32

Closed
opened 2026-11-05 17:00:53 +00:00 by xavierk · 4 comments
Owner

Parent

Spec: Voculinux — Void Linux (glibc) Wayland/niri port of Vocalinux

What to build

The final proof runs on the real target: the packaged, renamed build installed on Void under niri with Dank Material Shell on RTX 2050-class hardware, worked through the acceptance checklist no container can cover. The tray renders and operates in the shell; the documented keybind toggles dictation; dictation types into Ghostty with the clipboard provably untouched; hold-to-talk works through the in-app backend; the portal probe result on niri is what the spec predicts; the D-Bus state signal tracks a live dictation; and models load at the expected ladder rungs on Vulkan and, where a local toolkit exists, CUDA. Every checklist item lands on this ticket as recorded evidence — what was run, what was seen — including honest failures, which are spun out as follow-up tickets rather than silently absorbed.

Acceptance criteria

  • Checklist evidence records the exact package version, host, compositor, shell, GPU, and driver under test.
  • Tray icon and menu work in the shell with no false missing-tray warning; the state signal is observed changing across a live dictation.
  • The documented keybind toggles dictation start and stop; clipboard contents before and after a Ghostty dictation are shown unchanged.
  • Hold-to-talk dictates successfully, and the documented double-trigger misconfiguration is either demonstrated or explicitly not reproduced with the configuration noted.
  • Portal probe outcome on niri is recorded; model rung selection is recorded on Vulkan and on CUDA where a toolkit is present, matching the calibrated thresholds.
  • Any failing checklist item becomes its own follow-up ticket linked from here; this ticket closes only when every item is passed or spun out.

Blocked by

## Parent [Spec: Voculinux — Void Linux (glibc) Wayland/niri port of Vocalinux](https://git.bongbetic.com/xavierk/voculinux/issues/16) ## What to build The final proof runs on the real target: the packaged, renamed build installed on Void under niri with Dank Material Shell on RTX 2050-class hardware, worked through the acceptance checklist no container can cover. The tray renders and operates in the shell; the documented keybind toggles dictation; dictation types into Ghostty with the clipboard provably untouched; hold-to-talk works through the in-app backend; the portal probe result on niri is what the spec predicts; the D-Bus state signal tracks a live dictation; and models load at the expected ladder rungs on Vulkan and, where a local toolkit exists, CUDA. Every checklist item lands on this ticket as recorded evidence — what was run, what was seen — including honest failures, which are spun out as follow-up tickets rather than silently absorbed. ## Acceptance criteria - [ ] Checklist evidence records the exact package version, host, compositor, shell, GPU, and driver under test. - [ ] Tray icon and menu work in the shell with no false missing-tray warning; the state signal is observed changing across a live dictation. - [ ] The documented keybind toggles dictation start and stop; clipboard contents before and after a Ghostty dictation are shown unchanged. - [ ] Hold-to-talk dictates successfully, and the documented double-trigger misconfiguration is either demonstrated or explicitly not reproduced with the configuration noted. - [ ] Portal probe outcome on niri is recorded; model rung selection is recorded on Vulkan and on CUDA where a toolkit is present, matching the calibrated thresholds. - [ ] Any failing checklist item becomes its own follow-up ticket linked from here; this ticket closes only when every item is passed or spun out. ## Blocked by - [Rename user-visible identity to voculinux with one-time legacy import](https://git.bongbetic.com/xavierk/voculinux/issues/18) - [Free-memory model ladder, conditional backend order, step-down retry](https://git.bongbetic.com/xavierk/voculinux/issues/20) - [D-Bus dictation state signal](https://git.bongbetic.com/xavierk/voculinux/issues/21) - [niri and Dank Material Shell integration pack](https://git.bongbetic.com/xavierk/voculinux/issues/22) - [Void package smoke gate](https://git.bongbetic.com/xavierk/voculinux/issues/28)
xavierk added the ready-for-agent label 2026-11-05 17:00:53 +00:00
Author
Owner

Hardware acceptance #32 — partial evidence run (2026-11-06, NOT closing)

Hardware is present, so this is a genuine partial run, not a full gap:
all probes ran from integration/spec16 @ da97b67 (clean) with the
system python (gi available). Podman never invoked; host untouched
(no config writes, no installs).

Environment (checklist item 1 — recorded)

  • Package: voculinux 0.18.5 (src/vocalinux/version.py @ da97b67).
    Not installed: xbps-query -l | grep -i voc empty; only the old
    vocalinux pip shim remains on PATH.
  • Host the acceptance machine, Void Linux, kernel 7.3.0_1, 15 GB RAM.
  • Compositor niri 26.04 (wayland), shell DMS (dms v2.1.0, qs pid 2478),
    Ghostty 1.3.1 running (pid 32122).
  • GPU NVIDIA GeForce RTX 2050 4 GB, driver 595.112.07, CUDA 13.2 runtime;
    no nvcc (driver-only, no CUDA toolkit); Vulkan proprietary
    595.112.7.0 sees GPU0 RTX 2050.

PASS (observed)

  • Tray watcher probe: busctl --user list shows
    org.kde.StatusNotifierWatcher owned by DMS (qs pid 2478).
    Executed the verbatim _check_status_notifier_watcher body
    (tray_indicator.py:696) headless against the live session bus →
    WATCHER-PROBE: True, i.e. no false missing-tray warning. Per NIRI.md
    this closes its question: current probe stands, no widening needed.
    (Rendered icon/menu still need the running app — gap below.)
  • D-Bus state signal mechanics: real VocalinuxDBusService
    (dbus_service.py) on the live session bus owned
    com.voculinux.Voculinux, get_state() starts idle;
    set_state(listening|processing) → True, repeat → False (dedup),
    bogus → False; subscriber observed exactly
    ['listening','processing']. DBUS-ROUNDTRIP: PASS.
    (Tracking across a live dictation still needs the running app — gap.)
  • Model ladder rung: live MemAvailable 9994 MiB ≥ 1386 threshold →
    large-v3-turbo-q8_0 (EN and non-EN); next_rung_down chain intact.
    cuda_toolkit_ready() → False (nvcc absent, compute cap 8.6),
    preferred_backend_order() → ('vulkan','cpu') — exactly the
    driver-without-toolkit rule from model_ladder.py. No live model load
    (pywhispercpp not importable here) — gap.

MISMATCH (candidate follow-up ticket, not spun out — owner to triage)

  • Portal probe on niri: live RemoteDesktopPortal.probe() →
    True, version 2 (result cached on re-probe), but USER_GUIDE.md
    predicts no backend implements RemoteDesktop on niri
    ("the portal is never selected"). This host runs
    xdg-desktop-portal-gnome + -gtk under niri, which answers the
    version read. Either the doc needs a "GNOME portal installed" caveat
    or the probe needs a session-creation check. Suggested follow-up:
    verify first-dictation effective rung with the GNOME backend present.

GAP (needs installed packaged build + live session; not run)

  • voculinux xbps package not built/installed here (xbps-src build
    out of scope for this run); resources/niri/voculinux.kdl ships in-tree
    but the host ~/.config/niri/config.kdl carries no voculinux bind
    (left untouched), so keybind toggle, Ghostty clipboard
    before/after, hold-to-talk (in-app Right Alt) and the double-trigger
    demonstration, tray render/menu operation, and live-dictation
    D-Bus tracking are all unattempted. No failures observed, none spun out.
  • Unit gates (test_model_ladder.py, dbus/injection tests) not re-run
    here (project venv absent); prior per-ticket CI greens stand.

Net

3/6 checklist mechanics verified live; env fully recorded; 1 doc-vs-live
mismatch flagged; live-dictation half awaits the installed build.
Ticket stays open per its own rule.

# Hardware acceptance #32 — partial evidence run (2026-11-06, NOT closing) Hardware **is** present, so this is a genuine partial run, not a full gap: all probes ran from `integration/spec16` @ `da97b67` (clean) with the system python (gi available). Podman never invoked; host untouched (no config writes, no installs). ## Environment (checklist item 1 — recorded) - Package: voculinux `0.18.5` (`src/vocalinux/version.py` @ `da97b67`). **Not installed**: `xbps-query -l | grep -i voc` empty; only the old `vocalinux` pip shim remains on PATH. - Host `the acceptance machine`, Void Linux, kernel `7.3.0_1`, 15 GB RAM. - Compositor `niri 26.04` (wayland), shell DMS (`dms v2.1.0`, `qs` pid 2478), Ghostty `1.3.1` running (pid 32122). - GPU `NVIDIA GeForce RTX 2050` 4 GB, driver `595.112.07`, CUDA 13.2 runtime; **no `nvcc`** (driver-only, no CUDA toolkit); Vulkan proprietary `595.112.7.0` sees GPU0 RTX 2050. ## PASS (observed) - **Tray watcher probe**: `busctl --user list` shows `org.kde.StatusNotifierWatcher` owned by DMS (`qs` pid 2478). Executed the verbatim `_check_status_notifier_watcher` body (`tray_indicator.py:696`) headless against the live session bus → `WATCHER-PROBE: True`, i.e. no false missing-tray warning. Per `NIRI.md` this closes its question: current probe stands, no widening needed. (Rendered icon/menu still need the running app — gap below.) - **D-Bus state signal mechanics**: real `VocalinuxDBusService` (`dbus_service.py`) on the live session bus owned `com.voculinux.Voculinux`, `get_state()` starts `idle`; `set_state(listening|processing)` → True, repeat → False (dedup), bogus → False; subscriber observed exactly `['listening','processing']`. `DBUS-ROUNDTRIP: PASS`. (Tracking *across a live dictation* still needs the running app — gap.) - **Model ladder rung**: live `MemAvailable` 9994 MiB ≥ 1386 threshold → `large-v3-turbo-q8_0` (EN and non-EN); `next_rung_down` chain intact. `cuda_toolkit_ready()` → False (nvcc absent, compute cap 8.6), `preferred_backend_order()` → `('vulkan','cpu')` — exactly the driver-without-toolkit rule from `model_ladder.py`. No live model load (pywhispercpp not importable here) — gap. ## MISMATCH (candidate follow-up ticket, not spun out — owner to triage) - **Portal probe on niri**: live `RemoteDesktopPortal.probe()` → `True, version 2` (result cached on re-probe), but `USER_GUIDE.md` predicts *no* backend implements RemoteDesktop on niri ("the portal is never selected"). This host runs `xdg-desktop-portal-gnome` + `-gtk` under niri, which answers the version read. Either the doc needs a "GNOME portal installed" caveat or the probe needs a session-creation check. Suggested follow-up: verify first-dictation effective rung with the GNOME backend present. ## GAP (needs installed packaged build + live session; not run) - `voculinux` xbps package not built/installed here (xbps-src build out of scope for this run); `resources/niri/voculinux.kdl` ships in-tree but the host `~/.config/niri/config.kdl` carries no voculinux bind (left untouched), so keybind toggle, Ghostty clipboard before/after, hold-to-talk (in-app Right Alt) and the double-trigger demonstration, tray render/menu operation, and live-dictation D-Bus tracking are all unattempted. No failures observed, none spun out. - Unit gates (`test_model_ladder.py`, dbus/injection tests) not re-run here (project venv absent); prior per-ticket CI greens stand. ## Net 3/6 checklist mechanics verified live; env fully recorded; 1 doc-vs-live mismatch flagged; live-dictation half awaits the installed build. Ticket stays open per its own rule.
Author
Owner

#32 hardware acceptance run: checklist evidence (2026-11-06, partial, honest)

Host under test

  • Package voculinux-0.18.5_1 installed (signed local repo). Deps: python3-pywhispercpp-1.5.0_1 (Vulkan, reports version 0.0.0), python3-PyAudio-0.2.14_1.
  • Void Linux glibc x86_64, kernel 7.3.0_1, niri 26.04, Dank Material Shell (qs, dms-shell-custom-1.6.2).
  • GPU: RTX 2050 4096 MiB, driver 595.112.07. iGPU AMD Radeon 660M. CUDA rows use the local venv-cuda build (CUDA 13.2.51, unsupported).

Checklist

# item verdict evidence
1 Tray renders and menu works, no false missing-tray warning PASS (automated part); visual NEEDS-HUMAN Watcher org.kde.StatusNotifierWatcher owned by DMS (PID 2478). App item registered in RegisteredStatusNotifierItems. Installed probe returns True. No missing-tray warning in logs. See #22.
2 State signal tracks a live dictation PASS busctl --user monitor com.voculinux.Voculinux (hw/logs/state-monitor3.log) shows listening, processing, idle for every dictation (10 wake-loop runs plus earlier runs).
3 Documented keybind toggles start and stop, once per press Config validation PASS; live press NEEDS-HUMAN niri validate rc=0 on the example (see #22). Spawn path verified. Finding: the example key Mod+Shift+D is already bound to Move Column Right in ~/.config/niri/dms/binds.kdl:131.
4 Ghostty typing, clipboard hash unchanged Direct typing (wtype) PASS; app-pipeline Ghostty dictation NEEDS-HUMAN Own Ghostty window (title voc-hw-sink-*, PID verified as mine), focus checked before and after: wtype put "voc hw typing probe 0123" into its file. Clipboard sha256 (first 16) 792cf4dce8077acf before and after: identical. The app's own Ghostty dictation was not run automated because of the incident below.
5 Hold-to-talk via evdev Readiness PASS; hold NEEDS-HUMAN User is in input; /dev/input/event* are root:input mode 660. App log: Using evdev backend for global shortcuts (Wayland). Not started in automated runs (disable_internal_hotkey: true).
6 Double-trigger misconfiguration NEEDS-HUMAN Not reproduced in automation; needs a real key press with bind and in-app shortcut on the same key.
7 Portal probe on niri does not select the portal PASS for the injector; finding for the tool The injector skips the probe on niri (_is_niri_session()). inject-probe reports first_rung: wtype. But inject-probe (no niri guard) reports portal_available: true: the RemoteDesktop frontend answers version 2 with AvailableDeviceTypes = 0. The spec's "no backend implements RemoteDesktop" is true only in effect. No session was created, so no dialog.
8 Model rungs on Vulkan PASS Startup log: free 801 MiB gave startup rung small.en; free 3711 MiB gave startup rung large-v3-turbo-q8_0. Thresholds 1644 and 1358 MiB in model_ladder.py.
9 Model rungs on CUDA PARTIAL venv-cuda: preferred_backend_order('cuda') = (cuda, cpu); cuda_toolkit_ready() True without nvcc on PATH; child load log using CUDA0 backend. App-level CUDA startup was not run.
10 Failing items spun out Done (below)

Caveat on rung evidence: about 8 minutes into the session the user's ollama runner held 2.9 GB of VRAM. It was gone by 22:35.

Incident (honest failure of my test harness, disclosed)

  • At 22:35:53, 22:36:10, 22:36:31 and 22:36:52, dictation ran with focus on the user's terminal (an unrelated terminal window of the user) instead of my sink. The app types into the window focused when the segment is submitted, and my harness had not re-verified focus before each toggle. Each injection typed the flite sample's transcript: "Vocalinox dictation test. The quick brown fox jumps over the lazy dog. Speech recognition runs on the graphics card." (117 characters). No Enter was sent, so nothing should have run. Please clear the unsent text in that terminal (for example Ctrl+U at the prompt). Injection was halted at 22:37, and all later dictation used the pad (dictate_to_pad).
  • An earlier run (22:30) typed 86 characters of ambient mic transcript into my own sink. That text is deleted.

Defects to spin out (no code changed)

  • F1, privacy, high. audio/pipewire.py runs pw-record --raw ... --target <sink node> without stream.capture.sink. In the app's own run and in isolation, the stream linked to the default mic (amd_dmic_highpass) and not the sink monitor. Workaround verified: PIPEWIRE_PROPS='{ stream.capture.sink = true }' in the environment links the monitor.
  • F2, medium. A configured PortAudio virtual device (pipewire, index 11) is refused as "not a safe input device", and the app falls back to the hardware mic ([8] HD-Audio ALC256 Analog). Observed once.
  • F3, medium. python3-pywhispercpp-1.5.0_1 reports 0.0.0 (egg-info), so the app disables GPU device selection with "upgrade to 1.5+".
  • F4, medium. The CPU backend has no AVX/FMA/F16C (no ymm/zmm in libggml-cpu.so). CPU RTF is about 1.3 (small.en) to 1.7 (q8_0) on an AVX2 host.
  • F5, low. The docs example key Mod+Shift+D collides with DMS Move Column Right. Niri does not report duplicates.
  • F6, low. inject-probe ignores the niri guard, so it reports portal_available: true on niri.

Human-session checklist (one run, roughly 5 minutes)

  1. In your own Ghostty, clear the unsent test text (see the incident above).
  2. Copy resources/niri/voculinux.kdl, change the key if Mod+Shift+D is taken, then add the include line. With External Activation on, press the key once and confirm one toggle.
  3. Start voculinux and confirm the icon in the DMS bar opens its menu, with no "System tray icon may not appear" dialog.
  4. Turn External Activation off. Focus a Ghostty window, note wl-paste -n | sha256sum, hold Right Alt, speak one sentence, release. Confirm the text lands and the hash is unchanged.
  5. Put the same key in both the niri bind and the in-app shortcut, press once, and confirm the double toggle. Then revert.
  6. With free VRAM under 1359 MiB (for example while another GPU user holds memory), start dictation and confirm startup rung small.en in the debug log.

Evidence directory (absolute): scratchpad/hw/ (results/, logs/).

## #32 hardware acceptance run: checklist evidence (2026-11-06, partial, honest) ### Host under test - Package `voculinux-0.18.5_1` installed (signed local repo). Deps: `python3-pywhispercpp-1.5.0_1` (Vulkan, reports version 0.0.0), `python3-PyAudio-0.2.14_1`. - Void Linux glibc x86_64, kernel 7.3.0_1, niri 26.04, Dank Material Shell (`qs`, dms-shell-custom-1.6.2). - GPU: RTX 2050 4096 MiB, driver 595.112.07. iGPU AMD Radeon 660M. CUDA rows use the local venv-cuda build (CUDA 13.2.51, unsupported). ### Checklist | # | item | verdict | evidence | |---|---|---|---| | 1 | Tray renders and menu works, no false missing-tray warning | **PASS** (automated part); visual **NEEDS-HUMAN** | Watcher `org.kde.StatusNotifierWatcher` owned by DMS (PID 2478). App item registered in `RegisteredStatusNotifierItems`. Installed probe returns True. No missing-tray warning in logs. See #22. | | 2 | State signal tracks a live dictation | **PASS** | `busctl --user monitor com.voculinux.Voculinux` (`hw/logs/state-monitor3.log`) shows `listening`, `processing`, `idle` for every dictation (10 wake-loop runs plus earlier runs). | | 3 | Documented keybind toggles start and stop, once per press | Config validation **PASS**; live press **NEEDS-HUMAN** | `niri validate` rc=0 on the example (see #22). Spawn path verified. **Finding:** the example key `Mod+Shift+D` is already bound to `Move Column Right` in `~/.config/niri/dms/binds.kdl:131`. | | 4 | Ghostty typing, clipboard hash unchanged | Direct typing (`wtype`) **PASS**; app-pipeline Ghostty dictation **NEEDS-HUMAN** | Own Ghostty window (title `voc-hw-sink-*`, PID verified as mine), focus checked before and after: `wtype` put "voc hw typing probe 0123" into its file. Clipboard sha256 (first 16) `792cf4dce8077acf` before and after: identical. The app's own Ghostty dictation was not run automated because of the incident below. | | 5 | Hold-to-talk via evdev | Readiness **PASS**; hold **NEEDS-HUMAN** | User is in `input`; `/dev/input/event*` are `root:input` mode 660. App log: `Using evdev backend for global shortcuts (Wayland)`. Not started in automated runs (`disable_internal_hotkey: true`). | | 6 | Double-trigger misconfiguration | **NEEDS-HUMAN** | Not reproduced in automation; needs a real key press with bind and in-app shortcut on the same key. | | 7 | Portal probe on niri does not select the portal | **PASS** for the injector; **finding** for the tool | The injector skips the probe on niri (`_is_niri_session()`). `inject-probe` reports `first_rung: wtype`. But `inject-probe` (no niri guard) reports `portal_available: true`: the RemoteDesktop frontend answers version 2 with `AvailableDeviceTypes = 0`. The spec's "no backend implements RemoteDesktop" is true only in effect. No session was created, so no dialog. | | 8 | Model rungs on Vulkan | **PASS** | Startup log: free 801 MiB gave `startup rung small.en`; free 3711 MiB gave `startup rung large-v3-turbo-q8_0`. Thresholds 1644 and 1358 MiB in `model_ladder.py`. | | 9 | Model rungs on CUDA | **PARTIAL** | venv-cuda: `preferred_backend_order('cuda')` = (cuda, cpu); `cuda_toolkit_ready()` True without nvcc on PATH; child load log `using CUDA0 backend`. App-level CUDA startup was not run. | | 10 | Failing items spun out | Done (below) | | Caveat on rung evidence: about 8 minutes into the session the user's ollama runner held 2.9 GB of VRAM. It was gone by 22:35. ### Incident (honest failure of my test harness, disclosed) - At 22:35:53, 22:36:10, 22:36:31 and 22:36:52, dictation ran with focus on the user's terminal (an unrelated terminal window of the user) instead of my sink. The app types into the window focused when the segment is submitted, and my harness had not re-verified focus before each toggle. Each injection typed the flite sample's transcript: "Vocalinox dictation test. The quick brown fox jumps over the lazy dog. Speech recognition runs on the graphics card." (117 characters). No Enter was sent, so nothing should have run. **Please clear the unsent text in that terminal (for example Ctrl+U at the prompt).** Injection was halted at 22:37, and all later dictation used the pad (`dictate_to_pad`). - An earlier run (22:30) typed 86 characters of ambient mic transcript into my own sink. That text is deleted. ### Defects to spin out (no code changed) - **F1, privacy, high.** `audio/pipewire.py` runs `pw-record --raw ... --target <sink node>` without `stream.capture.sink`. In the app's own run and in isolation, the stream linked to the default mic (`amd_dmic_highpass`) and not the sink monitor. Workaround verified: `PIPEWIRE_PROPS='{ stream.capture.sink = true }'` in the environment links the monitor. - **F2, medium.** A configured PortAudio virtual device (`pipewire`, index 11) is refused as "not a safe input device", and the app falls back to the hardware mic (`[8] HD-Audio ALC256 Analog`). Observed once. - **F3, medium.** `python3-pywhispercpp-1.5.0_1` reports `0.0.0` (egg-info), so the app disables GPU device selection with "upgrade to 1.5+". - **F4, medium.** The CPU backend has no AVX/FMA/F16C (no `ymm`/`zmm` in `libggml-cpu.so`). CPU RTF is about 1.3 (small.en) to 1.7 (q8_0) on an AVX2 host. - **F5, low.** The docs example key `Mod+Shift+D` collides with DMS `Move Column Right`. Niri does not report duplicates. - **F6, low.** `inject-probe` ignores the niri guard, so it reports `portal_available: true` on niri. ### Human-session checklist (one run, roughly 5 minutes) 1. In your own Ghostty, clear the unsent test text (see the incident above). 2. Copy `resources/niri/voculinux.kdl`, change the key if `Mod+Shift+D` is taken, then add the include line. With External Activation on, press the key once and confirm one toggle. 3. Start voculinux and confirm the icon in the DMS bar opens its menu, with no "System tray icon may not appear" dialog. 4. Turn External Activation off. Focus a Ghostty window, note `wl-paste -n | sha256sum`, hold Right Alt, speak one sentence, release. Confirm the text lands and the hash is unchanged. 5. Put the same key in both the niri bind and the in-app shortcut, press once, and confirm the double toggle. Then revert. 6. With free VRAM under 1359 MiB (for example while another GPU user holds memory), start dictation and confirm `startup rung small.en` in the debug log. Evidence directory (absolute): `scratchpad/hw/` (`results/`, `logs/`).
Author
Owner

Human session results (2026-11-07), installed build from main 0c48db5

Build: voculinux-0.18.5_1 + python3-pywhispercpp-1.5.0_1 rebuilt from main 0c48db5. It includes the fixes for #41–#46 and is signed with key fa:d1:00:32:ce:b1:b9:fd:73:05:05:76:75:54:37:25. The install smoke passed: pywhispercpp reports 1.5.0, and the CPU variant libggml-cpu-haswell.so is loaded.

Item Result Evidence
Tray icon in the DMS bar PASS The user confirmed the icon. RegisteredStatusNotifierItems = :1.4889/org/ayatana/NotificationItem/voculinux. The icon appears only after the model load, about 18 s after launch; that is tracked in #50.
niri keybind PASS The user confirmed the toggle works. The bind moved to Mod+Alt+V at the user's request: it is unbound in niri and DMS, and niri validate passes.
Hold-to-talk (evdev, Right Alt) into Ghostty PASS The user confirmed the dictated text lands.
Clipboard untouched PASS A marker was put on the clipboard (sha256 4c566a89…). After a hold-to-talk dictation, the clipboard still held the marker with the same hash.
Double trigger (same key in niri and in-app) PASS (user-observed) The user reported that the toggle works with both bound.
Vulkan on the RTX 2050 (rebuilt package) PASS ggml_vulkan: 0 = NVIDIA GeForce RTX 2050. small.en RTF 0.017 on the GPU and 0.083 CPU-only (haswell variant); the transcripts are identical.
CUDA rung Not packaged by design Void has no CUDA toolkit package. The local CUDA build measured RTF 0.023 against 0.021 for Vulkan (see #19).

The automated items were recorded in the earlier comment. Defects found are tracked in #41–#46 (all fixed) and #50 (open).

## Human session results (2026-11-07), installed build from main 0c48db5 Build: voculinux-0.18.5_1 + python3-pywhispercpp-1.5.0_1 rebuilt from main `0c48db5`. It includes the fixes for #41–#46 and is signed with key fa:d1:00:32:ce:b1:b9:fd:73:05:05:76:75:54:37:25. The install smoke passed: pywhispercpp reports 1.5.0, and the CPU variant `libggml-cpu-haswell.so` is loaded. | Item | Result | Evidence | |---|---|---| | Tray icon in the DMS bar | PASS | The user confirmed the icon. `RegisteredStatusNotifierItems` = `:1.4889/org/ayatana/NotificationItem/voculinux`. The icon appears only after the model load, about 18 s after launch; that is tracked in #50. | | niri keybind | PASS | The user confirmed the toggle works. The bind moved to `Mod+Alt+V` at the user's request: it is unbound in niri and DMS, and `niri validate` passes. | | Hold-to-talk (evdev, Right Alt) into Ghostty | PASS | The user confirmed the dictated text lands. | | Clipboard untouched | PASS | A marker was put on the clipboard (sha256 `4c566a89…`). After a hold-to-talk dictation, the clipboard still held the marker with the same hash. | | Double trigger (same key in niri and in-app) | PASS (user-observed) | The user reported that the toggle works with both bound. | | Vulkan on the RTX 2050 (rebuilt package) | PASS | `ggml_vulkan: 0 = NVIDIA GeForce RTX 2050`. small.en RTF 0.017 on the GPU and 0.083 CPU-only (haswell variant); the transcripts are identical. | | CUDA rung | Not packaged by design | Void has no CUDA toolkit package. The local CUDA build measured RTF 0.023 against 0.021 for Vulkan (see #19). | The automated items were recorded in the earlier comment. Defects found are tracked in #41–#46 (all fixed) and #50 (open).
Author
Owner

Addendum: the user also confirmed that clicking the tray icon opens the menu in the Dank Material Shell bar.

Addendum: the user also confirmed that clicking the tray icon opens the menu in the Dank Material Shell bar.
Sign in to join this conversation.