a97764c5f7
MavenHelpGrammar keeps "как отменить напоминание" on SourceSelf, where the answer names the command Maven accepts, instead of leaking to search. PublicCurrentVersionGrammar anchors an explicitly current release on SourceWorld and declines first-person ownership. AmbiguousFragmentGrammar refuses filler plus an unresolved demonstrative rather than letting a statistical head invent context. ImplicitElapsedQueryGrammar reads Russian question word order in "давно я не тренировался" as recall; the declarative order stays a statement. ReminderCancellationReportGrammar keeps "я отменил напоминание" in the non-mutating chat lane. CommandProhibitionGrammar routes a direct negative command to a sentinel fn that can never collide with an enabled tool. ActHasEntityTarget stops a bare verb or a demonstrative-only tail from crossing into Nexus. Praxis attention now accepts "что там с X" for the four service names only. taskstatus separates command mood from result words so a first-person report cannot mutate the board. question.go exports the open-question and locative shapes the recall gate reads. --no-verify: master is the working branch this session by the owner's call. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
86 lines
3.2 KiB
Go
86 lines
3.2 KiB
Go
package router
|
|
|
|
import "testing"
|
|
|
|
// The three utterances from the 2026-08-07 week on the box that no local source
|
|
// could answer and three different local sources claimed anyway. Stage 0 has to
|
|
// say which side of the boundary they are on, because by the time the chain is
|
|
// walking, the only thing separating them from a weather forecast is a cosine.
|
|
func TestAWorldQuestionNamesTheWorld(t *testing.T) {
|
|
cases := []struct {
|
|
utterance string
|
|
rule string
|
|
}{
|
|
{"что такое TCP?", "definition-query"},
|
|
{"кто такой Линус Торвальдс?", "definition-query"},
|
|
{"что такая мембрана", "definition-query"},
|
|
{"кто такая Ада Лавлейс?", "definition-query"},
|
|
{"what is TCP?", "definition-query"},
|
|
{"сколько будет 17 на 23?", "arithmetic-query"},
|
|
{"посчитай 2+2", "arithmetic-query"},
|
|
{"сколько будет 5 умножить на 6", "arithmetic-query"},
|
|
{"какая последняя версия Go?", "public-current-version"},
|
|
}
|
|
for _, c := range cases {
|
|
dec, rule, ok := matchWorldQuery(c.utterance)
|
|
if !ok {
|
|
t.Errorf("%q: no world rule claimed it", c.utterance)
|
|
continue
|
|
}
|
|
if rule != c.rule {
|
|
t.Errorf("%q: claimed by %q, want %q", c.utterance, rule, c.rule)
|
|
}
|
|
if dec.Intent != IntentQuery {
|
|
t.Errorf("%q: intent %q, want query", c.utterance, dec.Intent)
|
|
}
|
|
if dec.Source != SourceWorld {
|
|
t.Errorf("%q: source %q, want %q", c.utterance, dec.Source, SourceWorld)
|
|
}
|
|
}
|
|
}
|
|
|
|
// The frame has to be the whole opening or the rule is reading somebody else's
|
|
// sentence. Every case here contains a world-question shape and is not one.
|
|
func TestAWorldRuleDeclinesWhatIsNotItsShape(t *testing.T) {
|
|
cases := []struct {
|
|
utterance string
|
|
why string
|
|
}{
|
|
{"напомни узнать что такое TCP", "a reminder that happens to quote the frame"},
|
|
{"запиши что такое TCP", "a capture that happens to quote the frame"},
|
|
{"сколько будет гостей", "an ask with no number is not arithmetic"},
|
|
{"что у меня сегодня?", "his agenda, and the agenda rules own it"},
|
|
{"кто там?", "not the frame"},
|
|
{"посчитай расходы", "no number, so the money source keeps it"},
|
|
}
|
|
for _, c := range cases {
|
|
if _, rule, ok := matchWorldQuery(c.utterance); ok {
|
|
t.Errorf("%q: claimed by %q, want no claim — %s", c.utterance, rule, c.why)
|
|
}
|
|
}
|
|
}
|
|
|
|
// The destination is advice about who may guess, never a filled slot. A rule
|
|
// that quietly captured the topic would change what every source below reads.
|
|
func TestNamingTheWorldFillsNoSlot(t *testing.T) {
|
|
dec, _, ok := matchWorldQuery("что такое TCP?")
|
|
if !ok {
|
|
t.Fatal("definition-query did not claim it")
|
|
}
|
|
if dec.Slots.Text != "" || dec.Slots.HasTime || dec.Slots.HasFn || dec.Slots.HasKey {
|
|
t.Errorf("slots = %+v, want none filled", dec.Slots)
|
|
}
|
|
if dec.Confidence != 1.0 {
|
|
t.Errorf("confidence = %v, want 1.0 for a stage-0 match", dec.Confidence)
|
|
}
|
|
}
|
|
|
|
func matchWorldQuery(utterance string) (Decision, string, bool) {
|
|
for _, g := range WorldQueryGrammars() {
|
|
if dec, _, ok := g.Evaluate(utterance); ok {
|
|
return dec, g.Name, true
|
|
}
|
|
}
|
|
return Decision{}, "", false
|
|
}
|