import { describe, expect, it } from "vitest"; import { RicciGraphAnalytics } from "./graph-analytics.js"; import type { OmegaSelfTimeKernelState } from "./self-time-kernel.js"; function makeKernel( files: OmegaSelfTimeKernelState["causalGraph"]["files"], edges: OmegaSelfTimeKernelState["causalGraph"]["edges"], ): OmegaSelfTimeKernelState { return { revision: 2, sessionKey: "agent:test:main", turnCount: 4, identity: { continuityId: "cont-1", firstSeenAt: 1, lastSeenAt: 4, }, world: { lastObservedChangedFiles: [], }, goals: [], tension: { openGoalCount: 0, staleGoalCount: 0, failureStreak: 0, repeatedFailureKinds: [], pendingCorrection: false, }, causalGraph: { files, edges, }, updatedAt: 4, }; } describe("RicciGraphAnalytics", () => { it("prioritizes low-success bottlenecks over busy but mostly successful files", () => { const kernel = makeKernel( [ { path: "src/busy.ts", writeCount: 6, failureCount: 2 }, { path: "src/bottleneck.ts", writeCount: 0, failureCount: 1 }, ], [ { goalId: "g1", filePath: "src/busy.ts", relation: "goal_targets_file", updatedAt: 1, updatedTurn: 1, }, { goalId: "g2", filePath: "src/busy.ts", relation: "goal_failed_on_file", updatedAt: 2, updatedTurn: 2, }, { goalId: "g3", filePath: "src/bottleneck.ts", relation: "goal_failed_on_file", updatedAt: 3, updatedTurn: 3, }, ], ); const recommendation = RicciGraphAnalytics.getFocusRecommendation(kernel); expect(recommendation).toContain("src/bottleneck.ts"); }); it("returns null when no file crosses the bottleneck threshold", () => { const kernel = makeKernel( [ { path: "src/stable.ts", writeCount: 4, failureCount: 0 }, { path: "src/healthy.ts", writeCount: 3, failureCount: 0 }, ], [ { goalId: "g1", filePath: "src/stable.ts", relation: "goal_wrote_file", updatedAt: 1, updatedTurn: 1, }, ], ); const recommendation = RicciGraphAnalytics.getFocusRecommendation(kernel); expect(recommendation).toBeNull(); }); it("sorts the most negative-curvature file first", () => { const kernel = makeKernel( [ { path: "src/stable.ts", writeCount: 3, failureCount: 0 }, { path: "src/failing.ts", writeCount: 0, failureCount: 1 }, ], [ { goalId: "g1", filePath: "src/failing.ts", relation: "goal_failed_on_file", updatedAt: 1, updatedTurn: 1, }, ], ); const analysis = RicciGraphAnalytics.analyze(kernel); expect(analysis[0]?.path).toBe("src/failing.ts"); expect((analysis[0]?.curvature ?? 0) < (analysis[1]?.curvature ?? 0)).toBe(true); }); });