Merge pull request 'reminder_verbs has no alarm verb, so an alarm never routes (V-627)' (#180) from task/627-reminder-verbs-has-no-alarm-verb-so-an-a into master

This commit was merged in pull request #180.
This commit is contained in:
2026-08-06 16:25:55 +02:00
7 changed files with 180 additions and 38 deletions
@@ -0,0 +1,51 @@
# Alarm verbs reach stage 0
**06-08-2026. V-627.** Measured with `TestONNXBaseline`, 91-case RU routing fixture,
classifier plus the ONNX embedder. No LLM arm in this run.
## What was wrong
`lexicon.ReminderVerbs` held five words and none of them named an alarm. `ReminderGrammar`
in `internal/router/stage0.go` did not read the set at all: it carried the literal
`напомни|remind me`. So no part of the cascade recognised `разбуди`.
Three fixture cases ride on that. Under the classifier they went to fact and act at high
confidence, so the failure was never a near miss:
- `ru-rem-005` "разбуди меня в 6:30" to fact at 0.918
- `ru-rem-009` "разбуди меня полвосьмого" to act at 0.941
- `en-rem-002` "wake me at 6:15" to fact at 0.899
Found while training the V-546 intent head, where the same three cases went to system. The
head reads a spoken time with no known verb in front of it as a clock question. The
classifier was making the same mistake in its own way.
## The change
Four alarm imperatives and bare `wake` join `reminder_verbs`. `ReminderGrammar` builds its
alternation from the set, longest alternative first, and eats an optional `мне`, `меня` or
`me` before the body.
Longest-first is load-bearing. Go's alternation is leftmost-first rather than longest-match,
so `напомнить` listed after `напомни` would never match.
## Result
**66/91 to 69/91, 72.5% to 75.8% full.** Three cases gained, none lost.
All three are the alarms above, and each now carries its time slot, which it did not before.
Clarify counts unchanged at 0 false and 8 missed. The two remaining system failures,
`какое число завтра` and `какой день недели послезавтра`, failed at baseline too.
## What this does not fix
The lexicon addition on its own moved nothing. Measured before touching the grammar:
**66/91**, exactly the baseline. Every consumer of `reminder_verbs` reads it after a reminder
route already exists. A verb that cannot win the route is a verb nobody asks about. The
grammar was the whole change.
Lemma matching in `isReminderVerb` now covers `разбудил` as well as `разбуди`, because one
lemma holds both. That is the trap `cmd/mavend/quiet_toggle.go` documents for `говори`. It
is tolerable here and not in the quiet toggle. `isReminderVerb` runs only on an utterance
already routed to reminder, and it decides where the subject starts. A quiet match flips a
daemon-wide setting from any channel.
@@ -0,0 +1,58 @@
# Moving the seed files onto the router prompt's boundaries
**06-08-2026. V-626.** Measured with `TestONNXBaseline`, 91-case RU routing fixture,
classifier plus the ONNX embedder. No LLM arm in this run.
`docs/evals/2026-08-06-seed-labels-vs-router-prompt.md` found three intent boundaries where
`models/seeds` and `routeSystem` disagree. This applies two of them and rejects the third,
because the third was measured and it costs a case.
## Baseline
**64/91, 70.3% full.** Latency p50 22.9ms.
## What moved
**Sensor and host state, system to query. 26 lines.** `какая температура воздуха`,
`сколько памяти занято`, `какой статус сервисов`. The prompt restricts system to the clock,
the calendar date and the assistant itself, which is the V-374 edit of 31-07-2026.
**World questions, chat to query. 8 lines.** `почему небо голубое`, `why is the sky blue`,
`как работает интернет`. Only the genuine world-knowledge lines. An opener about herself
stays in chat. `как тебя зовут` is a question word by rule 4 and about the assistant by
rule 8. The rules are ordered and rule 4 fires first, which reads wrong. That is a prompt
question rather than a seed question.
`system.txt` goes from 43 lines to 17 and `query.txt` from 64 to 98.
## Result
**66/91, 72.5% full.** Two cases gained, none lost.
- `en-sys-002` "turn quiet mode back on", quiet 2/3 to 3/3
- `ru-query-011` "почему сервер тормозит", homelab 5/6 to 6/6
Clarify counts unchanged at 0 false and 8 missed. The eight missed clarifies are the
`ambiguous` tag and this change does not touch them. `TestONNXRecall`, `TestONNXTopics`,
`TestONNXPersonalBoundary` and `TestONNXClaimConfidenceDistribution` all pass.
Thinning system to 17 lines did not hurt it. The two remaining system failures,
`какое число завтра` and `какой день недели послезавтра`, both failed at baseline too.
## The third boundary, measured and rejected
`reminder.txt` holds eight bare verbs: `поставь напоминание`, `создай напоминание`,
`set a reminder`. Rule 9 of the prompt calls an utterance with no named subject unknown.
By the prompt they do not belong in a reminder seed set.
Dropping them scores **65/91**, one below keeping them. `ru-rem-004` "поставь напоминание
через полчаса" falls from reminder to fact, because the centroid loses the phrase the
utterance is built from.
So the seed file and the prompt are not stale against each other here. They have different
jobs. A prompt classifies one utterance and can say it cannot. A nearest-neighbour centroid
is a shape to be near, and a bare verb phrase is part of that shape. The eight lines stay.
That distinction matters past this file. V-546 trains a classification head on labeled
utterances rather than a centroid, and the head is the prompt's kind of thing. These eight
lines are seed data and not training data.