recallnest 1.4.1 → 2.2.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 (166) hide show
  1. package/.dockerignore +11 -0
  2. package/CLAUDE.md +7 -3
  3. package/Dockerfile +20 -0
  4. package/README.md +202 -130
  5. package/README_CN.md +263 -190
  6. package/ROADMAP.md +128 -81
  7. package/SKILL.md +250 -0
  8. package/assets/dashboard.png +0 -0
  9. package/assets/knowledge-graph.png +0 -0
  10. package/assets/screenshots/ui-full.png +0 -0
  11. package/assets/screenshots/ui-overview.png +0 -0
  12. package/assets/screenshots/ui-search.png +0 -0
  13. package/assets/ui/app.js +227 -3
  14. package/assets/ui/index.html +81 -11
  15. package/assets/ui/styles.css +178 -2
  16. package/bin/recallnest.mjs +62 -0
  17. package/bun.lock +337 -0
  18. package/daily-recall.sh +23 -0
  19. package/daily-reflections/2026-04-02.md +35 -0
  20. package/daily-reflections/2026-04-03.md +37 -0
  21. package/daily-reflections/2026-04-04.md +37 -0
  22. package/daily-reflections/2026-04-05.md +35 -0
  23. package/daily-reflections/2026-04-06.md +36 -0
  24. package/daily-reflections/2026-04-07.md +35 -0
  25. package/daily-reflections/2026-04-08.md +35 -0
  26. package/daily-reflections/2026-04-12.md +35 -0
  27. package/data/alias-map.example.json +22 -0
  28. package/docs/plans/2026-04-01-recall-boost.md +100 -0
  29. package/docs/superpowers/plans/2026-04-11-constructive-retrieval-emotion.md +1195 -0
  30. package/docs/superpowers/specs/2026-04-11-constructive-retrieval-emotion-design.md +398 -0
  31. package/glama.json +6 -0
  32. package/integrations/setup-all.sh +31 -0
  33. package/package.json +10 -3
  34. package/plan-philosophy-upgrades.md +363 -0
  35. package/plan-product-upgrades.md +155 -0
  36. package/plan.md +140 -0
  37. package/research-memory-evolution.md +440 -0
  38. package/research-rl-agent-memory.md +330 -0
  39. package/scripts/backfill-anchors.ts +130 -0
  40. package/scripts/diagnose-vector-search.ts +132 -0
  41. package/scripts/migrate-language.ts +75 -0
  42. package/scripts/verify-emotion-decay.ts +148 -0
  43. package/src/__tests__/activity-counter.test.ts +96 -0
  44. package/src/__tests__/admission-control.test.ts +206 -0
  45. package/src/__tests__/anchor-generator.test.ts +67 -0
  46. package/src/__tests__/babel-integration.test.ts +139 -0
  47. package/src/__tests__/capture-engine.test.ts +5 -3
  48. package/src/__tests__/cascade-forget.test.ts +1 -1
  49. package/src/__tests__/cc8-cc1-essential-context.test.ts +298 -0
  50. package/src/__tests__/circuit-breaker.test.ts +99 -0
  51. package/src/__tests__/cluster-consolidation.test.ts +712 -0
  52. package/src/__tests__/confidence-metadata.test.ts +125 -0
  53. package/src/__tests__/confidence-tracker.test.ts +53 -0
  54. package/src/__tests__/consolidation-engine.test.ts +1 -1
  55. package/src/__tests__/constructive-retrieval.test.ts +509 -0
  56. package/src/__tests__/context-collapse-renderer.test.ts +214 -0
  57. package/src/__tests__/context-reconstructor.test.ts +65 -0
  58. package/src/__tests__/conversation-importer.test.ts +692 -0
  59. package/src/__tests__/data-checkup.test.ts +225 -0
  60. package/src/__tests__/decay-exemption.test.ts +84 -0
  61. package/src/__tests__/dedup-guard.test.ts +39 -0
  62. package/src/__tests__/distill-lock.test.ts +176 -0
  63. package/src/__tests__/dream-pipeline.test.ts +232 -0
  64. package/src/__tests__/emotion-decay.test.ts +46 -0
  65. package/src/__tests__/emotion-detector.test.ts +56 -0
  66. package/src/__tests__/emotion-phase1-integration.test.ts +153 -0
  67. package/src/__tests__/emotion-retrieval.test.ts +56 -0
  68. package/src/__tests__/ethics-layer.test.ts +476 -0
  69. package/src/__tests__/feature-flags-integration.test.ts +54 -0
  70. package/src/__tests__/frequency-tracker.test.ts +113 -0
  71. package/src/__tests__/graph-export.test.ts +489 -0
  72. package/src/__tests__/interference-detector.test.ts +203 -0
  73. package/src/__tests__/mcp-efficiency.test.ts +288 -0
  74. package/src/__tests__/memory-evolution-b2-b3-e1.test.ts +243 -0
  75. package/src/__tests__/memory-evolution.test.ts +271 -0
  76. package/src/__tests__/memory-lint.test.ts +271 -0
  77. package/src/__tests__/narrative-architecture.test.ts +456 -0
  78. package/src/__tests__/pending-review.test.ts +77 -0
  79. package/src/__tests__/post-retrieval-filter.test.ts +178 -0
  80. package/src/__tests__/prediction-engine.test.ts +349 -0
  81. package/src/__tests__/predictive-prospective-memory.test.ts +416 -0
  82. package/src/__tests__/preference-slots.test.ts +99 -0
  83. package/src/__tests__/query-expander-alias.test.ts +89 -0
  84. package/src/__tests__/recall-governor.test.ts +227 -0
  85. package/src/__tests__/resume-context.test.ts +156 -1
  86. package/src/__tests__/salience-scoring.test.ts +106 -0
  87. package/src/__tests__/session-distiller.test.ts +611 -0
  88. package/src/__tests__/skill-engine.test.ts +546 -0
  89. package/src/__tests__/skill-promotion.test.ts +349 -0
  90. package/src/__tests__/supersede-chain.test.ts +154 -0
  91. package/src/__tests__/temporal-validity.test.ts +160 -0
  92. package/src/__tests__/topic-tag.test.ts +113 -0
  93. package/src/__tests__/trusted-memory.test.ts +828 -0
  94. package/src/__tests__/write-verifier.test.ts +122 -0
  95. package/src/access-tracker.ts +3 -2
  96. package/src/activity-counter.ts +109 -0
  97. package/src/adaptive-retrieval.ts +6 -5
  98. package/src/admission-control.ts +163 -0
  99. package/src/anchor-generator.ts +80 -0
  100. package/src/api-server.ts +10 -0
  101. package/src/audit-log.ts +122 -0
  102. package/src/auto-gc.ts +98 -29
  103. package/src/auto-recall.ts +33 -4
  104. package/src/capture-engine.ts +372 -23
  105. package/src/cascade-forget.ts +3 -2
  106. package/src/cli.ts +107 -5
  107. package/src/compat.ts +22 -0
  108. package/src/confidence-tracker.ts +210 -47
  109. package/src/conflict-store.ts +12 -3
  110. package/src/consolidation-engine.ts +296 -8
  111. package/src/context-collapse-renderer.ts +222 -0
  112. package/src/context-composer-stable-selection.ts +5 -1
  113. package/src/context-composer.ts +239 -4
  114. package/src/context-reconstructor.ts +404 -0
  115. package/src/conversation-importer.ts +441 -0
  116. package/src/data-checkup.ts +232 -0
  117. package/src/decay-engine.ts +84 -0
  118. package/src/distill-lock.ts +122 -0
  119. package/src/doctor.ts +8 -10
  120. package/src/dream-pipeline.ts +227 -0
  121. package/src/emotion-detector.ts +90 -0
  122. package/src/eval.ts +3 -2
  123. package/src/forget-engine.ts +269 -0
  124. package/src/frequency-tracker.ts +175 -0
  125. package/src/graph-export.ts +644 -0
  126. package/src/ingest.ts +36 -6
  127. package/src/interference-detector.ts +187 -0
  128. package/src/kg-extractor.ts +15 -24
  129. package/src/kg-store.ts +2 -1
  130. package/src/language-hook.ts +67 -0
  131. package/src/llm-client.ts +289 -6
  132. package/src/mcp-server.ts +707 -80
  133. package/src/memory-assets.ts +22 -5
  134. package/src/memory-evolution.ts +365 -0
  135. package/src/memory-lint.ts +429 -0
  136. package/src/memory-output.ts +69 -0
  137. package/src/memory-schema.ts +74 -2
  138. package/src/narrative-schema.ts +79 -0
  139. package/src/narrative-tagger.ts +164 -0
  140. package/src/pii-detector.ts +98 -0
  141. package/src/post-retrieval-filter.ts +76 -0
  142. package/src/prediction-engine.ts +253 -0
  143. package/src/preference-slots.ts +65 -2
  144. package/src/prospective-memory.ts +215 -0
  145. package/src/query-expander.ts +67 -0
  146. package/src/recall-governor.ts +183 -0
  147. package/src/retention-policy.ts +90 -0
  148. package/src/retriever.ts +828 -55
  149. package/src/rif.ts +34 -8
  150. package/src/runtime-config.ts +23 -8
  151. package/src/scope-inventory.ts +4 -3
  152. package/src/scope-policy.ts +4 -0
  153. package/src/session-distiller.ts +307 -0
  154. package/src/session-output.ts +40 -0
  155. package/src/session-schema.ts +37 -0
  156. package/src/session-store.ts +7 -2
  157. package/src/skill-engine.ts +208 -0
  158. package/src/skill-promotion.ts +293 -0
  159. package/src/skill-schema.ts +39 -0
  160. package/src/store.ts +96 -10
  161. package/src/topic-tag.ts +66 -0
  162. package/src/tracker.ts +3 -1
  163. package/src/ui-server.ts +80 -8
  164. package/src/workflow-observation-scope-review.ts +2 -1
  165. package/src/workflow-observation-store.ts +2 -1
  166. package/src/write-verifier.ts +126 -0
@@ -0,0 +1,125 @@
1
+ /**
2
+ * F1: Memory Confidence Meta-tags — tests for structured confidence,
3
+ * source-based assignment, retrieval integration, and backward compat.
4
+ */
5
+
6
+ import { describe, expect, test } from "bun:test";
7
+ import {
8
+ assignDefaultConfidence,
9
+ getConfidence,
10
+ getConfidenceMetadata,
11
+ CONFIDENCE_DEFAULT,
12
+ type ConfidenceMetadata,
13
+ } from "../confidence-tracker.js";
14
+ import type { MemoryEntry } from "../store.js";
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Helper
18
+ // ---------------------------------------------------------------------------
19
+
20
+ function makeEntry(metadataObj: Record<string, unknown>): MemoryEntry {
21
+ return {
22
+ id: "test-001",
23
+ text: "test",
24
+ vector: [],
25
+ category: "events",
26
+ scope: "test",
27
+ importance: 0.7,
28
+ timestamp: Date.now(),
29
+ metadata: JSON.stringify(metadataObj),
30
+ };
31
+ }
32
+
33
+ // ---------------------------------------------------------------------------
34
+ // assignDefaultConfidence
35
+ // ---------------------------------------------------------------------------
36
+
37
+ describe("F1: assignDefaultConfidence", () => {
38
+ test("manual source → direct reliability, score 0.9", () => {
39
+ const c = assignDefaultConfidence("manual");
40
+ expect(c.score).toBe(0.9);
41
+ expect(c.reliability).toBe("direct");
42
+ });
43
+
44
+ test("agent source → inferred reliability, score 0.7", () => {
45
+ const c = assignDefaultConfidence("agent");
46
+ expect(c.score).toBe(0.7);
47
+ expect(c.reliability).toBe("inferred");
48
+ });
49
+
50
+ test("conversation_import source → hearsay, score 0.5", () => {
51
+ const c = assignDefaultConfidence("conversation_import");
52
+ expect(c.score).toBe(0.5);
53
+ expect(c.reliability).toBe("hearsay");
54
+ });
55
+
56
+ test("session_distill source → inferred, score 0.6", () => {
57
+ const c = assignDefaultConfidence("session_distill");
58
+ expect(c.score).toBe(0.6);
59
+ expect(c.reliability).toBe("inferred");
60
+ });
61
+
62
+ test("explicit override takes precedence", () => {
63
+ const c = assignDefaultConfidence("agent", { score: 0.95, reliability: "direct" });
64
+ expect(c.score).toBe(0.95);
65
+ expect(c.reliability).toBe("direct");
66
+ });
67
+
68
+ test("explicit score only, reliability defaults to inferred", () => {
69
+ const c = assignDefaultConfidence("manual", { score: 0.3 });
70
+ expect(c.score).toBe(0.3);
71
+ expect(c.reliability).toBe("inferred");
72
+ });
73
+ });
74
+
75
+ // ---------------------------------------------------------------------------
76
+ // getConfidence — backward compat
77
+ // ---------------------------------------------------------------------------
78
+
79
+ describe("F1: getConfidence backward compatibility", () => {
80
+ test("reads flat number confidence (legacy format)", () => {
81
+ const entry = makeEntry({ confidence: 0.42 });
82
+ expect(getConfidence(entry)).toBe(0.42);
83
+ });
84
+
85
+ test("reads structured confidence object", () => {
86
+ const entry = makeEntry({ confidence: { score: 0.88, reliability: "direct" } });
87
+ expect(getConfidence(entry)).toBe(0.88);
88
+ });
89
+
90
+ test("returns default when confidence missing", () => {
91
+ const entry = makeEntry({});
92
+ expect(getConfidence(entry)).toBe(CONFIDENCE_DEFAULT);
93
+ });
94
+ });
95
+
96
+ // ---------------------------------------------------------------------------
97
+ // getConfidenceMetadata
98
+ // ---------------------------------------------------------------------------
99
+
100
+ describe("F1: getConfidenceMetadata", () => {
101
+ test("extracts structured ConfidenceMetadata", () => {
102
+ const entry = makeEntry({
103
+ confidence: { score: 0.75, reliability: "hearsay", verifiedAt: 1000, verifiedBy: "user" },
104
+ });
105
+ const meta = getConfidenceMetadata(entry);
106
+ expect(meta).not.toBeNull();
107
+ expect(meta!.score).toBe(0.75);
108
+ expect(meta!.reliability).toBe("hearsay");
109
+ expect(meta!.verifiedAt).toBe(1000);
110
+ expect(meta!.verifiedBy).toBe("user");
111
+ });
112
+
113
+ test("wraps legacy flat number into ConfidenceMetadata", () => {
114
+ const entry = makeEntry({ confidence: 0.55 });
115
+ const meta = getConfidenceMetadata(entry);
116
+ expect(meta).not.toBeNull();
117
+ expect(meta!.score).toBe(0.55);
118
+ expect(meta!.reliability).toBe("inferred");
119
+ });
120
+
121
+ test("returns null when confidence missing", () => {
122
+ const entry = makeEntry({});
123
+ expect(getConfidenceMetadata(entry)).toBeNull();
124
+ });
125
+ });
@@ -4,6 +4,9 @@ import {
4
4
  confirmMemory,
5
5
  correctMemory,
6
6
  contradictMemory,
7
+ buildConfirmPatch,
8
+ buildCorrectPatch,
9
+ buildContradictPatch,
7
10
  getConfidence,
8
11
  applyConfidenceWeight,
9
12
  CONFIDENCE_DEFAULT,
@@ -178,6 +181,56 @@ describe("confidence-tracker", () => {
178
181
  });
179
182
  });
180
183
 
184
+ describe("patch builders (store-agnostic)", () => {
185
+ it("buildConfirmPatch returns metadata patch without touching store", () => {
186
+ const entry = makeEntry("e1", "test fact");
187
+ const patch = buildConfirmPatch(entry);
188
+ expect(patch).not.toBeNull();
189
+ expect(patch!.metadata.confidence).toBe(CONFIDENCE_CONFIRMED);
190
+ expect(patch!.update.entryId).toBe("e1");
191
+ expect(patch!.update.newConfidence).toBe(CONFIDENCE_CONFIRMED);
192
+ // Original entry metadata should NOT be mutated
193
+ expect(JSON.parse(entry.metadata!).confidence).toBeUndefined();
194
+ });
195
+
196
+ it("buildCorrectPatch includes correctedBy in history", () => {
197
+ const entry = makeEntry("e1", "old info");
198
+ const patch = buildCorrectPatch(entry, "new-id-123");
199
+ expect(patch).not.toBeNull();
200
+ expect(patch!.metadata.confidence).toBe(CONFIDENCE_CORRECTED);
201
+ expect(patch!.metadata.corrected_by).toBe("new-id-123");
202
+ const history = patch!.metadata.confidence_history as Array<{ correctedBy?: string }>;
203
+ expect(history[0].correctedBy).toBe("new-id-1"); // 8 chars
204
+ });
205
+
206
+ it("buildContradictPatch returns zero confidence", () => {
207
+ const entry = makeEntry("e1", "wrong");
208
+ const patch = buildContradictPatch(entry);
209
+ expect(patch!.metadata.confidence).toBe(CONFIDENCE_CONTRADICTED);
210
+ });
211
+
212
+ it("all patch builders return null for null entry", () => {
213
+ expect(buildConfirmPatch(null)).toBeNull();
214
+ expect(buildCorrectPatch(null)).toBeNull();
215
+ expect(buildContradictPatch(null)).toBeNull();
216
+ });
217
+
218
+ it("caps confidence history at 20 entries", () => {
219
+ const longHistory = Array.from({ length: 25 }, (_, i) => ({
220
+ action: "confirmed",
221
+ from: 0.5,
222
+ to: 1.0,
223
+ date: `2026-01-${String(i + 1).padStart(2, "0")}`,
224
+ }));
225
+ const entry = makeEntry("e1", "test", {
226
+ metadata: JSON.stringify({ confidence: 0.5, confidence_history: longHistory }),
227
+ });
228
+ const patch = buildConfirmPatch(entry);
229
+ const history = patch!.metadata.confidence_history as unknown[];
230
+ expect(history.length).toBeLessThanOrEqual(20);
231
+ });
232
+ });
233
+
181
234
  describe("confidence history", () => {
182
235
  it("accumulates multiple changes", async () => {
183
236
  const entry = makeEntry("e1", "evolving fact");
@@ -152,7 +152,7 @@ describe("ConsolidationEngine", () => {
152
152
 
153
153
  it("skips archived entries", async () => {
154
154
  const entryA = makeEntry({ id: "a", text: "active entry here", vector: [1, 0, 0] });
155
- const entryB = makeEntry({ id: "b", text: "archived entry here", vector: [0.95, 0.1, 0], metadata: JSON.stringify({ state: "archived" }) });
155
+ const entryB = makeEntry({ id: "b", text: "archived entry here", vector: [0.95, 0.1, 0], metadata: JSON.stringify({ evolution: { status: "archived" } }) });
156
156
 
157
157
  const { store } = createMockStore([entryA, entryB]);
158
158
  const engine = new ConsolidationEngine(store);