Files
claude 8015fdbb79 Harden semantic boundaries and repair dialogue state
Replace nearest-neighbour personal routing with a frozen class-balanced linear head measured on historical, stratified, cross-validation, holdout, and fresh challenge gates (V-702). Close the four repair handoff holes, preserve nested clarification flows, and route Russian possession statements through structural grammar rather than lexical exceptions (V-573). Owner explicitly requested direct commits to master.
2026-08-13 03:00:31 +04:00

113 lines
3.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package router
import (
"strings"
"unicode"
"github.com/kami/maven/internal/lexicon"
)
var possessionQuestionWords = func() map[string]bool {
words := make(map[string]bool)
for _, word := range append(lexicon.Interrogatives(), lexicon.NarrativeRequests()...) {
words[word] = true
}
return words
}()
// PossessionStatementGrammar recognises the Russian possessive construction
// “у меня …” as a statement to remember. Russian has no present-tense “have”:
// the preposition and genitive pronoun are the grammatical predicate, so a
// sentence such as “у меня новый ноутбук” contains no verb for a generic
// sentence parser to anchor on. Both the hash floor and the deployed routing
// heads have measured this exact shape as a query and would try to answer it
// instead of recording it.
//
// This is a token grammar, not a phrase regexp or a noun list. The two-token
// frame is a closed grammatical construction and the remainder stays open.
// Questions and explicit capture/reminder/narrative requests retain their
// narrower routes; only a plain declaration is claimed.
func PossessionStatementGrammar() Grammar {
return Grammar{Name: "possession-statement", Decide: possessionStatementDecision}
}
func possessionStatementDecision(utterance string) (Decision, bool) {
tokens := planTokens(utterance)
if len(tokens) < 3 || tokens[0] != "у" || tokens[1] != "меня" {
return Decision{}, false
}
if possessionQuestionShaped(utterance) || CarriesCaptureVerb(utterance) || carriesReminderVerbTokens(tokens) {
return Decision{}, false
}
return Decision{
Stage: 0,
Intent: IntentNote,
Confidence: 1,
Slots: Slots{Text: utterance},
}, true
}
// possessionQuestionShaped is the question half of this grammar over Russian
// word structure. IsQuestionShaped intentionally tokenises punctuation away,
// which makes the interrogative root in indefinite pronouns look like a
// question: “что-то сломалось”, “кто-нибудь пришёл”, “когда-то работало”. Here
// that would defeat the open possession statement this grammar exists for.
//
// Hyphenated indefinite forms are a closed grammatical construction, not a
// phrase list: interrogative+{то, либо, нибудь}, or кое+interrogative. Every
// other exact interrogative/narrative token remains a question, as does a
// question mark. No noun or payload vocabulary is involved.
func possessionQuestionShaped(text string) bool {
if strings.HasSuffix(strings.TrimSpace(text), "?") {
return true
}
for _, lexeme := range possessionLexemes(text) {
if possessionQuestionWords[lexeme] {
return true
}
parts := strings.Split(lexeme, "-")
if indefiniteQuestionCompound(parts) {
continue
}
for _, part := range parts {
if possessionQuestionWords[part] {
return true
}
}
}
return false
}
func possessionLexemes(text string) []string {
return strings.FieldsFunc(strings.ToLower(text), func(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '-'
})
}
func indefiniteQuestionCompound(parts []string) bool {
if len(parts) != 2 {
return false
}
if parts[0] == "кое" && possessionQuestionWords[parts[1]] {
return true
}
if !possessionQuestionWords[parts[0]] {
return false
}
switch parts[1] {
case "то", "либо", "нибудь":
return true
default:
return false
}
}
func carriesReminderVerbTokens(tokens []string) bool {
for _, verb := range lexicon.ReminderVerbs() {
if hasTok(tokens, verb) {
return true
}
}
return false
}