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,398 @@
1
+ # Constructive Retrieval + Emotional Valence — Design Spec
2
+
3
+ > Date: 2026-04-11
4
+ > Status: Approved
5
+ > Scope: RecallNest v1.5 upgrade
6
+ > Philosophy basis: Simulation Theory (Michaelian) + Affective Memory (cognitive science)
7
+ > Risk strategy: Triple fallback — every new path degrades gracefully to current behavior
8
+
9
+ ---
10
+
11
+ ## 1. Problem Statement
12
+
13
+ RecallNest's retrieval pipeline (21 stages) returns **raw stored text**. This is a "causal theory" model — faithfully reproducing what was stored. But human memory doesn't work this way: we reconstruct memories in context, adapting them to our current needs.
14
+
15
+ Additionally, the decay engine lacks an emotional dimension. Cognitive science shows emotionally charged memories decay slower and are retrieved preferentially in matching emotional contexts. RecallNest currently treats all memories as emotionally neutral.
16
+
17
+ ## 2. Goals
18
+
19
+ 1. **Constructive Retrieval**: When context benefits from it, synthesize a coherent narrative from top-N retrieved memories, adapted to the current query context
20
+ 2. **Emotional Valence**: Tag memories with emotional metadata at storage time, use it to modulate decay rates and retrieval scoring
21
+ 3. **Zero regression**: All new behavior behind feature flags, all paths fallback to current behavior
22
+
23
+ ## 3. Non-Goals
24
+
25
+ - Replacing the existing retrieval pipeline (it stays as-is)
26
+ - Complex emotion models (no 6-axis emotion wheels; just valence + arousal)
27
+ - Multi-agent shared memory (future phase)
28
+ - Autobiographical narrative architecture (future phase)
29
+
30
+ ---
31
+
32
+ ## 4. Constructive Retrieval
33
+
34
+ ### 4.1 Architecture
35
+
36
+ New component: `context-reconstructor.ts` (~200-300 LOC)
37
+
38
+ Position in pipeline:
39
+ ```
40
+ Existing 21-stage pipeline → top-N RetrievalResult[]
41
+ ↓
42
+ Reconstruction Gate
43
+ (should reconstruct?)
44
+ ↓ yes ↓ no
45
+ Context Reconstructor Return raw
46
+ ↓
47
+ Grounding Validator
48
+ ↓
49
+ Return { reconstructed, sources, confidence, raw }
50
+ ```
51
+
52
+ ### 4.2 Reconstruction Gate
53
+
54
+ Conditions for reconstruction (ALL must be true):
55
+ - Feature flag `RECALLNEST_CONSTRUCTIVE_RETRIEVAL=true`
56
+ - Caller opt-in: `reconstruct: true` in retrieval context
57
+ - Retrieved results count ≥ 3 (too few = not enough material)
58
+ - LLM client available and responding
59
+
60
+ If any condition fails → return raw results immediately. No error, no log noise.
61
+
62
+ ### 4.3 Context Reconstructor
63
+
64
+ **Input:**
65
+ ```ts
66
+ interface ReconstructionInput {
67
+ query: string; // current user query / resume context
68
+ results: RetrievalResult[]; // top-N from pipeline (max 10)
69
+ mode: "resume" | "search"; // affects prompt style
70
+ maxTokens?: number; // output budget (default 500)
71
+ }
72
+ ```
73
+
74
+ **LLM Prompt Strategy:**
75
+ ```
76
+ System: You are a memory reconstruction engine. Given a set of stored memories
77
+ and a current context, synthesize a coherent, contextually relevant summary.
78
+
79
+ Rules:
80
+ 1. Every factual claim MUST cite its source as [src:MEMORY_ID]
81
+ 2. Do NOT invent facts not present in any source memory
82
+ 3. If memories contradict each other, present both views with [conflict] tag
83
+ 4. Prioritize information most relevant to the current query context
84
+ 5. Keep output concise — this is context, not an essay
85
+
86
+ Current context: {query}
87
+
88
+ Source memories:
89
+ {for each result: [ID: {id}] {text} (importance: {importance}, stored: {date})}
90
+
91
+ Synthesize a contextually relevant reconstruction:
92
+ ```
93
+
94
+ **Output:**
95
+ ```ts
96
+ interface ReconstructionOutput {
97
+ reconstructed: string; // synthesized text with [src:ID] citations
98
+ sources: string[]; // list of cited memory IDs
99
+ confidence: number; // [0, 1] grounding confidence
100
+ fallbackReason?: string; // if degraded, why
101
+ raw: RetrievalResult[]; // always included
102
+ }
103
+ ```
104
+
105
+ ### 4.4 Grounding Validator
106
+
107
+ Three-layer validation, executed sequentially:
108
+
109
+ **Layer 1: ID Verification**
110
+ ```ts
111
+ for (const citedId of extractCitedIds(reconstructed)) {
112
+ if (!topNResults.some(r => r.id === citedId)) {
113
+ reconstructed = removeSentencesWithId(reconstructed, citedId);
114
+ confidence -= 0.2;
115
+ }
116
+ }
117
+ ```
118
+ - Extract all `[src:MEMORY_ID]` references from LLM output
119
+ - Verify each ID exists in the top-N result set
120
+ - Remove sentences citing non-existent IDs (hallucination)
121
+ - Penalize confidence per phantom citation
122
+
123
+ **Layer 2: Coverage Check**
124
+ ```ts
125
+ const coverage = computeSemanticOverlap(reconstructed, topNResults);
126
+ if (coverage < 0.6) {
127
+ return { reconstructed: null, fallbackReason: "low_grounding", raw };
128
+ }
129
+ ```
130
+ - Compute semantic overlap between reconstructed text and source memories
131
+ - Method: chunk reconstructed text into sentences, embed each, find max cosine similarity to any source memory
132
+ - Coverage = percentage of sentences with similarity > 0.7
133
+ - Below 60% → full degradation to raw results
134
+
135
+ **Layer 3: Timeout Guard**
136
+ ```ts
137
+ const result = await Promise.race([
138
+ reconstruct(input),
139
+ timeout(3000).then(() => ({ fallbackReason: "timeout" }))
140
+ ]);
141
+ ```
142
+ - 3-second hard timeout on entire reconstruction pipeline
143
+ - Timeout → return raw results
144
+
145
+ ### 4.5 Integration Points
146
+
147
+ **resume_context (context-composer.ts):**
148
+ - After assembling stable context + patterns + cases
149
+ - Call reconstructor with mode="resume", query=task description from checkpoint
150
+ - If reconstruction succeeds, use it as the primary context narrative
151
+ - Always keep raw results in response for transparency
152
+ - Default: reconstruction ON when feature flag is ON
153
+
154
+ **search_memory (mcp-server.ts):**
155
+ - New optional parameter: `reconstruct?: boolean` (default false)
156
+ - When true, pass through to retriever with reconstruct flag
157
+ - Return both reconstructed and raw in tool response
158
+
159
+ **brief_memory, memory_lint, list_pins, etc.:**
160
+ - Never reconstruct. These tools need raw data.
161
+
162
+ ### 4.6 Observability
163
+
164
+ - Trace stage: `reconstruction` added to TraceCollector
165
+ - Logged fields: `{ attempted: boolean, succeeded: boolean, confidence: number, fallbackReason?: string, latencyMs: number, sourceCount: number }`
166
+ - No memory content logged (privacy)
167
+
168
+ ---
169
+
170
+ ## 5. Emotional Valence
171
+
172
+ ### 5.1 Schema Extension
173
+
174
+ Add optional `emotion` field to memory metadata:
175
+
176
+ ```ts
177
+ interface EmotionMetadata {
178
+ valence: number; // [-1, 1] negative ← → positive
179
+ arousal: number; // [0, 1] calm ← → excited
180
+ label?: string; // human-readable: "frustration" | "excitement" | "neutral" | etc.
181
+ }
182
+ ```
183
+
184
+ Stored in `metadata` JSON string (no schema migration needed):
185
+ ```json
186
+ {
187
+ "tier": "working",
188
+ "emotion": { "valence": -0.7, "arousal": 0.8, "label": "frustration" }
189
+ }
190
+ ```
191
+
192
+ ### 5.2 Detection at Store Time
193
+
194
+ **Two-tier detection (store.ts / noise-filter.ts):**
195
+
196
+ **Tier 1: Heuristic (zero LLM cost, always runs)**
197
+ ```ts
198
+ const NEGATIVE_SIGNALS = ["失败", "痛苦", "困扰", "bug", "broken", "frustrat", "hate", "wrong", "error"];
199
+ const POSITIVE_SIGNALS = ["突破", "搞定", "成功", "solved", "great", "love", "perfect", "works"];
200
+ const HIGH_AROUSAL = ["!", "紧急", "urgent", "critical", "immediately", "ASAP"];
201
+
202
+ function heuristicEmotion(text: string): EmotionMetadata {
203
+ const negCount = NEGATIVE_SIGNALS.filter(s => text.toLowerCase().includes(s)).length;
204
+ const posCount = POSITIVE_SIGNALS.filter(s => text.toLowerCase().includes(s)).length;
205
+ const arousalCount = HIGH_AROUSAL.filter(s => text.includes(s)).length;
206
+
207
+ const valence = clamp((posCount - negCount) * 0.3, -1, 1);
208
+ const arousal = clamp(arousalCount * 0.3, 0, 1);
209
+ const label = valence > 0.3 ? "positive" : valence < -0.3 ? "negative" : "neutral";
210
+
211
+ return { valence, arousal, label };
212
+ }
213
+ ```
214
+
215
+ **Tier 2: LLM (optional, piggybacked on importance evaluation)**
216
+ - When LLM is called to evaluate importance (existing flow), add to prompt:
217
+ ```
218
+ Also rate the emotional tone:
219
+ - valence: [-1, 1] (negative to positive)
220
+ - arousal: [0, 1] (calm to excited)
221
+ - label: one word (e.g., "frustration", "excitement", "neutral")
222
+ ```
223
+ - Merged into existing LLM call → zero additional API cost
224
+ - LLM result overrides heuristic result when available
225
+
226
+ **Backward compatibility:** Existing memories without emotion field → treated as `{ valence: 0, arousal: 0, label: "neutral" }` everywhere.
227
+
228
+ ### 5.3 Decay Integration (decay-engine.ts)
229
+
230
+ **Modified half-life calculation:**
231
+ ```ts
232
+ function adjustedHalfLife(baseHalfLife: number, emotion?: EmotionMetadata): number {
233
+ if (!emotion) return baseHalfLife;
234
+ const emotionalIntensity = Math.abs(emotion.valence);
235
+ // Emotional memories last up to 30% longer
236
+ const boost = 1 + 0.3 * emotionalIntensity;
237
+ return baseHalfLife * boost;
238
+ }
239
+ ```
240
+
241
+ - Strong negative memory (valence = -0.9): half-life × 1.27
242
+ - Strong positive memory (valence = 0.8): half-life × 1.24
243
+ - Neutral memory (valence = 0.1): half-life × 1.03 (negligible)
244
+ - No emotion field: no change
245
+
246
+ **Arousal modulation (secondary):**
247
+ ```ts
248
+ // High arousal slightly accelerates initial strength but doesn't change half-life
249
+ // This models the "flashbulb memory" effect — vivid but not necessarily longer-lasting
250
+ const initialBoost = 1 + 0.1 * (emotion?.arousal ?? 0);
251
+ ```
252
+
253
+ ### 5.4 Retrieval Integration (retriever.ts)
254
+
255
+ **New scoring stage: `applyEmotionWeight` (after `applyImportanceWeight`)**
256
+
257
+ ```ts
258
+ function applyEmotionWeight(
259
+ results: ScoredResult[],
260
+ queryEmotion: EmotionMetadata | null
261
+ ): ScoredResult[] {
262
+ if (!queryEmotion || Math.abs(queryEmotion.valence) < 0.2) {
263
+ return results; // neutral query → no-op
264
+ }
265
+
266
+ return results.map(r => {
267
+ const memEmotion = parseEmotion(r.metadata);
268
+ if (!memEmotion) return r; // no emotion data → unchanged
269
+
270
+ // Emotional alignment boost: same-valence memories score higher
271
+ const alignment = 1 - Math.abs(queryEmotion.valence - memEmotion.valence) / 2;
272
+ const boost = 1.0 + 0.15 * alignment;
273
+
274
+ return { ...r, score: r.score * boost };
275
+ });
276
+ }
277
+ ```
278
+
279
+ - Query has emotional tone + memory has matching emotion → up to 15% score boost
280
+ - Query is neutral → stage is no-op (zero overhead)
281
+ - Memory has no emotion data → unchanged
282
+
283
+ **Query emotion detection:**
284
+ - Reuse heuristic detector on query text
285
+ - Lightweight, no LLM needed at query time
286
+
287
+ ### 5.5 Feature Flag
288
+
289
+ `RECALLNEST_EMOTION_SCORING=true` — controls:
290
+ - Emotion detection at store time
291
+ - Emotion-adjusted decay calculation
292
+ - Emotion scoring stage in retriever
293
+
294
+ When OFF: all emotion code paths are no-op. Existing behavior preserved exactly.
295
+
296
+ ---
297
+
298
+ ## 6. File Change Map
299
+
300
+ | File | Change Type | Description |
301
+ |------|-------------|-------------|
302
+ | `src/context-reconstructor.ts` | **NEW** | Reconstruction engine + grounding validator |
303
+ | `src/retriever.ts` | Modify | Add reconstruction gate at output + emotion scoring stage |
304
+ | `src/decay-engine.ts` | Modify | Add emotion-adjusted half-life |
305
+ | `src/memory-schema.ts` | Modify | Add EmotionMetadata type definition |
306
+ | `src/store.ts` | Modify | Call emotion detector at store time |
307
+ | `src/context-composer.ts` | Modify | Call reconstructor in resume flow |
308
+ | `src/mcp-server.ts` | Modify | Add `reconstruct` param to search_memory |
309
+ | `src/config.ts` | Modify | Add feature flags |
310
+ | `src/__tests__/context-reconstructor.test.ts` | **NEW** | Unit tests for reconstruction + grounding |
311
+ | `src/__tests__/emotion-scoring.test.ts` | **NEW** | Unit tests for emotion detection + decay + retrieval |
312
+
313
+ **Estimated LOC:**
314
+ - New code: ~400-500 lines
315
+ - Modified code: ~100-150 lines across existing files
316
+ - Tests: ~300-400 lines
317
+
318
+ ---
319
+
320
+ ## 7. Test Strategy
321
+
322
+ ### Unit Tests
323
+ - Reconstruction gate: all 4 conditions tested (flag off, no opt-in, too few results, LLM down)
324
+ - Grounding validator: phantom ID removal, coverage threshold, timeout
325
+ - Emotion heuristic: positive/negative/neutral/mixed texts
326
+ - Decay adjustment: verify half-life calculations
327
+ - Retrieval emotion stage: neutral query no-op, matching boost, missing data handling
328
+
329
+ ### Integration Tests
330
+ - End-to-end: store memories → search with reconstruct=true → verify output format
331
+ - End-to-end: store emotional memory → verify decay score after N days vs neutral memory
332
+ - resume_context with reconstruction → verify grounding and fallback
333
+
334
+ ### Regression Tests
335
+ - All feature flags OFF → existing test suite must pass unchanged (zero regression)
336
+ - Memories without emotion field → same scores as before
337
+
338
+ ---
339
+
340
+ ## 8. Rollout Plan
341
+
342
+ **Phase 1: Emotion Valence (low risk, no LLM dependency)**
343
+ 1. Add schema types
344
+ 2. Implement heuristic detector
345
+ 3. Integrate into store path
346
+ 4. Add decay adjustment
347
+ 5. Add retrieval scoring stage
348
+ 6. Tests
349
+ 7. Feature flag ON for testing
350
+
351
+ **Phase 2: Constructive Retrieval (medium risk, LLM dependent)**
352
+ 1. Implement context-reconstructor.ts
353
+ 2. Implement grounding validator
354
+ 3. Integrate into retriever output
355
+ 4. Integrate into context-composer
356
+ 5. Add search_memory parameter
357
+ 6. Tests
358
+ 7. Feature flag ON for testing
359
+
360
+ **Phase 3: LLM Emotion Detection (optional enhancement)**
361
+ 1. Piggyback on importance evaluation prompt
362
+ 2. Override heuristic when available
363
+ 3. A/B test heuristic vs LLM accuracy
364
+
365
+ ---
366
+
367
+ ## 9. Success Criteria
368
+
369
+ - [ ] Feature flags OFF → all existing tests pass (baseline per CLAUDE.md)
370
+ - [ ] Emotion-tagged memories decay 20-30% slower than neutral (verified in test)
371
+ - [ ] Reconstruction produces grounded output (coverage ≥ 0.6) in ≥ 80% of cases
372
+ - [ ] Reconstruction fallback triggers correctly when LLM is unavailable
373
+ - [ ] resume_context with reconstruction provides more contextually relevant summaries (qualitative)
374
+ - [ ] No additional LLM API calls for emotion detection (piggybacked on existing calls)
375
+ - [ ] Reconstruction latency < 3s in 95% of cases
376
+
377
+ ---
378
+
379
+ ## 10. Open Questions (resolved)
380
+
381
+ | Question | Decision |
382
+ |----------|----------|
383
+ | How aggressive should reconstruction be? | **Moderate (B)**: LLM rewrite from top-N, not fragment synthesis |
384
+ | What emotion model? | **Valence-Arousal**: simple, proven, low overhead |
385
+ | When to reconstruct by default? | **resume_context only**; search_memory opt-in |
386
+ | Grounding threshold? | **0.6 coverage**; tunable via config |
387
+ | Timeout? | **3 seconds**; hard cutoff |
388
+
389
+ ---
390
+
391
+ ## Sources
392
+
393
+ - Michaelian, K. — Simulation Theory of Memory
394
+ - Ebbinghaus Forgetting Curve + Weibull extensions
395
+ - Cognitive science consensus on emotional memory persistence
396
+ - [Stanford Encyclopedia of Philosophy: Memory](https://plato.stanford.edu/entries/memory/)
397
+ - [Memory in the Age of AI Agents](https://arxiv.org/abs/2512.13564)
398
+ - [SuperLocalMemory V3.3: Biologically-Inspired Forgetting](https://arxiv.org/html/2604.04514)
package/glama.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "maintainers": [
4
+ "AliceLJY"
5
+ ]
6
+ }
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+ # RecallNest — setup all three terminals at once (idempotent)
3
+ # Usage: bash integrations/setup-all.sh
4
+
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+
9
+ echo "RecallNest — setting up all terminals"
10
+ echo "======================================"
11
+ echo ""
12
+
13
+ echo "--- Claude Code ---"
14
+ bash "$SCRIPT_DIR/claude-code/setup.sh"
15
+ echo ""
16
+
17
+ echo "--- Codex ---"
18
+ bash "$SCRIPT_DIR/codex/setup.sh"
19
+ echo ""
20
+
21
+ echo "--- Gemini CLI ---"
22
+ bash "$SCRIPT_DIR/gemini-cli/setup.sh"
23
+ echo ""
24
+
25
+ echo "======================================"
26
+ echo "All terminals configured."
27
+ echo ""
28
+ echo "Next steps:"
29
+ echo " 1. Restart each terminal"
30
+ echo " 2. Run: bun run seed:continuity"
31
+ echo " 3. Run: bun run src/cli.ts doctor"
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "recallnest",
3
- "version": "1.4.1",
3
+ "version": "2.2.0",
4
4
  "description": "RecallNest \u2014 MCP-native, local-first memory search and distillation for AI conversations",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
8
- "recallnest": "src/cli.ts",
9
- "local-memory": "src/cli.ts"
8
+ "recallnest": "bin/recallnest.mjs",
9
+ "local-memory": "bin/recallnest.mjs"
10
10
  },
11
11
  "scripts": {
12
12
  "search": "bun run src/cli.ts search",
@@ -35,13 +35,20 @@
35
35
  "ui": "bun run src/ui-server.ts",
36
36
  "api": "bun run src/api-server.ts"
37
37
  },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
38
41
  "dependencies": {
39
42
  "@lancedb/lancedb": "^0.26.0",
40
43
  "@modelcontextprotocol/sdk": "^1.27.1",
41
44
  "commander": "^12.0.0",
42
45
  "openai": "^4.0.0",
46
+ "tsx": "^4.19.0",
43
47
  "zod": "^3.25.76"
44
48
  },
49
+ "optionalDependencies": {
50
+ "babel-memory": ">=1.0.0"
51
+ },
45
52
  "repository": {
46
53
  "type": "git",
47
54
  "url": "git+https://github.com/AliceLJY/recallnest.git"