package main import ( "testing" "github.com/kami/maven/internal/router" ) // The floor, and it is the reason a destination is safe to add at all: a box // whose model is down names nothing, and naming nothing has to walk the chain // the way it walked before the field existed. func TestNoDestinationWalksTheWholeChain(t *testing.T) { walk, skipped := queryWalk(router.SourceUnknown, false) if len(skipped) != 0 { t.Errorf("skipped %d sources with no destination named, want none", len(skipped)) } if len(walk) != len(querySources) { t.Fatalf("walk has %d sources, want the whole table of %d", len(walk), len(querySources)) } for i := range walk { if walk[i].name != querySources[i].name { t.Fatalf("position %d is %q, want %q", i, walk[i].name, querySources[i].name) } } } // The 2026-08-07 defects, one per line. Each is a source that decides by seed // similarity claiming a turn that was never its own, and then answering it // because it has no lookup that could come back empty. func TestANamedDestinationSilencesTheOtherGuessers(t *testing.T) { cases := []struct { dest router.Source utterance string silenced string anchored bool // a stage 0 grammar named the destination }{ {router.SourceWorld, "что такое TCP?", "weather", true}, {router.SourceWorld, "сколько будет 17 на 23?", "weather", true}, {router.SourceWorld, "кто такой Линус Торвальдс?", "personal", true}, {router.SourceRecall, "какой у меня любимый язык?", "feeds", false}, {router.SourceCalendar, "что в календаре на завтра?", "weather", true}, } for _, c := range cases { walk, skipped := queryWalk(c.dest, c.anchored) if inWalk(walk, c.silenced) { t.Errorf("%q named %q: %q is still asked", c.utterance, c.dest, c.silenced) } if !inWalk(skipped, c.silenced) { t.Errorf("%q named %q: %q is missing from the record of who was skipped", c.utterance, c.dest, c.silenced) } } } // Naming the world must not send the turn outside. His notes, his facts and the // boundary in front of them are the invariant CLAUDE.md states as "the owner's // data first, then the world", and a destination a model wrote must not be able // to reverse it. func TestNamingTheWorldStillReadsHisDataFirst(t *testing.T) { walk, _ := queryWalk(router.SourceWorld, true) for _, look := range []string{"fact-by-key", "embed", "memory", "notes"} { if !inWalk(walk, look) { t.Errorf("%q was dropped; only the sources that guess may be dropped", look) } } if posOf(walk, "notes") > posOf(walk, "search") { t.Error("search is asked before his notes are") } if posOf(walk, "search") < 0 { t.Fatal("search is not in the walk at all") } } // The boundary belongs to his data, so naming recall keeps it. That is what // makes "какой у меня любимый язык?" answer "не нашла у тебя такой записи" // rather than reaching SearXNG once nothing local had it. func TestNamingRecallKeepsTheBoundary(t *testing.T) { walk, _ := queryWalk(router.SourceRecall, true) if !inWalk(walk, "personal") { t.Fatal("the personal boundary was skipped on a turn named for his own data") } if posOf(walk, "personal") > posOf(walk, "search") { t.Error("the boundary no longer sits in front of the world") } } // The owner's call of 2026-08-09 (V-666): only a stage 0 grammar may take the // personal boundary off a turn. The routing heads and the resident model both // name a destination by inference, and an inferred SourceWorld would send a // question about him upstream. Every other guesser still goes. func TestOnlyAGrammarMayDropTheBoundary(t *testing.T) { walk, skipped := queryWalk(router.SourceWorld, false) if !inWalk(walk, "personal") { t.Error("an inferred destination took the boundary off the turn") } if !inWalk(skipped, "weather") { t.Error("weather is still asked; the rule covers the boundary alone") } if posOf(walk, "personal") > posOf(walk, "search") { t.Error("the boundary no longer sits in front of the world") } if anchored, _ := queryWalk(router.SourceWorld, true); inWalk(anchored, "personal") { t.Error(`a grammar named the world and the boundary stayed: ` + `"кто такой Линус Торвальдс?" is answered "не нашла у тебя такой записи" again`) } } // Whatever the destination, the walk is a subsequence of the table. Every // comment on that table argues an order between two sources, and none of those // reasons is about this field. func TestTheWalkNeverReordersTheTable(t *testing.T) { for _, dest := range append([]router.Source{router.SourceUnknown}, router.Sources...) { walk, skipped := queryWalk(dest, true) if len(walk)+len(skipped) != len(querySources) { t.Errorf("%q: %d walked + %d skipped, want %d", dest, len(walk), len(skipped), len(querySources)) } last := -1 for _, s := range walk { at := posOf(querySources, s.name) if at <= last { t.Errorf("%q: %q is out of table order", dest, s.name) } last = at } } } func inWalk(list []querySource, name string) bool { return posOf(list, name) >= 0 } func posOf(list []querySource, name string) int { for i, s := range list { if s.name == name { return i } } return -1 }