Forge
csharpc0b81713
1using AgentNotes.Core;
2using System.Text;
3using System.Text.Json;
4
5namespace AgentNotesMcp.Tests;
6
7public sealed class KnowledgeRootsRouteContextTests
8{
9 [Fact]
10 public void RouteContext_IncludesKnowledgeRootsOverlay_WhenRegistryMatchesGroupQuery()
11 {
12 using var primary = LocalSettingsLoaderTests.TempKnowledgeRoot.Create();
13 using var group = MultiRootKnowledgeTests.CreateGroupKbRootPublic();
14 using var runtime = MultiRootKnowledgeTests.InstallWithReadOnlyPublic(primary.Path, group.Path);
15 SeedKnowledgeRootsRouting(primary.Path);
16
17 var storage = new NotesStorage();
18 var workspace = Path.Combine(Path.GetTempPath(), "AgentNotesMcpTests", Guid.NewGuid().ToString("N"));
19 Directory.CreateDirectory(workspace);
20
21 var json = storage.RouteContext(workspace, "group smoke test", null, maxSections: 6, maxChars: 12000);
22 using var doc = JsonDocument.Parse(json);
23 var root = doc.RootElement;
24
25 Assert.True(root.GetProperty("knowledge_roots_overlay_applied").GetBoolean());
26 Assert.True(root.GetProperty("knowledge_roots_registry_hits").GetInt32() >= 1);
27
28 var assembled = root.GetProperty("assembled_context").GetString() ?? "";
29 Assert.Contains("knowledge-roots-routing-v1", assembled);
30 Assert.Contains("knowledge_root_id=group", assembled, StringComparison.Ordinal);
31 Assert.Contains("group-kb smoke", assembled, StringComparison.OrdinalIgnoreCase);
32 }
33
34 [Fact]
35 public void RouteContext_IncludesPrefixRegistry_WhenQueryMatchesCatalogSegment()
36 {
37 using var primary = LocalSettingsLoaderTests.TempKnowledgeRoot.Create();
38 using var group = CreateGroupKbWithOpenStackPrefix();
39 using var runtime = MultiRootKnowledgeTests.InstallWithReadOnlyPublic(primary.Path, group.Path);
40 SeedKnowledgeRootsRoutingWithPrefix(primary.Path);
41
42 var storage = new NotesStorage();
43 var workspace = Path.Combine(Path.GetTempPath(), "AgentNotesMcpTests", Guid.NewGuid().ToString("N"));
44 Directory.CreateDirectory(workspace);
45
46 var json = storage.RouteContext(workspace, "aiguiders-open mission cards", null, maxSections: 8, maxChars: 12000);
47 using var doc = JsonDocument.Parse(json);
48 var root = doc.RootElement;
49
50 Assert.True(root.GetProperty("knowledge_roots_overlay_applied").GetBoolean());
51 Assert.True(root.GetProperty("knowledge_roots_registry_hits").GetInt32() >= 1);
52
53 var assembled = root.GetProperty("assembled_context").GetString() ?? "";
54 Assert.Contains("Prefix:", assembled, StringComparison.Ordinal);
55 Assert.Contains("aiguiders-open", assembled, StringComparison.OrdinalIgnoreCase);
56 Assert.Contains("open-stack hub", assembled, StringComparison.OrdinalIgnoreCase);
57 }
58
59 [Fact]
60 public void RouteContext_NoOverlay_WhenUnrelatedQueryAndNoRegistryMatch()
61 {
62 using var primary = LocalSettingsLoaderTests.TempKnowledgeRoot.Create();
63 using var group = MultiRootKnowledgeTests.CreateGroupKbRootPublic();
64 using var runtime = MultiRootKnowledgeTests.InstallWithReadOnlyPublic(primary.Path, group.Path);
65 SeedKnowledgeRootsRouting(primary.Path);
66
67 var storage = new NotesStorage();
68 var workspace = Path.Combine(Path.GetTempPath(), "AgentNotesMcpTests", Guid.NewGuid().ToString("N"));
69 Directory.CreateDirectory(workspace);
70
71 Assert.Equal("OK", storage.UpsertSection(workspace, "current-task", "Ship release flow for unrelated feature"));
72
73 var json = storage.RouteContext(workspace, "release flow", null, maxSections: 3, maxChars: 5000);
74 using var doc = JsonDocument.Parse(json);
75 var root = doc.RootElement;
76
77 Assert.False(root.GetProperty("knowledge_roots_overlay_applied").GetBoolean());
78 var assembled = root.GetProperty("assembled_context").GetString() ?? "";
79 Assert.DoesNotContain("knowledge_root_id=group", assembled);
80 }
81
82 private static MultiRootKnowledgeTests.GroupKbRoot CreateGroupKbWithOpenStackPrefix()
83 {
84 var path = Path.Combine(Path.GetTempPath(), "AgentNotesMcpTests", "group-kb", Guid.NewGuid().ToString("N"));
85 var openDir = Path.Combine(path, "knowledge", "work", "projects", "aiguiders-open");
86 Directory.CreateDirectory(Path.Combine(path, "knowledge", "group"));
87 Directory.CreateDirectory(openDir);
88 File.WriteAllText(
89 Path.Combine(path, "knowledge", "group", "smoke-test-v1.md"),
90 "# Group KB smoke\n\ngroup-kb smoke test content.\n",
91 Encoding.UTF8);
92 File.WriteAllText(
93 Path.Combine(openDir, "README.md"),
94 "# Open stack hub\n\nopen-stack hub for tests.\n",
95 Encoding.UTF8);
96 File.WriteAllText(Path.Combine(path, "agent-notes.md"), "# Group hot (stub)\n", Encoding.UTF8);
97 return new MultiRootKnowledgeTests.GroupKbRoot(path);
98 }
99
100 private static void SeedKnowledgeRootsRouting(string primaryPath) =>
101 WriteKnowledgeRootsIndex(primaryPath, "group/smoke-test-v1.md => group\n");
102
103 private static void SeedKnowledgeRootsRoutingWithPrefix(string primaryPath) =>
104 WriteKnowledgeRootsIndex(
105 primaryPath,
106 """
107 group/smoke-test-v1.md => group
108 work/projects/aiguiders-open/ => group
109 """);
110
111 private static void WriteKnowledgeRootsIndex(string primaryPath, string body)
112 {
113 Directory.CreateDirectory(Path.Combine(primaryPath, "knowledge", "work", "local"));
114 File.WriteAllText(
115 Path.Combine(primaryPath, "knowledge", "work", "local", "knowledge-roots-index-v1.md"),
116 body,
117 Encoding.UTF8);
118
119 File.WriteAllText(
120 Path.Combine(primaryPath, "agent-notes.md"),
121 """
122 <!-- section:knowledge-roots-routing-v1 -->
123 chmod ugo: group=read-only via knowledge_root_id=group; user=primary writes.
124 Registry: work/local/knowledge-roots-index-v1.md
125 <!-- /section:knowledge-roots-routing-v1 -->
126 <!-- section:current-task -->
127 unrelated default task
128 <!-- /section:current-task -->
129 """,
130 Encoding.UTF8);
131 }
132}
133
View only · write via MCP/CIDE