recallnest 2.2.0 → 2.2.1

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 (232) hide show
  1. package/.env +4 -0
  2. package/config.json +55 -0
  3. package/logs/daily-recall.error.log +0 -0
  4. package/logs/daily-recall.log +30 -0
  5. package/logs/ingest-2026-04-11.log +110 -0
  6. package/logs/ingest-2026-04-12.log +90 -0
  7. package/logs/launchagent-stderr.log +0 -0
  8. package/logs/launchagent-stdout.log +0 -0
  9. package/package.json +1 -1
  10. package/.claude-plugin/CLAUDE.md +0 -29
  11. package/.claude-plugin/marketplace.json +0 -18
  12. package/.dockerignore +0 -11
  13. package/.github/workflows/ci.yml +0 -28
  14. package/.mcp.json +0 -9
  15. package/CHANGELOG.md +0 -51
  16. package/DEMO.md +0 -94
  17. package/Dockerfile +0 -20
  18. package/EVAL.md +0 -89
  19. package/FAILURES.md +0 -75
  20. package/OPERATIONS.md +0 -59
  21. package/ROADMAP.md +0 -245
  22. package/SKILL.md +0 -250
  23. package/assets/dashboard.png +0 -0
  24. package/assets/knowledge-graph.png +0 -0
  25. package/assets/recallnest-workbench.png +0 -0
  26. package/assets/screenshots/ui-full.png +0 -0
  27. package/assets/screenshots/ui-overview.png +0 -0
  28. package/assets/screenshots/ui-search.png +0 -0
  29. package/assets/ui/app.js +0 -1031
  30. package/assets/ui/index.html +0 -224
  31. package/assets/ui/styles.css +0 -781
  32. package/assets/wechat-qr.jpg +0 -0
  33. package/bun.lock +0 -337
  34. package/daily-reflections/2026-03-05.md +0 -15
  35. package/daily-reflections/2026-03-06.md +0 -15
  36. package/daily-reflections/2026-03-07.md +0 -7
  37. package/daily-reflections/2026-03-08.md +0 -34
  38. package/daily-reflections/2026-03-09.md +0 -35
  39. package/daily-reflections/2026-03-10.md +0 -36
  40. package/daily-reflections/2026-03-11.md +0 -35
  41. package/daily-reflections/2026-03-12.md +0 -36
  42. package/daily-reflections/2026-03-13.md +0 -35
  43. package/daily-reflections/2026-03-14.md +0 -35
  44. package/daily-reflections/2026-03-15.md +0 -35
  45. package/daily-reflections/2026-03-16.md +0 -41
  46. package/daily-reflections/2026-03-17.md +0 -10
  47. package/daily-reflections/2026-03-18.md +0 -10
  48. package/daily-reflections/2026-03-19.md +0 -10
  49. package/daily-reflections/2026-03-20.md +0 -10
  50. package/daily-reflections/2026-03-21.md +0 -10
  51. package/daily-reflections/2026-03-22.md +0 -10
  52. package/daily-reflections/2026-03-23.md +0 -10
  53. package/daily-reflections/2026-03-24.md +0 -10
  54. package/daily-reflections/2026-03-25.md +0 -32
  55. package/daily-reflections/2026-03-26.md +0 -37
  56. package/daily-reflections/2026-03-27.md +0 -35
  57. package/daily-reflections/2026-03-28.md +0 -35
  58. package/daily-reflections/2026-03-29.md +0 -35
  59. package/daily-reflections/2026-03-30.md +0 -36
  60. package/daily-reflections/2026-03-31.md +0 -35
  61. package/daily-reflections/2026-04-01.md +0 -35
  62. package/daily-reflections/2026-04-02.md +0 -35
  63. package/daily-reflections/2026-04-03.md +0 -37
  64. package/daily-reflections/2026-04-04.md +0 -37
  65. package/daily-reflections/2026-04-05.md +0 -35
  66. package/daily-reflections/2026-04-06.md +0 -36
  67. package/daily-reflections/2026-04-07.md +0 -35
  68. package/daily-reflections/2026-04-08.md +0 -35
  69. package/daily-reflections/2026-04-12.md +0 -35
  70. package/data/alias-map.example.json +0 -22
  71. package/docs/api-reference.md +0 -1291
  72. package/docs/architecture.md +0 -168
  73. package/docs/memory-boundary-contract.md +0 -226
  74. package/docs/memory-categories.md +0 -119
  75. package/docs/pipeline-audit-ultramemory.md +0 -177
  76. package/docs/plans/2026-03-08-query-expansion.md +0 -270
  77. package/docs/plans/2026-03-16-continuity-layer.md +0 -196
  78. package/docs/plans/2026-04-01-recall-boost.md +0 -100
  79. package/docs/plans/mcp-tiering-plan.md +0 -126
  80. package/docs/research/recall-quality-audit-2026-03-22.md +0 -153
  81. package/docs/self-evolution.md +0 -198
  82. package/docs/superpowers/plans/2026-03-19-ingest-pipeline-upgrade.md +0 -782
  83. package/docs/superpowers/plans/2026-04-11-constructive-retrieval-emotion.md +0 -1195
  84. package/docs/superpowers/specs/2026-03-19-ingest-pipeline-upgrade-design.md +0 -77
  85. package/docs/superpowers/specs/2026-03-23-pull-claude-desktop-design.md +0 -95
  86. package/docs/superpowers/specs/2026-04-11-constructive-retrieval-emotion-design.md +0 -398
  87. package/eval/continuity/results-2026-03-16.md +0 -117
  88. package/eval/continuity/results-2026-03-19.md +0 -453
  89. package/eval/continuity/runbook.md +0 -110
  90. package/eval/continuity/seed-cases.md +0 -54
  91. package/eval/reports/2026-03-06-abstract-query-baseline.md +0 -96
  92. package/eval/reports/2026-03-06-aws-ssh-baseline.md +0 -82
  93. package/eval/reports/2026-03-06-baseline.md +0 -82
  94. package/eval/reports/query-expansion.md +0 -138
  95. package/glama.json +0 -6
  96. package/lm +0 -19
  97. package/plan-philosophy-upgrades.md +0 -363
  98. package/plan-product-upgrades.md +0 -155
  99. package/plan-v1.2-distributable.md +0 -105
  100. package/plan.md +0 -140
  101. package/research-memory-evolution.md +0 -440
  102. package/research-rl-agent-memory.md +0 -330
  103. package/scripts/archive-distilled-junk.ts +0 -116
  104. package/scripts/backfill-anchors.ts +0 -130
  105. package/scripts/backfill-l0l1l2.ts +0 -98
  106. package/scripts/blind-scan.ts +0 -588
  107. package/scripts/cleanup-step1-exact-dups.ts +0 -117
  108. package/scripts/cleanup-step2-template-dups.ts +0 -113
  109. package/scripts/cleanup-step3-stale-content.ts +0 -149
  110. package/scripts/cleanup-step4-orphan-scopes.ts +0 -131
  111. package/scripts/delete-distilled-junk.ts +0 -88
  112. package/scripts/diagnose-vector-search.ts +0 -132
  113. package/scripts/distill-facts.ts +0 -305
  114. package/scripts/health-check.ts +0 -343
  115. package/scripts/incremental-ingest.sh +0 -71
  116. package/scripts/migrate-language.ts +0 -75
  117. package/scripts/mlp-health-check.ts +0 -382
  118. package/scripts/pull-claude-desktop.ts +0 -515
  119. package/scripts/re-ingest-cc.sh +0 -66
  120. package/scripts/rebalance-memory-health.ts +0 -181
  121. package/scripts/run-desktop-ingest.sh +0 -11
  122. package/scripts/start-server.sh +0 -12
  123. package/scripts/verify-emotion-decay.ts +0 -148
  124. package/scripts/viz-dashboard.html +0 -423
  125. package/scripts/viz-export.ts +0 -703
  126. package/src/__tests__/access-tracker-novelty.test.ts +0 -228
  127. package/src/__tests__/activity-counter.test.ts +0 -96
  128. package/src/__tests__/admission-control.test.ts +0 -206
  129. package/src/__tests__/anchor-generator.test.ts +0 -67
  130. package/src/__tests__/auto-consolidation.test.ts +0 -168
  131. package/src/__tests__/auto-recall.test.ts +0 -131
  132. package/src/__tests__/babel-integration.test.ts +0 -139
  133. package/src/__tests__/batch-dedup.test.ts +0 -65
  134. package/src/__tests__/capture-engine.test.ts +0 -1144
  135. package/src/__tests__/capture-heuristic.test.ts +0 -171
  136. package/src/__tests__/cascade-forget.test.ts +0 -210
  137. package/src/__tests__/category-min-scores.test.ts +0 -33
  138. package/src/__tests__/cc8-cc1-essential-context.test.ts +0 -298
  139. package/src/__tests__/circuit-breaker.test.ts +0 -99
  140. package/src/__tests__/cluster-consolidation.test.ts +0 -712
  141. package/src/__tests__/confidence-metadata.test.ts +0 -125
  142. package/src/__tests__/confidence-tracker.test.ts +0 -249
  143. package/src/__tests__/conflict-advisor.test.ts +0 -206
  144. package/src/__tests__/conflict-escalation.test.ts +0 -149
  145. package/src/__tests__/conflict-lifecycle.test.ts +0 -83
  146. package/src/__tests__/conflict-output.test.ts +0 -85
  147. package/src/__tests__/conflict-store.test.ts +0 -374
  148. package/src/__tests__/consolidation-engine.test.ts +0 -181
  149. package/src/__tests__/constructive-retrieval.test.ts +0 -509
  150. package/src/__tests__/context-collapse-renderer.test.ts +0 -214
  151. package/src/__tests__/context-composer-pins.test.ts +0 -64
  152. package/src/__tests__/context-composer-task-selection.test.ts +0 -24
  153. package/src/__tests__/context-reconstructor.test.ts +0 -65
  154. package/src/__tests__/context-renderer.test.ts +0 -91
  155. package/src/__tests__/continuity-eval.test.ts +0 -275
  156. package/src/__tests__/continuity-schema.test.ts +0 -97
  157. package/src/__tests__/conversation-importer.test.ts +0 -692
  158. package/src/__tests__/core-recall-eval.test.ts +0 -235
  159. package/src/__tests__/core-summary.test.ts +0 -109
  160. package/src/__tests__/data-checkup.test.ts +0 -225
  161. package/src/__tests__/decay-exemption.test.ts +0 -84
  162. package/src/__tests__/dedup-actions.test.ts +0 -58
  163. package/src/__tests__/dedup-guard.test.ts +0 -39
  164. package/src/__tests__/deterministic-id.test.ts +0 -39
  165. package/src/__tests__/distill-lock.test.ts +0 -176
  166. package/src/__tests__/doctor.test.ts +0 -303
  167. package/src/__tests__/dream-pipeline.test.ts +0 -232
  168. package/src/__tests__/drill-down.test.ts +0 -108
  169. package/src/__tests__/embedder.test.ts +0 -122
  170. package/src/__tests__/emotion-decay.test.ts +0 -46
  171. package/src/__tests__/emotion-detector.test.ts +0 -56
  172. package/src/__tests__/emotion-phase1-integration.test.ts +0 -153
  173. package/src/__tests__/emotion-retrieval.test.ts +0 -56
  174. package/src/__tests__/entity-resolver.test.ts +0 -58
  175. package/src/__tests__/ethics-layer.test.ts +0 -476
  176. package/src/__tests__/event-segmenter.test.ts +0 -153
  177. package/src/__tests__/feature-flags-integration.test.ts +0 -54
  178. package/src/__tests__/frequency-tracker.test.ts +0 -113
  179. package/src/__tests__/graph-export.test.ts +0 -489
  180. package/src/__tests__/hotness-blend.test.ts +0 -76
  181. package/src/__tests__/ingest.test.ts +0 -360
  182. package/src/__tests__/interference-detector.test.ts +0 -203
  183. package/src/__tests__/kg-extractor.test.ts +0 -184
  184. package/src/__tests__/kg-store.test.ts +0 -198
  185. package/src/__tests__/llm-consolidation.test.ts +0 -226
  186. package/src/__tests__/mcp-efficiency.test.ts +0 -288
  187. package/src/__tests__/memory-boundaries.test.ts +0 -237
  188. package/src/__tests__/memory-evolution-b2-b3-e1.test.ts +0 -243
  189. package/src/__tests__/memory-evolution.test.ts +0 -271
  190. package/src/__tests__/memory-health-rebalance.test.ts +0 -144
  191. package/src/__tests__/memory-lint.test.ts +0 -271
  192. package/src/__tests__/memory-output.test.ts +0 -215
  193. package/src/__tests__/multi-vector.test.ts +0 -242
  194. package/src/__tests__/narrative-architecture.test.ts +0 -456
  195. package/src/__tests__/pending-review.test.ts +0 -77
  196. package/src/__tests__/post-retrieval-filter.test.ts +0 -178
  197. package/src/__tests__/ppr-traversal.test.ts +0 -256
  198. package/src/__tests__/prediction-engine.test.ts +0 -349
  199. package/src/__tests__/predictive-prospective-memory.test.ts +0 -416
  200. package/src/__tests__/preference-guard-smoke.test.ts +0 -211
  201. package/src/__tests__/preference-matcher.test.ts +0 -230
  202. package/src/__tests__/preference-slots.test.ts +0 -205
  203. package/src/__tests__/prospective-memory.test.ts +0 -283
  204. package/src/__tests__/query-entity-detector.test.ts +0 -171
  205. package/src/__tests__/query-expander-alias.test.ts +0 -89
  206. package/src/__tests__/query-expander.test.ts +0 -34
  207. package/src/__tests__/recall-governor.test.ts +0 -227
  208. package/src/__tests__/recall-mode.test.ts +0 -64
  209. package/src/__tests__/result-synthesizer.test.ts +0 -198
  210. package/src/__tests__/resume-context.test.ts +0 -4898
  211. package/src/__tests__/retrieval-trace.test.ts +0 -213
  212. package/src/__tests__/retriever-boundary-weight.test.ts +0 -136
  213. package/src/__tests__/retroactive-boost.test.ts +0 -223
  214. package/src/__tests__/salience-scoring.test.ts +0 -106
  215. package/src/__tests__/scope-inventory.test.ts +0 -200
  216. package/src/__tests__/scope-policy.test.ts +0 -69
  217. package/src/__tests__/session-checkpoint.test.ts +0 -259
  218. package/src/__tests__/session-distiller.test.ts +0 -611
  219. package/src/__tests__/session-gc.test.ts +0 -215
  220. package/src/__tests__/skill-engine.test.ts +0 -546
  221. package/src/__tests__/skill-promotion.test.ts +0 -349
  222. package/src/__tests__/store-scope-audit.test.ts +0 -81
  223. package/src/__tests__/supersede-chain.test.ts +0 -154
  224. package/src/__tests__/temporal-parser.test.ts +0 -241
  225. package/src/__tests__/temporal-validity.test.ts +0 -160
  226. package/src/__tests__/term-registry.test.ts +0 -121
  227. package/src/__tests__/tool-output-compressor.test.ts +0 -133
  228. package/src/__tests__/topic-tag.test.ts +0 -113
  229. package/src/__tests__/trusted-memory.test.ts +0 -828
  230. package/src/__tests__/version-manager.test.ts +0 -213
  231. package/src/__tests__/workflow-observation.test.ts +0 -400
  232. package/src/__tests__/write-verifier.test.ts +0 -122
@@ -1,363 +0,0 @@
1
- # Implementation Plan: Memory Philosophy-Driven RecallNest Upgrades
2
-
3
- > Date: 2026-04-11
4
- > Status: ✅ ALL 5 PHASES COMPLETE (commits a9e53d3..d150b8d, 1391 tests / 0 fail)
5
- > Source: Memory philosophy research map + Codex code analysis + Explorer codebase audit
6
-
7
- ---
8
-
9
- ## Overview
10
-
11
- Five upgrade phases derived from memory philosophy research, each mapped to concrete code changes in the RecallNest codebase. Phase 1 (Emotional Valence in Decay) is implementation-ready today -- the building blocks exist but are not wired into production paths. Phases 2-5 build outward from that foundation. All phases are designed to be independently mergeable and testable.
12
-
13
- ## Dependency Graph
14
-
15
- ```
16
- Phase 1 (Emotion Decay) <- standalone, no dependencies
17
- Phase 2 (Ethics Layer) <- standalone, no dependencies on Phase 1
18
- Phase 3 (Narrative) <- standalone, enriches Phase 4 if done first
19
- Phase 4 (Constructive) <- benefits from Phase 3 (narrative siblings), Phase 1 (emotion salience)
20
- Phase 5 (Predictive) <- benefits from Phase 4 (reconstruction surface)
21
- ```
22
-
23
- Phases 1, 2, and 3 can run in parallel. Phase 4 benefits from all three. Phase 5 builds on Phase 4.
24
-
25
- ## Time Estimates
26
-
27
- | Phase | Estimated Effort | Complexity |
28
- |-------|-----------------|------------|
29
- | Phase 1 | 3-4 hours | Low -- wiring existing code |
30
- | Phase 2 | 2-3 days | Medium -- new forget engine + lifecycle unification |
31
- | Phase 3 | 2-3 days | Medium -- new metadata layer + write/read points |
32
- | Phase 4 | 3-4 days | High -- LLM pipeline changes + grounding rewrite |
33
- | Phase 5 | 2-3 days | Medium -- new prediction engine + surface layer |
34
- | **Total** | **~12-15 days** | |
35
-
36
- ---
37
-
38
- ## Phase 1: Emotional Valence in Decay (TODAY)
39
-
40
- ### Goal
41
- Wire the existing emotion-adjusted decay functions (`adjustHalfLifeForEmotion`, `computeArousalBoost`) into the production retrieval and evolution scoring paths. Extend `EmotionMetadata` with `salience` and `source` fields. Recalculate emotion on text updates. Backfill emotion on import.
42
-
43
- ### Current State
44
- - `emotion-detector.ts` -- keyword heuristic, zero LLM cost, fully tested
45
- - `decay-engine.ts:99-119` -- `adjustHalfLifeForEmotion()` and `computeArousalBoost()` exist with tests but are NOT called from production code
46
- - `store.ts:370` -- `detectEmotionIfEnabled()` auto-annotates on `store()`
47
- - `retriever.ts:261` -- `applyEmotionWeight()` retrieval scoring is live
48
- - `retriever.ts:1657` -- `applyTimeDecay()` does NOT use emotion-adjusted half-life
49
- - `memory-evolution.ts:306` -- `computeDecayScore()` has no emotion factor
50
- - Feature flag: `RECALLNEST_EMOTION_SCORING=true`
51
-
52
- ### Files Changed
53
-
54
- | File | Function(s) | Change |
55
- |------|------------|--------|
56
- | `src/memory-schema.ts` | `EmotionMetadata`, `EmotionMetadataSchema` | Add `salience` and `source` fields |
57
- | `src/retriever.ts` | `applyTimeDecay()` (line 1657) | Wire `adjustHalfLifeForEmotion()` into half-life computation |
58
- | `src/memory-evolution.ts` | `computeDecayScore()` (line 306), weight constants | Add emotion salience factor, rebalance weights |
59
- | `src/store.ts` | `update()` (line 863) | Recalculate emotion when text changes |
60
- | `src/store.ts` | `importEntry()` (line 433) | Backfill emotion if absent |
61
- | `src/emotion-detector.ts` | `detectEmotion()` | Compute `salience` from |valence| + arousal |
62
- | Tests | New + updated | Emotion-decay integration, update re-detection, import backfill |
63
-
64
- ### Steps
65
-
66
- #### 1.1 Extend EmotionMetadata schema
67
- **File:** `src/memory-schema.ts` (lines 40-53)
68
-
69
- - [x] Add `salience?: number` field to `EmotionMetadata` interface (0-1 composite of |valence| + arousal)
70
- - [x] Add `source?: "keyword" | "llm" | "user"` field to `EmotionMetadata` interface
71
- - [x] Update `EmotionMetadataSchema` Zod object to include `salience: z.number().min(0).max(1).optional()` and `source: z.enum(["keyword", "llm", "user"]).optional()`
72
- - [x] Verify `parseEmotion()` still works with old data (no salience/source)
73
- - **Why:** Salience is the single composite signal that decay and evolution scoring will consume. Source enables future LLM-based emotion detection without breaking keyword entries.
74
- - **Risk:** Low -- additive optional fields, backward compatible
75
-
76
- #### 1.2 Compute salience in detectEmotion
77
- **File:** `src/emotion-detector.ts`, function `detectEmotion()` (line 62)
78
-
79
- - [x] After computing `valence` and `arousal`, compute `salience = clamp((Math.abs(valence) + arousal) / 2, 0, 1)`
80
- - [x] Add `salience` and `source: "keyword"` to the returned `EmotionMetadata` object
81
- - [x] Update `detectEmotionIfEnabled()` -- no change needed (passes through)
82
- - **Why:** Decay engine needs a single 0-1 signal, not separate valence/arousal. Formula: average of emotional intensity and arousal, giving equal weight to "how emotional" and "how urgent."
83
- - **Risk:** Low -- pure addition to return value
84
-
85
- #### 1.3 Wire emotion into applyTimeDecay
86
- **File:** `src/retriever.ts`, method `applyTimeDecay()` (line 1657)
87
-
88
- - [x] Import `adjustHalfLifeForEmotion` from `decay-engine.ts` and `parseEmotion` from `memory-schema.ts`
89
- - [x] At line 1670-1672 (after `this.accessTracker.computeEffectiveHalfLife()`), add emotion adjustment: if `isEmotionScoringEnabled()`, parse emotion from `r.entry.metadata`, call `adjustHalfLifeForEmotion(halfLife, emotion)` to get final half-life
90
- - [x] Guard behind `isEmotionScoringEnabled()` flag check
91
- - [x] The arousal boost (`computeArousalBoost()`) applies to score before decay
92
-
93
- **Current code pattern:**
94
- ```typescript
95
- const halfLife = this.accessTracker
96
- ? this.accessTracker.computeEffectiveHalfLife(baseHalfLife, r.entry.metadata)
97
- : baseHalfLife;
98
- const tier = resolveTier(r.entry.metadata);
99
- const factor = weibullDecay(ageDays, halfLife, tier);
100
- return { ...r, score: clamp01(r.score * factor, r.score * 0.3) };
101
- ```
102
-
103
- **Target code:**
104
- ```typescript
105
- let halfLife = this.accessTracker
106
- ? this.accessTracker.computeEffectiveHalfLife(baseHalfLife, r.entry.metadata)
107
- : baseHalfLife;
108
- // HP-emo: Emotion-adjusted half-life — strong emotion slows forgetting
109
- const emotion = isEmotionScoringEnabled() ? parseEmotion(r.entry.metadata) : null;
110
- if (emotion) {
111
- halfLife = adjustHalfLifeForEmotion(halfLife, emotion);
112
- }
113
- const tier = resolveTier(r.entry.metadata);
114
- const factor = weibullDecay(ageDays, halfLife, tier);
115
- const arousalFactor = emotion ? computeArousalBoost(emotion) : 1.0;
116
- return { ...r, score: clamp01(r.score * arousalFactor * factor, r.score * 0.3) };
117
- ```
118
-
119
- - **Why:** This is the primary gap -- emotion detection runs on write, emotion weight runs on retrieval scoring, but the decay curve itself ignores emotion. A frustrating debugging session should decay slower than a neutral log entry.
120
- - **Risk:** Medium -- touches the core scoring pipeline. Parse emotion once per result to avoid double-parse overhead.
121
-
122
- #### 1.4 Add emotion factor to computeDecayScore
123
- **File:** `src/memory-evolution.ts`, function `computeDecayScore()` (line 306), constants at lines 292-295
124
-
125
- - [x] Import `parseEmotion`, `isEmotionScoringEnabled` from `memory-schema.ts`
126
- - [x] Add optional `metadata?: string` parameter to `computeDecayScore()` (backward compatible)
127
- - [x] When `isEmotionScoringEnabled()` and metadata is provided, extract salience
128
- - [x] Rebalance weights from `0.2/0.3/0.5` to `0.15/0.25/0.45/0.15`:
129
- ```typescript
130
- const EMOTION_WEIGHT = isEmotionScoringEnabled() ? 0.15 : 0;
131
- const TIME_W = isEmotionScoringEnabled() ? 0.15 : 0.2;
132
- const FREQ_W = isEmotionScoringEnabled() ? 0.25 : 0.3;
133
- const IMP_W = isEmotionScoringEnabled() ? 0.45 : 0.5;
134
- // Final: TIME_W * timeDecay + FREQ_W * frequencyScore + IMP_W * importance + EMOTION_WEIGHT * salience
135
- ```
136
- - [x] Update all callers to pass metadata where available:
137
- - `auto-gc.ts:142` -- pass `entry.metadata`
138
- - `retriever.ts:1712` (applyEvolutionDecayBlend) -- pass `r.entry.metadata`
139
- - **Why:** The evolution decay score determines GC archival and evolution blend. Without emotion, high-emotion events get same decay as routine logs.
140
- - **Risk:** Medium -- changes GC archival threshold behavior. Emotional memories will resist archival slightly more (desirable).
141
-
142
- #### 1.5 Re-detect emotion on text update
143
- **File:** `src/store.ts`, method `update()` (line 863)
144
-
145
- - [x] After building the `updated` entry, if `updates.text` is provided (text changed), re-run emotion detection:
146
- ```typescript
147
- if (updates.text) {
148
- const emotionResult = detectEmotionIfEnabled(updated.text);
149
- if (emotionResult) {
150
- const meta = JSON.parse(updated.metadata || "{}");
151
- meta.emotion = emotionResult;
152
- updated.metadata = JSON.stringify(meta);
153
- }
154
- }
155
- ```
156
- - [x] Place this BEFORE the `table!.delete` + `table!.add` at lines 918-920
157
- - **Why:** When text is updated (e.g., supersede-with-edit), stale emotion metadata creates scoring inaccuracy.
158
- - **Risk:** Low -- only fires when text is explicitly changed
159
-
160
- #### 1.6 Backfill emotion on importEntry
161
- **File:** `src/store.ts`, method `importEntry()` (line 433)
162
-
163
- - [x] After building `full` entry, check if emotion is already present in metadata. If not, detect and inject:
164
- ```typescript
165
- const metaParsed = JSON.parse(full.metadata || "{}");
166
- if (!metaParsed.emotion) {
167
- const emotionResult = detectEmotionIfEnabled(full.text);
168
- if (emotionResult) {
169
- metaParsed.emotion = emotionResult;
170
- full.metadata = JSON.stringify(metaParsed);
171
- }
172
- }
173
- ```
174
- - **Why:** Imported entries may pre-date emotion detection. Backfilling ensures all entries have emotion metadata.
175
- - **Risk:** Low -- only adds when absent, never overwrites
176
-
177
- #### 1.7 Tests
178
- - [x] **emotion-decay.test.ts**: Add test that `salience` is present in `detectEmotion()` output and matches expected formula
179
- - [x] **emotion-decay.test.ts**: Add test that `source` field is `"keyword"` in `detectEmotion()` output
180
- - [x] **New: emotion-evolution-decay.test.ts**: Test `computeDecayScore` with emotion metadata yields higher score than without
181
- - [x] **New: emotion-evolution-decay.test.ts**: Test backward compat -- no metadata param still works
182
- - [x] **New: emotion-evolution-decay.test.ts**: Test weight rebalancing (weights sum to 1.0)
183
- - [x] **Extend retriever tests**: Two entries, same age/importance/frequency, different emotion -- emotional one scores higher after `applyTimeDecay`
184
- - [x] **Store tests**: Verify `update()` with text change re-detects emotion
185
- - [x] **Store tests**: Verify `importEntry()` backfills emotion when absent, preserves when present
186
- - [x] Run `bun test` -- all 1000+ tests must pass
187
-
188
- ### Verification
189
- 1. `bun test` -- full green, baseline maintained
190
- 2. Manual check: store emotional memory, retrieve at simulated t=30d, confirm higher score vs neutral
191
- 3. Check `computeDecayScore` output for emotional vs neutral with same evo params
192
-
193
- ### Risks for Phase 1
194
- - **Double-parse overhead in applyTimeDecay**: Parse emotion once per result, pass to both functions
195
- - **Weight rebalancing changes GC behavior**: Test with existing GC tests
196
- - **Feature flag dependency**: All changes gated by `RECALLNEST_EMOTION_SCORING=true`. Flag off = identical to current
197
-
198
- ---
199
-
200
- ## Phase 2: Memory Ethics Layer
201
-
202
- ### Goal
203
- Add privacy tiers, build a proper forget engine with cascade deletion, unify lifecycle state inconsistency, expose `forget_memory` MCP tool with audit logging.
204
-
205
- ### Current State
206
- - `cascade-forget.ts:91` reads legacy `meta.state` -- inconsistent with `evolution.status`
207
- - `consolidation-engine.ts:71-77` reads BOTH `isActiveMemory()` and `meta.state`
208
- - `audit-log.ts` exists but lacks "forget" operation type
209
- - `KGStore.deleteBySource()` exists at `kg-store.ts:314` but never called from forget path
210
- - No privacy tier field exists
211
-
212
- ### Files Changed
213
-
214
- | File | Function(s) | Change |
215
- |------|------------|--------|
216
- | `src/memory-schema.ts` | New types | `PrivacyTier` type + Zod schema |
217
- | `src/forget-engine.ts` | **New file** | Full cascade forget with KG cleanup, audit, privacy checks |
218
- | `src/audit-log.ts` | `AuditOperation` type | Add `"forget"` and `"cascade_forget"` operations |
219
- | `src/cascade-forget.ts` | `cascadeForget()` | Migrate `meta.state` to `evolution.status` |
220
- | `src/consolidation-engine.ts` | `isActive()` | Remove legacy `meta.state` double-check |
221
- | `src/capture-engine.ts` | KG extraction gate | Privacy tier check before KG extraction |
222
- | `src/mcp-server.ts` | New tool | `forget_memory` MCP tool |
223
- | `src/store.ts` | `store()`, `StoreMemoryInput` | Accept optional `privacyTier` |
224
- | Tests | New | forget-engine, privacy-tier, lifecycle-state tests |
225
-
226
- ### Steps
227
-
228
- #### 2.1 Add PrivacyTier to schema
229
- - [x] `PrivacyTier` type: `"ephemeral" | "private" | "durable" | "shared"`
230
- - [x] `PrivacyTierSchema` Zod enum
231
- - [x] Optional `privacyTier` in `StoreMemoryInputSchema`
232
-
233
- #### 2.2 Unify lifecycle state
234
- - [x] `cascade-forget.ts:91` -- replace `meta.state` with `isActiveMemory()`
235
- - [x] `consolidation-engine.ts:70-77` -- simplify to only `isActiveMemory()`
236
- - [x] Grep for any other `meta.state` reads, migrate them all
237
-
238
- #### 2.3 Extend audit operations
239
- - [x] Add `"forget"` and `"cascade_forget"` to `AuditOperation` union
240
-
241
- #### 2.4 Build forget engine (NEW: `src/forget-engine.ts`)
242
- - [x] `forgetMemory()`: fetch → privacy check → evidence export → KG delete → pin archive → cascade → primary delete → audit
243
- - [x] `forgetByScope()` for bulk scope-level forget
244
- - [x] Confirmation gate for `"durable"` entries
245
-
246
- #### 2.5 Privacy tier gate in capture
247
- - [x] Before KG extraction, skip if `privacyTier === "ephemeral" | "private"`
248
-
249
- #### 2.6 Register `forget_memory` MCP tool
250
- - [x] Schema: `{ memoryId: string, confirm: boolean, reason?: string }`
251
- - [x] Returns deletion summary + evidence paths
252
-
253
- #### 2.7 Tests
254
- - [x] forget-engine: KG cleanup, cascade demotion, audit trail
255
- - [x] Privacy tier blocks without confirm
256
- - [x] Evidence export for high-importance memories
257
- - [x] Consolidation/cascade-forget regression with new `isActiveMemory()`
258
- - [x] `bun test` full green
259
-
260
- ### Verification
261
- 1. Store memory → extract KG → forget → verify KG triples gone
262
- 2. Audit log shows complete forget trail
263
- 3. `"ephemeral"` memory produces no KG triples
264
-
265
- ---
266
-
267
- ## Phase 3: Autobiographical Narrative Architecture
268
-
269
- ### Goal
270
- Add orthogonal narrative metadata layer (life-period / general-event / specific-event) on top of existing 6 categories. Enable temporal grouping and narrative retrieval without disrupting category logic.
271
-
272
- ### Current State
273
- - 6 categories hardcoded across `memory-schema.ts`, `memory-boundaries.ts`, `retriever.ts`, `context-composer.ts` -- **do not modify**
274
- - `event-segmenter.ts:105` has `segmentEvents()`, `temporal-parser.ts:15` has date parsing
275
-
276
- ### Files Changed
277
-
278
- | File | Function(s) | Change |
279
- |------|------------|--------|
280
- | `src/narrative-schema.ts` | **New file** | Narrative metadata types + Zod schemas |
281
- | `src/narrative-tagger.ts` | **New file** | Rule-based narrative period/event assignment |
282
- | `src/capture-engine.ts` | `buildStructuredMetadata()` | Inject narrative metadata |
283
- | `src/ingest.ts` | `buildIngestedEntry()` | Inject narrative metadata |
284
- | `src/retriever.ts` | New method | `expandNarrativeSiblings()` |
285
- | `src/context-composer.ts` | Result rendering | Group by narrative period |
286
- | `src/memory-output.ts` | Rendering | Narrative period labels |
287
- | `src/graph-export.ts` | Graph edges | Narrative relationship edges |
288
-
289
- ### Steps
290
- - [x] 3.1 Define `NarrativeMetadata` interface: `lifePeriodId/Label`, `generalEventId/Label`, `specificEventId/Label`, `startAt`, `endAt`, `sequence`
291
- - [x] 3.2 Build rule-based narrative tagger (scope prefix, temporal clustering, keyword signals)
292
- - [x] 3.3 Inject narrative at write points (`capture-engine.ts:140`, `ingest.ts:662`)
293
- - [x] 3.4 `expandNarrativeSiblings()` in retriever: pull entries sharing same `generalEventId`
294
- - [x] 3.5 Rendering updates: group by `lifePeriodLabel`, narrative edges in graph export
295
- - [x] 3.6 Tests + `bun test` full green
296
-
297
- ---
298
-
299
- ## Phase 4: Constructive Retrieval
300
-
301
- ### Goal
302
- Replace "top-k then summarize" with multi-source candidate expansion + grounded reconstruction. Return reconstruction as first-class object.
303
-
304
- ### Current State
305
- - `context-reconstructor.ts:91` exists, `retriever.ts:706` `runReconstruction()` exists
306
- - `mcp-server.ts:888` supports `reconstruct=true`
307
- - But: only top-k summarize, `metadata._reconstruction` is hacky, `computeCoverage()` is lexical
308
-
309
- ### Steps
310
- - [x] 4.1 Define `ReconstructionOutput` with sources, confidence, contradictions
311
- - [x] 4.2 Add candidate expansion: KG neighbors + evolution chains + cluster members + narrative siblings
312
- - [x] 4.3 Replace lexical coverage with source-map grounding + contradiction detection
313
- - [x] 4.4 Return reconstruction as first-class object (remove `metadata._reconstruction` hack)
314
- - [x] 4.5 Update MCP rendering for new output shape
315
- - [x] 4.6 Pass checkpoint context (openLoops, nextActions) into reconstruction prompt
316
- - [x] 4.7 Tests + `bun test` full green
317
-
318
- ---
319
-
320
- ## Phase 5: Predictive Prospective Memory
321
-
322
- ### Goal
323
- Evolve `prospective-memory.ts` from explicit reminders to include pattern-predicted suggestions. Surface behavioral insights as ephemeral predicted reminders.
324
-
325
- ### Current State
326
- - `prospective-memory.ts` -- `setReminder()`, `checkTriggers()`, `fireReminder()` explicit only
327
- - Behavioral signals: checkpoint openLoops, workflow observations, frequency tracker, access tracker, topic tags
328
-
329
- ### Steps
330
- - [x] 5.1 Extend `ProspectiveMetadata` with `source`, `confidence`, `evidence`, `lastSuggestedAt`, `acceptedAt`
331
- - [x] 5.2 Build `prediction-engine.ts`: collect signals, score predictions, threshold at confidence >= 0.6
332
- - [x] 5.3 `suggestPredictedReminders()`: deduplicate vs existing, store as ephemeral, auto-expire 7d
333
- - [x] 5.4 Surface in `search_memory` as separate "Suggested Reminders" section
334
- - [x] 5.5 Acceptance/promotion flow: repeated/accepted → promote to explicit; ignored → demote
335
- - [x] 5.6 Tests + `bun test` full green
336
-
337
- ---
338
-
339
- ## Global Risks & Mitigations
340
-
341
- | Risk | Impact | Mitigation |
342
- |------|--------|-----------|
343
- | Feature flag proliferation | Complexity | Phase 1-2 reuse `RECALLNEST_EMOTION_SCORING`. Phase 3-5 add `RECALLNEST_NARRATIVE_MODE` and `RECALLNEST_PREDICTIVE_MEMORY` |
344
- | Metadata JSON bloat | Storage + parse cost | Each phase adds ~100 bytes/entry. Total metadata stays under 2KB |
345
- | Scoring formula instability | Retrieval quality regression | Every weight change gated by feature flag and tested against eval cases |
346
- | LLM cost creep (Phase 4-5) | Token spend | Phase 1-3 zero LLM. Phase 4 reuses existing reconstruction budget. Phase 5 zero LLM (heuristic) |
347
-
348
- ---
349
-
350
- ## Success Criteria
351
-
352
- - [x] Phase 1: Emotional memories decay 20-30% slower than neutral memories of same age
353
- - [x] Phase 1: `computeDecayScore` with emotion gives higher scores for high-salience memories
354
- - [x] Phase 1: All existing tests pass, emotion-decay tests extended
355
- - [x] Phase 2: `forget_memory` MCP tool deletes entry + KG triples + cascade demotes + audit logs
356
- - [x] Phase 2: No more `meta.state` reads anywhere in codebase (all `evolution.status`)
357
- - [x] Phase 3: Ingested sessions have narrative metadata with period/event IDs
358
- - [x] Phase 3: Search returns narrative siblings alongside direct matches
359
- - [x] Phase 4: Reconstruction uses expanded candidate set (KG + evolution + cluster)
360
- - [x] Phase 4: Reconstruction is first-class return object, not metadata hack
361
- - [x] Phase 5: Predicted reminders surface from behavioral signals
362
- - [x] Phase 5: Predictions auto-expire and respect acceptance/rejection
363
- - [x] All phases: `bun test` passes with baseline maintained or increased
@@ -1,155 +0,0 @@
1
- # RecallNest 产品化升级实施计划
2
-
3
- ## 目标
4
-
5
- 把 RecallNest 从"引擎很强但用户无感"变成"用户能看到记忆在成长"。
6
-
7
- ## 四个升级(按优先级)
8
-
9
- ---
10
-
11
- ### Upgrade 1: SKILL.md — 记忆伙伴使用协议
12
-
13
- **做什么**:在 repo 根目录创建 `SKILL.md`,教 LLM 怎么当好记忆伙伴(不只是 API 文档)。
14
-
15
- **内容结构**:
16
- - Session Protocol(resume → work → checkpoint)
17
- - Onboarding Flow(首次检测:memory_stats 为 0 时引导)
18
- - Memory Feedback(store 后回显,search 后展示匹配)
19
- - Tool Decision Tree(什么时候 store vs checkpoint vs pin)
20
- - Weekly Health Check(data_checkup + dream + lint)
21
-
22
- **改动**:
23
- - 新建 `SKILL.md`(~250 行 markdown)
24
- - 零代码改动
25
-
26
- **风险**:低。纯文档。
27
-
28
- ---
29
-
30
- ### Upgrade 2: Memory Lint — 记忆体检
31
-
32
- **做什么**:新增 MCP tool + CLI 命令,对记忆做质量自检。
33
-
34
- **检查项**:
35
- | 检查 | 复用什么 | 怎么做 |
36
- |------|---------|--------|
37
- | 矛盾检测 | `detectHeuristicContradiction`(consolidation-engine.ts) | 同 scope 同 category 内两两比较 |
38
- | 重复检测 | `cosineSimilarity`(multi-vector.ts) | 向量相似度 > 0.92 的配对 |
39
- | 陈旧检测 | `parseEvolution` 的 accessCount/lastAccessedAt | 90 天未被召回 + accessCount ≤ 1 |
40
- | 孤儿检测 | consolidatedInto 指向的 ID | 不存在的引用 |
41
- | 健康分 | 综合以上 | 100 - (矛盾×10 + 重复×5 + 陈旧×2 + 孤儿×3) |
42
-
43
- **改动**:
44
- - 新建 `src/memory-lint.ts`(~180 行)
45
- - 新建 `src/__tests__/memory-lint.test.ts`(~150 行)
46
- - 改 `src/mcp-server.ts`:注册 `memory_lint` tool(~25 行)
47
- - 改 `src/cli.ts`:增加 `lint` 命令(~30 行)
48
- - 改 `src/api-server.ts`:增加 `GET /v1/lint`(~20 行)
49
- - 改 `src/consolidation-engine.ts`:export `detectHeuristicContradiction`(1 行)
50
- - 改 `package.json`:增加 `lint:memory` 脚本
51
-
52
- **性能守卫**:矛盾/重复检测是 O(n²),每个 scope/category 组限 200 条,按 importance 降序取。
53
-
54
- **预计**:~405 LOC
55
-
56
- **风险**:中。矛盾检测基于启发式,会有误报,报告中标注"启发式建议"。
57
-
58
- ---
59
-
60
- ### Upgrade 3: Dashboard 仪表盘首页
61
-
62
- **做什么**:现有 UI(port 4317)只有搜索,加一个 Dashboard 首页 tab。
63
-
64
- **展示内容**:
65
- - 总记忆数 + 分类分布(bar chart,纯 CSS 实现,不引入图表库)
66
- - 本周/本月新增趋势
67
- - 健康分(来自 Lint)
68
- - 最近召回 Top N
69
- - 沉睡记忆列表(90天未召回)
70
-
71
- **改动**:
72
- - 改 `src/ui-server.ts`:新增 4 个 API endpoint(~80 行)
73
- - `GET /api/dashboard-stats`
74
- - `GET /api/recent-recalls`
75
- - `GET /api/lint-summary`
76
- - `GET /api/stale-memories`
77
- - 改 `assets/ui/index.html`:增加 Dashboard tab(~60 行)
78
- - 改 `assets/ui/app.js`:Dashboard 渲染逻辑(~120 行)
79
- - 改 `assets/ui/styles.css`:Dashboard 样式(~80 行)
80
-
81
- **依赖**:Upgrade 2(Lint 的健康分)。可以先不接 Lint,用 placeholder。
82
-
83
- **预计**:~340 LOC
84
-
85
- **风险**:中。Growth trend 需要扫全量 entries 按时间分桶,大库可能慢。缓存 60s 缓解。
86
-
87
- ---
88
-
89
- ### Upgrade 4: HTML 知识图谱
90
-
91
- **做什么**:把记忆导出为一个交互式 HTML 文件,浏览器打开即可看到力导向图。
92
-
93
- **节点/边设计**:
94
- - 节点 = 每条记忆,颜色按 category(profile=金, preferences=蓝, entities=绿, events=灰, cases=红, patterns=紫)
95
- - 边 = scope 关系 + consolidation 链 + supersede 链 + cluster 关系
96
- - 支持缩放、拖拽、点击查看详情
97
-
98
- **改动**:
99
- - 新建 `src/graph-export.ts`(~250 行)
100
- - `buildMemoryGraph()`:从 store 构建节点/边
101
- - `renderGraphHTML()`:生成自包含 HTML(D3.js via CDN,或 `--offline` 内嵌)
102
- - `exportMemoryGraph()`:写文件到 `data/exports/`
103
- - 新建 `src/__tests__/graph-export.test.ts`(~100 行)
104
- - 改 `src/mcp-server.ts`:注册 `export_graph` tool(~25 行)
105
- - 改 `src/cli.ts`:增加 `graph` 命令(~25 行)
106
- - 改 `src/ui-server.ts`:增加 `/api/graph` endpoint(~20 行)
107
-
108
- **默认上限**:200 节点(按 importance 降序),避免图谱变成乱麻。
109
-
110
- **预计**:~420 LOC
111
-
112
- **风险**:中高。>100 节点时力导向布局可能卡顿。限制节点数+scope 过滤。
113
-
114
- ---
115
-
116
- ## 实施顺序
117
-
118
- ```
119
- Phase 1(可独立合并)
120
- ├── 1.1 SKILL.md(无代码依赖)
121
- └── 1.2 memory-lint.ts + tests
122
-
123
- Phase 2(依赖 1.2)
124
- ├── 2.1 Lint MCP tool + CLI
125
- └── 2.2 Lint API endpoint
126
-
127
- Phase 3(依赖 Phase 2)
128
- └── 3.1 Dashboard 首页
129
-
130
- Phase 4(独立,可与 1-3 并行)
131
- └── 4.1 HTML 知识图谱
132
- ```
133
-
134
- **可并行**:SKILL.md 和 Graph Export 不依赖其他升级。
135
-
136
- ## 总改动量
137
-
138
- | 升级 | 新文件 | 改动文件 | 新增 LOC |
139
- |------|--------|---------|---------|
140
- | SKILL.md | 1 | 0 | ~250 (markdown) |
141
- | Memory Lint | 2 | 4 | ~405 |
142
- | Dashboard | 0 | 4 | ~340 |
143
- | Knowledge Graph | 2 | 3 | ~420 |
144
- | **总计** | **5** | **~8** | **~1,415** |
145
-
146
- ## 成功标准
147
-
148
- - [ ] SKILL.md 覆盖 5 个核心场景
149
- - [ ] `memory_lint` MCP tool 返回矛盾/重复/陈旧/孤儿数量 + 0-100 健康分
150
- - [ ] `bun run src/cli.ts lint` CLI 输出相同报告
151
- - [ ] Dashboard tab 展示总记忆数、分类分布、健康分、沉睡记忆
152
- - [ ] `bun run src/cli.ts graph` 生成有效 HTML,浏览器打开有交互图谱
153
- - [ ] 现有 1168 个测试全部通过
154
- - [ ] 新增测试 > 20 个
155
- - [ ] 不引入新 npm 依赖
@@ -1,105 +0,0 @@
1
- # RecallNest v1.2: 首个可传播版本 Plan
2
-
3
- > 目标:别人 15 分钟能跑起来,30 分钟能感知价值
4
- > 负责人:CC (实现) + 用户 (审批)
5
- > 预计:3-4 天
6
-
7
- ---
8
-
9
- ## 阻塞项(必须修,按优先级排)
10
-
11
- ### B1: `recallnest doctor` 命令(新增) ✅ DONE
12
- **问题**:用户装完后没有一键验证手段,每个环节都可能静默失败
13
- **方案**:新增 `lm doctor` 子命令,检查清单:
14
- - [x] Bun 运行时可用?(检测版本)
15
- - [x] Jina API key 已配置?(读 .env)
16
- - [x] Jina API key 有效?(发一个测试 embedding 请求)
17
- - [x] CC transcript 路径可访问?(auto-detect 或 config)
18
- - [x] LanceDB 数据目录可写?
19
- - [x] 已有索引?多少条?
20
- - 输出:绿色 PASS / 红色 FAIL + 修复建议
21
-
22
- ### B2: README 安装体验重写 ✅ DONE
23
- **问题**:Bun 未提及、Jina key 获取无引导、步骤跳跃
24
- **方案**:
25
- - [x] Prerequisites 段:明确列出 Bun ≥1.0 + Node ≥20(Bun 优先,Node 作为 fallback 说明)
26
- - [x] 快速开始改为 5 步 copy-paste:clone → install → 配 key → doctor → search
27
- - [x] 每步附带预期输出(用户知道"成功了"长什么样)
28
- - [x] 添加 "Troubleshooting" 段:Bun not found / Jina 401 / 路径不存在
29
-
30
- ### B3: Jina API key 前置验证 ✅ DONE
31
- **问题**:config 加载成功,但第一次 ingest 才报 embedding 失败,错误信息是 OpenAI SDK 的原始 401
32
- **方案**:
33
- - [x] `ingest` 命令启动时,先调 embedder 发一个测试请求(embed "test")
34
- - [x] 失败则立即报错:`Jina API key invalid or missing. Get one at https://jina.ai/embeddings/`
35
- - [x] `doctor` 命令复用同一验证逻辑
36
-
37
- ### B4: Gemini 支持诚实化 ✅ DONE
38
- **问题**:README 说支持 Gemini CLI,config 里有 gemini 源,但实际 Gemini 会话是加密 protobuf,解析不了
39
- **方案**:
40
- - [x] README 中 Gemini 行标注为 `Coming soon`(不是 ✅)
41
- - [x] config.json.example 中移除 gemini source(新用户不会误配)
42
- - [x] ingest 遇到 gemini source 时打印明确 warning:`Gemini CLI sessions are encrypted protobuf; skipping`
43
- - [x] doctor 显示 Gemini 状态为 warn(已有配置的用户看到明确提示)
44
- - 不删代码,保留未来扩展能力
45
-
46
- ### B5: 配置路径健壮化 ✅ DONE
47
- **问题**:`./data/lancedb` 是相对路径,换目录就炸;auto-detect 失败后建议不够具体
48
- **方案**:
49
- - [x] config.json.example 默认路径改为 `~/.recallnest/data/lancedb`(绝对,用户无感)
50
- - [x] 首次运行自动创建目录(validateStoragePath 已有 mkdirSync recursive)
51
- - [x] auto-detect 失败时,给出完整示例(含用户名的真实路径)
52
- - [x] config.json 加入 .gitignore,用户配置不被 git 覆盖
53
- - [x] findConfigPath 失败时提示 `cp config.json.example config.json`
54
-
55
- ---
56
-
57
- ## 加分项(做了更好,不阻塞发布)
58
-
59
- ### P1: Demo 查询内置 ✅ DONE
60
- - [x] `lm demo` 命令:用 3 个内置 query 跑搜索,展示结果格式
61
- - [x] 显示索引统计 + 每条结果的分数/来源/预览
62
-
63
- ### P2: 一键安装脚本
64
- - [ ] `curl -fsSL https://raw.githubusercontent.com/.../install.sh | bash`
65
- - [ ] 检测 Bun → clone → npm install → 提示配 key → 跑 doctor
66
- - [ ] 可以 Q2 再做,现在 README 手动步骤够用
67
-
68
- ### P3: CI 基础 ✅ DONE
69
- - [x] GitHub Actions:push/PR 时跑 `doctor --ci` + TypeScript check
70
- - [x] `lm doctor --ci` 模式跳过 API key 在线验证
71
-
72
- ### P4: CHANGELOG.md ✅ DONE
73
- - [x] v1.0.0 到 v1.2.0 的变更记录
74
- - [x] 后续每个 release 维护
75
-
76
- ---
77
-
78
- ## 不做的事(明确排除)
79
-
80
- - ❌ 不做 Docker 化(用户群是 CLI/MCP 用户,不是 Docker 用户)
81
- - ❌ 不做 NPM 发布(先 git clone 模式验证需求)
82
- - ❌ 不做 UI 重写(现有 UI 够用,不是本次重点)
83
- - ❌ 不做多用户支持(单 operator 场景)
84
- - ❌ 不重写检索逻辑(已经够好,不是本次范围)
85
-
86
- ---
87
-
88
- ## 执行顺序
89
-
90
- ```
91
- Day 1: B1 (doctor) + B3 (Jina 验证) — 核心安全网 ✅
92
- Day 2: B5 (路径健壮化) + B4 (Gemini 诚实化) + B2 (README 重写) ✅
93
- Day 3: P1 (demo 查询) + P3 (CI) + P4 (CHANGELOG) ✅
94
- Day 4: 自测完整流程
95
- ```
96
-
97
- ---
98
-
99
- ## 验收标准
100
-
101
- 1. 全新 macOS 机器(有 Bun),从 clone 到第一条搜索结果 ≤ 15 分钟
102
- 2. `lm doctor` 全绿
103
- 3. Jina key 错误时,3 秒内给出明确修复建议
104
- 4. README 无需翻代码即可完成安装
105
- 5. `lm search "telegram bridge"` 返回有意义结果