/** * KHAELOR * File: tests/memory/memory.test.ts * Description: Project-memory tests — parse/append round-trip, provenance anchors, purge candidates (v2 §5). * * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai */ import { describe, expect, it } from "vitest"; import { appendMemoryEntry, parseMemory, purgeCandidates } from "../../src/memory/index.js"; const PROVENANCE = { session: "01ABCDEF", tool: "toolu_1", confidence: "high" as const, date: "2026-08-10", }; describe("project memory", () => { it("creates the file with a header and section on first append", () => { const content = appendMemoryEntry(null, { section: "conventions", text: "Errors flow through Result, never throw in src/core.", provenance: PROVENANCE, }); expect(content).toContain("# Project memory"); expect(content).toContain("## Conventions"); expect(content).toContain("- Errors flow through Result"); expect(content).toContain(""); }); it("round-trips entries with provenance through parseMemory", () => { let content = appendMemoryEntry(null, { section: "commands", text: "Build: npm run check", provenance: PROVENANCE }); content = appendMemoryEntry(content, { section: "pitfalls", text: "Never touch the render buffer outside the 16ms tick.", provenance: { ...PROVENANCE, confidence: "medium" }, }); const entries = parseMemory(content); expect(entries).toHaveLength(2); expect(entries[0]?.section).toBe("Commands"); expect(entries[0]?.provenance?.confidence).toBe("high"); expect(entries[1]?.section).toBe("Pitfalls"); expect(entries[1]?.provenance?.tool).toBe("toolu_1"); }); it("appends into an existing section, not a duplicate one", () => { let content = appendMemoryEntry(null, { section: "commands", text: "Build: npm run check", provenance: PROVENANCE }); content = appendMemoryEntry(content, { section: "commands", text: "Test: npm test", provenance: PROVENANCE }); expect(content.match(/## Commands/g)).toHaveLength(1); const entries = parseMemory(content); expect(entries.filter((entry) => entry.section === "Commands")).toHaveLength(2); }); it("flags low-confidence entries as purge candidates (v2 §5.4)", () => { let content = appendMemoryEntry(null, { section: "notes", text: "Solid fact.", provenance: PROVENANCE }); content = appendMemoryEntry(content, { section: "notes", text: "Shaky guess.", provenance: { ...PROVENANCE, confidence: "low" }, }); const candidates = purgeCandidates(parseMemory(content)); expect(candidates).toHaveLength(1); expect(candidates[0]?.text).toContain("Shaky guess"); }); });