@monotykamary/pi-vcc 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/npm-shrinkwrap.json +2 -2
  2. package/package.json +1 -1
  3. package/src/core/brief.ts +245 -1
  4. package/src/core/causal-keys.ts +56 -0
  5. package/src/core/summarize.ts +53 -3
  6. package/__tests__/helpers.ts +0 -135
  7. package/__tests__/root-causes.test.ts +0 -858
  8. package/demo.gif +0 -0
  9. package/knip.json +0 -4
  10. package/scripts/audit-sessions.ts +0 -88
  11. package/scripts/benchmark-real-sessions.ts +0 -25
  12. package/scripts/compare-before-after.ts +0 -36
  13. package/scripts/dump-branch-output.ts +0 -20
  14. package/stress-debug.ts +0 -202
  15. package/stress-degradation-curve.ts +0 -251
  16. package/tests/australian-government.test.ts +0 -479
  17. package/tests/before-compact-hook.test.ts +0 -185
  18. package/tests/before-compact.test.ts +0 -227
  19. package/tests/breadcrumbs.test.ts +0 -312
  20. package/tests/brief.test.ts +0 -215
  21. package/tests/build-sections.test.ts +0 -59
  22. package/tests/compile.test.ts +0 -89
  23. package/tests/content.test.ts +0 -66
  24. package/tests/deep-extraction.test.ts +0 -322
  25. package/tests/extract-goals.test.ts +0 -86
  26. package/tests/extract-preferences.test.ts +0 -30
  27. package/tests/filter-noise.test.ts +0 -61
  28. package/tests/fixtures.ts +0 -61
  29. package/tests/format-recall.test.ts +0 -87
  30. package/tests/format.test.ts +0 -73
  31. package/tests/government-domain.test.ts +0 -542
  32. package/tests/lineage.test.ts +0 -33
  33. package/tests/load-messages.test.ts +0 -49
  34. package/tests/model-threshold-hook.test.ts +0 -311
  35. package/tests/model-threshold.test.ts +0 -223
  36. package/tests/normalize.test.ts +0 -104
  37. package/tests/proactive-threshold.test.ts +0 -490
  38. package/tests/real-sessions.test.ts +0 -38
  39. package/tests/recall-expand.test.ts +0 -15
  40. package/tests/recall-scope.test.ts +0 -32
  41. package/tests/recall-tool-scope.test.ts +0 -67
  42. package/tests/render-entries.test.ts +0 -92
  43. package/tests/report.test.ts +0 -58
  44. package/tests/sanitize.test.ts +0 -24
  45. package/tests/search-entries.test.ts +0 -233
  46. package/tests/stress-100-compactions.test.ts +0 -373
  47. package/tests/support/load-session.ts +0 -23
  48. package/tests/support/real-sessions.ts +0 -51
  49. package/tests/threshold-integration.test.ts +0 -335
@@ -1,73 +0,0 @@
1
- import { describe, it, expect } from "bun:test";
2
- import { formatSummary } from "../src/core/format";
3
- import type { SectionData } from "../src/sections";
4
-
5
- const empty: SectionData = {
6
- sessionGoal: [],
7
- outstandingContext: [],
8
- filesAndChanges: [],
9
- commits: [],
10
- userPreferences: [],
11
- typeCatalog: [],
12
- symbolChanges: [],
13
- briefTranscript: "",
14
- transcriptEntries: [],
15
- };
16
-
17
- describe("formatSummary", () => {
18
- it("returns empty string for all-empty sections", () => {
19
- expect(formatSummary(empty)).toBe("");
20
- });
21
-
22
- it("formats a single header section", () => {
23
- const data = {
24
- ...empty,
25
- sessionGoal: ["fix auth bug"],
26
- };
27
- const r = formatSummary(data);
28
- expect(r).toContain("[Session Goal]");
29
- expect(r).toContain("- fix auth bug");
30
- });
31
-
32
- it("separates header and brief transcript with ---", () => {
33
- const data = {
34
- ...empty,
35
- sessionGoal: ["goal"],
36
- briefTranscript: "[user]\ndo something",
37
- };
38
- const r = formatSummary(data);
39
- expect(r).toContain("[Session Goal]");
40
- expect(r).toContain("---");
41
- expect(r).toContain("[user]\ndo something");
42
- });
43
-
44
- it("renders brief transcript alone when no header sections", () => {
45
- const data = {
46
- ...empty,
47
- briefTranscript: "[user]\nhi\n\n[assistant]\nhello",
48
- };
49
- const r = formatSummary(data);
50
- expect(r).toContain("[user]\nhi\n\n[assistant]\nhello");
51
- });
52
-
53
- it("joins multiple header sections with blank line", () => {
54
- const data = {
55
- ...empty,
56
- sessionGoal: ["goal"],
57
- outstandingContext: ["blocker"],
58
- };
59
- const r = formatSummary(data);
60
- expect(r).toContain("[Session Goal]");
61
- expect(r).toContain("[Outstanding Context]");
62
- expect(r).toContain("\n\n");
63
- });
64
-
65
- it("wraps long lines so compaction TUI rendering stays bounded", () => {
66
- const data = {
67
- ...empty,
68
- briefTranscript: `[assistant]\n${"word ".repeat(80)}`,
69
- };
70
- const r = formatSummary(data);
71
- expect(Math.max(...r.split("\n").map((line) => line.length))).toBeLessThanOrEqual(120);
72
- });
73
- });
@@ -1,542 +0,0 @@
1
- import { describe, it, expect } from "bun:test";
2
- import { mkdtempSync, writeFileSync, rmSync } from "fs";
3
- import { tmpdir } from "os";
4
- import { join } from "path";
5
- import { searchEntries } from "../src/core/search-entries";
6
- import { formatRecallOutput } from "../src/core/format-recall";
7
- import { registerRecallTool } from "../src/tools/recall";
8
- import type { RenderedEntry } from "../src/core/render-entries";
9
- import type { Message } from "@earendil-works/pi-ai";
10
- import type { SearchHit } from "../src/core/search-entries";
11
-
12
- // ── Government session fixtures ──
13
-
14
- // Realistic government-conversation entries. High lexical overlap:
15
- // "policy", "document", "review", "compliance", "regulation", "approval"
16
- // appear in most entries — exactly the pattern that caused half-session returns.
17
-
18
- const govEntries: RenderedEntry[] = [
19
- { index: 0, role: "user", summary: "Draft the new information security policy for FY2027" },
20
- { index: 1, role: "assistant", summary: "I'll review the existing policy template and draft the update.", files: ["policies/infosec-2026.md"] },
21
- { index: 2, role: "tool_result", summary: "[Read] policies/infosec-2026.md" },
22
- { index: 3, role: "assistant", summary: "The current policy covers data classification and access control. I'll draft revisions for the new compliance requirements." },
23
- { index: 4, role: "user", summary: "Make sure it complies with OMB Circular A-130 and FedRAMP requirements" },
24
- { index: 5, role: "assistant", summary: "Adding FedRAMP compliance and OMB A-130 references to the policy document.", files: ["policies/infosec-2027.md"] },
25
- { index: 6, role: "tool_result", summary: "[Edit] policies/infosec-2027.md" },
26
- { index: 7, role: "user", summary: "Send the policy document for review by the compliance office" },
27
- { index: 8, role: "assistant", summary: "The policy document has been routed to the compliance review office for approval." },
28
- { index: 9, role: "user", summary: "Update the regulation tracking spreadsheet with the new policy" },
29
- { index: 10, role: "assistant", summary: "Updating the regulation tracking spreadsheet with the new policy entry.", files: ["tracking/regulations-2027.xlsx"] },
30
- { index: 11, role: "tool_result", summary: "[Edit] tracking/regulations-2027.xlsx" },
31
- { index: 12, role: "user", summary: "Review the document clearance procedure memo" },
32
- { index: 13, role: "assistant", summary: "The document clearance procedure requires review by the policy office, compliance division, and legal counsel before approval.", files: ["memos/clearance-procedure.md"] },
33
- { index: 14, role: "tool_result", summary: "[Read] memos/clearance-procedure.md" },
34
- { index: 15, role: "user", summary: "Check if the new policy meets all regulation requirements" },
35
- { index: 16, role: "assistant", summary: "Cross-referencing the policy against all applicable regulation and compliance requirements." },
36
- { index: 17, role: "user", summary: "The compliance office returned the document with comments" },
37
- { index: 18, role: "assistant", summary: "Incorporating compliance office feedback into the policy document. Main comments address review timeline and approval workflow.", files: ["policies/infosec-2027.md"] },
38
- { index: 19, role: "tool_result", summary: "[Edit] policies/infosec-2027.md" },
39
- { index: 20, role: "user", summary: "Submit for final approval through the document management system" },
40
- { index: 21, role: "assistant", summary: "The updated policy document has been submitted through the document management system for final review and approval." },
41
- ];
42
-
43
- const govMessages: Message[] = [
44
- { role: "user", content: "Draft the new information security policy for FY2027" } as any,
45
- { role: "assistant", content: [{ type: "text", text: "I'll review the existing policy template and draft the update." }] } as any,
46
- { role: "toolResult", content: [{ type: "text", text: "Current policy content: data classification, access control, incident response procedures" }], toolName: "Read", isError: false } as any,
47
- { role: "assistant", content: [{ type: "text", text: "The current policy covers data classification and access control. I'll draft revisions for the new compliance requirements." }] } as any,
48
- { role: "user", content: "Make sure it complies with OMB Circular A-130 and FedRAMP requirements" } as any,
49
- { role: "assistant", content: [{ type: "text", text: "Adding FedRAMP compliance and OMB A-130 references to the policy document." }] } as any,
50
- { role: "toolResult", content: [{ type: "text", text: "File edited: added FedRAMP Section 4.2, OMB A-130 compliance annex" }], toolName: "Edit", isError: false } as any,
51
- { role: "user", content: "Send the policy document for review by the compliance office" } as any,
52
- { role: "assistant", content: [{ type: "text", text: "The policy document has been routed to the compliance review office for approval." }] } as any,
53
- { role: "user", content: "Update the regulation tracking spreadsheet with the new policy" } as any,
54
- { role: "assistant", content: [{ type: "text", text: "Updating the regulation tracking spreadsheet with the new policy entry." }] } as any,
55
- { role: "toolResult", content: [{ type: "text", text: "Spreadsheet updated: row added for infosec-2027 policy" }], toolName: "Edit", isError: false } as any,
56
- { role: "user", content: "Review the document clearance procedure memo" } as any,
57
- { role: "assistant", content: [{ type: "text", text: "The document clearance procedure requires review by the policy office, compliance division, and legal counsel before approval." }] } as any,
58
- { role: "toolResult", content: [{ type: "text", text: "Clearance memo: 3-stage review, policy office → compliance → legal approval" }], toolName: "Read", isError: false } as any,
59
- { role: "user", content: "Check if the new policy meets all regulation requirements" } as any,
60
- { role: "assistant", content: [{ type: "text", text: "Cross-referencing the policy against all applicable regulation and compliance requirements." }] } as any,
61
- { role: "user", content: "The compliance office returned the document with comments" } as any,
62
- { role: "assistant", content: [{ type: "text", text: "Incorporating compliance office feedback into the policy document. Main comments address review timeline and approval workflow." }] } as any,
63
- { role: "toolResult", content: [{ type: "text", text: "File edited: addressed compliance comments on review timeline" }], toolName: "Edit", isError: false } as any,
64
- { role: "user", content: "Submit for final approval through the document management system" } as any,
65
- { role: "assistant", content: [{ type: "text", text: "The updated policy document has been submitted through the document management system for final review and approval." }] } as any,
66
- ];
67
-
68
- // ── Session file helpers for integration tests ──
69
-
70
- const register = () => {
71
- let tool: any;
72
- registerRecallTool({ registerTool: (t: any) => { tool = t; } } as any);
73
- return tool;
74
- };
75
-
76
- const makeGovSession = () => {
77
- const dir = mkdtempSync(join(tmpdir(), "pi-vcc-gov-"));
78
- const file = join(dir, "session.jsonl");
79
- const lines = govMessages.map((msg, i) =>
80
- JSON.stringify({ type: "message", id: `m${i}`, message: msg })
81
- );
82
- writeFileSync(file, lines.join("\n") + "\n", "utf8");
83
- return { dir, file };
84
- };
85
-
86
- const invoke = async (tool: any, file: string, params: Record<string, unknown>, branchIds?: string[]) => {
87
- const ids = branchIds ?? govMessages.map((_, i) => `m${i}`);
88
- const result = await tool.execute("tool-call", params, undefined, undefined, {
89
- sessionManager: {
90
- getSessionFile: () => file,
91
- getBranch: () => ids.map((id) => ({ id })),
92
- getEntries: () => ids.map((id) => ({ id })),
93
- },
94
- });
95
- return result.content[0].text as string;
96
- };
97
-
98
- // ── Tests ──
99
-
100
- describe("government domain: searchEntries", () => {
101
- it("high-overlap multi-term query does not return half the session", () => {
102
- // Before the fix, "review policy compliance" would match ~18/22 entries
103
- // because each term alone appears in most government messages.
104
- // With MIN_TERM_MATCH_FOR_MULTITERM=2, only entries matching ≥2 terms qualify.
105
- const r = searchEntries(govEntries, govMessages, "review policy compliance");
106
- // Should be substantially fewer than total session size (22).
107
- // 11/22 is just at 50% — the multi-term floor helps, but this particular
108
- // query has 3 extremely common terms where ≥2 still qualifies most entries.
109
- // The important thing is it's strictly less than 22 (without the fix it was 22).
110
- expect(r.length).toBeLessThan(govEntries.length);
111
- // Every result should match at least 2 of the 3 terms
112
- for (const hit of r) {
113
- expect(hit.matchCount).toBeGreaterThanOrEqual(2);
114
- }
115
- });
116
-
117
- it("all-common-vocabulary query still returns relevant results", () => {
118
- // "document policy review approval" — 4 terms, all extremely common.
119
- // Should still find the most relevant entries, not return nothing or everything.
120
- const r = searchEntries(govEntries, govMessages, "document policy review approval");
121
- expect(r.length).toBeGreaterThan(0);
122
- expect(r.length).toBeLessThan(govEntries.length);
123
- // Best result should be the one matching the most terms
124
- expect(r[0].matchCount).toBeGreaterThanOrEqual(2);
125
- });
126
-
127
- it("specific query (uncommon term) returns narrow results", () => {
128
- // "FedRAMP" is a specific term appearing in only ~2 entries
129
- const r = searchEntries(govEntries, govMessages, "FedRAMP");
130
- expect(r.length).toBeLessThanOrEqual(3);
131
- expect(r.some((h) => h.index === 4 || h.index === 5)).toBe(true);
132
- });
133
-
134
- it("regulation reference regex finds matches", () => {
135
- // Government workers search for regulation citations like "A-130" or "Circular A-.*"
136
- const r = searchEntries(govEntries, govMessages, "A-130");
137
- expect(r.length).toBeGreaterThanOrEqual(1);
138
- });
139
-
140
- it("OMB Circular regex returns targeted results", () => {
141
- const r = searchEntries(govEntries, govMessages, "OMB.*Circular");
142
- expect(r.length).toBeGreaterThanOrEqual(1);
143
- // Should not match unrelated entries
144
- expect(r.every((h) => h.summary.includes("OMB") || h.snippet?.includes("OMB"))).toBe(true);
145
- });
146
-
147
- it("single-common-term 2-word query uses OR (no multi-term floor)", () => {
148
- // 2 terms → floor is 1. "memorandum" appears once, "approval" appears multiple times.
149
- // OR logic: any entry with either term should match.
150
- const r = searchEntries(govEntries, govMessages, "memorandum approval");
151
- expect(r.length).toBeGreaterThan(0);
152
- });
153
-
154
- it("thinking content with government jargon is searchable", () => {
155
- const entries: RenderedEntry[] = [
156
- { index: 0, role: "user", summary: "Update the FISMA report" },
157
- { index: 1, role: "assistant", summary: "Working on FISMA report" },
158
- ];
159
- const msgs: Message[] = [
160
- { role: "user", content: "Update the FISMA report" } as any,
161
- { role: "assistant", content: [
162
- { type: "thinking", thinking: "Need to align with the NIST SP 800-53 control framework before submitting" },
163
- { type: "text", text: "Working on FISMA report" },
164
- ] } as any,
165
- ];
166
- // "NIST" only appears in thinking content — should still be findable
167
- const r = searchEntries(entries, msgs, "NIST 800-53");
168
- expect(r).toHaveLength(1);
169
- expect(r[0].index).toBe(1);
170
- expect(r[0].snippet).toContain("NIST");
171
- });
172
-
173
- it("BM25 score ratio filters tangential mentions", () => {
174
- // Entry #8 mentions "compliance" but is about routing the document.
175
- // Entry #3 discusses compliance requirements in detail.
176
- // A query for "compliance requirements" should rank #3 much higher
177
- // and the score ratio threshold should drop the weakest tangential matches.
178
- const r = searchEntries(govEntries, govMessages, "compliance requirements");
179
- // The detailed match (#3) should be present and ranked highly
180
- expect(r.some((h) => h.index === 3)).toBe(true);
181
- // The top result should be the best match, not just any match.
182
- // Total results should be less than the full session even though
183
- // "compliance" is extremely common in these entries.
184
- expect(r.length).toBeLessThan(govEntries.length);
185
- });
186
-
187
- it("large government session: regex hard cap prevents half-session return", () => {
188
- // Simulate a 200-entry session where every entry mentions "policy document"
189
- const bigEntries: RenderedEntry[] = Array.from({ length: 200 }, (_, i) => ({
190
- index: i,
191
- role: (i % 2 === 0 ? "user" : "assistant") as any,
192
- summary: i % 2 === 0
193
- ? `Review policy document section ${Math.floor(i / 2)} for compliance approval`
194
- : `Processed policy document section ${Math.floor(i / 2)} — review pending`,
195
- }));
196
- const bigMsgs: Message[] = bigEntries.map((e) => ({
197
- role: e.role === "user" ? "user" : "assistant",
198
- content: e.summary,
199
- } as any));
200
-
201
- // Regex that matches everything
202
- const rRegex = searchEntries(bigEntries, bigMsgs, "policy.*document");
203
- expect(rRegex.length).toBeLessThanOrEqual(50);
204
-
205
- // Natural language that would previously match ~200/200
206
- const rNl = searchEntries(bigEntries, bigMsgs, "policy document compliance approval review");
207
- expect(rNl.length).toBeLessThanOrEqual(50);
208
- // With 5 terms → MIN_TERM_MATCH_FOR_MULTITERM=2, every entry matches ≥2
209
- // but the hard cap + score ratio still bound the results
210
- expect(rNl.length).toBeLessThan(bigEntries.length * 0.3);
211
- });
212
- });
213
-
214
- describe("government domain: formatRecallOutput", () => {
215
- it("groups multi-turn policy review into segments", () => {
216
- const hits: SearchHit[] = [
217
- { index: 0, role: "user", summary: "Draft the new information security policy", snippet: "security policy" },
218
- { index: 1, role: "assistant", summary: "I'll review the existing policy template", snippet: undefined },
219
- { index: 7, role: "user", summary: "Send the policy document for review", snippet: undefined },
220
- { index: 8, role: "assistant", summary: "Routed to compliance review office", snippet: undefined },
221
- ];
222
- const r = formatRecallOutput(hits, "policy");
223
- expect(r).toContain("---");
224
- expect(r).toContain("security policy");
225
- });
226
-
227
- it("search output stays bounded for many matched segments", () => {
228
- // Build 20 matching segments (user/assistant pairs about policy)
229
- const hits: SearchHit[] = Array.from({ length: 40 }, (_, i) => ({
230
- index: i,
231
- role: i % 2 === 0 ? "user" : "assistant",
232
- summary: i % 2 === 0
233
- ? `Review policy document ${Math.floor(i / 2)}`
234
- : `Processed policy document ${Math.floor(i / 2)}`,
235
- snippet: "policy",
236
- }));
237
- const r = formatRecallOutput(hits, "policy");
238
- expect(r).toContain("matches");
239
- // Should produce structured output, not an unmanageable wall of text
240
- expect(r.split("---").length).toBeGreaterThan(1);
241
- });
242
- });
243
-
244
- describe("government domain: vcc_recall integration", () => {
245
- it("paginates government vocabulary queries without dumping the session", async () => {
246
- const { dir, file } = makeGovSession();
247
- try {
248
- const tool = register();
249
-
250
- // Query with all-common government vocabulary
251
- const all = await invoke(tool, file, { query: "policy review compliance document" });
252
- // Should show match results, not dump everything at once
253
- expect(all).toMatch(/matches/);
254
- // Page size is 5, so we should see at most 5 result entries per page
255
- const matchLines = all.split("\n").filter((l: string) => /^> #\d+/.test(l.trim()));
256
- expect(matchLines.length).toBeLessThanOrEqual(5);
257
- } finally {
258
- rmSync(dir, { recursive: true, force: true });
259
- }
260
- });
261
-
262
- it("page cap prevents walking through entire session on vague queries", async () => {
263
- const { dir, file } = makeGovSession();
264
- try {
265
- const tool = register();
266
-
267
- // Request a page way beyond the cap
268
- const result = await invoke(tool, file, { query: "policy document review", page: 11 });
269
- expect(result).toContain("Too many results");
270
- expect(result).toContain("more specific query");
271
- } finally {
272
- rmSync(dir, { recursive: true, force: true });
273
- }
274
- });
275
-
276
- it("specific government term returns narrow results", async () => {
277
- const { dir, file } = makeGovSession();
278
- try {
279
- const tool = register();
280
-
281
- // "FedRAMP" is specific — only ~2 entries match
282
- const result = await invoke(tool, file, { query: "FedRAMP" });
283
- expect(result).toContain("matches");
284
- expect(result).toContain("FedRAMP");
285
- // Should NOT show pagination (single page of results)
286
- expect(result).not.toMatch(/Page \d+\/\d+/);
287
- } finally {
288
- rmSync(dir, { recursive: true, force: true });
289
- }
290
- });
291
-
292
- it("regulation citation regex works through integration", async () => {
293
- const { dir, file } = makeGovSession();
294
- try {
295
- const tool = register();
296
-
297
- const result = await invoke(tool, file, { query: "A-130|FedRAMP" });
298
- expect(result).toContain("matches");
299
- expect(result).toMatch(/A-130|FedRAMP/);
300
- } finally {
301
- rmSync(dir, { recursive: true, force: true });
302
- }
303
- });
304
-
305
- it("scope all includes off-lineage government entries", async () => {
306
- const { dir, file } = makeGovSession();
307
- try {
308
- const tool = register();
309
-
310
- // Only first 5 entries are in the active lineage
311
- const lineageIds = govMessages.slice(0, 5).map((_, i) => `m${i}`);
312
- const lineageResult = await invoke(tool, file, { query: "FedRAMP" }, lineageIds);
313
- // FedRAMP is in entry #4 — inside the lineage
314
- expect(lineageResult).toMatch(/matches|FedRAMP/);
315
-
316
- // But entry about OMB A-130 is also #4 (in lineage) and #5 (outside)
317
- const allResult = await invoke(tool, file, { query: "FedRAMP", scope: "all" }, lineageIds);
318
- expect(allResult).toContain("scope: all");
319
- } finally {
320
- rmSync(dir, { recursive: true, force: true });
321
- }
322
- });
323
-
324
- it("no-query browse returns last 25 entries, not the whole session", async () => {
325
- // Build a 60-entry session
326
- const dir = mkdtempSync(join(tmpdir(), "pi-vcc-gov-browse-"));
327
- const file = join(dir, "session.jsonl");
328
- const entries = Array.from({ length: 60 }, (_, i) =>
329
- JSON.stringify({
330
- type: "message",
331
- id: `m${i}`,
332
- message: { role: "user", content: `Policy document review item ${i} for compliance approval` },
333
- })
334
- );
335
- writeFileSync(file, entries.join("\n") + "\n", "utf8");
336
-
337
- try {
338
- const tool = register();
339
- const allIds = Array.from({ length: 60 }, (_, i) => `m${i}`);
340
- const rawResult = await tool.execute("tool-call", {}, undefined, undefined, {
341
- sessionManager: {
342
- getSessionFile: () => file,
343
- getBranch: () => allIds.map((id) => ({ id })),
344
- getEntries: () => allIds.map((id) => ({ id })),
345
- },
346
- });
347
- const result = rawResult.content[0].text as string;
348
- // DEFAULT_RECENT = 25, so at most 25 entries returned
349
- const indexLines = result.split("\n").filter((l: string) => /^#\d+/.test(l.trim()));
350
- expect(indexLines.length).toBeLessThanOrEqual(25);
351
- // Should start past the midpoint of the session, not at #0
352
- const firstIndex = parseInt(indexLines[0]?.match(/#(\d+)/)?.[1] ?? "0");
353
- expect(firstIndex).toBeGreaterThan(30);
354
- // Should NOT include entry #0
355
- expect(result).not.toContain("#0 [user]");
356
- } finally {
357
- rmSync(dir, { recursive: true, force: true });
358
- }
359
- });
360
-
361
- it("expand returns full content for specific government entries", async () => {
362
- const { dir, file } = makeGovSession();
363
- try {
364
- const tool = register();
365
-
366
- const result = await invoke(tool, file, { expand: [0] });
367
- expect(result).toContain("#0 [user]");
368
- expect(result).toContain("information security policy");
369
- } finally {
370
- rmSync(dir, { recursive: true, force: true });
371
- }
372
- });
373
- });
374
-
375
- describe("government domain: stress scenarios", () => {
376
- it("cross-referenced regulation query in verbose session", () => {
377
- // Simulate a session where an agent is cross-referencing multiple
378
- // regulations across many documents. Every entry mentions "regulation"
379
- // or "compliance" but specific regulation IDs are rare.
380
- const entries: RenderedEntry[] = [
381
- { index: 0, role: "user", summary: "Cross-reference FISMA with NIST SP 800-53" },
382
- { index: 1, role: "assistant", summary: "Reviewing FISMA requirements against NIST SP 800-53 control catalog for compliance alignment." },
383
- { index: 2, role: "tool_result", summary: "[Read] regulations/fisma-2027.txt" },
384
- { index: 3, role: "assistant", summary: "FISMA Section 3.2 maps to NIST controls AC-2, AU-1, and CA-7." },
385
- { index: 4, role: "user", summary: "Now check HIPAA compliance against the same regulation framework" },
386
- { index: 5, role: "assistant", summary: "Cross-referencing HIPAA Security Rule with NIST SP 800-66 for compliance." },
387
- { index: 6, role: "tool_result", summary: "[Read] regulations/hipaa-security-rule.txt" },
388
- { index: 7, role: "assistant", summary: "HIPAA §164.312 maps to NIST controls AC-3, AU-9, and SC-8." },
389
- { index: 8, role: "user", summary: "Generate compliance gap analysis document" },
390
- { index: 9, role: "assistant", summary: "Generating compliance gap analysis across FISMA, HIPAA, and NIST frameworks.", files: ["reports/compliance-gap-analysis.md"] },
391
- { index: 10, role: "tool_result", summary: "[Write] reports/compliance-gap-analysis.md" },
392
- { index: 11, role: "assistant", summary: "Compliance gap analysis document created. 3 gaps identified in access control and audit regulation." },
393
- ];
394
- const msgs: Message[] = [
395
- { role: "user", content: "Cross-reference FISMA with NIST SP 800-53" } as any,
396
- { role: "assistant", content: [{ type: "text", text: "Reviewing FISMA requirements against NIST SP 800-53 control catalog for compliance alignment." }] } as any,
397
- { role: "toolResult", content: [{ type: "text", text: "FISMA implementation guidance for 2027" }], toolName: "Read", isError: false } as any,
398
- { role: "assistant", content: [{ type: "text", text: "FISMA Section 3.2 maps to NIST controls AC-2, AU-1, and CA-7." }] } as any,
399
- { role: "user", content: "Now check HIPAA compliance against the same regulation framework" } as any,
400
- { role: "assistant", content: [{ type: "text", text: "Cross-referencing HIPAA Security Rule with NIST SP 800-66 for compliance." }] } as any,
401
- { role: "toolResult", content: [{ type: "text", text: "HIPAA Security Rule provisions" }], toolName: "Read", isError: false } as any,
402
- { role: "assistant", content: [{ type: "text", text: "HIPAA §164.312 maps to NIST controls AC-3, AU-9, and SC-8." }] } as any,
403
- { role: "user", content: "Generate compliance gap analysis document" } as any,
404
- { role: "assistant", content: [{ type: "text", text: "Generating compliance gap analysis across FISMA, HIPAA, and NIST frameworks." }] } as any,
405
- { role: "toolResult", content: [{ type: "text", text: "File written successfully" }], toolName: "Write", isError: false } as any,
406
- { role: "assistant", content: [{ type: "text", text: "Compliance gap analysis document created. 3 gaps identified in access control and audit regulation." }] } as any,
407
- ];
408
-
409
- // Specific regulation ID should find the right entries
410
- const fisma = searchEntries(entries, msgs, "HIPAA §164");
411
- expect(fisma.length).toBeGreaterThan(0);
412
- expect(fisma.some((h) => h.index === 7)).toBe(true);
413
-
414
- // "compliance NIST regulation" — 3 terms → ≥2 required
415
- // This would previously match almost every entry
416
- const broad = searchEntries(entries, msgs, "compliance NIST regulation");
417
- expect(broad.length).toBeLessThan(entries.length);
418
- expect(broad.length).toBeGreaterThan(0);
419
- // Top result should be about cross-referencing (hits all 3 terms)
420
- expect(broad[0].matchCount).toBeGreaterThanOrEqual(2);
421
- });
422
-
423
- it("approval-chain session: workflow state queries", () => {
424
- // Government approval chains: each step mentions "approval" and "review"
425
- // but the specific step differs.
426
- const entries: RenderedEntry[] = [
427
- { index: 0, role: "user", summary: "Submit travel authorization for approval" },
428
- { index: 1, role: "assistant", summary: "Travel authorization TA-2027-0442 submitted for supervisor review and approval." },
429
- { index: 2, role: "user", summary: "Check the approval status of TA-2027-0442" },
430
- { index: 3, role: "assistant", summary: "TA-2027-0442 is pending review by direct supervisor. Approval chain: supervisor → division chief → finance office." },
431
- { index: 4, role: "user", summary: "Supervisor approved — route to division chief" },
432
- { index: 5, role: "assistant", summary: "TA-2027-0442 routed to division chief for review and approval. Current status: 1 of 3 approvals completed." },
433
- { index: 6, role: "user", summary: "Division chief returned it — needs updated cost estimate" },
434
- { index: 7, role: "assistant", summary: "TA-2027-0442 returned for revision. Updated cost estimate required before resubmission for approval." },
435
- { index: 8, role: "user", summary: "Updated — resubmit for approval" },
436
- { index: 9, role: "assistant", summary: "TA-2027-0442 resubmitted. Approval chain restarted: supervisor review → division chief → finance approval." },
437
- ];
438
- const msgs: Message[] = entries.map((e) => ({
439
- role: e.role === "user" ? "user" : "assistant" as any,
440
- content: e.summary,
441
- } as any));
442
-
443
- // Specific tracking ID
444
- const byId = searchEntries(entries, msgs, "TA-2027-0442");
445
- expect(byId.length).toBeGreaterThanOrEqual(3);
446
- expect(byId.every((h) => h.summary.includes("TA-2027-0442"))).toBe(true);
447
-
448
- // "approval review" — 2 terms, no floor. Would previously match nearly
449
- // every entry. Score ratio should keep results reasonable.
450
- const generic = searchEntries(entries, msgs, "approval review status");
451
- expect(generic.length).toBeLessThan(entries.length);
452
- expect(generic.length).toBeGreaterThan(0);
453
- });
454
-
455
- it("long-form policy document content: clip boundary search", () => {
456
- // Government documents are long. Important terms may be beyond the
457
- // 300-char clip boundary in rendered summaries. Search must use
458
- // the full message content.
459
- const longPolicy =
460
- "SECTION 1. PURPOSE AND SCOPE\n" +
461
- "This policy establishes the framework for information security\n" +
462
- "management across all departmental units. It applies to all\n" +
463
- "employees, contractors, and affiliated personnel.\n\n".repeat(10) +
464
- "SECTION 4. SPECIAL ACCESS PROGRAM (SAP) PROVISIONS\n" +
465
- "Personnel requiring access to Special Access Program\n" +
466
- "information must complete SAP indoctrination briefing per\n" +
467
- "DoD Manual 5205.07 Volume 2 before being granted access.\n" +
468
- "SAP compliance violations are subject to investigation under\n" +
469
- "DoDI 5205.11 and may result in access termination.\n\n".repeat(5);
470
-
471
- const entries: RenderedEntry[] = [
472
- { index: 0, role: "user", summary: "Discuss the SAP provisions in the security policy" },
473
- { index: 1, role: "assistant", summary: longPolicy.slice(0, 300) }, // clipped summary
474
- ];
475
- const msgs: Message[] = [
476
- { role: "user", content: "Discuss the SAP provisions in the security policy" } as any,
477
- { role: "assistant", content: [{ type: "text", text: longPolicy }] } as any,
478
- ];
479
-
480
- // "SAP indoctrination" is well beyond the 300-char clip boundary.
481
- // Both entries are returned because #0 also contains "SAP provisions" matching
482
- // the first query term. This is correct OR behavior for a 2-term query.
483
- const r = searchEntries(entries, msgs, "SAP indoctrination");
484
- expect(r.length).toBeGreaterThanOrEqual(1);
485
- // The long document (#1) should be the top result (both terms match)
486
- expect(r[0].index).toBe(1);
487
- expect(r[0].snippet).toContain("SAP");
488
- });
489
-
490
- it("memo and directive numbering: regex on government citation patterns", () => {
491
- const entries: RenderedEntry[] = [
492
- { index: 0, role: "user", summary: "Find all references to DoD Directive 5200.01" },
493
- { index: 1, role: "assistant", summary: "DoD Directive 5200.01 is referenced in 3 policy documents." },
494
- { index: 2, role: "user", summary: "Now check DoD Instruction 5205.11" },
495
- { index: 3, role: "assistant", summary: "DoD Instruction 5205.11 covers SAP investigation procedures." },
496
- { index: 4, role: "user", summary: "What about DoD Manual 5205.07?" },
497
- { index: 5, role: "assistant", summary: "DoD Manual 5205.07 Volume 2 covers SAP indoctrination briefing requirements." },
498
- ];
499
- const msgs: Message[] = entries.map((e) => ({
500
- role: e.role === "user" ? "user" : "assistant" as any,
501
- content: e.summary,
502
- } as any));
503
-
504
- // Match any DoD 5200-5205 series citation
505
- const r = searchEntries(entries, msgs, "DoD.*520[0-5]");
506
- expect(r.length).toBeGreaterThanOrEqual(3);
507
-
508
- // Specific directive number
509
- const r2 = searchEntries(entries, msgs, "5200.01");
510
- expect(r2).toHaveLength(2);
511
- });
512
-
513
- it("mixed acronyms in government session: FISMA vs FedRAMP vs FIPS", () => {
514
- const entries: RenderedEntry[] = [
515
- { index: 0, role: "user", summary: "Map FISMA controls to our system" },
516
- { index: 1, role: "assistant", summary: "FISMA compliance requires annual assessment under NIST SP 800-53." },
517
- { index: 2, role: "user", summary: "Also check FedRAMP authorization status" },
518
- { index: 3, role: "assistant", summary: "FedRAMP authorization is separate from FISMA but shares NIST control baselines." },
519
- { index: 4, role: "user", summary: "Validate FIPS 140-2 compliance for cryptographic modules" },
520
- { index: 5, role: "assistant", summary: "FIPS 140-2 validation is required for all cryptographic modules per OMB policy." },
521
- ];
522
- const msgs: Message[] = entries.map((e) => ({
523
- role: e.role === "user" ? "user" : "assistant" as any,
524
- content: e.summary,
525
- } as any));
526
-
527
- // Each acronym has distinct entries — search should be discriminate
528
- const fisma = searchEntries(entries, msgs, "FISMA");
529
- expect(fisma.length).toBeGreaterThanOrEqual(2);
530
-
531
- const fedramp = searchEntries(entries, msgs, "FedRAMP");
532
- expect(fedramp.length).toBeLessThanOrEqual(2);
533
-
534
- const fips = searchEntries(entries, msgs, "FIPS 140");
535
- expect(fips.length).toBeLessThanOrEqual(2);
536
-
537
- // Broad query: "compliance authorization" — 2 terms, common in gov
538
- // Should not dump the whole session
539
- const broad = searchEntries(entries, msgs, "compliance authorization assessment");
540
- expect(broad.length).toBeLessThan(entries.length);
541
- });
542
- });
@@ -1,33 +0,0 @@
1
- import { describe, it, expect } from "bun:test";
2
- import { getActiveLineageEntryIds } from "../src/core/lineage";
3
-
4
- describe("getActiveLineageEntryIds", () => {
5
- it("returns IDs from active branch", () => {
6
- const ids = getActiveLineageEntryIds({
7
- getBranch: () => [{ id: "a" }, { id: "b" }, { id: "c" }],
8
- });
9
- expect([...ids]).toEqual(["a", "b", "c"]);
10
- });
11
-
12
- it("falls back to getEntries when getBranch throws", () => {
13
- const ids = getActiveLineageEntryIds({
14
- getBranch: () => {
15
- throw new Error("boom");
16
- },
17
- getEntries: () => [{ id: "x" }, { id: "y" }],
18
- });
19
- expect([...ids]).toEqual(["x", "y"]);
20
- });
21
-
22
- it("returns empty set when both branch and entries are unavailable", () => {
23
- const ids = getActiveLineageEntryIds({
24
- getBranch: () => {
25
- throw new Error("boom");
26
- },
27
- getEntries: () => {
28
- throw new Error("boom2");
29
- },
30
- });
31
- expect(ids.size).toBe(0);
32
- });
33
- });