# Start Commands *Last verified: 2026-08-02 @ 7079a24. Living doc: correct it in place, do not append.* All commands assume `ROOT=/home/kami/apps/Maven` and the local Go toolchain at `$ROOT/deps/go/go/bin/go`. ## Prerequisites ```bash export ROOT=/home/kami/apps/Maven export CGO_CFLAGS="-I$ROOT/deps/include -I$ROOT/deps/whisper.cpp/ggml/include" export CGO_LDFLAGS="-L$ROOT/deps/lib -Wl,-rpath,$ROOT/deps/lib" export LD_LIBRARY_PATH="$ROOT/deps/lib" export PATH="$ROOT/deps/go/go/bin:$PATH" ``` ## Build everything ```bash cd "$ROOT" go build ./cmd/mavend/ go build ./cmd/mavsttd/ # needs CGO (whisper.cpp) go build ./cmd/mavttsd/ # pure Go ``` ## mavend — daemon (core) ```bash cd "$ROOT" ./mavend -config mavend.json ``` Config path: `~/.config/maven/mavend.json`. Full example with all options. > The `phraser.model_path` below is an example — point it at whatever GGUF you > have locally. The deployed value lives in `deploy/mavend.json`, currently > `Qwen3.5-0.8B.Q4_K_M.gguf`; the target is the CPT'd Qwen3-1.7B (#122). ```json { "db_path": "/home/kami/.local/share/maven/maven.db", "socket_path": "/run/user/1000/maven/mavend.sock", "tick_interval": "60s", "repeat_interval": "5m", "ntfy": { "base_url": "https://ntfy.kvmx.ru", "topic": "maven" }, "phraser": { "model_path": "/mnt/hdd1/llms/Qwen3-Maven-1.7B-Q8_0.gguf", "bin_path": "/usr/local/bin/llama-server", "n_gpu_layers": -1 }, "voice": { "enabled": true, "bind": "127.0.0.1:9100", "lang": "ru", "embedder": { "model_path": "models/embedder/model.onnx", "tokenizer_path": "models/embedder/tokenizer.json", "lib_path": "deps/onnxruntime-linux-x64-1.17.1/lib/libonnxruntime.so.1.17.1" } } } ``` Omit the `embedder` block entirely to use the deterministic HashEmbedder floor (no ML, no ONNX runtime dependency). Useful for testing or low-resource setups. ## mavsttd — STT worker (optional, remote whisper.cpp) Requires `LD_LIBRARY_PATH` to include deps/lib (for libwhisper.so, libggml-vulkan.so). ```bash cd "$ROOT" export LD_LIBRARY_PATH="$ROOT/deps/lib" ./mavsttd -socket /run/user/$UID/maven/stt.sock -model models/stt/ggml-small.bin ``` Without `-model` it runs as a stub (deterministic, no ML). ## mavttsd — TTS worker (optional, remote Piper) Requires `LD_LIBRARY_PATH` to include deps/piper (for Piper's espeak-ng). ```bash cd "$ROOT" export LD_LIBRARY_PATH="$ROOT/deps/piper" ./mavttsd -socket /run/user/$UID/maven/tts.sock -piper deps/piper/piper -model models/tts/ru_RU-irina-medium.onnx -espeak_data deps/piper/espeak-ng-data ``` Without `-piper` it runs as a stub. `-lexicon deploy/tts-lexicon.json` adds the pronunciation dictionary: a flat JSON object of name to Russian spelling, applied to the text just before piper reads it. It is how `Vikunja` is said as a word rather than spelled out, and how `SearXNG` and `homesrv` are said at all. Off unless the flag is set; a path that is set and unreadable stops mavttsd rather than letting it say names wrong in silence. Adding a name needs a restart of mavttsd and nothing else. ## mavweb — PWA voice bridge (WebSocket ↔ TCP) No CGo, no deps; builds with stock Go. ```bash cd "$ROOT" go build ./cmd/mavweb/ ./mavweb -addr :9200 -voice 127.0.0.1:9100 ``` To also receive proactive nudges in-app, pass the ntfy WebSocket subscribe URL (the PWA connects to it directly; the auth token stays server-side config): ```bash ./mavweb -addr :9200 -voice 127.0.0.1:9100 \ -ntfy 'wss://ntfy.kvmx.ru/maven/ws?auth=' ``` `` is a *read*-capable ntfy access token, base64url-encoded (ntfy's browser-WS auth: `Bearer tk_...` can't set a header, so ntfy takes it as the `?auth=` query param). Without `-ntfy`, the PWA stays voice-only. ### presence-signal ingest (`-core`) Pass mavend's IPC socket so mavweb can feed presence via `/api/signal`: ```bash ./mavweb -addr :9200 -voice 127.0.0.1:9100 \ -core /run/user/1000/maven/mavend.sock ``` - **page_heartbeat** (weak, τ=4min) — the PWA auto-pings every 30s. Nothing to do. - **desk_active** (strongest, τ=8min) — a *workstation* signal (hyprland), so it can't be a homesrv module. Run `scripts/desk-active.sh` on the PC via a systemd-user timer, gated by hypridle (see the script header). Posts over wg. - **wg_handshake** (coarse, τ=20min) — still unfed; it's homesrv-local (`wg show latest-handshakes`), a natural small poller to add next. Allowlisted keys only; without `-core`, `/api/signal` returns 503 and presence stays cold-start `away`. Open http://10.42.0.1:9200/ (or http://voice.kvmx.ru:9200/) on your phone from inside the WireGuard tunnel. Tap & hold to speak; release to send; the reply plays automatically. ## mavpoll — env poller (netdata + uptime-kuma → facts) Thin adapter: reads netdata alarms + kuma monitor status and writes `env` facts through core's IPC socket. This is what makes `service_down` (sev4) and `netdata_critical` (sev3) rules fire on real data. Runs on homesrv where both services live — hit them on localhost, not the public `.kvmx.ru` names. ```bash cd "$ROOT" go build ./cmd/mavpoll/ # netdata only (kuma disabled until its API key exists): ./mavpoll -socket /run/user/$UID/maven/mavend.sock -netdata http://127.0.0.1:19999 # with kuma: create an API key in Kuma → Settings → API Keys, then: ./mavpoll -socket /run/user/$UID/maven/mavend.sock \ -netdata http://127.0.0.1:19999 \ -kuma http://127.0.0.1:3001/metrics -kuma-key ``` Writes only on value change (append-only, no per-tick churn). `service_down` aggregates any monitor reading 0 as "down"; per-service granularity is a later add. netdata `-timeout`/`-interval` tunable; defaults 8s / 60s. ### nginx (optional) ```bash sudo cp cmd/mavweb/nginx.conf /etc/nginx/sites-available/voice.kvmx.ru sudo ln -sf /etc/nginx/sites-available/voice.kvmx.ru /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx ``` ## Quick smoke test (stubs, no models) ```bash cd "$ROOT" ./mavend -config mavend.json # voice enabled, no stt/tts/embedder config → all stubs ``` ## Run all tests ```bash cd "$ROOT" go test ./internal/router/ ./internal/delivery/... ./cmd/mavend/ ./cmd/mavsttd/ ./cmd/mavttsd/ ``` ## Benchmark ```bash cd "$ROOT" go test -bench=. ./internal/router/ ./cmd/mavsttd/ ./cmd/mavttsd/ ```