返回 DeepSeek-Reasonix
ablation_test.go
根目录 / internal / boot / ablation_test.go
1 package boot
2
3 import (
4 "context"
5 "path/filepath"
6 "testing"
7
8 "reasonix/internal/ablation"
9 "reasonix/internal/event"
10 )
11
12 func builtToolNames(t *testing.T, set ablation.Set) map[string]bool {
13 t.Helper()
14 ctrl, err := Build(context.Background(), Options{
15 SessionDir: filepath.Join(t.TempDir(), "sessions"),
16 TokenMode: TokenModeFull,
17 Sink: event.Discard,
18 Ablation: set,
19 })
20 if err != nil {
21 t.Fatalf("Build(%s): %v", set.Arm(), err)
22 }
23 defer ctrl.Close()
24 names := map[string]bool{}
25 for _, e := range ctrl.ToolContractEntries() {
26 names[e.Name] = true
27 }
28 return names
29 }
30
31 func TestAblationRemovesOnlyTheTargetedToolSurfaces(t *testing.T) {
32 isolateConfigHome(t)
33 t.Chdir(robustTempDir(t))
34
35 full := builtToolNames(t, ablation.Set{})
36 for _, name := range []string{"task", "read_only_task", "history", "memory", "remember", "list_sessions"} {
37 if !full[name] {
38 t.Fatalf("control arm is missing %s; the ablation assertions below would be vacuous", name)
39 }
40 }
41
42 noSubagent := builtToolNames(t, ablation.New(ablation.Subagent))
43 for _, name := range []string{"task", "read_only_task", "parallel_tasks", "fleet"} {
44 if noSubagent[name] {
45 t.Errorf("subagent ablation left %s registered", name)
46 }
47 }
48 if !noSubagent["history"] || !noSubagent["memory"] {
49 t.Error("subagent ablation must not touch the retrieval surfaces")
50 }
51
52 noRetrieval := builtToolNames(t, ablation.New(ablation.Retrieval))
53 for _, name := range []string{"history", "memory"} {
54 if noRetrieval[name] {
55 t.Errorf("retrieval ablation left the BM25-backed %s registered", name)
56 }
57 }
58 for _, name := range []string{"remember", "forget", "list_sessions", "read_session", "task"} {
59 if !noRetrieval[name] {
60 t.Errorf("retrieval ablation dropped %s, which is not a retrieval surface", name)
61 }
62 }
63 }
64
64 lines GO