package config import "testing" // What counts as a LOCAL model alias, and where that is demanded (ADR-034, ADR-035 review). // A private transcript may be sent to a local model and to nothing else; the check is a // guard against a misconfiguration or a crafted alias, so it must be strict about shape, // not just about a prefix. func TestIsLocalModel_AcceptsRealLocalAliasesAndNothingShapedLikeAnEscape(t *testing.T) { tests := []struct { alias string want bool }{ {"koala/phi4-mini", true}, {"iguana/gemma4-26b", true}, {"iguana/gemma4-31b-think", true}, {"koala/qwen36-35b-a3b", true}, {"iguana/kb-whisper", true}, {"iguana/hf.co-model_v1:q4", true}, {"", false}, {"koala/", false}, {"iguana/", false}, {"gemma4-26b", false}, {"berget/mistral-small", false}, {"berget/koala/x", false}, {"xkoala/x", false}, {"Koala/x", false}, {" koala/x", false}, {"koala/x ", false}, {"koala/x y", false}, {"koala/x\n", false}, {"koala/../berget/kb", false}, {"koala//berget/mistral-small", false}, {"koala/x/y", false}, {"koala/x?host=berget", false}, {"koala/x#frag", false}, {"koala/x@evil", false}, {"koalа/x", false}, // Cyrillic а } for _, tt := range tests { t.Run(tt.alias, func(t *testing.T) { if got := IsLocalModel(tt.alias); got != tt.want { t.Errorf("IsLocalModel(%q) = %v, want %v", tt.alias, got, tt.want) } }) } } func TestLoad_UploadChatModelMustBeLocalBecauseTheWholeTranscriptIsSentToIt(t *testing.T) { for _, alias := range []string{"berget/mistral-small", "gemini/gemini-2.5-pro", "gemma4-26b", "koala/../berget/kb"} { t.Run(alias, func(t *testing.T) { clearUploadEnv(t) setEnv(t, map[string]string{"TAPIR_UPLOAD_CHAT_MODEL": alias}) if _, err := Load(); err == nil { t.Errorf("Load accepted TAPIR_UPLOAD_CHAT_MODEL=%q: a private transcript of up to 90,000 characters would be sent to it", alias) } }) } } func TestLoad_ALocalUploadChatModelIsAccepted(t *testing.T) { clearUploadEnv(t) setEnv(t, map[string]string{"TAPIR_UPLOAD_CHAT_MODEL": "iguana/gemma4-31b"}) cfg, err := Load() if err != nil { t.Fatalf("Load: %v", err) } if cfg.UploadChatModel != "iguana/gemma4-31b" { t.Errorf("UploadChatModel = %q", cfg.UploadChatModel) } }