package bot import ( "regexp" "testing" ) // TestTriggeredCharterHome pins the home-thread gate: in a member bot's own // thread the OWNER triggers without a mention; the bot's persona-named // editions (no uid) and anyone else never do. func TestTriggeredCharterHome(t *testing.T) { r := &Runtime{ Session: &Session{Name: "Eleven"}, ai: &anthropicClient{}, Charters: true, mention: regexp.MustCompile(`(?i)(^|[^a-z0-9])@Eleven\b`), charterHomes: map[string]charterHome{"th-home": {BotID: "bot-1", Owner: "u-owner"}}, } cases := []struct { name string thread string text string uid string want bool }{ {"owner, no mention, home thread", "th-home", "Hello?", "u-owner", true}, {"owner, other thread", "th-else", "Hello?", "u-owner", false}, {"persona edition (no uid), home thread", "th-home", "Tonight's news…", "", false}, {"someone else's uid, home thread", "th-home", "Hello?", "u-other", false}, {"mention still works anywhere", "th-else", "@Eleven hi", "u-owner", true}, } for _, c := range cases { tc := &ThreadCtx{ID: c.thread, Kind: "group"} if got := r.triggered(tc, c.text, c.uid); got != c.want { t.Errorf("%s: triggered = %v, want %v", c.name, got, c.want) } } // Without a model there is no conversational brain to answer — the home // thread must not trigger the deterministic floor's degrade hint. r.ai = nil if r.triggered(&ThreadCtx{ID: "th-home", Kind: "group"}, "Hello?", "u-owner") { t.Error("home thread must not trigger without an AI brain") } }