Commit Graph

7 Commits

Author SHA1 Message Date
kami f1a809121b shutdown: close the sockets, or the database never gets sealed
mavend seals its encrypted database in `defer st.Close()` when run() returns.
It had not returned since 2026-07-21. Every restart since then decrypted the
same eleven-day-old ciphertext and rolled back everything written in between:
the Telegram nudge that kept firing was a fact being un-written on each boot.

The goroutine dump named it. main → srv.Close() → ipc.(*Server).Close →
wg.Wait(), waiting on per-connection goroutines parked in readFrame. Close
shut the listener and nothing else, so the idle persistent sockets held by
mavweb, mavpoll, mavcaldav and mavmaild blocked shutdown forever. `docker
compose stop -t 60` spent the whole sixty seconds and then took a SIGKILL.

So: track the accepted conns and close them, in ipc and in voice, which had
the identical defect. Bound all three waits — the two per-server ones and the
worker wait in main — because the seal matters more than any single in-flight
call. A dropped RPC costs one reply; a missed seal costs a session.

The regression test leaves a client connected and idle, which is the case the
old tests avoided by closing the client first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TrVSBKe3RFDF4fGYKWYQnX
2026-08-01 20:05:52 +04:00
kami 28a940ebbe feat: LLM router with chat intent and Cyrillic wake-word support
- Add LLMRouter: grammar-constrained LFM call for intent classification
  after stage-0, before classifier cascade. Errors fall through gracefully.
- Add IntentChat: conversational intent with no store side-effect, routed
  through LLM -> phraser chat endpoint.
- Extract slots for Chat: no structured slots, full utterance is payload.
- Extend stage-0 grammars to fire through Cyrillic wake-word spellings
  (Мэйвен/Мейвен/Майвен/etc.) produced by Russian STT model.
- StripWakeToken helper strips leading wake in any script so time/date
  grammars still match when wake is present.
- Add classifier examples for chat utterances (EN + RU).
- Wire LLMRouter into Router.Config; optional, nil-safe.
2026-07-10 15:48:48 +04:00
kami d52f60c54e maven: fix test mocks for CalendarEvents interface (verification)
- Add CalendarEvents method to recordingAPI in auth_test.go
- Add CalendarEvents method to fakeCore in handlers_test.go

Co-Authored-By: opencode <opencode@anthropic.com>
2026-07-06 04:20:16 +04:00
kami 359ae81d1f piper: pipe cleanup on early return, write error; misc error hygiene
piper_handler: close stdin/stdout pipes on Start() failure and on
WriteString error instead of leaking fds. Propagate WriteString error.

worker/client: log SetDeadline errors instead of discarding them.

voice/session: pushAudio marshals params inline and returns the marshal
error instead of swallowing it via mustParams (removed).

tool/matcher: log ListTools errors instead of silently returning an
empty allowlist that refuses every act.

config: applyDefaults now sets RouterThreshold and ToolTimeout defaults
so consumers self-contained defaults are belt-and-suspenders.
2026-07-03 12:11:24 +02:00
kami 861e418669 worker+voice: per-conn context, store error hygiene, StateDir wiring, pipe leak
worker/server.go: dispatch now receives a per-connection context instead of
context.Background(), so handler cancellation propagates on conn close.

voice/server.go: same — per-conn context fed through safeDispatch into
HandlePushToTalk instead of context.Background().

store/reminders.go: propagate LastInsertId error.
store/nudges.go: propagate LastInsertId and RowsAffected errors.
store/tools.go: propagate RowsAffected error.

config/config.go: applyDefaults now respects StateDir when set, using it as
the base for empty DBPath/SocketPath instead of silently ignoring it.

phraser/llmphraser.go: close stderr pipe fd when cmd.Start() fails.
2026-07-03 11:03:14 +02:00
kami b77f209686 voice: pre-route quiet-hours toggle, whisper ctx cancellation, stale reply fix
- resolveQuietToggle runs in HandlePushToTalk before the router so
  'тихий режим' works regardless of classifier confidence.
- whisper_full() runs in a goroutine with ctx.Done() select so the
  handler returns promptly on timeout/shutdown.
- StubReplier.IntentQuery no longer claims query is unimplemented.
2026-07-03 10:56:44 +02:00
kami 612583d59a initial commit 2026-07-03 00:32:48 +02:00