diff --git a/cmd/mavend/personalboundary.go b/cmd/mavend/personalboundary.go index cda5cf4..d14f80a 100644 --- a/cmd/mavend/personalboundary.go +++ b/cmd/mavend/personalboundary.go @@ -77,6 +77,17 @@ var worldSeeds = []string{ "что мне почитать про историю", "что я должен знать про питон", "what can i watch tonight", + // A third shape that looks personal and is not: asking when something + // happens (Vikunja #553). "во сколько закат сегодня" scored personal, + // because "что у меня сегодня" and "когда моя встреча" put that frame on + // the personal side and nothing here answered it. The sunset is the one + // thing on his list that is the same for everybody standing outside. + // "сегодня" is carried on purpose. Without it these caught nothing: the + // day word is most of what pulls the frame personal, because "что у меня + // сегодня" is a personal seed and the day word is the half it shares. + "во сколько сегодня открывается магазин", + "когда сегодня начинается матч", + "во сколько сегодня восход солнца", } // personalBoundary holds the embedded seeds. Zero value is usable and means diff --git a/cmd/mavend/personalboundary_test.go b/cmd/mavend/personalboundary_test.go index 65c34ca..8fb9801 100644 --- a/cmd/mavend/personalboundary_test.go +++ b/cmd/mavend/personalboundary_test.go @@ -68,6 +68,14 @@ func TestONNXPersonalBoundary(t *testing.T) { {"я хочу узнать про рим", false}, {"кто такой гагарин", false}, {"how do i boil an egg", false}, + // Asking when a public thing happens (Vikunja #553). "во сколько закат + // сегодня" was answered "не знаю — не нашла у тебя такой записи", + // because the frame lived only on the personal side. The pair above it + // is the control: "во сколько у меня встреча" is the same frame about + // something that IS his, and it has to stay personal. + {"во сколько закат сегодня", false}, + {"когда сегодня заканчивается концерт", false}, + {"во сколько завтра открывается аптека", false}, } h := &reactiveHandler{recall: recallWiring{embedder: emb}} diff --git a/cmd/mavend/topics.go b/cmd/mavend/topics.go index 944f19e..e566e39 100644 --- a/cmd/mavend/topics.go +++ b/cmd/mavend/topics.go @@ -188,6 +188,30 @@ var topicSeedSets = map[topicLabel][]string{ // An attention question is about the state of his things; this is not. "что ты умеешь", "what did i say about backups", + // World questions that name a day (Vikunja #553). Weather was the only + // topic whose seeds carry a day word — four of its eight do — so every + // "какой сегодня X" landed nearest it and cleared the margin: the + // dollar rate by 0.0220 and a public holiday by 0.0398, against 0.0883 + // for a real weather question. The gate then asked "для какого города?" + // about the dollar. + // + // The margin was not the knob. 0.0398 is not a coin flip, and raising + // the bar far enough to catch it would take real weather questions with + // it. What was missing is the negative class: a day word means the + // question is about a day, and says nothing about whether it is about + // the sky. + "сколько стоит биткоин сегодня", + "какой завтра праздник в стране", + "во сколько сегодня восход солнца", + "кто вчера победил в чемпионате", + // The frame itself, twice. "какая сегодня погода" is a weather seed, + // and the four above did not move "какой сегодня курс доллара" or + // "что интересного произошло сегодня в мире" off weather, because what + // pulls them is the frame and not the noun. A frame that both topics + // use has to sit on both sides, or the side that owns it wins every + // noun it has never seen. + "какой сегодня курс валют", + "что сегодня происходит в мире", }, } diff --git a/cmd/mavend/topics_test.go b/cmd/mavend/topics_test.go index 76cb99c..d6194e0 100644 --- a/cmd/mavend/topics_test.go +++ b/cmd/mavend/topics_test.go @@ -100,6 +100,21 @@ func TestONNXTopics(t *testing.T) { // A task read-back is not a list read-back, and the two collide on // "что у меня". {"какие у меня сейчас задачи", topicOther, listFloor}, + // World questions that name a day (Vikunja #553). Weather was the only + // topic carrying day words, so all of these read as weather and two of + // them cleared the margin: the gate asked "для какого города?" about + // the dollar. The last two are far from any seed on purpose — the + // first three are close enough to the new topicOther seeds that they + // would pass on similarity alone. + {"какой сегодня курс доллара", topicOther, isWeatherQuery}, + {"какой сегодня праздник", topicOther, isWeatherQuery}, + {"что интересного произошло сегодня в мире", topicOther, isWeatherQuery}, + {"во сколько завтра открывается музей", topicOther, isWeatherQuery}, + {"кто сегодня играет в лиге чемпионов", topicOther, isWeatherQuery}, + // The control the seeds above must not cost: real weather still reads + // as weather, including the two that lean on the keyword floor. + {"будет ли завтра дождь в москве", topicWeather, isWeatherQuery}, + {"какая температура завтра утром", topicWeather, isWeatherQuery}, } h := &reactiveHandler{recall: recallWiring{embedder: emb}}