recallnest 2.2.0 → 2.3.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.
- package/.env +4 -0
- package/CLAUDE.md +1 -1
- package/README.md +30 -5
- package/README_CN.md +30 -5
- package/config.json +55 -0
- package/connectors/examples/email-adapter.ts +73 -0
- package/connectors/examples/logs-adapter.ts +103 -0
- package/connectors/examples/rss-adapter.ts +95 -0
- package/logs/daily-recall.error.log +0 -0
- package/logs/daily-recall.log +60 -0
- package/logs/ingest-2026-04-11.log +110 -0
- package/logs/ingest-2026-04-12.log +90 -0
- package/logs/ingest-2026-04-13.log +87 -0
- package/logs/launchagent-stderr.log +0 -0
- package/logs/launchagent-stdout.log +0 -0
- package/package.json +1 -1
- package/src/cli.ts +30 -0
- package/src/connector-types.ts +57 -0
- package/src/conversation-importer.ts +25 -1
- package/src/data-checkup.ts +31 -1
- package/src/doctor.ts +29 -0
- package/src/ingest.ts +203 -0
- package/src/mcp-server.ts +2 -2
- package/src/obsidian-connector.ts +282 -0
- package/src/session-schema.ts +2 -2
- package/src/source-heartbeat.ts +108 -0
- package/.claude-plugin/CLAUDE.md +0 -29
- package/.claude-plugin/marketplace.json +0 -18
- package/.dockerignore +0 -11
- package/.github/workflows/ci.yml +0 -28
- package/.mcp.json +0 -9
- package/CHANGELOG.md +0 -51
- package/DEMO.md +0 -94
- package/Dockerfile +0 -20
- package/EVAL.md +0 -89
- package/FAILURES.md +0 -75
- package/OPERATIONS.md +0 -59
- package/ROADMAP.md +0 -245
- package/SKILL.md +0 -250
- package/assets/dashboard.png +0 -0
- package/assets/knowledge-graph.png +0 -0
- package/assets/recallnest-workbench.png +0 -0
- package/assets/screenshots/ui-full.png +0 -0
- package/assets/screenshots/ui-overview.png +0 -0
- package/assets/screenshots/ui-search.png +0 -0
- package/assets/ui/app.js +0 -1031
- package/assets/ui/index.html +0 -224
- package/assets/ui/styles.css +0 -781
- package/assets/wechat-qr.jpg +0 -0
- package/bun.lock +0 -337
- package/daily-reflections/2026-03-05.md +0 -15
- package/daily-reflections/2026-03-06.md +0 -15
- package/daily-reflections/2026-03-07.md +0 -7
- package/daily-reflections/2026-03-08.md +0 -34
- package/daily-reflections/2026-03-09.md +0 -35
- package/daily-reflections/2026-03-10.md +0 -36
- package/daily-reflections/2026-03-11.md +0 -35
- package/daily-reflections/2026-03-12.md +0 -36
- package/daily-reflections/2026-03-13.md +0 -35
- package/daily-reflections/2026-03-14.md +0 -35
- package/daily-reflections/2026-03-15.md +0 -35
- package/daily-reflections/2026-03-16.md +0 -41
- package/daily-reflections/2026-03-17.md +0 -10
- package/daily-reflections/2026-03-18.md +0 -10
- package/daily-reflections/2026-03-19.md +0 -10
- package/daily-reflections/2026-03-20.md +0 -10
- package/daily-reflections/2026-03-21.md +0 -10
- package/daily-reflections/2026-03-22.md +0 -10
- package/daily-reflections/2026-03-23.md +0 -10
- package/daily-reflections/2026-03-24.md +0 -10
- package/daily-reflections/2026-03-25.md +0 -32
- package/daily-reflections/2026-03-26.md +0 -37
- package/daily-reflections/2026-03-27.md +0 -35
- package/daily-reflections/2026-03-28.md +0 -35
- package/daily-reflections/2026-03-29.md +0 -35
- package/daily-reflections/2026-03-30.md +0 -36
- package/daily-reflections/2026-03-31.md +0 -35
- package/daily-reflections/2026-04-01.md +0 -35
- package/daily-reflections/2026-04-02.md +0 -35
- package/daily-reflections/2026-04-03.md +0 -37
- package/daily-reflections/2026-04-04.md +0 -37
- package/daily-reflections/2026-04-05.md +0 -35
- package/daily-reflections/2026-04-06.md +0 -36
- package/daily-reflections/2026-04-07.md +0 -35
- package/daily-reflections/2026-04-08.md +0 -35
- package/daily-reflections/2026-04-12.md +0 -35
- package/data/alias-map.example.json +0 -22
- package/docs/api-reference.md +0 -1291
- package/docs/architecture.md +0 -168
- package/docs/memory-boundary-contract.md +0 -226
- package/docs/memory-categories.md +0 -119
- package/docs/pipeline-audit-ultramemory.md +0 -177
- package/docs/plans/2026-03-08-query-expansion.md +0 -270
- package/docs/plans/2026-03-16-continuity-layer.md +0 -196
- package/docs/plans/2026-04-01-recall-boost.md +0 -100
- package/docs/plans/mcp-tiering-plan.md +0 -126
- package/docs/research/recall-quality-audit-2026-03-22.md +0 -153
- package/docs/self-evolution.md +0 -198
- package/docs/superpowers/plans/2026-03-19-ingest-pipeline-upgrade.md +0 -782
- package/docs/superpowers/plans/2026-04-11-constructive-retrieval-emotion.md +0 -1195
- package/docs/superpowers/specs/2026-03-19-ingest-pipeline-upgrade-design.md +0 -77
- package/docs/superpowers/specs/2026-03-23-pull-claude-desktop-design.md +0 -95
- package/docs/superpowers/specs/2026-04-11-constructive-retrieval-emotion-design.md +0 -398
- package/eval/continuity/results-2026-03-16.md +0 -117
- package/eval/continuity/results-2026-03-19.md +0 -453
- package/eval/continuity/runbook.md +0 -110
- package/eval/continuity/seed-cases.md +0 -54
- package/eval/reports/2026-03-06-abstract-query-baseline.md +0 -96
- package/eval/reports/2026-03-06-aws-ssh-baseline.md +0 -82
- package/eval/reports/2026-03-06-baseline.md +0 -82
- package/eval/reports/query-expansion.md +0 -138
- package/glama.json +0 -6
- package/lm +0 -19
- package/plan-philosophy-upgrades.md +0 -363
- package/plan-product-upgrades.md +0 -155
- package/plan-v1.2-distributable.md +0 -105
- package/plan.md +0 -140
- package/research-memory-evolution.md +0 -440
- package/research-rl-agent-memory.md +0 -330
- package/scripts/archive-distilled-junk.ts +0 -116
- package/scripts/backfill-anchors.ts +0 -130
- package/scripts/backfill-l0l1l2.ts +0 -98
- package/scripts/blind-scan.ts +0 -588
- package/scripts/cleanup-step1-exact-dups.ts +0 -117
- package/scripts/cleanup-step2-template-dups.ts +0 -113
- package/scripts/cleanup-step3-stale-content.ts +0 -149
- package/scripts/cleanup-step4-orphan-scopes.ts +0 -131
- package/scripts/delete-distilled-junk.ts +0 -88
- package/scripts/diagnose-vector-search.ts +0 -132
- package/scripts/distill-facts.ts +0 -305
- package/scripts/health-check.ts +0 -343
- package/scripts/incremental-ingest.sh +0 -71
- package/scripts/migrate-language.ts +0 -75
- package/scripts/mlp-health-check.ts +0 -382
- package/scripts/pull-claude-desktop.ts +0 -515
- package/scripts/re-ingest-cc.sh +0 -66
- package/scripts/rebalance-memory-health.ts +0 -181
- package/scripts/run-desktop-ingest.sh +0 -11
- package/scripts/start-server.sh +0 -12
- package/scripts/verify-emotion-decay.ts +0 -148
- package/scripts/viz-dashboard.html +0 -423
- package/scripts/viz-export.ts +0 -703
- package/src/__tests__/access-tracker-novelty.test.ts +0 -228
- package/src/__tests__/activity-counter.test.ts +0 -96
- package/src/__tests__/admission-control.test.ts +0 -206
- package/src/__tests__/anchor-generator.test.ts +0 -67
- package/src/__tests__/auto-consolidation.test.ts +0 -168
- package/src/__tests__/auto-recall.test.ts +0 -131
- package/src/__tests__/babel-integration.test.ts +0 -139
- package/src/__tests__/batch-dedup.test.ts +0 -65
- package/src/__tests__/capture-engine.test.ts +0 -1144
- package/src/__tests__/capture-heuristic.test.ts +0 -171
- package/src/__tests__/cascade-forget.test.ts +0 -210
- package/src/__tests__/category-min-scores.test.ts +0 -33
- package/src/__tests__/cc8-cc1-essential-context.test.ts +0 -298
- package/src/__tests__/circuit-breaker.test.ts +0 -99
- package/src/__tests__/cluster-consolidation.test.ts +0 -712
- package/src/__tests__/confidence-metadata.test.ts +0 -125
- package/src/__tests__/confidence-tracker.test.ts +0 -249
- package/src/__tests__/conflict-advisor.test.ts +0 -206
- package/src/__tests__/conflict-escalation.test.ts +0 -149
- package/src/__tests__/conflict-lifecycle.test.ts +0 -83
- package/src/__tests__/conflict-output.test.ts +0 -85
- package/src/__tests__/conflict-store.test.ts +0 -374
- package/src/__tests__/consolidation-engine.test.ts +0 -181
- package/src/__tests__/constructive-retrieval.test.ts +0 -509
- package/src/__tests__/context-collapse-renderer.test.ts +0 -214
- package/src/__tests__/context-composer-pins.test.ts +0 -64
- package/src/__tests__/context-composer-task-selection.test.ts +0 -24
- package/src/__tests__/context-reconstructor.test.ts +0 -65
- package/src/__tests__/context-renderer.test.ts +0 -91
- package/src/__tests__/continuity-eval.test.ts +0 -275
- package/src/__tests__/continuity-schema.test.ts +0 -97
- package/src/__tests__/conversation-importer.test.ts +0 -692
- package/src/__tests__/core-recall-eval.test.ts +0 -235
- package/src/__tests__/core-summary.test.ts +0 -109
- package/src/__tests__/data-checkup.test.ts +0 -225
- package/src/__tests__/decay-exemption.test.ts +0 -84
- package/src/__tests__/dedup-actions.test.ts +0 -58
- package/src/__tests__/dedup-guard.test.ts +0 -39
- package/src/__tests__/deterministic-id.test.ts +0 -39
- package/src/__tests__/distill-lock.test.ts +0 -176
- package/src/__tests__/doctor.test.ts +0 -303
- package/src/__tests__/dream-pipeline.test.ts +0 -232
- package/src/__tests__/drill-down.test.ts +0 -108
- package/src/__tests__/embedder.test.ts +0 -122
- package/src/__tests__/emotion-decay.test.ts +0 -46
- package/src/__tests__/emotion-detector.test.ts +0 -56
- package/src/__tests__/emotion-phase1-integration.test.ts +0 -153
- package/src/__tests__/emotion-retrieval.test.ts +0 -56
- package/src/__tests__/entity-resolver.test.ts +0 -58
- package/src/__tests__/ethics-layer.test.ts +0 -476
- package/src/__tests__/event-segmenter.test.ts +0 -153
- package/src/__tests__/feature-flags-integration.test.ts +0 -54
- package/src/__tests__/frequency-tracker.test.ts +0 -113
- package/src/__tests__/graph-export.test.ts +0 -489
- package/src/__tests__/hotness-blend.test.ts +0 -76
- package/src/__tests__/ingest.test.ts +0 -360
- package/src/__tests__/interference-detector.test.ts +0 -203
- package/src/__tests__/kg-extractor.test.ts +0 -184
- package/src/__tests__/kg-store.test.ts +0 -198
- package/src/__tests__/llm-consolidation.test.ts +0 -226
- package/src/__tests__/mcp-efficiency.test.ts +0 -288
- package/src/__tests__/memory-boundaries.test.ts +0 -237
- package/src/__tests__/memory-evolution-b2-b3-e1.test.ts +0 -243
- package/src/__tests__/memory-evolution.test.ts +0 -271
- package/src/__tests__/memory-health-rebalance.test.ts +0 -144
- package/src/__tests__/memory-lint.test.ts +0 -271
- package/src/__tests__/memory-output.test.ts +0 -215
- package/src/__tests__/multi-vector.test.ts +0 -242
- package/src/__tests__/narrative-architecture.test.ts +0 -456
- package/src/__tests__/pending-review.test.ts +0 -77
- package/src/__tests__/post-retrieval-filter.test.ts +0 -178
- package/src/__tests__/ppr-traversal.test.ts +0 -256
- package/src/__tests__/prediction-engine.test.ts +0 -349
- package/src/__tests__/predictive-prospective-memory.test.ts +0 -416
- package/src/__tests__/preference-guard-smoke.test.ts +0 -211
- package/src/__tests__/preference-matcher.test.ts +0 -230
- package/src/__tests__/preference-slots.test.ts +0 -205
- package/src/__tests__/prospective-memory.test.ts +0 -283
- package/src/__tests__/query-entity-detector.test.ts +0 -171
- package/src/__tests__/query-expander-alias.test.ts +0 -89
- package/src/__tests__/query-expander.test.ts +0 -34
- package/src/__tests__/recall-governor.test.ts +0 -227
- package/src/__tests__/recall-mode.test.ts +0 -64
- package/src/__tests__/result-synthesizer.test.ts +0 -198
- package/src/__tests__/resume-context.test.ts +0 -4898
- package/src/__tests__/retrieval-trace.test.ts +0 -213
- package/src/__tests__/retriever-boundary-weight.test.ts +0 -136
- package/src/__tests__/retroactive-boost.test.ts +0 -223
- package/src/__tests__/salience-scoring.test.ts +0 -106
- package/src/__tests__/scope-inventory.test.ts +0 -200
- package/src/__tests__/scope-policy.test.ts +0 -69
- package/src/__tests__/session-checkpoint.test.ts +0 -259
- package/src/__tests__/session-distiller.test.ts +0 -611
- package/src/__tests__/session-gc.test.ts +0 -215
- package/src/__tests__/skill-engine.test.ts +0 -546
- package/src/__tests__/skill-promotion.test.ts +0 -349
- package/src/__tests__/store-scope-audit.test.ts +0 -81
- package/src/__tests__/supersede-chain.test.ts +0 -154
- package/src/__tests__/temporal-parser.test.ts +0 -241
- package/src/__tests__/temporal-validity.test.ts +0 -160
- package/src/__tests__/term-registry.test.ts +0 -121
- package/src/__tests__/tool-output-compressor.test.ts +0 -133
- package/src/__tests__/topic-tag.test.ts +0 -113
- package/src/__tests__/trusted-memory.test.ts +0 -828
- package/src/__tests__/version-manager.test.ts +0 -213
- package/src/__tests__/workflow-observation.test.ts +0 -400
- package/src/__tests__/write-verifier.test.ts +0 -122
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# RecallNest 召回优化实施清单
|
|
2
|
-
|
|
3
|
-
> 2026-04-01 发现问题:高频信息(如"轮巡仓库")召回失败
|
|
4
|
-
> 根因:短查询 vs 长文档 embedding 距离过大 + 无频率加权
|
|
5
|
-
> 与已有 P1-P5 互补,本清单聚焦**检索召回**环节
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## P0: 短查询召回增强(优先级最高)
|
|
10
|
-
|
|
11
|
-
### P0.1 双层索引 — 原文 + 检索锚点
|
|
12
|
-
|
|
13
|
-
- [ ] `capture-engine.ts` / `ingest.ts`:存储时同时生成一句话摘要(≤80 chars),存入 `metadata.anchor`
|
|
14
|
-
- [ ] `search.ts`:检索时同时搜原文向量和 anchor 向量,取 max score
|
|
15
|
-
- [ ] 效果:短 query "轮巡仓库" 匹配短 anchor "每日轮巡4个win4r仓库",距离大幅缩短
|
|
16
|
-
- **预估:** ~120 LOC
|
|
17
|
-
- **风险:** 低——不改原文存储,纯增量字段
|
|
18
|
-
- **依赖:** 无
|
|
19
|
-
|
|
20
|
-
### P0.2 高频 boost — 重复提及自动提权
|
|
21
|
-
|
|
22
|
-
- [ ] 新增 `frequency-tracker.ts`:记录 query→memory 的命中次数
|
|
23
|
-
- [ ] 评分公式:`final_score = base_score × (1 + log2(hit_count) × boost_factor)`
|
|
24
|
-
- [ ] hit_count ≥ 3 → peripheral 自动升为 core tier
|
|
25
|
-
- [ ] 持久化:写入 `data/frequency-stats.json`,跨 session 累积
|
|
26
|
-
- **预估:** ~100 LOC
|
|
27
|
-
- **风险:** 中——需要平衡 boost 幅度,避免旧高频记忆永远压过新记忆
|
|
28
|
-
- **依赖:** 无
|
|
29
|
-
|
|
30
|
-
### P0.3 短查询自动扩展
|
|
31
|
-
|
|
32
|
-
- [ ] `search.ts`:检测 query ≤ 6 字符时,调用 LLM 扩展为 3-5 个同义关键词
|
|
33
|
-
- [ ] 扩展结果缓存到 `data/query-expansion-cache.json`,相同 query 不重复调用
|
|
34
|
-
- [ ] 备选:不用 LLM,维护一个 `data/alias-map.json` 手动/自动映射("轮巡" → "轮巡 仓库 patrol repo 每日检查")
|
|
35
|
-
- **预估:** ~60 LOC(alias-map 方案)/ ~100 LOC(LLM 方案)
|
|
36
|
-
- **风险:** alias-map 低;LLM 方案增加延迟 ~200ms
|
|
37
|
-
- **依赖:** 无
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## 高频 vs 查重 平衡机制(P0.2 的关键设计)
|
|
42
|
-
|
|
43
|
-
### 问题
|
|
44
|
-
|
|
45
|
-
高频 boost 和去重是一对矛盾:
|
|
46
|
-
- **boost 说**:提到 10 次的东西一定重要,提权!
|
|
47
|
-
- **dedup 说**:同一条信息存了 10 遍,应该合并!
|
|
48
|
-
|
|
49
|
-
### 设计方案:分层计数,不是分层存储
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
存储层:dedup 照做,相同内容只保留 1 条(现有 consolidation 逻辑不变)
|
|
53
|
-
计数层:新增 frequency-tracker,记录的是 **query 命中次数**,不是存储条数
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**关键区分:**
|
|
57
|
-
|
|
58
|
-
| 维度 | 存储去重 | 召回加权 |
|
|
59
|
-
|------|---------|---------|
|
|
60
|
-
| 触发时机 | 写入时(store/ingest) | 检索时(search) |
|
|
61
|
-
| 操作对象 | 重复的 memory 条目 | query→memory 的命中频率 |
|
|
62
|
-
| 目标 | 数据库不膨胀 | 高频信息排前面 |
|
|
63
|
-
| 互相影响 | 不影响——去重后只剩 1 条,但那 1 条的 hit_count 持续累积 |
|
|
64
|
-
|
|
65
|
-
### 边界情况处理
|
|
66
|
-
|
|
67
|
-
1. **旧高频 vs 新相关**
|
|
68
|
-
- 时间衰减:`effective_hits = hit_count × decay(days_since_last_hit)`
|
|
69
|
-
- 30 天没被命中 → hit_count 等效减半,不会永远霸榜
|
|
70
|
-
|
|
71
|
-
2. **高频但已过时**
|
|
72
|
-
- 用户说"轮巡仓库从4个变成3个了" → store_memory 更新
|
|
73
|
-
- 旧条目被 consolidation 标记为 superseded → hit_count 不继承
|
|
74
|
-
- 新条目从 0 开始计,但因为用户接下来会频繁触发,很快追上
|
|
75
|
-
|
|
76
|
-
3. **频率统计粒度**
|
|
77
|
-
- 按 memory_id 计数,不按 query 文本
|
|
78
|
-
- "轮巡" "轮巡仓库" "patrol repo" 命中同一条 memory → 同一个 counter +1
|
|
79
|
-
- 避免同义词分散计数
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## 与现有 P1-P5 的关系
|
|
84
|
-
|
|
85
|
-
| 现有项 | 关系 |
|
|
86
|
-
|--------|------|
|
|
87
|
-
| P1 摘要保真 | P0.1 的 anchor 生成需要 P1 的保真约束,但可并行开发 |
|
|
88
|
-
| P2 聚类摘要 | 互补——P2 解决注入时省 token,P0 解决检索时找得到 |
|
|
89
|
-
| P3 增量 ingest | P0.1 的 anchor 字段需要对已有数据 backfill,P3 的增量逻辑可复用 |
|
|
90
|
-
| P4 data-checkup | 可加一项检查:anchor 字段覆盖率(多少 memory 已有 anchor) |
|
|
91
|
-
| P5 大文件门控 | 无直接关系 |
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## 验证标准
|
|
96
|
-
|
|
97
|
-
- [ ] `search_memory("轮巡")` → 返回轮巡仓库相关记忆,score ≥ 70%
|
|
98
|
-
- [ ] `search_memory("轮巡仓库")` → 返回结果,score ≥ 80%
|
|
99
|
-
- [ ] 高频记忆(命中 ≥5 次)自动出现在 `resume_context` 的 core 区
|
|
100
|
-
- [ ] 去重后数据库条目数不增长(frequency 只在 tracker 层累积)
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
# MCP Tool Surface Tiering Plan
|
|
2
|
-
|
|
3
|
-
## Goal
|
|
4
|
-
Reduce MCP tool surface from 24 to ~10 for daily agents, moving governance tools to CLI-only.
|
|
5
|
-
|
|
6
|
-
## Current Tools (24)
|
|
7
|
-
|
|
8
|
-
### Tier 1: Core (5) — Always Exposed
|
|
9
|
-
- `resume_context` — startup continuity
|
|
10
|
-
- `search_memory` — proactive recall
|
|
11
|
-
- `store_memory` — durable write
|
|
12
|
-
- `checkpoint_session` — work handoff
|
|
13
|
-
- `latest_checkpoint` — checkpoint read
|
|
14
|
-
|
|
15
|
-
### Tier 2: Advanced (10) — Exposed by Default
|
|
16
|
-
- `store_case` — structured case write
|
|
17
|
-
- `store_workflow_pattern` — structured pattern write
|
|
18
|
-
- `promote_memory` — evidence → durable
|
|
19
|
-
- `explain_memory` — retrieval explain
|
|
20
|
-
- `distill_memory` — compact briefing
|
|
21
|
-
- `brief_memory` — create brief asset
|
|
22
|
-
- `pin_memory` — pin for reuse
|
|
23
|
-
- `list_assets` — list assets
|
|
24
|
-
- `list_pins` — list pins
|
|
25
|
-
- `memory_stats` — db stats
|
|
26
|
-
|
|
27
|
-
### Tier 3: Governance (9) — CLI Only, Not MCP
|
|
28
|
-
- `workflow_observe`
|
|
29
|
-
- `workflow_health`
|
|
30
|
-
- `workflow_evidence`
|
|
31
|
-
- `list_conflicts`
|
|
32
|
-
- `resolve_conflict`
|
|
33
|
-
- `audit_conflicts`
|
|
34
|
-
- `escalate_conflicts`
|
|
35
|
-
- `list_dirty_briefs`
|
|
36
|
-
- `clean_dirty_briefs`
|
|
37
|
-
|
|
38
|
-
## Implementation
|
|
39
|
-
|
|
40
|
-
### Step 1: Add Tier Config
|
|
41
|
-
Add to `mcp-server.ts`:
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
// Environment: RECALLNEST_MCP_TIER=core|advanced|full (default: advanced)
|
|
45
|
-
const MCP_TIER = process.env.RECALLNEST_MCP_TIER || "advanced";
|
|
46
|
-
|
|
47
|
-
const TOOL_TIERS: Record<string, "core" | "advanced" | "governance"> = {
|
|
48
|
-
// Core (always)
|
|
49
|
-
resume_context: "core",
|
|
50
|
-
search_memory: "core",
|
|
51
|
-
store_memory: "core",
|
|
52
|
-
checkpoint_session: "core",
|
|
53
|
-
latest_checkpoint: "core",
|
|
54
|
-
|
|
55
|
-
// Advanced
|
|
56
|
-
store_case: "advanced",
|
|
57
|
-
store_workflow_pattern: "advanced",
|
|
58
|
-
promote_memory: "advanced",
|
|
59
|
-
explain_memory: "advanced",
|
|
60
|
-
distill_memory: "advanced",
|
|
61
|
-
brief_memory: "advanced",
|
|
62
|
-
pin_memory: "advanced",
|
|
63
|
-
list_assets: "advanced",
|
|
64
|
-
list_pins: "advanced",
|
|
65
|
-
memory_stats: "advanced",
|
|
66
|
-
export_memory: "advanced",
|
|
67
|
-
|
|
68
|
-
// Governance (CLI-only)
|
|
69
|
-
workflow_observe: "governance",
|
|
70
|
-
workflow_health: "governance",
|
|
71
|
-
workflow_evidence: "governance",
|
|
72
|
-
list_conflicts: "governance",
|
|
73
|
-
resolve_conflict: "governance",
|
|
74
|
-
audit_conflicts: "governance",
|
|
75
|
-
escalate_conflicts: "governance",
|
|
76
|
-
list_dirty_briefs: "governance",
|
|
77
|
-
clean_dirty_briefs: "governance",
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
function shouldRegisterTool(toolName: string): boolean {
|
|
81
|
-
const tier = TOOL_TIERS[toolName];
|
|
82
|
-
if (!tier) return true; // unknown tools always register
|
|
83
|
-
if (MCP_TIER === "full") return true;
|
|
84
|
-
if (MCP_TIER === "advanced") return tier !== "governance";
|
|
85
|
-
if (MCP_TIER === "core") return tier === "core";
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Step 2: Wrap Tool Registrations
|
|
91
|
-
Replace `server.tool()` calls with conditional registration:
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
function registerTool(...) {
|
|
95
|
-
if (!shouldRegisterTool(name)) {
|
|
96
|
-
console.log(`[MCP] Skipping ${name} (tier: ${TOOL_TIERS[name]})`);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
server.tool(name, description, schema, handler);
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Step 3: Update CLI for Governance Tools
|
|
104
|
-
Ensure governance tools are fully accessible via CLI:
|
|
105
|
-
- `recallnest workflow-observe ...` → already exists
|
|
106
|
-
- `recallnest conflicts list ...` → already exists
|
|
107
|
-
- Add `recallnest dirty-briefs list/clean` if missing
|
|
108
|
-
|
|
109
|
-
## Testing
|
|
110
|
-
|
|
111
|
-
1. Default run: `bun src/mcp-server.ts` → should register ~15 tools (core + advanced)
|
|
112
|
-
2. Tier=core: `RECALLNEST_MCP_TIER=core bun src/mcp-server.ts` → 5 tools
|
|
113
|
-
3. Tier=full: `RECALLNEST_MCP_TIER=full bun src/mcp-server.ts` → 24 tools (backward compatible)
|
|
114
|
-
4. Smoke test: MCP import works for all tiers
|
|
115
|
-
|
|
116
|
-
## Files to Modify
|
|
117
|
-
|
|
118
|
-
- `src/mcp-server.ts` — add tier config + conditional registration
|
|
119
|
-
|
|
120
|
-
## Verification
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
cd ~/recallnest
|
|
124
|
-
RECALLNEST_MCP_TIER=core bun src/mcp-server.ts &
|
|
125
|
-
# Check logs for registered tools
|
|
126
|
-
```
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
# RecallNest Recall Quality Audit — 2026-03-22
|
|
2
|
-
|
|
3
|
-
## Executive Summary
|
|
4
|
-
|
|
5
|
-
This audit assessed three dimensions of RecallNest's memory quality: **ingest noise ratio**, **case/pattern recall relevance**, and **checkpoint content quality**. The system has strong retrieval-side relevance mechanisms (multi-stage scoring, reranking, noise filtering) and robust checkpoint sanitization, but suffers from weak ingest-side validation for evidence-layer data and a critical gap in case recall — 5,853 stored cases are effectively invisible due to over-aggressive filtering. The top 5 issues are ranked below with concrete fix suggestions.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Top 5 Highest-Impact Quality Issues
|
|
10
|
-
|
|
11
|
-
### 1. Case Recall is Effectively Broken (CRITICAL)
|
|
12
|
-
|
|
13
|
-
**Finding**: 0 out of 5 probes returned any case results, despite 5,853 cases in the store. Vector search finds relevant cases (similarity 0.70–0.74), but the selection pipeline filters them all out.
|
|
14
|
-
|
|
15
|
-
**Root cause**: `isTaskCandidateUseful` in `src/ranking.ts:168` rejects non-structured cases (`if (category === "cases" && !structured) return false`). Most stored cases are raw transcript chunks in `cc:` scopes, not structured `Case: problem/solution` format. Additionally, `selectTaskResults` in `src/context-composer-task-selection.ts:298-300` filters non-durable candidates when durable ones exist.
|
|
16
|
-
|
|
17
|
-
**Impact**: The entire case recall subsystem provides zero value. Users who stored debugging solutions, fix recipes, or incident resolutions never see them recalled.
|
|
18
|
-
|
|
19
|
-
**Fix suggestion**:
|
|
20
|
-
- **File**: `src/ranking.ts` — `isTaskCandidateUseful` function (~line 168)
|
|
21
|
-
- **Approach**: Relax the structured-only filter for cases with high vector similarity (>0.72). Add a fallback path: if zero structured cases pass, allow top-N unstructured cases with high similarity scores through. This preserves precision for normal recall but prevents the "zero results" cliff.
|
|
22
|
-
- **Classification**: Quick win (localized change, testable in isolation)
|
|
23
|
-
|
|
24
|
-
### 2. Noise Filtering Only at Retrieval, Not Ingest (MODERATE-HIGH)
|
|
25
|
-
|
|
26
|
-
**Finding**: The noise filter in `src/noise-filter.ts` only runs during `hybridRetrieval()` and `vectorOnlyRetrieval()` — NOT during ingest. Noisy data (bash progress output, screenshot base64, tool-use tags, system messages, permission instructions) is stored permanently in the evidence layer. The noise occupies embedding space, dilutes vector search quality, and wastes MMR diversity budget on filtering out junk.
|
|
27
|
-
|
|
28
|
-
**Root cause**: The ingest pipeline in `src/ingest.ts` only validates on text length (> 8 chars). No content quality check, no protocol filtering, no diagnostic artifact detection. 59.2% of all 39,580 entries are category "fact" — many are low-signal transcript snippets. 84.5% are from ephemeral `cc:*` session scopes.
|
|
29
|
-
|
|
30
|
-
**Impact**: The store is bloated with low-value entries. Retrieval-side filtering is a band-aid — the noisy entries still consume storage, slow vector search, and can occasionally leak through retrieval filters into recall results.
|
|
31
|
-
|
|
32
|
-
**Fix suggestion**:
|
|
33
|
-
- **File**: `src/ingest.ts` — add pre-storage filtering after chunking
|
|
34
|
-
- **File**: `src/noise-filter.ts` — extract shared noise patterns into reusable functions
|
|
35
|
-
- **Approach**: Apply the existing noise filter patterns at ingest time as a hard gate. Add additional ingest-specific patterns: reject chunks under 30 chars matching boilerplate, base64-heavy content, bash progress output, and tool-use protocol tags. Score chunk information density and skip purely routine/acknowledgment content.
|
|
36
|
-
- **Classification**: Deeper refactor (needs heuristic set + testing against real transcripts to avoid false negatives)
|
|
37
|
-
|
|
38
|
-
### 3. Checkpoint Scope Normalization Gap (MODERATE)
|
|
39
|
-
|
|
40
|
-
**Finding**: Three different scope strings exist for the same project: `project:recallnest` (114 checkpoints), `recallnest` (24), and `project:RecallNest` (4). A `resume_context` call with one variant misses checkpoints stored under another.
|
|
41
|
-
|
|
42
|
-
**Root cause**: No scope normalization at checkpoint save time. The 24 `recallnest` checkpoints are from March 16–17 before conventions solidified. The 4 `project:RecallNest` checkpoints have a case mismatch.
|
|
43
|
-
|
|
44
|
-
**Impact**: `getLatest()` by scope can return a stale checkpoint instead of the truly latest one if the most recent was stored under a non-canonical scope string. This directly affects continuity recovery quality.
|
|
45
|
-
|
|
46
|
-
**Fix suggestion**:
|
|
47
|
-
- **File**: `src/session-engine.ts` — checkpoint save path
|
|
48
|
-
- **Approach**: Add a `normalizeScope()` function that lowercases and ensures `project:` prefix. Apply it both at save time and at query time. For historical data, run a one-time migration script to normalize existing checkpoint scopes.
|
|
49
|
-
- **Classification**: Quick win (small utility function + migration script)
|
|
50
|
-
|
|
51
|
-
### 4. Empty/Fallback Checkpoints Displace Useful Recovery Data (MODERATE)
|
|
52
|
-
|
|
53
|
-
**Finding**: ~44% of checkpoints (69 of 156) have sanitization artifacts. Of these, ~10% (16) have only fallback summary text ("Checkpoint captured current task state without repo-state details.") plus empty structured fields. These provide zero recovery value but can be returned by `getLatest()`, displacing useful checkpoints.
|
|
54
|
-
|
|
55
|
-
**Additional concern**: No checkpoint expiry mechanism exists. All 156 checkpoints persist indefinitely (156 files in ~6 days = ~9,500/year projected). No age-based pruning, no size limits, no archive mechanism. File-system based storage means O(n) scan on every retrieval.
|
|
56
|
-
|
|
57
|
-
**Root cause**: The checkpoint API accepts and stores checkpoints even when all meaningful fields are empty or sanitized away.
|
|
58
|
-
|
|
59
|
-
**Impact**: If a fallback-only checkpoint is the most recent for a scope, `resume_context` returns useless continuity data. Combined with no expiry, checkpoint directory will grow unbounded.
|
|
60
|
-
|
|
61
|
-
**Fix suggestion**:
|
|
62
|
-
- **File**: `src/session-engine.ts` — `checkpoint_session` handler
|
|
63
|
-
- **Approach**: (a) Add a quality gate before saving: if summary would be fallback AND decisions/openLoops/nextActions are all empty, either reject with a warning or mark as `quality: "minimal"` so `getLatest()` can prefer higher-quality alternatives. (b) Add checkpoint age check in `resume_context` — warn if > 24h old. (c) Implement expiry: archive checkpoints older than 30 days.
|
|
64
|
-
- **Classification**: Quick win for quality gate; medium effort for expiry
|
|
65
|
-
|
|
66
|
-
### 5. Importance Defaults Too Permissive + Weak Tier Inference (MODERATE)
|
|
67
|
-
|
|
68
|
-
**Finding**: Most ingested transcript memories get default importance 0.7 — no distinction between high-value technical insights and casual chat. Tier assignment is purely category-based (`profile`/`patterns` -> "working", everything else -> "peripheral") with no semantic quality analysis.
|
|
69
|
-
|
|
70
|
-
**Root cause**: No importance scoring at ingest time. The decay engine (`src/decay-engine.ts`) uses a 3-tier system (core/working/peripheral) with different Weibull decay curves, but tier promotion requires 3+ accesses or importance >= 0.5 (peripheral -> working) or 10+ accesses or importance >= 0.8 (working -> core). Since everything starts at 0.7 importance, most evidence-layer memories sit at "peripheral" tier forever.
|
|
71
|
-
|
|
72
|
-
**Impact**: Low-value transcript entries compete fairly with high-value durable memories in retrieval scoring. The importance weight formula `0.7 + 0.3 * importance` gives a 0.7-importance entry 91% the score of a 1.0-importance entry — barely distinguishable.
|
|
73
|
-
|
|
74
|
-
**Fix suggestion**:
|
|
75
|
-
- **File**: `src/ingest.ts` — post-parse stage; `src/decay-engine.ts` — tier logic
|
|
76
|
-
- **Approach**: Use LLM (already integrated via `smartExtractBatch` in ingest.ts:328) to assign importance during ingestion. For non-LLM path, use heuristics: code-heavy content -> importance 0.8, error resolution -> 0.85, boilerplate -> 0.3. Widen the importance multiplier range (e.g., `0.5 + 0.5 * importance`) to make it more discriminating.
|
|
77
|
-
- **Classification**: Deeper refactor (needs scoring model + tuning)
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## Additional Findings
|
|
82
|
-
|
|
83
|
-
### What's Working Well
|
|
84
|
-
|
|
85
|
-
| Area | Rating | Evidence |
|
|
86
|
-
|---|---|---|
|
|
87
|
-
| Tool output filtering | Excellent | 98.7% clean — `parseCCTranscript` type filter is effective |
|
|
88
|
-
| Hybrid retrieval pipeline | Excellent | 8-stage scoring with RRF fusion, Weibull decay, MMR diversity |
|
|
89
|
-
| Checkpoint schema design | Good | Strict Zod validation, appropriate field limits, well-structured |
|
|
90
|
-
| Repo-state sanitizer (post-deploy) | Excellent | Zero leaks since March 18 deployment |
|
|
91
|
-
| Checkpoint summary quality | Good | 75% of checkpoints have rich, actionable content |
|
|
92
|
-
| Durable memory dedup | Good | Two-stage vector + LLM semantic dedup with canonical key matching |
|
|
93
|
-
| Cross-encoder reranking | Good | Jina/Pinecone/Voyage reranking available for semantic re-ranking |
|
|
94
|
-
| Retrieval profiles | Good | 4 task-tuned profiles (default, writing, debug, fact-check) with appropriate tuning |
|
|
95
|
-
| Cue coverage diversity | Good | Greedy set-cover algorithm prevents duplicate pattern recall |
|
|
96
|
-
| Entity capture | Good | Specific, useful entities (file paths, tool names, PR refs). 8-entity limit sufficient |
|
|
97
|
-
|
|
98
|
-
### Pattern vs Case Recall Asymmetry
|
|
99
|
-
|
|
100
|
-
Patterns recall well because they tend to be durable and structured (967 eligible entries, 2.5% of store). Cases fail because the same filtering criteria are applied but cases in the store are overwhelmingly unstructured transcript chunks. This is a design asymmetry — the system was built for curated patterns but cases accumulated organically.
|
|
101
|
-
|
|
102
|
-
### Dedup Gap When LLM Unavailable
|
|
103
|
-
|
|
104
|
-
Evidence-layer transcript ingest skips LLM semantic dedup if no embedder is available (`src/ingest.ts:817-821`) — it queues for later processing but still ingests the raw chunk with only vector dedup. When LLM is unavailable, borderline-similar chunks (similarity 0.68-0.80) are stored as separate entries, leading to near-duplicate pollution.
|
|
105
|
-
|
|
106
|
-
### Checkpoint Coverage Details
|
|
107
|
-
|
|
108
|
-
- 156 checkpoints across 94 sessions (March 16-22)
|
|
109
|
-
- March 21 has only 3 checkpoints vs 28-46 on other days — potential gap
|
|
110
|
-
- `resume_context` correctly uses checkpoint as first line of recovery with entity supplementation
|
|
111
|
-
- 220-char headline truncation loses detail from rich summaries, but full checkpoint is available in response body
|
|
112
|
-
- **No checkpoint-to-durable promotion pipeline**: High-quality checkpoint decisions never automatically become durable memories
|
|
113
|
-
- **Limited coverage in resume_context**: Only 3-5 lines from checkpoint extracted (<5% of max checkpoint content)
|
|
114
|
-
|
|
115
|
-
### Distillation Opportunity
|
|
116
|
-
|
|
117
|
-
23,441 "fact" entries could be periodically distilled into fewer, higher-quality durable memories. This would improve the signal-to-noise ratio of the entire store and make vector search more effective. The existing `distill_memory` tool could be leveraged for this.
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## Quick Wins vs Deeper Refactors
|
|
122
|
-
|
|
123
|
-
### Quick Wins (1-2 days each)
|
|
124
|
-
|
|
125
|
-
1. **Relax case recall filter** — Allow high-similarity unstructured cases when zero structured cases match (`src/ranking.ts`)
|
|
126
|
-
2. **Scope normalization** — `normalizeScope()` at save + query time (`src/session-engine.ts`)
|
|
127
|
-
3. **Empty checkpoint gate** — Reject or flag checkpoints with all-fallback content (`src/session-engine.ts`)
|
|
128
|
-
4. **Historical data cleanup** — Re-sanitize 9 pre-guard checkpoint files (one-time script)
|
|
129
|
-
5. **Checkpoint staleness warning** — Warn in `resume_context` when checkpoint is >24h old (`src/context-composer.ts`)
|
|
130
|
-
|
|
131
|
-
### Deeper Refactors (1-2 weeks each)
|
|
132
|
-
|
|
133
|
-
1. **Ingest-time noise filtering** — Apply noise patterns + content quality scoring at ingest (`src/ingest.ts` + `src/noise-filter.ts`)
|
|
134
|
-
2. **Importance scoring at ingest** — LLM or heuristic-based importance assignment during ingestion (`src/ingest.ts`)
|
|
135
|
-
3. **Case promotion pipeline** — Auto-promote high-quality `cc:` cases to `memory:` scope based on structure detection and retrieval frequency
|
|
136
|
-
4. **Fact distillation pipeline** — Periodic batch job to consolidate 23,441 low-value fact entries into curated durable memories
|
|
137
|
-
5. **Checkpoint expiry and indexing** — Archive old checkpoints + migrate from filesystem scan to indexed storage
|
|
138
|
-
6. **Checkpoint-to-durable promotion** — Auto-promote high-quality decisions/nextActions to `events` or `cases` memory category
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## Methodology
|
|
143
|
-
|
|
144
|
-
- **Architecture review**: Full codebase analysis of 89 source files (~19,500 LOC TypeScript) across all subsystems — ingestion, retrieval, checkpoint, conflict, workflow observation.
|
|
145
|
-
- **Ingest noise analysis**: Traced the parser pipeline through `src/ingest.ts`, analyzed noise filter patterns in `src/noise-filter.ts`, reviewed dedup thresholds and LLM fallback behavior. Parsed 10 real CC transcripts, classified 792 text blocks for noise type.
|
|
146
|
-
- **Case/pattern recall analysis**: Ran 5 `composeResumeContext` probes with different task prompts against `project:recallnest` scope. Traced the selection pipeline through `src/ranking.ts` and `src/context-composer-task-selection.ts`. Compared vector search results vs final pipeline output.
|
|
147
|
-
- **Checkpoint audit**: Schema analysis of `src/session-schema.ts` + `src/session-engine.ts`, then quality review of all 156 checkpoint files from March 16-22. Field-level emptiness analysis, scrubbing effectiveness verification, scope distribution analysis.
|
|
148
|
-
- **Retrieval pipeline audit**: Full trace through `src/retriever.ts` 8-stage scoring pipeline, `src/decay-engine.ts` Weibull decay, `src/embedder.ts` multi-provider embedding, and `src/retrieval-profiles.ts` task-tuned profiles.
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
*Report generated 2026-03-22 by recallnest-quality-8ad2b7 team (coordinator + 3 research agents)*
|
|
153
|
-
*Supersedes earlier draft by recallnest-quality-69722c team*
|
package/docs/self-evolution.md
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
# Self-Evolution: How RecallNest Memories and Workflows Evolve
|
|
2
|
-
|
|
3
|
-
> 自我进化原理:RecallNest 不只让记忆自己整合、衰减、上浮,也开始观察 workflow 什么时候做对、什么时候做错。
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
Traditional memory systems are append-only: store everything, search later, hope for the best. Over time, they bloat with duplicates, outdated entries, and noise.
|
|
8
|
-
|
|
9
|
-
RecallNest takes a different approach: **memories evolve**. They consolidate, decay, and surface based on usage — just like biological memory.
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
Store → Classify → Decay → Access → Consolidate → Promote/Demote
|
|
13
|
-
│ │ │ │ │ │
|
|
14
|
-
▼ ▼ ▼ ▼ ▼ ▼
|
|
15
|
-
New 6 types Weibull "Use it Merge Core ↔
|
|
16
|
-
memory auto- curve or lose similar Working ↔
|
|
17
|
-
assigned over it" entries Peripheral
|
|
18
|
-
time
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Workflow Observation Loop
|
|
24
|
-
|
|
25
|
-
RecallNest now separates self-evolution signals from regular memory.
|
|
26
|
-
|
|
27
|
-
Instead of turning every workflow failure into another `events` row, RecallNest records workflow observations in a dedicated append-only store:
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
Observe → Inspect → Health → Evidence → Fix / Test
|
|
31
|
-
│ │ │ │ │
|
|
32
|
-
▼ ▼ ▼ ▼ ▼
|
|
33
|
-
record aggregate degrade package repair the
|
|
34
|
-
success/ 7d / 30d or stay top workflow,
|
|
35
|
-
failure health healthy signals then observe again
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
- **`workflow_observe`** records whether `resume_context`, `checkpoint_session`, or another workflow primitive succeeded, failed, was corrected, or was missed
|
|
39
|
-
- **`workflow_health`** aggregates recent observations into a health report or degraded-workflow dashboard
|
|
40
|
-
- **`workflow_evidence`** packages recent issue observations and suggestions so tests, rules, and prompts can be tightened
|
|
41
|
-
- these records live outside the 6 memory categories and are not composed into `resume_context`
|
|
42
|
-
- managed MCP / HTTP continuity calls now append `resume_context` / `checkpoint_session` observations automatically, and checkpoint repo-state sanitization is recorded as `corrected`
|
|
43
|
-
|
|
44
|
-
That boundary is deliberate: self-evolution needs operational telemetry, not more noisy durable memory.
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## The Three-Tier Lifecycle
|
|
49
|
-
|
|
50
|
-
Every memory lives in one of three tiers:
|
|
51
|
-
|
|
52
|
-
| Tier | Description | Typical Size |
|
|
53
|
-
|------|-------------|--------------|
|
|
54
|
-
| **Core** | Essential knowledge, accessed frequently | ~5% of total |
|
|
55
|
-
| **Working** | Actively useful, moderate access | ~25% of total |
|
|
56
|
-
| **Peripheral** | Rarely accessed, candidates for archival | ~70% of total |
|
|
57
|
-
|
|
58
|
-
> 三层生命周期:核心层(常用的 5%)→ 工作层(中等频率 25%)→ 边缘层(低频 70%)
|
|
59
|
-
|
|
60
|
-
### Promotion and Demotion
|
|
61
|
-
|
|
62
|
-
Memories move between tiers based on access patterns:
|
|
63
|
-
|
|
64
|
-
- **Promotion** (peripheral → working → core): Memory accessed ≥ N times within a window
|
|
65
|
-
- **Demotion** (core → working → peripheral): Memory not accessed for extended period
|
|
66
|
-
- **Archival**: Peripheral memories with zero access beyond decay threshold get archived (not deleted)
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Weibull Decay
|
|
71
|
-
|
|
72
|
-
RecallNest uses the [Weibull distribution](https://en.wikipedia.org/wiki/Weibull_distribution) for time-based memory decay, inspired by human forgetting curves.
|
|
73
|
-
|
|
74
|
-
> Weibull 衰减模型比简单的线性衰减更符合人类遗忘曲线:开始衰减慢,后面加速。
|
|
75
|
-
|
|
76
|
-
### Why Weibull, not Exponential?
|
|
77
|
-
|
|
78
|
-
| Model | Behavior | Problem |
|
|
79
|
-
|-------|----------|---------|
|
|
80
|
-
| Linear | Constant decay rate | Too aggressive early on |
|
|
81
|
-
| Exponential | Fast initial decay | Important but old memories vanish too quickly |
|
|
82
|
-
| **Weibull** | Slow start, accelerating decay | Matches human memory: recent stays fresh, old fades naturally |
|
|
83
|
-
|
|
84
|
-
### Formula
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
decay(t) = exp(-(t / λ)^k)
|
|
88
|
-
|
|
89
|
-
where:
|
|
90
|
-
t = days since last access
|
|
91
|
-
λ = scale parameter (half-life, default: 120 days)
|
|
92
|
-
k = shape parameter (default: 1.5, gives the "slow then fast" curve)
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### Impact on Search
|
|
96
|
-
|
|
97
|
-
Decay factor multiplies the retrieval score:
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
final_score = relevance_score × decay(days_since_access)
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
A highly relevant but stale memory can still surface if the semantic match is strong enough.
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## Memory Consolidation
|
|
108
|
-
|
|
109
|
-
Over time, you accumulate many memories about the same topic. Consolidation merges them.
|
|
110
|
-
|
|
111
|
-
> 记忆整合:找到主题相近的记忆簇,按策略合并或去重,保持记忆库精简。
|
|
112
|
-
|
|
113
|
-
### Merge vs. Append Strategies
|
|
114
|
-
|
|
115
|
-
| Category | Strategy | Why |
|
|
116
|
-
|----------|----------|-----|
|
|
117
|
-
| `profile` | **Merge** | User identity evolves; latest version wins |
|
|
118
|
-
| `preferences` | **Merge** | Preferences update within the same slot; concrete item preferences stay separate |
|
|
119
|
-
| `entities` | **Merge** | Entity info accumulates; consolidate |
|
|
120
|
-
| `patterns` | **Merge** | Patterns refine over time |
|
|
121
|
-
| `events` | **Append** | Events are facts; dedup but keep distinct entries |
|
|
122
|
-
| `cases` | **Append** | Case studies are unique; dedup only exact matches |
|
|
123
|
-
|
|
124
|
-
### How It Works
|
|
125
|
-
|
|
126
|
-
1. For each category, compute pairwise cosine similarity
|
|
127
|
-
2. Cluster entries with similarity > threshold (default: 0.85)
|
|
128
|
-
3. For **merge** categories: LLM combines the cluster into one entry, archives originals
|
|
129
|
-
4. For **append** categories: remove exact duplicates, keep distinct entries
|
|
130
|
-
5. Update access counts (merged entry inherits the sum)
|
|
131
|
-
|
|
132
|
-
`preferences` needs one extra guard: do not collapse same-brand, different-item preferences into one topic-level memory. A summary can exist, but it should not replace the atomic preference facts. The same idea now also applies to slot-aware reply-style and tool-choice preferences.
|
|
133
|
-
|
|
134
|
-
### Safety
|
|
135
|
-
|
|
136
|
-
- Default mode is **dry-run**: preview changes before applying
|
|
137
|
-
- Original entries are **archived**, never deleted
|
|
138
|
-
- Consolidation is triggered manually or via scheduled task, never automatic
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
## Gap Detection
|
|
143
|
-
|
|
144
|
-
RecallNest tracks what you search for and notices when searches consistently return poor results.
|
|
145
|
-
|
|
146
|
-
> 缺口检测:分析搜索日志,找出你经常问但记忆库覆盖不足的主题。
|
|
147
|
-
|
|
148
|
-
### How It Works
|
|
149
|
-
|
|
150
|
-
1. Log every search query and its top result score
|
|
151
|
-
2. Periodically analyze: which topics have avg score < threshold?
|
|
152
|
-
3. Cluster low-score queries by topic
|
|
153
|
-
4. Generate a gap report with suggestions
|
|
154
|
-
|
|
155
|
-
### Example Gap Report
|
|
156
|
-
|
|
157
|
-
```
|
|
158
|
-
Topic: "deployment pipeline"
|
|
159
|
-
Searches: 8 in last 30 days
|
|
160
|
-
Avg top score: 0.12
|
|
161
|
-
Suggestion: Consider documenting your deployment workflow
|
|
162
|
-
|
|
163
|
-
Topic: "API rate limiting"
|
|
164
|
-
Searches: 5 in last 30 days
|
|
165
|
-
Avg top score: 0.18
|
|
166
|
-
Suggestion: Store your rate limiting strategy and past incidents
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Access-Based Surfacing ("Use It or Lose It")
|
|
172
|
-
|
|
173
|
-
> 用进废退:经常被搜到的记忆权重上升,长期无人问津的权重下降。
|
|
174
|
-
|
|
175
|
-
The access tracker records every time a memory appears in search results. This creates a feedback loop:
|
|
176
|
-
|
|
177
|
-
```
|
|
178
|
-
Accessed often → higher tier → higher base score → more likely to surface
|
|
179
|
-
Never accessed → lower tier → lower base score → gradually fades
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
This is the "use it or lose it" principle applied to AI memory.
|
|
183
|
-
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
## Putting It All Together
|
|
187
|
-
|
|
188
|
-
A typical memory lifecycle:
|
|
189
|
-
|
|
190
|
-
1. **Day 0**: New memory stored → classified as `events` → tier: `peripheral`
|
|
191
|
-
2. **Day 1-30**: Searched 5 times → promoted to `working`
|
|
192
|
-
3. **Day 30-90**: Searched 15 more times → promoted to `core`
|
|
193
|
-
4. **Day 120**: Consolidated with 3 similar memories → single refined entry
|
|
194
|
-
5. **Day 180+**: Access drops to zero → demoted to `working`
|
|
195
|
-
6. **Day 365+**: Still no access → demoted to `peripheral`, Weibull decay significant
|
|
196
|
-
7. **Archival**: If importance < threshold after extended inactivity → archived
|
|
197
|
-
|
|
198
|
-
The result: your memory index stays lean, relevant, and self-maintaining.
|