package main import ( "strings" "github.com/kami/maven/internal/lexicon" "github.com/kami/maven/internal/morph" ) // correctionFragment reports that an utterance replaces a referent and states // nothing of its own: "нет, не маме, а папе" (V-576). // // Measured on the box 2026-08-06, that fragment routed to note and was filed. // It is not a repair either, because it names no intent, so parseRepair // declines it and repair.go is the wrong place to catch it. This is the note // path saying it has nothing to store. // // Three offline tests, all of them narrow on purpose. The sentence opens with a // refusal word from the lexicon, it carries the contrastive "а" that names the // replacement, and no token in it is a verb form. The verb test is what keeps // the rule off real notes: "нет, я не поеду, а останусь" says something, and a // Russian verb carries its own subject and tense. func correctionFragment(utterance string) bool { toks := repairTokens(strings.ToLower(strings.TrimSpace(utterance))) if len(toks) < 3 { return false } if !refusalWord(toks[0]) { return false } var negated, contrasted bool for _, tok := range toks[1:] { switch tok { case "не", "not": negated = true case "а", "but": contrasted = true } if morph.IsVerbForm(tok) { return false } } return negated && contrasted } // refusalWord reports that a token is a one-word refusal. The lexicon set holds // phrases too ("не надо"), and those are not what opens a correction. func refusalWord(tok string) bool { for _, w := range lexicon.ConfirmNo() { if strings.ContainsRune(w, ' ') { continue } if w == tok { return true } } return false }