Merge pull request 'Deploy mavwaked and mavenclient on workpc, so the wake path is proven' (#216) from task/515-deploy-mavwaked-workpc into master
This commit was merged in pull request #216.
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
# maven-voice-tunnel — the ssh leg that carries the voice wire to homesrv.
|
||||||
|
#
|
||||||
|
# Runs on workpc, as a user unit (`systemctl --user`), beside mavgpud.service.
|
||||||
|
#
|
||||||
|
# WHY THIS EXISTS AT ALL. internal/voice is plaintext and unauthenticated.
|
||||||
|
# Its own server doc says production binds inside the wg tunnel, because "the
|
||||||
|
# wg layer IS the L0 floor". workpc is not a wg peer, it sits on wlan0. So ssh
|
||||||
|
# is the substitute floor: it authenticates with his key and encrypts the leg,
|
||||||
|
# and mavend's published port stays on homesrv loopback (127.0.0.1:9110).
|
||||||
|
# Nothing about this puts a Maven port on the LAN.
|
||||||
|
#
|
||||||
|
# Do not replace this with a LAN bind. SurfaceVoice caps acts at L0, so an
|
||||||
|
# unauthorized speaker could not run a destructive tool. It would still hear
|
||||||
|
# his facts, his notes and his calendar read back, and L0 does not cap reading.
|
||||||
|
#
|
||||||
|
# install: cp to ~/.config/systemd/user/ on workpc
|
||||||
|
# systemctl --user enable --now maven-voice-tunnel.service
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=SSH tunnel to mavend's voice wire on homesrv
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
# -N: no remote command, forwarding only.
|
||||||
|
# ExitOnForwardFailure: fail loudly rather than sit up with a dead forward,
|
||||||
|
# which is what makes Restart meaningful.
|
||||||
|
# ServerAlive*: a laptop that suspends drops the tunnel silently otherwise.
|
||||||
|
ExecStart=/usr/bin/ssh -N \
|
||||||
|
-o ExitOnForwardFailure=yes \
|
||||||
|
-o ServerAliveInterval=30 \
|
||||||
|
-o ServerAliveCountMax=3 \
|
||||||
|
-o BatchMode=yes \
|
||||||
|
-L 127.0.0.1:9100:127.0.0.1:9110 \
|
||||||
|
kami@192.168.1.104
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
# mavwaked — always-on listening, on workpc where the microphone is.
|
||||||
|
#
|
||||||
|
# User unit, beside mavgpud.service and maven-voice-tunnel.service. It is a
|
||||||
|
# user unit because it needs his ALSA session and his ssh agent, and because
|
||||||
|
# it should stop when he logs out.
|
||||||
|
#
|
||||||
|
# THERE IS NO WAKE WORD YET (V-487 stage two). Anything spoken near the fifine
|
||||||
|
# becomes a turn. What makes that safe rather than expensive is voiceSender:
|
||||||
|
# it sends Surface=SurfaceVoice, which caps every command at L0, so no
|
||||||
|
# accidental trigger runs a destructive act. It does not stop her answering
|
||||||
|
# out loud, so this unit is his to stop when the room is not his alone.
|
||||||
|
#
|
||||||
|
# -vad-model is passed on purpose. Silero answers "is this frame speech" where
|
||||||
|
# the energy floor answers "is this frame loud". It declines white noise at
|
||||||
|
# the same RMS 0 frames to 68-99, and still hears all four spoken fixtures
|
||||||
|
# (docs/evals/2026-08-09-silero-vad.md). It costs 509us a frame, 1.7% of one
|
||||||
|
# core, and never touches the GPU. Drop the flag and the energy floor is back.
|
||||||
|
#
|
||||||
|
# -barge-in is NOT passed. The threshold is room-specific and this room has no
|
||||||
|
# number yet. Turn it on only after reading the "suppressed while speaking"
|
||||||
|
# means out of this unit's own journal, never by guessing.
|
||||||
|
#
|
||||||
|
# install: cp to ~/.config/systemd/user/ on workpc
|
||||||
|
# systemctl --user enable --now mavwaked.service
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Maven always-on listening (VAD, no wake word yet)
|
||||||
|
# The tunnel is the only path to mavend and the only thing authenticating it.
|
||||||
|
Requires=maven-voice-tunnel.service
|
||||||
|
After=maven-voice-tunnel.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
# card 0 is the fifine USB microphone. Named, and not "default", because the
|
||||||
|
# default device follows whatever pipewire last decided and this daemon should
|
||||||
|
# not change ears when he plugs in a headset.
|
||||||
|
#
|
||||||
|
# plughw and not hw. mavwaked asks arecord for 16kHz mono, which is what the
|
||||||
|
# whole pipeline is canonical in. The fifine offers 2 channels at 44100 or
|
||||||
|
# 48000 and nothing else, so bare hw:0,0 dies on "Channels count non
|
||||||
|
# available" before a frame is read. plughw puts ALSA's downmix and resampler
|
||||||
|
# in front. Any replacement microphone wants the same treatment.
|
||||||
|
Environment=LD_LIBRARY_PATH=%h/.local/lib
|
||||||
|
ExecStart=%h/.local/bin/mavwaked \
|
||||||
|
-device plughw:0,0 \
|
||||||
|
-addr 127.0.0.1:9100 \
|
||||||
|
-lang ru \
|
||||||
|
-vad-model %h/.local/share/maven/models/silero_vad.onnx \
|
||||||
|
-onnx-lib %h/.local/lib/libonnxruntime.so
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -53,6 +53,19 @@ services:
|
|||||||
# the decrypted working copy lives in RAM (see db_tmpfs in mavend.json).
|
# the decrypted working copy lives in RAM (see db_tmpfs in mavend.json).
|
||||||
tmpfs:
|
tmpfs:
|
||||||
- /dev/shm
|
- /dev/shm
|
||||||
|
# the voice wire, for mavwaked and mavenclient on workpc (V-515).
|
||||||
|
#
|
||||||
|
# LOOPBACK ONLY, and that is the whole security argument. internal/voice
|
||||||
|
# is plaintext with no auth: its own server doc says production binds
|
||||||
|
# inside the wg tunnel, "the wg layer IS the L0 floor". workpc is not a wg
|
||||||
|
# peer, it is on wlan0. So the tunnel is ssh instead, terminated on this
|
||||||
|
# loopback address, and nothing new is on the LAN. Anyone who could reach
|
||||||
|
# a LAN-bound port here could push audio and hear his facts read back.
|
||||||
|
# SurfaceVoice caps acts at L0; it does not cap reading.
|
||||||
|
#
|
||||||
|
# Host 9100 is Vikunja's MCP, hence 9110. The container side stays 9100
|
||||||
|
# so mavweb keeps reaching mavend:9100 by name.
|
||||||
|
ports: ["127.0.0.1:9110:9100"]
|
||||||
|
|
||||||
mavsttd:
|
mavsttd:
|
||||||
<<: *image
|
<<: *image
|
||||||
|
|||||||
Reference in New Issue
Block a user