diff --git a/CLAUDE.md b/CLAUDE.md index a2a6492..45cec54 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,7 +32,11 @@ See `docs/rearchitecture.md` for the target architecture, `docs/design.md` for t GPU and the workstation has 16GB of VRAM. So the resident model, STT and TTS become preferred remotes with a floor on homesrv. The workstation is never assumed up. Fall back silently when it would only do the job better. Name the gap when the 1.7B cannot do it at all. The embedder -stays on homesrv permanently, because it backs that floor. Read `docs/offload.md` before +stays on homesrv permanently, because it backs that floor. It is multilingual-e5-small, +quantized and asymmetric — `EmbedQuery` and `EmbedPassage` apply the `query:`/`passage:` +prefixes it was trained with, and calling plain `Embed` on a note is a bug. It replaced +MiniLM and bought ten points of recall@1 and 2.5× the speed; see +`docs/evals/2026-08-04-recall-e5-small.md`. Read `docs/offload.md` before touching a daemon seam or adding a model caller. Vikunja #483 is the umbrella, #484 to #487 are the work. @@ -73,8 +77,8 @@ Pure-Go packages (`router`, `memory`, `mavweb`, …) run under a plain `go test | `mavweb` | HTTP UI + PWA (`/dash`, `/history`, `/trace`, `/notifications`, `/tools`); WebAuthn auth. Connects to mavend's socket. | | `mavsttd` | Speech-to-text (whisper.cpp, CGO). | | `mavttsd` | Text-to-speech (piper subprocess). | -| `mavwaked` | Wake-word / VAD gate. | -| `mavenclient` | Voice loop client (mic → stt → core → tts). | +| `mavwaked` | Wake-word / VAD gate. **Not on homesrv** — see below. | +| `mavenclient` | Voice loop client (mic → stt → core → tts). **Not on homesrv** — see below. | | `mavpoll` | Telegram long-poll reach. | | `mavcaldav` | CalDAV calendar sync. | | `mavmaild` | Mail reader (IMAP, read-only). Holds the IMAP password; core never sees it. | @@ -83,6 +87,15 @@ Daemons are wired socket-to-socket, not linked. `internal/ipc` is the client/ser protocol; the config in `deploy/mavend.json` (with `${VAR}` env expansion from gitignored `deploy/telegram.env`) sets socket paths, model paths, and the phraser/embedder blocks. +**Seven of the nine run on homesrv. `mavwaked` and `mavenclient` do not, and that is the +decision, not an oversight** (Vikunja #463, `docs/plans/17-where-the-voice-loop-runs.md`). +homesrv has a microphone — it is a laptop — but it is in the wrong room, so a wake-word +daemon there listens to nobody. They belong on a client machine where he is standing. +`ipc.Dial` already takes `tcp://host:port?token=...` through the netaddr seam, so nothing +needs building to allow it, but no such machine exists yet. **The consequence: the wake +word and the VAD gate are covered by unit tests and by nothing else, and no amount of +sitting at the box changes that.** Push-to-talk through `/dash` is what QA actually covers. + ## The ecosystem: Nexus, Praxis, Hexis Maven is one of four services. It owns conversation and personal memory. It does not @@ -267,8 +280,11 @@ world questions, so she needs to read external sources. What replaces it: ## Web UI conventions -Server-rendered pages share `cmd/mavweb/static/ui.css` (served at `/ui.css`) and the `nav` -partial (`navHTML` in `cmd/mavweb/main.go`, `{{template "nav" ""}}`). No +Server-rendered pages share `cmd/mavweb/static/ui.css` (served at `/ui.css`) and the shell +partial in `cmd/mavweb/shell.html`: a page opens with `{{template "shellTop" ""}}` +and closes with `{{template "shellBottom"}}`, and the key marks the active sidebar link. +Every page is its own embedded `.html` file next to `main.go` — no page markup lives in Go, +and the sidebar is data (`sidebarSections`, `pageIcon`) the template renders. No per-page `