recallnest 1.4.1 → 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 (233) hide show
  1. package/.env +4 -0
  2. package/CLAUDE.md +7 -3
  3. package/README.md +202 -130
  4. package/README_CN.md +263 -190
  5. package/bin/recallnest.mjs +62 -0
  6. package/config.json +55 -0
  7. package/daily-recall.sh +23 -0
  8. package/integrations/setup-all.sh +31 -0
  9. package/logs/daily-recall.error.log +0 -0
  10. package/logs/daily-recall.log +30 -0
  11. package/logs/ingest-2026-04-11.log +110 -0
  12. package/logs/ingest-2026-04-12.log +90 -0
  13. package/logs/launchagent-stderr.log +0 -0
  14. package/logs/launchagent-stdout.log +0 -0
  15. package/package.json +10 -3
  16. package/src/access-tracker.ts +3 -2
  17. package/src/activity-counter.ts +109 -0
  18. package/src/adaptive-retrieval.ts +6 -5
  19. package/src/admission-control.ts +163 -0
  20. package/src/anchor-generator.ts +80 -0
  21. package/src/api-server.ts +10 -0
  22. package/src/audit-log.ts +122 -0
  23. package/src/auto-gc.ts +98 -29
  24. package/src/auto-recall.ts +33 -4
  25. package/src/capture-engine.ts +372 -23
  26. package/src/cascade-forget.ts +3 -2
  27. package/src/cli.ts +107 -5
  28. package/src/compat.ts +22 -0
  29. package/src/confidence-tracker.ts +210 -47
  30. package/src/conflict-store.ts +12 -3
  31. package/src/consolidation-engine.ts +296 -8
  32. package/src/context-collapse-renderer.ts +222 -0
  33. package/src/context-composer-stable-selection.ts +5 -1
  34. package/src/context-composer.ts +239 -4
  35. package/src/context-reconstructor.ts +404 -0
  36. package/src/conversation-importer.ts +441 -0
  37. package/src/data-checkup.ts +232 -0
  38. package/src/decay-engine.ts +84 -0
  39. package/src/distill-lock.ts +122 -0
  40. package/src/doctor.ts +8 -10
  41. package/src/dream-pipeline.ts +227 -0
  42. package/src/emotion-detector.ts +90 -0
  43. package/src/eval.ts +3 -2
  44. package/src/forget-engine.ts +269 -0
  45. package/src/frequency-tracker.ts +175 -0
  46. package/src/graph-export.ts +644 -0
  47. package/src/ingest.ts +36 -6
  48. package/src/interference-detector.ts +187 -0
  49. package/src/kg-extractor.ts +15 -24
  50. package/src/kg-store.ts +2 -1
  51. package/src/language-hook.ts +67 -0
  52. package/src/llm-client.ts +289 -6
  53. package/src/mcp-server.ts +707 -80
  54. package/src/memory-assets.ts +22 -5
  55. package/src/memory-evolution.ts +365 -0
  56. package/src/memory-lint.ts +429 -0
  57. package/src/memory-output.ts +69 -0
  58. package/src/memory-schema.ts +74 -2
  59. package/src/narrative-schema.ts +79 -0
  60. package/src/narrative-tagger.ts +164 -0
  61. package/src/pii-detector.ts +98 -0
  62. package/src/post-retrieval-filter.ts +76 -0
  63. package/src/prediction-engine.ts +253 -0
  64. package/src/preference-slots.ts +65 -2
  65. package/src/prospective-memory.ts +215 -0
  66. package/src/query-expander.ts +67 -0
  67. package/src/recall-governor.ts +183 -0
  68. package/src/retention-policy.ts +90 -0
  69. package/src/retriever.ts +828 -55
  70. package/src/rif.ts +34 -8
  71. package/src/runtime-config.ts +23 -8
  72. package/src/scope-inventory.ts +4 -3
  73. package/src/scope-policy.ts +4 -0
  74. package/src/session-distiller.ts +307 -0
  75. package/src/session-output.ts +40 -0
  76. package/src/session-schema.ts +37 -0
  77. package/src/session-store.ts +7 -2
  78. package/src/skill-engine.ts +208 -0
  79. package/src/skill-promotion.ts +293 -0
  80. package/src/skill-schema.ts +39 -0
  81. package/src/store.ts +96 -10
  82. package/src/topic-tag.ts +66 -0
  83. package/src/tracker.ts +3 -1
  84. package/src/ui-server.ts +80 -8
  85. package/src/workflow-observation-scope-review.ts +2 -1
  86. package/src/workflow-observation-store.ts +2 -1
  87. package/src/write-verifier.ts +126 -0
  88. package/.claude-plugin/CLAUDE.md +0 -29
  89. package/.claude-plugin/marketplace.json +0 -18
  90. package/.github/workflows/ci.yml +0 -28
  91. package/.mcp.json +0 -9
  92. package/CHANGELOG.md +0 -51
  93. package/DEMO.md +0 -94
  94. package/EVAL.md +0 -89
  95. package/FAILURES.md +0 -75
  96. package/OPERATIONS.md +0 -59
  97. package/ROADMAP.md +0 -198
  98. package/assets/recallnest-workbench.png +0 -0
  99. package/assets/ui/app.js +0 -807
  100. package/assets/ui/index.html +0 -154
  101. package/assets/ui/styles.css +0 -605
  102. package/assets/wechat-qr.jpg +0 -0
  103. package/daily-reflections/2026-03-05.md +0 -15
  104. package/daily-reflections/2026-03-06.md +0 -15
  105. package/daily-reflections/2026-03-07.md +0 -7
  106. package/daily-reflections/2026-03-08.md +0 -34
  107. package/daily-reflections/2026-03-09.md +0 -35
  108. package/daily-reflections/2026-03-10.md +0 -36
  109. package/daily-reflections/2026-03-11.md +0 -35
  110. package/daily-reflections/2026-03-12.md +0 -36
  111. package/daily-reflections/2026-03-13.md +0 -35
  112. package/daily-reflections/2026-03-14.md +0 -35
  113. package/daily-reflections/2026-03-15.md +0 -35
  114. package/daily-reflections/2026-03-16.md +0 -41
  115. package/daily-reflections/2026-03-17.md +0 -10
  116. package/daily-reflections/2026-03-18.md +0 -10
  117. package/daily-reflections/2026-03-19.md +0 -10
  118. package/daily-reflections/2026-03-20.md +0 -10
  119. package/daily-reflections/2026-03-21.md +0 -10
  120. package/daily-reflections/2026-03-22.md +0 -10
  121. package/daily-reflections/2026-03-23.md +0 -10
  122. package/daily-reflections/2026-03-24.md +0 -10
  123. package/daily-reflections/2026-03-25.md +0 -32
  124. package/daily-reflections/2026-03-26.md +0 -37
  125. package/daily-reflections/2026-03-27.md +0 -35
  126. package/daily-reflections/2026-03-28.md +0 -35
  127. package/daily-reflections/2026-03-29.md +0 -35
  128. package/daily-reflections/2026-03-30.md +0 -36
  129. package/daily-reflections/2026-03-31.md +0 -35
  130. package/daily-reflections/2026-04-01.md +0 -35
  131. package/docs/api-reference.md +0 -1291
  132. package/docs/architecture.md +0 -168
  133. package/docs/memory-boundary-contract.md +0 -226
  134. package/docs/memory-categories.md +0 -119
  135. package/docs/pipeline-audit-ultramemory.md +0 -177
  136. package/docs/plans/2026-03-08-query-expansion.md +0 -270
  137. package/docs/plans/2026-03-16-continuity-layer.md +0 -196
  138. package/docs/plans/mcp-tiering-plan.md +0 -126
  139. package/docs/research/recall-quality-audit-2026-03-22.md +0 -153
  140. package/docs/self-evolution.md +0 -198
  141. package/docs/superpowers/plans/2026-03-19-ingest-pipeline-upgrade.md +0 -782
  142. package/docs/superpowers/specs/2026-03-19-ingest-pipeline-upgrade-design.md +0 -77
  143. package/docs/superpowers/specs/2026-03-23-pull-claude-desktop-design.md +0 -95
  144. package/eval/continuity/results-2026-03-16.md +0 -117
  145. package/eval/continuity/results-2026-03-19.md +0 -453
  146. package/eval/continuity/runbook.md +0 -110
  147. package/eval/continuity/seed-cases.md +0 -54
  148. package/eval/reports/2026-03-06-abstract-query-baseline.md +0 -96
  149. package/eval/reports/2026-03-06-aws-ssh-baseline.md +0 -82
  150. package/eval/reports/2026-03-06-baseline.md +0 -82
  151. package/eval/reports/query-expansion.md +0 -138
  152. package/lm +0 -19
  153. package/plan-v1.2-distributable.md +0 -105
  154. package/scripts/archive-distilled-junk.ts +0 -116
  155. package/scripts/backfill-l0l1l2.ts +0 -98
  156. package/scripts/blind-scan.ts +0 -588
  157. package/scripts/cleanup-step1-exact-dups.ts +0 -117
  158. package/scripts/cleanup-step2-template-dups.ts +0 -113
  159. package/scripts/cleanup-step3-stale-content.ts +0 -149
  160. package/scripts/cleanup-step4-orphan-scopes.ts +0 -131
  161. package/scripts/delete-distilled-junk.ts +0 -88
  162. package/scripts/distill-facts.ts +0 -305
  163. package/scripts/health-check.ts +0 -343
  164. package/scripts/incremental-ingest.sh +0 -71
  165. package/scripts/mlp-health-check.ts +0 -382
  166. package/scripts/pull-claude-desktop.ts +0 -515
  167. package/scripts/re-ingest-cc.sh +0 -66
  168. package/scripts/rebalance-memory-health.ts +0 -181
  169. package/scripts/run-desktop-ingest.sh +0 -11
  170. package/scripts/start-server.sh +0 -12
  171. package/scripts/viz-dashboard.html +0 -423
  172. package/scripts/viz-export.ts +0 -703
  173. package/src/__tests__/access-tracker-novelty.test.ts +0 -228
  174. package/src/__tests__/auto-consolidation.test.ts +0 -168
  175. package/src/__tests__/auto-recall.test.ts +0 -131
  176. package/src/__tests__/batch-dedup.test.ts +0 -65
  177. package/src/__tests__/capture-engine.test.ts +0 -1142
  178. package/src/__tests__/capture-heuristic.test.ts +0 -171
  179. package/src/__tests__/cascade-forget.test.ts +0 -210
  180. package/src/__tests__/category-min-scores.test.ts +0 -33
  181. package/src/__tests__/confidence-tracker.test.ts +0 -196
  182. package/src/__tests__/conflict-advisor.test.ts +0 -206
  183. package/src/__tests__/conflict-escalation.test.ts +0 -149
  184. package/src/__tests__/conflict-lifecycle.test.ts +0 -83
  185. package/src/__tests__/conflict-output.test.ts +0 -85
  186. package/src/__tests__/conflict-store.test.ts +0 -374
  187. package/src/__tests__/consolidation-engine.test.ts +0 -181
  188. package/src/__tests__/context-composer-pins.test.ts +0 -64
  189. package/src/__tests__/context-composer-task-selection.test.ts +0 -24
  190. package/src/__tests__/context-renderer.test.ts +0 -91
  191. package/src/__tests__/continuity-eval.test.ts +0 -275
  192. package/src/__tests__/continuity-schema.test.ts +0 -97
  193. package/src/__tests__/core-recall-eval.test.ts +0 -235
  194. package/src/__tests__/core-summary.test.ts +0 -109
  195. package/src/__tests__/dedup-actions.test.ts +0 -58
  196. package/src/__tests__/deterministic-id.test.ts +0 -39
  197. package/src/__tests__/doctor.test.ts +0 -303
  198. package/src/__tests__/drill-down.test.ts +0 -108
  199. package/src/__tests__/embedder.test.ts +0 -122
  200. package/src/__tests__/entity-resolver.test.ts +0 -58
  201. package/src/__tests__/event-segmenter.test.ts +0 -153
  202. package/src/__tests__/hotness-blend.test.ts +0 -76
  203. package/src/__tests__/ingest.test.ts +0 -360
  204. package/src/__tests__/kg-extractor.test.ts +0 -184
  205. package/src/__tests__/kg-store.test.ts +0 -198
  206. package/src/__tests__/llm-consolidation.test.ts +0 -226
  207. package/src/__tests__/memory-boundaries.test.ts +0 -237
  208. package/src/__tests__/memory-health-rebalance.test.ts +0 -144
  209. package/src/__tests__/memory-output.test.ts +0 -215
  210. package/src/__tests__/multi-vector.test.ts +0 -242
  211. package/src/__tests__/ppr-traversal.test.ts +0 -256
  212. package/src/__tests__/preference-guard-smoke.test.ts +0 -211
  213. package/src/__tests__/preference-matcher.test.ts +0 -230
  214. package/src/__tests__/preference-slots.test.ts +0 -106
  215. package/src/__tests__/prospective-memory.test.ts +0 -283
  216. package/src/__tests__/query-entity-detector.test.ts +0 -171
  217. package/src/__tests__/query-expander.test.ts +0 -34
  218. package/src/__tests__/recall-mode.test.ts +0 -64
  219. package/src/__tests__/result-synthesizer.test.ts +0 -198
  220. package/src/__tests__/resume-context.test.ts +0 -4743
  221. package/src/__tests__/retrieval-trace.test.ts +0 -213
  222. package/src/__tests__/retriever-boundary-weight.test.ts +0 -136
  223. package/src/__tests__/retroactive-boost.test.ts +0 -223
  224. package/src/__tests__/scope-inventory.test.ts +0 -200
  225. package/src/__tests__/scope-policy.test.ts +0 -69
  226. package/src/__tests__/session-checkpoint.test.ts +0 -259
  227. package/src/__tests__/session-gc.test.ts +0 -215
  228. package/src/__tests__/store-scope-audit.test.ts +0 -81
  229. package/src/__tests__/temporal-parser.test.ts +0 -241
  230. package/src/__tests__/term-registry.test.ts +0 -121
  231. package/src/__tests__/tool-output-compressor.test.ts +0 -133
  232. package/src/__tests__/version-manager.test.ts +0 -213
  233. package/src/__tests__/workflow-observation.test.ts +0 -400
@@ -1,168 +0,0 @@
1
- # Architecture
2
-
3
- > 架构总览:RecallNest 的分层设计,从接入层到存储层。
4
-
5
- 边界说明:
6
-
7
- - structured capture 写 durable memory
8
- - checkpoint store 写 session state
9
- - raw ingest 写 evidence
10
-
11
- See [memory-boundary-contract.md](./memory-boundary-contract.md).
12
-
13
- ## System Architecture
14
-
15
- ```
16
- ┌─────────────────────────────────────────────────────────────┐
17
- │ Client Layer │
18
- ├──────────┬──────────┬──────────┬──────────┬─────────────────┤
19
- │ Claude │ Gemini │ Codex │ Custom │ curl / any │
20
- │ Code │ CLI │ │ Agents │ HTTP client │
21
- └────┬─────┴────┬─────┴────┬─────┴────┬─────┴────┬────────────┘
22
- │ │ │ │ │
23
- └──── MCP (stdio) ───┘ └── HTTP ──┘
24
- │ │
25
- ▼ ▼
26
- ┌─────────────────────────────────────────────────────────────┐
27
- │ Integration Layer │
28
- ├────────────────────────┬────────────────────────────────────┤
29
- │ MCP Server │ HTTP API Server │
30
- │ (mcp-server.ts) │ (api-server.ts) │
31
- │ │ port 4318 │
32
- │ Tools: │ │
33
- │ - search_memory │ Endpoints: │
34
- │ - memory_stats │ - POST /v1/recall │
35
- │ - brief_memory │ - POST /v1/store │
36
- │ - distill_memory │ - POST /v1/search │
37
- │ - pin_memory │ - GET /v1/stats │
38
- │ - explain_memory │ - GET /v1/health │
39
- │ - export_memory │ - POST /v1/consolidate │
40
- │ │ - GET /v1/gaps │
41
- └────────────┬───────────┴──────────────┬─────────────────────┘
42
- │ │
43
- ▼ ▼
44
- ┌─────────────────────────────────────────────────────────────┐
45
- │ Core Engine │
46
- ├─────────────────────────────────────────────────────────────┤
47
- │ │
48
- │ ┌─────────────┐ ┌──────────────┐ ┌────────────────────┐ │
49
- │ │ Retriever │ │ Classifier │ │ Query Expander │ │
50
- │ │ (hybrid: │ │ (6 categories│ │ (synonym + │ │
51
- │ │ vector + │ │ auto-assign)│ │ semantic expand) │ │
52
- │ │ BM25 + RRF) │ │ │ │ │ │
53
- │ └──────┬───────┘ └──────────────┘ └────────────────────┘ │
54
- │ │ │
55
- │ ┌──────┴───────┐ ┌──────────────┐ ┌────────────────────┐ │
56
- │ │ Decay │ │ Access │ │ Noise Filter │ │
57
- │ │ Engine │ │ Tracker │ │ (relevance │ │
58
- │ │ (Weibull) │ │ (use it or │ │ threshold) │ │
59
- │ │ │ │ lose it) │ │ │ │
60
- │ └──────────────┘ └──────────────┘ └────────────────────┘ │
61
- │ │
62
- │ ┌──────────────┐ ┌──────────────┐ │
63
- │ │ Consolidator │ │ Gap Detector │ ← Self-Evolution │
64
- │ │ (merge/dedup)│ │ (find blind │ │
65
- │ │ │ │ spots) │ │
66
- │ └──────────────┘ └──────────────┘ │
67
- │ │
68
- └──────────────────────────┬──────────────────────────────────┘
69
- │
70
- ▼
71
- ┌─────────────────────────────────────────────────────────────┐
72
- │ Storage Layer │
73
- ├─────────────────────────┬───────────────────────────────────┤
74
- │ LanceDB │ Jina Embeddings │
75
- │ (vector + columnar) │ (v5, 1024-dim) │
76
- │ │ │
77
- │ Tables: │ Task-aware: │
78
- │ - memories (main) │ - retrieval.query (for searches) │
79
- │ - access_log │ - retrieval.passage (for docs) │
80
- │ - search_log │ │
81
- └─────────────────────────┴───────────────────────────────────┘
82
- ```
83
-
84
- ## Data Flow
85
-
86
- ### Ingestion Pipeline
87
-
88
- ```
89
- Source Files Processing Storage
90
- ───────────── ────────── ───────
91
-
92
- CC transcripts ─┐
93
- │ ┌──────────────────┐ ┌───────────┐
94
- Codex sessions ─┼──►│ Chunker │──►│ Embedder │──► LanceDB
95
- │ │ (split by turn, │ │ (Jina v5) │
96
- Gemini chats ───┤ │ noise filter) │ └───────────┘
97
- │ └──────────────────┘
98
- Memory .md ─────┘ │
99
- ▼
100
- ┌──────────────┐
101
- │ Classifier │
102
- │ (6 categories│
103
- │ + tier) │
104
- └──────────────┘
105
- ```
106
-
107
- > 入库流程:多源文件 → 分块 → 过滤噪音 → 分类 → 嵌入向量 → 存入 LanceDB
108
-
109
- ### Search Pipeline
110
-
111
- ```
112
- Query Results
113
- ───── ───────
114
-
115
- "Docker debugging"
116
- │
117
- ▼
118
- ┌──────────────┐ ┌──────────────┐ ┌───────────────┐
119
- │ Query │───►│ Hybrid │───►│ Post-process │──► Top-K
120
- │ Expander │ │ Retrieval │ │ │ Results
121
- │ (synonyms) │ │ │ │ - Decay │
122
- └──────────────┘ │ Vector: 0.7 │ │ - Access boost│
123
- │ BM25: 0.3 │ │ - Score floor │
124
- │ RRF merge │ │ - Dedup │
125
- └──────────────┘ └───────────────┘
126
- ```
127
-
128
- ## Key Design Decisions
129
-
130
- | Decision | Rationale |
131
- |----------|-----------|
132
- | **LanceDB** (not SQLite/Postgres) | Native vector search, columnar storage, zero-config, single-file DB |
133
- | **Jina v5** (not OpenAI embeddings) | Task-aware embeddings (query vs passage), better multilingual, 1024-dim sweet spot |
134
- | **Hybrid retrieval** (vector + BM25) | Vector alone misses keyword matches; BM25 alone misses semantic similarity |
135
- | **RRF fusion** | Reciprocal Rank Fusion is parameter-free and robust across score distributions |
136
- | **Weibull decay** (not exponential) | Better models human forgetting: slow start, accelerating fade |
137
- | **6 categories** (not free-form tags) | Structured enough for filtering and lifecycle rules, simple enough to auto-classify |
138
- | **HTTP API + MCP** (not just MCP) | MCP is great for CLI tools, but HTTP API works with any language/framework |
139
- | **Bun runtime** | Fast startup, native TypeScript, good for CLI tools and local servers |
140
-
141
- ## File Map
142
-
143
- ```
144
- src/
145
- ├── api-server.ts # HTTP API server (port 4318)
146
- ├── mcp-server.ts # MCP server (stdio transport)
147
- ├── cli.ts # CLI entry point (lm command)
148
- ├── store.ts # LanceDB storage layer
149
- ├── retriever.ts # Hybrid retrieval (vector + BM25 + RRF)
150
- ├── embedder.ts # Jina embedding client
151
- ├── ingest.ts # Multi-source ingestion pipeline
152
- ├── chunker.ts # Text chunking with noise filtering
153
- ├── decay-engine.ts # Weibull time decay
154
- ├── access-tracker.ts # "Use it or lose it" tracking
155
- ├── noise-filter.ts # Low-quality content filter
156
- ├── query-expander.ts # Query expansion (synonyms)
157
- ├── retrieval-profiles.ts # 4 search profiles (precision/balanced/exploratory/recent)
158
- ├── memory-output.ts # Output formatting
159
- ├── memory-assets.ts # Brief/pin/export asset management
160
- ├── asset-sync.ts # Asset indexing
161
- ├── runtime-config.ts # Config loading
162
- ├── llm-client.ts # LLM client for smart extraction
163
- ├── doctor.ts # Health check diagnostics
164
- ├── adaptive-retrieval.ts # Adaptive retrieval strategies
165
- ├── stderr-log.ts # Logging
166
- ├── tracker.ts # Ingestion tracker (incremental)
167
- └── __tests__/ # Test suite
168
- ```
@@ -1,226 +0,0 @@
1
- # Memory Boundary Contract
2
-
3
- > RecallNest 先解决“谁能写什么、谁说了算”,再继续堆功能。没有边界的记忆系统,只会把更多垃圾写进库里。
4
-
5
- ## Why This Exists
6
-
7
- The same fact should not be authored by every memory path.
8
-
9
- RecallNest now distinguishes between:
10
-
11
- - `canonical`: stable facts maintained in curated docs outside the raw memory index
12
- - `durable`: reusable structured memory that RecallNest is allowed to recall across windows
13
- - `session`: current task state captured by `checkpoint_session`
14
- - `observation`: append-only workflow health records used for self-evolution, not for stable recall
15
- - `evidence`: raw transcripts and unstructured ingest that are useful as hints, but not authority
16
-
17
- The core rule is:
18
-
19
- **One fact may have multiple mirrors, but only one authority write path.**
20
-
21
- ---
22
-
23
- ## The Five Layers
24
-
25
- | Layer | What it stores | Authority write path | Can be mirrored into LanceDB? | Conflict policy |
26
- |-------|----------------|----------------------|-------------------------------|-----------------|
27
- | `canonical` | Stable identity, user profile, long-lived project rules | Curated docs such as `USER.md`, `PROJECT.md`, hand-maintained notes | Yes, as read-only mirrors | Manual review / canonical wins |
28
- | `durable` | Reusable `profile`, `preferences`, `entities`, `cases`, `patterns`, `events` | Structured writes such as `store_memory`, `store_case`, `store_workflow_pattern` | Yes | Category-specific: merge or append |
29
- | `session` | Current objective, summary, decisions, open loops, next actions | `checkpoint_session` | No, not as durable memory | Latest checkpoint wins |
30
- | `observation` | Workflow success/failure/correction/missed records for self-evolution | `workflow_observe`, `POST /v1/workflow-observe`, `recallnest workflow-observe` | No | Append-only |
31
- | `evidence` | Raw transcripts, loose snippets, import artifacts, candidate facts | `ingest.ts` and other unstructured importers | Already stored in the main index, but treated as low-trust evidence | Never overrides higher layers |
32
-
33
- ---
34
-
35
- ## Authority Rules
36
-
37
- ### 1. Structured memory creates durable authority
38
-
39
- These write paths are allowed to author durable memory:
40
-
41
- - `store_memory`
42
- - `store_case`
43
- - `store_workflow_pattern`
44
- - `POST /v1/store`
45
- - `POST /v1/case`
46
- - `POST /v1/pattern`
47
- - `POST /v1/capture`
48
-
49
- They write metadata with:
50
-
51
- - `boundary.layer = "durable"`
52
- - `boundary.authority = "structured-memory"`
53
-
54
- ### 2. Session state stays in the checkpoint store
55
-
56
- `checkpoint_session` is the authority for current task state. It must not be treated as durable memory.
57
-
58
- That means:
59
-
60
- - session summaries do not go back into the durable memory index automatically
61
- - `resume_context` may read the latest checkpoint
62
- - durable memory and checkpoints are combined at read time, not merged into one store
63
-
64
- ### 3. Workflow observation stays in its own store
65
-
66
- Workflow observations are operational records, not regular memory.
67
-
68
- That means:
69
-
70
- - `workflow_observe` writes append-only records to a dedicated observation store
71
- - observations are not one of the six memory categories
72
- - observations do not get promoted into stable recall by default
73
- - `workflow_health` and `workflow_evidence` read the observation store directly instead of searching LanceDB memory
74
-
75
- This boundary matters because self-evolution signals should not pollute `resume_context`.
76
-
77
- ### 4. Transcript ingest is evidence, not authority
78
-
79
- Raw conversations from:
80
-
81
- - Claude Code
82
- - Codex
83
- - Gemini CLI
84
-
85
- are useful, but they are not allowed to mint authoritative stable facts.
86
-
87
- Current enforcement:
88
-
89
- - transcript-derived `profile` and `preferences` are downgraded to stored `events`
90
- - transcript-derived records are marked with `boundary.layer = "evidence"`
91
- - `resume_context` does not use transcript/evidence records as stable context
92
- - evidence only becomes durable through explicit structured write or `promote_memory`
93
-
94
- ### 5. Durable beats evidence at read time
95
-
96
- When RecallNest composes startup context:
97
-
98
- - `canonical` beats `durable`
99
- - `durable` beats `evidence`
100
- - `session` is composed alongside them, not flattened into durable memory
101
- - `observation` is excluded from startup context unless a caller explicitly asks for workflow health/evidence
102
-
103
- If durable `cases` or `patterns` exist, they should be preferred over raw transcript fragments.
104
-
105
- ---
106
-
107
- ## Category Ownership
108
-
109
- | Category | Preferred authority | Evidence mirror allowed? | Notes |
110
- |----------|---------------------|--------------------------|-------|
111
- | `profile` | curated docs or structured `store_memory` | Yes | Raw transcript profile statements are not authoritative |
112
- | `preferences` | curated docs or structured `store_memory` | Yes | Raw preference chatter is especially easy to overfit |
113
- | `entities` | structured memory or curated docs | Yes | Mentions in transcripts are hints, not stable truth |
114
- | `events` | structured memory or ingest | Yes | Safe append-only history bucket |
115
- | `cases` | `store_case` | Yes | Transcript debug stories can exist as evidence, but durable cases should be explicit |
116
- | `patterns` | `store_workflow_pattern` or structured `store_memory` | Yes | Reusable workflows should be promoted deliberately |
117
-
118
- Workflow observations are intentionally outside this table. They are not a seventh memory category.
119
-
120
- ---
121
-
122
- ## Conflict Policy
123
-
124
- | Category type | Policy |
125
- |---------------|--------|
126
- | `profile`, `preferences`, `entities`, `patterns` | `latest-wins` within the same authority layer |
127
- | `events`, `cases` | `append-only` |
128
- | cross-layer conflicts | Higher-authority layer wins; lower layer stays as evidence |
129
-
130
- Cross-layer conflicts must not silently overwrite higher-authority data.
131
-
132
- Current implementation detail:
133
-
134
- - if an evidence promotion targets a `latest-wins` durable category and the same `canonicalKey` already exists with different text, RecallNest creates an open conflict candidate instead of silently overwriting the durable record
135
- - narrow exception: if the occupied durable memory and the incoming promotion resolve to the same preference slot (currently brand-item preferences such as `preferences:brand-item:<brand>:<item>`, reply-style preferences such as `preferences:reply-style:concise:direct`, or tool-choice preferences such as `preferences:tool-choice:bun:over:node`), RecallNest collapses the promotion onto the existing durable owner instead of opening a conflict
136
- - if a durable write reuses an existing `canonicalKey` under a different durable category, RecallNest creates an open conflict candidate instead of silently creating a second durable owner
137
- - conflicts can then be resolved explicitly by keeping the existing durable memory or accepting the incoming promoted text
138
- - if the exact same conflict fingerprint appears again after a previous review, RecallNest reopens the existing conflict record instead of creating a duplicate review item
139
-
140
- ---
141
-
142
- ## Canonical Keys
143
-
144
- Durable writes can carry a `canonicalKey`.
145
-
146
- Use it when different observations should map to the same durable fact or workflow, for example:
147
-
148
- - `user-reply-style`
149
- - `project-recallnest-positioning`
150
- - `workflow-cross-window-handoff`
151
-
152
- Current behavior:
153
-
154
- - exact same `canonicalKey` + same durable text => dedupe
155
- - same `canonicalKey` on merge-type categories => update latest durable record
156
- - same `canonicalKey` on append-type categories => keep append behavior unless the text is identical
157
- - evidence promotion into an occupied merge-type `canonicalKey` => open conflict candidate for manual review, unless the occupied durable owner and incoming promotion are the same atomic preference slot
158
- - reusing a `canonicalKey` across different durable categories => open conflict candidate for manual review
159
-
160
- This gives RecallNest an explicit way to say “these two writes refer to the same durable memory”.
161
-
162
- ---
163
-
164
- ## Promotion Path
165
-
166
- Raw evidence should not silently become durable memory.
167
-
168
- Instead, RecallNest now supports an explicit promotion path:
169
-
170
- - MCP: `promote_memory`
171
- - HTTP: `POST /v1/promote`
172
-
173
- Promotion rules:
174
-
175
- - source memory must be evidence or transcript-derived
176
- - target durable memory gets a new durable boundary
177
- - promoted record keeps first-hop provenance via `promotedFrom.memoryId`
178
- - same-slot auto-collapse and repeated exact promotions append observation trail under `provenanceHistory[*]` without silently overwriting durable wording
179
- - optional `text` lets the caller replace raw transcript wording with a clean durable statement
180
- - if the promoted text disagrees with an existing durable record for the same `canonicalKey`, RecallNest stores an open conflict candidate instead of silently overwriting the durable record
181
- - if the promotion would reuse a `canonicalKey` that is already owned by another durable category, RecallNest stores an open conflict candidate instead of creating a second durable owner
182
-
183
- Conflict handling entry points:
184
-
185
- - MCP: `list_conflicts`, `resolve_conflict`
186
- - HTTP: `GET /v1/conflicts`, `POST /v1/conflicts/resolve`
187
- - CLI: `recallnest conflicts list/show/resolve`
188
-
189
- Conflict review helpers:
190
-
191
- - list and inspect views expose derived advice (`keep_existing`, `accept_incoming`, `manual_review`) with conservative confidence levels
192
- - when a same-category promotion conflict is close enough to merge, advice may also include a conservative `mergeSuggestion` for human review
193
- - conflict resolution now supports `merge`, which rewrites the existing durable owner with either an explicit `mergedText` or the derived `mergeSuggestion`
194
- - list views can also be grouped by cluster so repeated conflicts on the same `canonicalKey` are reviewed as one review stream instead of many isolated rows
195
- - audit views summarize `stale` / `escalated` clusters first so terminal operators can review the highest-risk conflicts without manually scanning every row
196
- - escalation views can explicitly stamp `stale` / `escalated` conflicts with review metadata so operators know which aging conflicts were already triaged
197
- - CLI audit now supports `--export --format md|json`, so operators can persist a conflict review snapshot for handoff or later triage
198
-
199
- ---
200
-
201
- ## Enforcement Points In Code
202
-
203
- Current implementation:
204
-
205
- - [ingest.ts](../src/ingest.ts): transcript ingest writes evidence metadata and downgrades risky stable categories
206
- - [capture-engine.ts](../src/capture-engine.ts): structured writes stamp durable boundary metadata and create promotion conflict candidates when needed
207
- - [conflict-engine.ts](../src/conflict-engine.ts): builds and resolves explicit conflict candidates
208
- - [conflict-store.ts](../src/conflict-store.ts): persists conflict candidates outside the main LanceDB index
209
- - [context-composer.ts](../src/context-composer.ts): startup continuity ignores evidence-only stable recall
210
- - [memory-boundaries.ts](../src/memory-boundaries.ts): shared boundary resolution and read guards
211
- - [workflow-observation-store.ts](../src/workflow-observation-store.ts): persists dedicated append-only workflow observations outside regular memory
212
- - [workflow-observation-engine.ts](../src/workflow-observation-engine.ts): computes workflow health reports and evidence packs without touching durable recall
213
-
214
- ---
215
-
216
- ## Practical Consequences
217
-
218
- This contract is intentionally conservative:
219
-
220
- - transcript recall can still help search and debugging
221
- - structured memory is how facts graduate into durable continuity
222
- - checkpoints carry active work state
223
- - workflow observations can guide repair and evaluation, but they do not become stable context automatically
224
- - startup continuity should prefer fewer high-trust facts over more noisy fragments
225
-
226
- That tradeoff is deliberate. A smaller but cleaner memory layer is more useful than a larger index with no ownership rules.
@@ -1,119 +0,0 @@
1
- # Memory Categories
2
-
3
- > 6 类分类体系:RecallNest 自动将每条记忆归入 6 个类别之一,便于过滤和差异化管理。
4
-
5
- ## The Six Categories
6
-
7
- RecallNest classifies every memory into one of six categories. Classification happens automatically during ingestion using keyword heuristics and (optionally) LLM-based analysis.
8
-
9
- Category is not the same thing as authority.
10
-
11
- - Structured writes can author durable memory.
12
- - Raw transcript ingest is treated as evidence-first input.
13
- - Stable transcript claims should not override curated or structured memory.
14
- - Workflow observations are not a seventh memory category; they live in a separate observation store and never become durable recall by default.
15
-
16
- See [memory-boundary-contract.md](./memory-boundary-contract.md) for the layer and authority rules.
17
-
18
- | Category | What It Stores | Examples | Consolidation |
19
- |----------|---------------|----------|---------------|
20
- | **profile** | Who the user is — role, background, identity | "Data scientist with 5 years experience", "Works at Acme Corp" | Merge (latest wins) |
21
- | **preferences** | How the user likes things done | "Prefers TDD", "Uses Bun over Node", "Commit after every change" | Merge (slot-aware; item facts stay atomic) |
22
- | **entities** | Named things — projects, tools, people, repos | "Project X uses LanceDB", "Bob handles DevOps" | Merge (accumulate) |
23
- | **events** | Things that happened — incidents, decisions, milestones | "Migrated to AWS on 2026-01-15", "Bot crashed due to OOM" | Append (dedup only) |
24
- | **cases** | Debugging stories, troubleshooting workflows | "Fixed Docker crash by increasing memory limit", "API timeout was caused by DNS" | Append (dedup only) |
25
- | **patterns** | Recurring techniques, best practices, anti-patterns | "Always grep callers after API change", "Use mv to Trash, never rm" | Merge (refine) |
26
-
27
- ---
28
-
29
- ## Why Categories Matter
30
-
31
- ### 1. Smarter Search
32
-
33
- Filter by category to reduce noise:
34
-
35
- ```bash
36
- # MCP: search only debugging cases
37
- search_memory("Docker crash", category="cases")
38
-
39
- # HTTP API: same thing
40
- curl -X POST localhost:4318/v1/search \
41
- -d '{"query": "Docker crash", "category": "cases"}'
42
- ```
43
-
44
- > 按类别过滤能显著减少噪音:搜 debug 问题时只看 cases,搜用户偏好时只看 preferences。
45
-
46
- ### 2. Different Lifecycle Rules
47
-
48
- Not all memories age the same way:
49
-
50
- - **profile** and **preferences**: Slow decay — identity and habits change slowly
51
- - **events**: Medium decay — historical facts stay relevant for months
52
- - **cases**: Medium decay — debugging patterns remain useful
53
- - **patterns**: Slow decay — best practices persist
54
- - **entities**: Fast update — project details change frequently
55
-
56
- ### 3. Consolidation Strategy
57
-
58
- Merge-type categories (profile, preferences, entities, patterns) benefit from periodic consolidation — combining 5 similar entries into 1 refined one.
59
-
60
- For `preferences`, merge should be slot-aware, not topic-wide. Rewordings of the same preference can collapse, but concrete item/object preferences under the same brand or theme should stay as separate facts, and higher-value slots such as reply style or tool choice should keep their own stable owners.
61
-
62
- Append-type categories (events, cases) keep distinct entries but remove exact duplicates.
63
-
64
- ---
65
-
66
- ## Classification Rules
67
-
68
- ### Automatic (Keyword Heuristics)
69
-
70
- During ingestion, RecallNest scans for signal words:
71
-
72
- | Signal | Category |
73
- |--------|----------|
74
- | "I am", "my role", "background", "experience" | `profile` |
75
- | "prefer", "always", "never", "like to", "style" | `preferences` |
76
- | Names, URLs, project names, tool names | `entities` |
77
- | Dates, "happened", "decided", "migrated", "shipped" | `events` |
78
- | "fixed", "debugged", "root cause", "workaround", "error" | `cases` |
79
- | "pattern", "best practice", "rule", "always do", "anti-pattern" | `patterns` |
80
-
81
- Transcript-derived `profile` / `preferences` may still be detected during extraction, but RecallNest can downgrade them to evidence-only storage rather than treating them as durable truth.
82
-
83
- ### Manual Override
84
-
85
- When storing via API, you can specify the category explicitly:
86
-
87
- ```json
88
- POST /v1/store
89
- {
90
- "text": "Always run tests before pushing",
91
- "category": "patterns"
92
- }
93
- ```
94
-
95
- If omitted, defaults to `"events"`.
96
-
97
- ---
98
-
99
- ## Category Distribution
100
-
101
- A healthy memory index typically looks like:
102
-
103
- ```
104
- events ████████████████████████ 45%
105
- cases ████████████ 20%
106
- entities ████████ 15%
107
- patterns ██████ 10%
108
- preferences ███ 5%
109
- profile ██ 5%
110
- ```
111
-
112
- Check yours with:
113
-
114
- ```bash
115
- curl http://localhost:4318/v1/stats
116
- # or via MCP: memory_stats
117
- ```
118
-
119
- > 如果某个类别占比异常(比如 events 占了 90%),说明分类规则可能需要调优。