router/semantic: baseline types, test helpers, leakage test (slice 13)
Baseline types: LegacyRouter interface (satisfied by *router.Router), LegacyCase with PrerouteConsumed flag for command-prohibition detection, LegacyReport with fast-path/residual/router-residual/pre-route breakdowns, ContrastFamilyReport for per-transform-family scoring. Test helpers: buildSeededClassifier (hash embedder seeded from models/seeds/*.txt), actVerbList, seed file loading. TestContrastFamiliesShareSplitGroup verifies that all contrastive variants of one base seed share exactly one SplitGroup, preventing train/eval leakage across the contrast family split.
This commit is contained in:
@@ -287,3 +287,53 @@ func TestFamilyID(t *testing.T) {
|
||||
t.Error("different base IDs produced same FamilyID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContrastFamiliesShareSplitGroup(t *testing.T) {
|
||||
exs, err := LoadCorpus()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Group contrastive examples by their base source_id.
|
||||
baseGroups := map[string]map[string]bool{} // source_id → {split_group: true}
|
||||
for _, e := range exs {
|
||||
if e.Source != "contrastive" {
|
||||
continue
|
||||
}
|
||||
if baseGroups[e.SourceID] == nil {
|
||||
baseGroups[e.SourceID] = map[string]bool{}
|
||||
}
|
||||
baseGroups[e.SourceID][e.SplitGroup] = true
|
||||
}
|
||||
|
||||
// Every base seed's contrastive variants must share exactly one
|
||||
// split_group (the base seed's own group).
|
||||
for sourceID, groups := range baseGroups {
|
||||
if len(groups) != 1 {
|
||||
t.Errorf("base %q has contrastive variants in %d split groups: %v",
|
||||
sourceID, len(groups), groups)
|
||||
}
|
||||
}
|
||||
|
||||
// Also verify that contrastive variants share the split_group with
|
||||
// their base seed from ru_routing_v1.
|
||||
ruGroups := map[string]string{} // source_id → split_group
|
||||
for _, e := range exs {
|
||||
if e.Source == "ru_routing_v1" {
|
||||
ruGroups[e.SourceID] = e.SplitGroup
|
||||
}
|
||||
}
|
||||
for sourceID, groups := range baseGroups {
|
||||
var contrastGroup string
|
||||
for g := range groups {
|
||||
contrastGroup = g
|
||||
}
|
||||
if ruGroup, ok := ruGroups[sourceID]; ok && contrastGroup != ruGroup {
|
||||
t.Errorf("base %q: ru_routing_v1 split_group=%q, contrastive split_group=%q",
|
||||
sourceID, ruGroup, contrastGroup)
|
||||
}
|
||||
}
|
||||
|
||||
t.Logf("contrast family leakage check passed: %d base seeds, all groups consistent",
|
||||
len(baseGroups))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user