smart_brain 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/MEMPAL_GUIDE.md +1074 -0
  4. data/README.en.md +173 -173
  5. data/README.md +467 -173
  6. data/config/brain.yml +69 -1
  7. data/conversation_demo.rb +438 -438
  8. data/db/migrate/002_turn_events_payload.sql +9 -0
  9. data/db/migrate/003_tiers_and_lifecycle.sql +28 -0
  10. data/db/migrate/004_kg_edges.sql +30 -0
  11. data/db/migrate/005_domains_and_memory_scopes.sql +163 -0
  12. data/docs/coding_todo.md +139 -0
  13. data/docs/context_package.md +220 -0
  14. data/docs/evidence_pack.md +190 -0
  15. data/docs/gap_vs_mempal.md +161 -0
  16. data/docs/mcp.md +93 -0
  17. data/docs/memory_types.md +278 -0
  18. data/docs/multi_scope_memory_refactor_plan.md +483 -0
  19. data/docs/multi_scope_migration.md +65 -0
  20. data/docs/policies.md +308 -0
  21. data/docs/retrieval_plan.md +231 -0
  22. data/docs/smartbrain_design.md +299 -0
  23. data/docs/user_guide.md +546 -0
  24. data/example.rb +91 -91
  25. data/examples/01_memory_basic.rb +57 -0
  26. data/examples/02_governance.rb +63 -0
  27. data/examples/03_postgres_persistence.rb +63 -0
  28. data/examples/04_ollama_llm.rb +69 -0
  29. data/examples/05_smart_rag_integration.rb +79 -0
  30. data/examples/06_multi_scope_memory.rb +50 -0
  31. data/examples/README.md +49 -0
  32. data/exe/smart_brain +168 -0
  33. data/lib/smart_brain/adapters/smart_rag/direct_client.rb +16 -5
  34. data/lib/smart_brain/adapters/smart_rag/http_client.rb +16 -5
  35. data/lib/smart_brain/adapters/smart_rag/null_client.rb +7 -2
  36. data/lib/smart_brain/adapters/smart_rag/scope_filter.rb +60 -0
  37. data/lib/smart_brain/configuration.rb +57 -0
  38. data/lib/smart_brain/consolidator/working_summary.rb +80 -12
  39. data/lib/smart_brain/context_composer/composer.rb +40 -3
  40. data/lib/smart_brain/contracts/retrieval_plan.rb +10 -0
  41. data/lib/smart_brain/contracts/scope_context.rb +46 -0
  42. data/lib/smart_brain/contracts/scope_ref.rb +25 -0
  43. data/lib/smart_brain/db.rb +109 -0
  44. data/lib/smart_brain/event_store/in_memory.rb +6 -2
  45. data/lib/smart_brain/event_store/postgres.rb +199 -0
  46. data/lib/smart_brain/fusion/merger.rb +31 -2
  47. data/lib/smart_brain/governance/briefing.rb +146 -0
  48. data/lib/smart_brain/governance/fact_check.rb +110 -0
  49. data/lib/smart_brain/governance/knowledge_graph.rb +60 -0
  50. data/lib/smart_brain/governance/lifecycle.rb +225 -0
  51. data/lib/smart_brain/governance/tiers.rb +60 -0
  52. data/lib/smart_brain/memory_extractor/extractor.rb +25 -7
  53. data/lib/smart_brain/memory_store/in_memory.rb +202 -17
  54. data/lib/smart_brain/memory_store/postgres.rb +500 -0
  55. data/lib/smart_brain/model_provider/base.rb +87 -0
  56. data/lib/smart_brain/model_provider/factory.rb +49 -0
  57. data/lib/smart_brain/model_provider/ollama.rb +60 -0
  58. data/lib/smart_brain/model_provider/openai.rb +60 -0
  59. data/lib/smart_brain/model_provider/stub.rb +26 -0
  60. data/lib/smart_brain/model_provider.rb +7 -0
  61. data/lib/smart_brain/observability/tracker.rb +39 -1
  62. data/lib/smart_brain/retrievers/exact_retriever.rb +6 -0
  63. data/lib/smart_brain/retrievers/memory_retriever.rb +59 -5
  64. data/lib/smart_brain/runtime.rb +288 -16
  65. data/lib/smart_brain/scopes/conflict_resolver.rb +67 -0
  66. data/lib/smart_brain/scopes/registry.rb +133 -0
  67. data/lib/smart_brain/scopes/resolver.rb +32 -0
  68. data/lib/smart_brain/server/http_app.rb +143 -0
  69. data/lib/smart_brain/server/mcp_server.rb +385 -0
  70. data/lib/smart_brain/server/service.rb +129 -0
  71. data/lib/smart_brain/support/levenshtein.rb +35 -0
  72. data/lib/smart_brain/version.rb +5 -5
  73. data/lib/smart_brain.rb +80 -35
  74. metadata +88 -36
@@ -0,0 +1,483 @@
1
+ # SmartBrain 多级记忆域改造计划
2
+
3
+ > 目标版本:SmartBrain 0.2.0
4
+ > 文档状态:已实施(2026-08-03)
5
+ > 改造范围:SmartBrain 核心、存储、治理、检索、SmartRAG adapter、Ruby/HTTP/MCP/CLI 契约
6
+
7
+ ## 1. 背景
8
+
9
+ SmartBrain 0.1.x 使用 `session_id` 同时承担对话隔离和长期记忆隔离。该模型适合单会话 Agent,但无法自然表达以下共享关系:
10
+
11
+ - 全局记忆:跨项目、跨专家、跨任务共享;
12
+ - 项目记忆:同一项目的不同任务共享;
13
+ - 专家记忆:同一专家跨项目、跨任务复用;
14
+ - 任务记忆:只在当前任务内生效;
15
+ - 会话事件:只属于一次连续对话。
16
+
17
+ 如果通过拼接 `session_id` 或向多个 session 复制记忆模拟这些层级,会引入重复数据、冲突不一致、治理链断裂和召回难以解释等问题。因此,0.2.0 将长期记忆归属从 session 中拆出,引入 domain 和 memory scope。
18
+
19
+ ## 2. 目标与非目标
20
+
21
+ ### 2.1 目标
22
+
23
+ 1. 支持 `global/project/expert/task` 四类业务记忆 scope。
24
+ 2. 保持 turns、messages、tool calls、refs 和 working summary 的 session 隔离。
25
+ 3. 一次 compose 可以联合检索多个 scope,并统一去重、冲突消解、排序和裁剪。
26
+ 4. 支持记忆在 scope 之间受控提升,并保留证据与审计链。
27
+ 5. 支持 domain 级数据隔离,禁止跨 domain 召回。
28
+ 6. InMemory 与 PostgreSQL 后端保持行为一致。
29
+ 7. Ruby、HTTP、MCP、CLI 旧调用在兼容期内继续工作。
30
+ 8. SmartRAG 资源检索遵循相同的 domain/scope 边界。
31
+
32
+ ### 2.2 非目标
33
+
34
+ - 本阶段不实现组织级 RBAC 或远程租户鉴权。
35
+ - 不自动推断调用方有权访问哪些 scope;调用方负责提供 scope context,SmartBrain 负责契约校验和 domain 隔离。
36
+ - 不在本阶段实现任意 DAG 形式的 scope 继承。
37
+ - 不允许模型将未经验证的记忆自动提升到 global、project 或 expert scope。
38
+ - 不在本阶段移除 0.1.x 的 session-only API。
39
+
40
+ ## 3. 核心概念
41
+
42
+ ### 3.1 Domain
43
+
44
+ `domain_id` 是最外层数据隔离边界,可对应一个用户、租户或 Agent 应用实例。同一请求引用的 session 和 scope 必须属于同一 domain。
45
+
46
+ 注意:知识生命周期接口现有的 `domain` 字段表示知识主题,不承担隔离职责。新字段始终命名为 `domain_id`。
47
+
48
+ ### 3.2 Memory Scope
49
+
50
+ Memory Scope 表示长期记忆的归属与共享范围:
51
+
52
+ | scope_type | 含义 | 示例 |
53
+ |---|---|---|
54
+ | `global` | domain 内全局共享 | `global:default` |
55
+ | `project` | 项目内共享 | `project:project-001` |
56
+ | `expert` | 专家跨任务复用 | `expert:coding` |
57
+ | `task` | 当前任务私有 | `task:task-030` |
58
+ | `session` | 兼容旧数据的内部私有 scope | `session:conv-001` |
59
+
60
+ `session` scope 是兼容设施,不属于面向业务的四级记忆模型。
61
+
62
+ ### 3.3 Session
63
+
64
+ Session 继续表示一次连续对话。以下数据仍以 `session_id` 为主归属:
65
+
66
+ - turns/messages/tool_calls/refs;
67
+ - recent turns;
68
+ - rolling working summary;
69
+ - commit/compose trace。
70
+
71
+ 长期记忆记录 `scope_id`,同时通过 `source_session_id` 保留来源会话。
72
+
73
+ ### 3.4 ScopeRef 与 ScopeContext
74
+
75
+ ScopeRef 的公共结构:
76
+
77
+ ```ruby
78
+ { type: 'project', id: 'project-001' }
79
+ ```
80
+
81
+ ScopeContext 的公共结构:
82
+
83
+ ```ruby
84
+ {
85
+ read: [
86
+ { type: 'global', id: 'default' },
87
+ { type: 'project', id: 'project-001' },
88
+ { type: 'expert', id: 'coding' },
89
+ { type: 'task', id: 'task-030' }
90
+ ],
91
+ write: [
92
+ { type: 'project', id: 'project-001' },
93
+ { type: 'task', id: 'task-030' }
94
+ ],
95
+ default_write: { type: 'task', id: 'task-030' }
96
+ }
97
+ ```
98
+
99
+ `read` 必须去重,且所有 scope 必须属于请求的 `domain_id`。`write` 必须是 `read` 的子集,`default_write` 必须包含在 `write` 中。省略 `write` 时默认仅允许写入 `default_write`。
100
+
101
+ ## 4. 目标数据模型
102
+
103
+ ### 4.1 新表
104
+
105
+ ```text
106
+ domains
107
+ - id text primary key
108
+ - metadata_json jsonb
109
+ - created_at timestamptz
110
+ - updated_at timestamptz
111
+
112
+ memory_scopes
113
+ - id text primary key
114
+ - domain_id text not null references domains(id)
115
+ - scope_type text not null
116
+ - external_id text not null
117
+ - parent_scope_id text null references memory_scopes(id)
118
+ - metadata_json jsonb
119
+ - created_at timestamptz
120
+ - updated_at timestamptz
121
+ - unique(domain_id, scope_type, external_id)
122
+
123
+ session_scope_links
124
+ - session_id text not null references sessions(id)
125
+ - scope_id text not null references memory_scopes(id)
126
+ - access_mode text not null
127
+ - priority integer not null
128
+ - created_at timestamptz
129
+ - primary key(session_id, scope_id)
130
+ ```
131
+
132
+ `access_mode` 初期支持 `read` 和 `read_write`。`priority` 只用于稳定排序和诊断,不能绕过冲突策略。
133
+
134
+ ### 4.2 现有表调整
135
+
136
+ - `sessions` 增加 `domain_id`;
137
+ - `memory_items` 增加 `scope_id`、`source_session_id`;
138
+ - `entities` 增加 `scope_id`、`source_session_id`;
139
+ - `kg_edges` 增加 `scope_id`、`source_session_id`;
140
+ - `knowledge_events` 继续通过 memory item 追踪 scope;
141
+ - `summaries`、`turns`、`messages`、`refs` 保持 session 归属。
142
+
143
+ 新增主要索引:
144
+
145
+ ```text
146
+ memory_items(scope_id, status, lifecycle_status)
147
+ memory_items(scope_id, type, key)
148
+ kg_edges(scope_id, status)
149
+ entities(scope_id, canonical, kind)
150
+ sessions(domain_id)
151
+ ```
152
+
153
+ 0.2.0 不立即删除旧 `memory_items.session_id` 和 `kg_edges.session_id`,先作为兼容字段保留,并在后续版本评估移除。
154
+
155
+ ## 5. 公共 API 设计
156
+
157
+ ### 5.1 Commit
158
+
159
+ ```ruby
160
+ SmartBrain.commit_turn(
161
+ domain_id: 'default',
162
+ session_id: 'conv-001',
163
+ scope_context: scope_context,
164
+ turn_events: turn_events
165
+ )
166
+ ```
167
+
168
+ 单条结构化记忆允许覆盖默认写 scope:
169
+
170
+ ```ruby
171
+ decisions: [{
172
+ key: 'decision:db:storage',
173
+ decision: '项目使用 PostgreSQL',
174
+ scope_ref: { type: 'project', id: 'project-001' }
175
+ }]
176
+ ```
177
+
178
+ messages 和 refs 忽略 `scope_ref`,始终写入 session。entities 和 edges 默认跟随 `default_write`,显式指定时必须通过 scope 写权限检查。
179
+
180
+ ### 5.2 Compose
181
+
182
+ ```ruby
183
+ SmartBrain.compose_context(
184
+ domain_id: 'default',
185
+ session_id: 'conv-001',
186
+ scope_context: scope_context,
187
+ user_message: '继续实现数据库迁移',
188
+ agent_state: {}
189
+ )
190
+ ```
191
+
192
+ compose 使用当前 session 的 recent turns 和 summary,使用 `scope_context.read` 检索长期记忆与 KG。
193
+
194
+ ### 5.3 Search、Brief、KG 与治理
195
+
196
+ 以下接口同步增加 `domain_id` 和 scope 参数:
197
+
198
+ - `search_memory`;
199
+ - `brief`、`wake_up`;
200
+ - `fact_check`;
201
+ - `kg_add`、`kg_query`、`kg_stats`、`kg_timeline`;
202
+ - `distill`、`promote`、`demote`、`retract`。
203
+
204
+ 按 ID 操作 memory item 时从记录解析 domain/scope,并校验调用上下文,不依赖调用方重复提供正确归属。
205
+
206
+ ## 6. Commit 写入策略
207
+
208
+ commit 的目标执行顺序:
209
+
210
+ 1. 规范化 `domain_id`、`session_id` 和 `scope_context`;
211
+ 2. 确保 domain、session、scope 和 session-scope link 存在;
212
+ 3. 将 messages、tool calls 和 refs 写入 session EventStore;
213
+ 4. Extractor 生成结构化记忆候选;
214
+ 5. Scope Resolver 为每条候选解析目标 scope;
215
+ 6. MemoryStore 在目标 scope 内执行 upsert 和冲突记录;
216
+ 7. entities、KG edges 使用同一 scope 解析规则;
217
+ 8. Consolidator 更新当前 session 的 working summary;
218
+ 9. commit explain 记录每条数据的 scope、来源和拒绝原因。
219
+
220
+ 默认写入策略保持保守:自动抽取只写 `default_write`。写入 global/project/expert 必须由调用方显式指定,或通过跨 scope promotion 完成。
221
+
222
+ ## 7. 多 Scope 检索与冲突消解
223
+
224
+ compose 的目标流程:
225
+
226
+ ```text
227
+ resolve scopes
228
+ -> retrieve per scope
229
+ -> lifecycle/status filter
230
+ -> resolve same-key conflicts
231
+ -> KG expansion
232
+ -> optional SmartRAG retrieval
233
+ -> memory/resource fusion
234
+ -> tier order and token budget
235
+ -> ContextPackage
236
+ ```
237
+
238
+ ### 7.1 同 Key 冲突
239
+
240
+ 对相同 `type + key` 的 active 记忆采用以下规则:
241
+
242
+ 1. 钉入的 `dao_tian` 原则不被普通记忆覆盖;
243
+ 2. 普通记忆按 `task > project > expert > global` 选择;
244
+ 3. 同 scope 内使用现有 active/superseded/retracted 规则;
245
+ 4. 未选中的候选进入 `debug.shadowed`,保留覆盖原因;
246
+ 5. 没有稳定 key 的 evidence 不做 scope shadow,仅参与相关性排序。
247
+
248
+ 项目约束默认高于专家习惯。例如项目明确要求 MySQL 时,不能因为 coding expert 偏好 PostgreSQL 而改变当前项目决策。
249
+
250
+ ### 7.2 排序与预算
251
+
252
+ scope specificity 只能作为排序信号之一,不能完全取代 query relevance。Composer 仍以 mind-model tier 控制原则优先级,并为每个 scope 设置可配置上限,防止某个 scope 独占上下文。
253
+
254
+ 建议新增配置:
255
+
256
+ ```yaml
257
+ policies:
258
+ scopes:
259
+ allowed_types: [global, project, expert, task, session]
260
+ conflict_priority: [task, project, expert, global, session]
261
+ max_items_per_scope: 10
262
+ require_explicit_elevated_write: true
263
+ ```
264
+
265
+ ## 8. 跨 Scope 治理
266
+
267
+ 新增接口:
268
+
269
+ ```ruby
270
+ SmartBrain.promote_to_scope(
271
+ memory_item_id: memory_item_id,
272
+ target_scope: { type: 'project', id: 'project-001' },
273
+ verification_refs: refs,
274
+ reason: '项目决策已确认',
275
+ reviewer: 'human'
276
+ )
277
+ ```
278
+
279
+ 跨 scope promotion 不移动或原地修改源记录,而是在目标 scope 创建新记录,并保存:
280
+
281
+ - source memory item ID;
282
+ - source scope;
283
+ - target scope;
284
+ - supporting/verification refs;
285
+ - reviewer 与 reason;
286
+ - promotion event ID。
287
+
288
+ 目标记录必须能沿 provenance 回溯到源 session。后续需支持 `demote_from_scope`、retract 和 promotion lineage 查询。
289
+
290
+ ## 9. SmartRAG Scope 传播
291
+
292
+ RetrievalPlan 增加 scope 上下文:
293
+
294
+ ```ruby
295
+ {
296
+ debug: {
297
+ caller: {
298
+ app: 'smart_brain',
299
+ domain_id: 'default',
300
+ session_id: 'conv-001'
301
+ }
302
+ },
303
+ scope_context: scope_context
304
+ }
305
+ ```
306
+
307
+ SmartRAG adapter 负责将 scope 映射为 SmartRAG 的 `topic_ids`、`document_ids` 或其他过滤条件。SmartBrain 不在核心层绑定具体 topic 命名规则。
308
+
309
+ 若 SmartRAG 无法应用某个 scope 过滤,adapter 必须返回 warning,并写入 `explain.ignored_fields`。生产配置可选择在过滤无法应用时 fail closed,避免跨项目或跨 domain 召回。
310
+
311
+ ## 10. ContextPackage 与可观测性
312
+
313
+ Memory evidence 增加:
314
+
315
+ ```ruby
316
+ {
317
+ scope: { type: 'project', id: 'project-001' },
318
+ source_session_id: 'conv-001'
319
+ }
320
+ ```
321
+
322
+ ContextPackage debug 增加:
323
+
324
+ - `scopes_read`;
325
+ - `scope_stats`;
326
+ - `shadowed`;
327
+ - `scope_budget`;
328
+ - `scope_filter_warnings`。
329
+
330
+ diagnostics 增加:
331
+
332
+ - 每种 scope 的写入量和召回量;
333
+ - shadow/conflict 数量;
334
+ - 跨 scope promotion 数量;
335
+ - domain/scope 校验失败数量;
336
+ - SmartRAG scope filter 失败数量。
337
+
338
+ ## 11. 兼容与迁移策略
339
+
340
+ ### 11.1 旧 API
341
+
342
+ 未传 `domain_id` 和 `scope_context` 的调用使用:
343
+
344
+ ```text
345
+ domain_id = legacy
346
+ read/default_write = session:<session_id>
347
+ ```
348
+
349
+ 这样旧 session 之间仍保持隔离,不会因升级意外共享记忆。
350
+
351
+ ### 11.2 PostgreSQL 数据迁移
352
+
353
+ 迁移脚本为每个旧 session:
354
+
355
+ 1. 创建或复用 `legacy` domain;
356
+ 2. 创建 `session:<session_id>` 内部 scope;
357
+ 3. 建立 session-scope link;
358
+ 4. 回填 memory items、entities 和 KG edges 的 `scope_id` 与 `source_session_id`;
359
+ 5. 迁移完成后执行 orphan 和跨 domain 一致性检查。
360
+
361
+ 迁移必须幂等,且不删除旧字段或旧数据。
362
+
363
+ ## 12. 分阶段实施
364
+
365
+ ### Phase A:契约与骨架
366
+
367
+ - 增加 ScopeRef、ScopeContext contracts;
368
+ - 增加 domain/scope 配置;
369
+ - 定义兼容映射;
370
+ - 补充契约和序列化测试。
371
+
372
+ 验收:新旧参数均可校验;非法 scope type、重复 scope、跨 domain 引用被拒绝。
373
+
374
+ ### Phase B:数据库与 Store
375
+
376
+ - 增加 005 migration;
377
+ - 实现 scope registry/resolver;
378
+ - 改造 InMemory Store;
379
+ - 改造 PostgreSQL Store;
380
+ - 完成旧数据回填。
381
+
382
+ 验收:两个后端在 CRUD、隔离、upsert 和查询上行为一致。
383
+
384
+ ### Phase C:Commit 路由
385
+
386
+ - Runtime 接受 domain/scope context;
387
+ - Extractor 保留或透传 scope_ref;
388
+ - memory/entity/KG 写入目标 scope;
389
+ - explain 增加写入路由信息。
390
+
391
+ 验收:默认写 task,显式写 project/expert/global,messages 始终只写 session。
392
+
393
+ ### Phase D:Compose 与冲突处理
394
+
395
+ - 实现多 scope retrieval;
396
+ - 实现 Scope ConflictResolver;
397
+ - 改造 memory retriever、KG expansion、Fusion、Composer;
398
+ - 增加 scope 预算与 debug。
399
+
400
+ 验收:四级联合召回可用,task/project/expert/global 冲突结果稳定且可解释。
401
+
402
+ ### Phase E:治理能力
403
+
404
+ - 实现 promote_to_scope;
405
+ - 扩展 knowledge events 与 provenance;
406
+ - 扩展 brief、wake_up、fact_check、KG;
407
+ - 增加 demote/retract 行为测试。
408
+
409
+ 验收:高层记忆有证据与审计链,能够回溯源 scope 和 session。
410
+
411
+ ### Phase F:SmartRAG、协议与工具面
412
+
413
+ - 扩展 RetrievalPlan 和 adapter;
414
+ - 更新 Ruby/HTTP/MCP/CLI;
415
+ - 更新用户指南和 examples;
416
+ - 增加 scope diagnostics。
417
+
418
+ 验收:所有调用面支持新参数,SmartRAG scope filter 可验证且默认不泄漏。
419
+
420
+ ### Phase G:兼容与发布
421
+
422
+ - 运行完整旧测试套件;
423
+ - 增加迁移演练和回滚验证;
424
+ - 增加 PostgreSQL 集成测试;
425
+ - 发布 0.2.0 和迁移说明。
426
+
427
+ 验收:0.1.x 旧调用继续通过,升级前后 session-only 行为一致。
428
+
429
+ ## 13. 测试矩阵
430
+
431
+ 必须覆盖:
432
+
433
+ 1. domain A 无法读取 domain B 的 session、memory、entity 和 KG;
434
+ 2. 同一 domain 的多个 session 可以共享 project/expert/global scope;
435
+ 3. task scope 不会泄漏到同项目其他任务;
436
+ 4. project 记忆覆盖 expert/global 的同 key 普通记忆;
437
+ 5. task 记忆覆盖 project 记忆;
438
+ 6. dao_tian 原则不被普通 task 记忆覆盖;
439
+ 7. lifecycle candidate/demoted 仍不会进入自动 context;
440
+ 8. promotion 保留 source memory、scope、session 和 evidence;
441
+ 9. InMemory/PostgreSQL 返回顺序和 shadow 结果一致;
442
+ 10. 旧 API 和旧 PostgreSQL 数据迁移后行为不变;
443
+ 11. MCP/HTTP/CLI 的 schema、参数和错误响应一致;
444
+ 12. SmartRAG filter 未应用时产生 warning 或按配置 fail closed。
445
+
446
+ ## 14. 发布门槛
447
+
448
+ SmartBrain 0.2.0 发布前必须满足:
449
+
450
+ - 所有 0.1.x 自动化测试继续通过;
451
+ - scope 新测试在 InMemory 和 PostgreSQL 后端全部通过;
452
+ - migration 可重复运行,且有旧数据校验报告;
453
+ - compose evidence 能解释 scope 和 source session;
454
+ - 未传新参数的客户端无需修改即可运行;
455
+ - SmartRAG 不会在过滤失败时静默跨 scope 返回资源;
456
+ - 文档包含升级、回滚和兼容期说明。
457
+
458
+ ## 15. 建议的代码改动边界
459
+
460
+ 主要新增或修改位置:
461
+
462
+ ```text
463
+ lib/smart_brain.rb
464
+ lib/smart_brain/runtime.rb
465
+ lib/smart_brain/configuration.rb
466
+ lib/smart_brain/contracts/
467
+ lib/smart_brain/scopes/
468
+ lib/smart_brain/event_store/
469
+ lib/smart_brain/memory_store/
470
+ lib/smart_brain/memory_extractor/
471
+ lib/smart_brain/retrievers/
472
+ lib/smart_brain/fusion/
473
+ lib/smart_brain/context_composer/
474
+ lib/smart_brain/governance/
475
+ lib/smart_brain/adapters/smart_rag/
476
+ lib/smart_brain/server/
477
+ db/migrate/005_domains_and_memory_scopes.sql
478
+ spec/
479
+ docs/
480
+ examples/
481
+ ```
482
+
483
+ 实施时应先完成契约和存储层,再修改 Runtime;不要在 Store 尚未具备双后端一致性之前接入 SmartRAG 或上层应用。
@@ -0,0 +1,65 @@
1
+ # SmartBrain 0.2.0 Multi-Scope Migration
2
+
3
+ ## Upgrade
4
+
5
+ Back up the PostgreSQL database before upgrading. Then run:
6
+
7
+ ```bash
8
+ SMARTBRAIN_BACKEND=postgres bundle exec smart_brain migrate
9
+ ```
10
+
11
+ Migration `005_domains_and_memory_scopes.sql` is idempotent. It preserves the
12
+ legacy `session_id` columns, creates `legacy/session:<session_id>` scopes, and
13
+ backfills memory, entity, and KG provenance. Calls that omit `domain_id` and
14
+ `scope_context` continue to use the isolated legacy session scope.
15
+
16
+ Validate the upgrade with:
17
+
18
+ ```sql
19
+ SELECT count(*) FROM memory_items WHERE scope_id IS NULL OR source_session_id IS NULL;
20
+ SELECT count(*) FROM entities WHERE scope_id IS NULL OR source_session_id IS NULL;
21
+ SELECT count(*) FROM kg_edges WHERE scope_id IS NULL OR source_session_id IS NULL;
22
+ ```
23
+
24
+ All three counts must be zero.
25
+
26
+ ## Rollback
27
+
28
+ Application rollback is supported during the compatibility period because the
29
+ old `session_id` columns and data remain intact. Stop 0.2 writers, deploy the
30
+ 0.1 application, and switch clients back to session-only calls.
31
+
32
+ Do not drop `domains`, `memory_scopes`, `session_scope_links`, or the new
33
+ columns during an operational rollback. Removing them is a separate destructive
34
+ cleanup after all 0.2 data has been exported or mapped back to legacy sessions.
35
+
36
+ ## New Context
37
+
38
+ New clients should provide explicit read and write scopes:
39
+
40
+ ```ruby
41
+ scope_context = {
42
+ read: [
43
+ { type: 'global', id: 'default' },
44
+ { type: 'project', id: 'project-001' },
45
+ { type: 'task', id: 'task-030' }
46
+ ],
47
+ write: [
48
+ { type: 'project', id: 'project-001' },
49
+ { type: 'task', id: 'task-030' }
50
+ ],
51
+ default_write: { type: 'task', id: 'task-030' }
52
+ }
53
+ ```
54
+
55
+ Per-item `scope_ref` writes are accepted only when the target appears in
56
+ `scope_context.write`.
57
+
58
+ ## Validation Record
59
+
60
+ The 2026-08-03 local PostgreSQL rehearsal completed successfully:
61
+
62
+ - migration `005` was run repeatedly through the migration command and the PostgreSQL test setup;
63
+ - the full suite passed with `92 examples, 0 failures` with PostgreSQL enabled;
64
+ - `memory_items`, `entities`, and `kg_edges` each reported zero rows with missing `scope_id` or `source_session_id`;
65
+ - legacy session-only persistence/recall and scoped ordering, shadow diagnostics, governance, and promotion provenance passed after runtime restart.