Commit Graph

4 Commits

Author SHA1 Message Date
kami 8c6332f95c mavmaild: own its state volume, retire aged-out UIDs, stop restart-looping
The commented compose service mounted dbdata, the encrypted database volume,
read-write, for one JSON file of UIDs. The header of that same file says only
mavend holds the key and the db volume, and the whole argument for a separate
reader is that a compromise on either side does not reach the other. It gets its
own volume now, at its own path, so neither can be restored from a backup of the
other.

The high-water mark only advances through a contiguous run, and a failed ingest
is deliberately not marked. One message that never ingested therefore pinned the
mark forever: after the lookback window passed it could never be fetched again,
so the gap never closed, every UID above it stayed in the explicit set, and save
rewrote all of them every poll. FetchSince now reports the SEARCH window and the
poller retires everything below it, since a UID that can no longer be searched
for can never be read.

On ErrUnknownMethod the daemon logged "stopping" and then exited at the next
tick with status 0. The compose service inherits restart: unless-stopped, which
restarts a clean exit, so the real behaviour was a loop of four IMAP logins an
hour against a mailbox core would not accept anything from. It now stays up and
polls nothing.

The reader also sends the Junk verdict instead of counting bulk locally, which
is what the wire doc says it does. The verdict carries no mail content, since
nothing on the other side will read it. RunWith is gone, so the tests fake the
read rather than the transport.
Found in review of #65.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TrVSBKe3RFDF4fGYKWYQnX
2026-08-01 14:08:32 +04:00
kami 4c40a183cf feat: event store, pattern inference, and routine proposals
- Add events table (migration #4): stores normalized (action, object, ts)
  triples extracted from facts, indexed for recurrence detection.
- Add proposed_routines table: stores inferred recurring patterns with
  proposed/accepted/dismissed status and optional linked reminder.
- Add pattern package: Extractor normalizes fact text into (action, object)
  pairs with TTS normalization; Detector groups events to find recurring
  patterns and proposes routines.
- Add internal/ttsnorm: text normalization pipeline for Russian/English
  (lowercase, punctuation strip, number normalization, stopword removal).
- Add chat seed file for LLM phraser.
2026-07-10 15:49:03 +04:00
kami bf4009ca4f voice/seeds: track seed files, add russian time parser, guard replySystem
five fixes spotted during routing investigation:

- gitignore: replace blanket models/ ignore with per-dir exceptions
  (/models/embedder/, /models/stt/, /models/tts/) so the seed text
  files under models/seeds/ are tracked in version control
- query.txt: fix merged line — 'сколько стоит свет в этом месяце' and
  'найди заметку про сервер' were fused with no separator
- reminder.txt: add 11 pure-verb reminder seeds without time expressions
  to shift centroid toward the reminding intent rather than time-lexicon
- StubDateTimeParser: add Russian 'через <N> <unit>'/'через час'/'через
  полчаса', 'сегодня'/'завтра'/'послезавтра' with optional clock, and
  'в <clock>' scan. Add Russian word numbers (один-десять) and unit
  inflections (час/часа/часов, минута/минуты/минут, день/дня/дней,
  неделя/недели/недель). Also adds missing English day/week units.
- replySystem: guard time branch against duration queries ('сколько
  времени прошло') reaching it via the classifier path after the
  stage-0 grammar's build filter rejects them. Mirrors stage0.go
  duration keywords.
2026-07-06 18:38:48 +04:00
kami ce3d8e65f2 voice/routing: fix time-query misroute (seed collision, threshold, stage-0 grammars)
three bugs causing time queries to land on reminder or fact intent:

- seed collision: query.txt and system.txt shared identical time/date
  seeds (который час, сколько времени), making system intent
  indistinguishable from query intent in centroid space
- threshold (0.35) too low for ONNX embedder — cosine similarities
  cluster 0.5-0.7 for related intents, so Clarify never fired
- reminder centroid contaminated by time-lexicon (every seed has a time
  expression), pulling any time-word utterance toward reminder intent

fixes:
- remove 3 duplicate time/date seeds from query.txt (keep in system.txt)
- DefaultRouterThreshold 0.35 -> 0.55
- stage-0 grammar for напомни/remind me -> IntentReminder, bypasses
  classifier (fixes 'напомни через час' being misrouted to fact)
- stage-0 grammars for time/date system queries (сколько времени,
  который час, какой сегодня день) -> IntentSystem, with Build filter
  to exclude elapsed/duration queries (сколько времени прошло)
- time parser fallback in applyAction for stage-0 reminder matches
  (extractor doesn't run on stage-0 decisions)
2026-07-06 18:23:13 +04:00