diff --git a/README.md b/README.md
index e4c57512..8da5cde7 100644
--- a/README.md
+++ b/README.md
@@ -142,9 +142,6 @@ Partner/
- [模型提供商](doc/model/providers.md)
- [ContextWorkspace](doc/context/context-workspace.md)
- [行动系统](doc/action/action.md)
-
-### 待完成
-
- [记忆存储与组织](doc/memory/memory.md)
---
diff --git a/doc/memory/after-rolling.md b/doc/memory/after-rolling.md
new file mode 100644
index 00000000..e8d9c4f6
--- /dev/null
+++ b/doc/memory/after-rolling.md
@@ -0,0 +1,45 @@
+# AfterRolling
+
+`AfterRolling` 是 `DialogRolling` 完成一次上下文滚动后的扩展点。它不生成原始记忆,而是消费已经生成的 `RollingResult`
+,适用于维护组织层索引、补充组织信息,或执行与新记忆相关的异步副作用。
+
+```mermaid
+flowchart TD
+ A["DialogRolling.triggerRolling"] --> B["buildRollingResult"]
+ B --> C["MemoryCapability.updateMemoryUnit"]
+ C --> D["MemoryUnit / MemorySlice"]
+ D --> E["applyRolling"]
+ E --> F["dialog_history ContextBlock"]
+ E --> G["rollChatMessagesWithSnapshot"]
+ E --> H["AfterRollingRegistry.trigger"]
+ H --> I["AfterRolling consumer[]"]
+```
+
+rolling 的主流程先完成原始记忆写入和当前上下文窗口裁剪,然后再触发 `AfterRollingRegistry`。因此,`AfterRolling` consumer
+面对的是已经稳定生成的记忆结果,而不是待写入的临时数据。
+
+## RollingResult
+
+`RollingResult` 是 rolling 阶段传递给后处理 consumer 的数据包。
+
+| 字段 | 说明 |
+|---------------------|-----------------------|
+| `memoryUnit` | 本次 rolling 写入或更新的记忆单元 |
+| `memorySlice` | 本次 rolling 新生成的记忆切片 |
+| `incrementMessages` | 本次进入记忆的增量消息 |
+| `summary` | 本次切片摘要 |
+| `rollingSize` | rolling 发生时的对话窗口大小 |
+| `retainDivisor` | rolling 后保留近期上下文的比例参数 |
+
+这些字段让 consumer 可以同时看到三类信息:已经落盘的记忆对象、原始增量消息,以及本次 rolling 对上下文窗口的处理参数。
+
+## 当前 consumer
+
+当前 memory 侧的主要 consumer 是 `MemoryRecallProfileExtractor`。它消费 `RollingResult`,读取当前主题树、切片摘要和原始消息片段,提取:
+
+- `topicPath`
+- `relatedTopicPaths`
+- `ActivationProfile`
+
+随后它调用 `MemoryRuntime.recordMemory(...)`,把新切片写入主题索引和日期索引。也就是说,原始记忆的生成发生在
+`DialogRolling` 中,索引和召回组织信息的补充发生在 `AfterRolling` consumer 中。
diff --git a/doc/memory/memory-retrieval.md b/doc/memory/memory-retrieval.md
new file mode 100644
index 00000000..69fbfd8b
--- /dev/null
+++ b/doc/memory/memory-retrieval.md
@@ -0,0 +1,113 @@
+# 记忆检索
+
+本文说明 Partner 记忆系统的组织层。存储层只保存稳定的 `MemoryUnit` 与 `MemorySlice`,检索层在这些数据之上建立可替换的召回结构。
+
+当前默认实现是 `MemoryRuntime`:它维护主题路径索引和日期索引,并把索引结果重新解析为可注入上下文的 `ActivatedMemorySlice`。
+
+| 索引 | 作用 |
+|---------------------------|------------------------------------------|
+| `TopicMemoryIndex` | 按主题路径组织 `MemorySlice`,支持主主题、父主题和相关主题扩散召回 |
+| `DateMemoryIndex` | 按日期记录 `MemorySlice` 引用,支持按日期直接召回 |
+| `MemoryRuntimeStateCodec` | 负责主题索引和日期索引的持久化与恢复 |
+
+## 索引建立
+
+`MemoryRuntime` 不直接生成原始记忆。原始记忆由 `DialogRolling` 写入 `MemoryUnit` 后,`AfterRolling` consumer 会消费
+`RollingResult`,为新产生的 `MemorySlice` 提取主题路径、相关主题和激活参数,再调用 `MemoryRuntime.recordMemory(...)` 建立索引。
+
+```mermaid
+flowchart TD
+ A["DialogRolling"] --> B["RollingResult"]
+ B --> C["AfterRollingRegistry"]
+ C --> D["MemoryRecallProfileExtractor"]
+ D --> E["topicPath
主主题路径"]
+ D --> F["relatedTopicPaths
相关主题路径"]
+ D --> G["ActivationProfile
激活 / 扩散 / 上下文独立权重"]
+ B --> H["MemoryUnit"]
+ B --> I["MemorySlice"]
+ H --> J["SliceRef
unitId + sliceId"]
+ I --> J
+ I --> K["LocalDate
由 slice timestamp 转换"]
+ J --> L["MemoryRuntime.recordMemory"]
+ E --> L
+ F --> L
+ G --> L
+ K --> L
+ L --> M["DateMemoryIndex.record"]
+ L --> N["TopicMemoryIndex.recordBinding"]
+ L --> O["TopicMemoryIndex.ensureTopicPaths"]
+ M --> P["date -> SliceRef[]"]
+ N --> Q["topicPath -> TopicBinding[]"]
+ O --> R["related topic path nodes"]
+```
+
+`TopicMemoryIndex` 的绑定对象不是完整记忆内容,而是 `SliceRef`。它只记录 `unitId`、`sliceId`、时间戳、相关主题路径和
+`ActivationProfile`。真正需要展示原始消息时,`MemoryRuntime` 会再回到 `MemoryCapability` 读取对应 `MemoryUnit` 和
+`MemorySlice`。
+
+主题路径使用 `->` 表示层级,例如:
+
+```text
+project->partner->memory
+```
+
+`TopicMemoryIndex` 会按路径建立树节点;绑定到某个节点的 slice 表示该记忆切片属于这个主题。相关主题路径不会直接复制
+slice,而是作为扩散召回的候选入口参与后续评分。
+
+## 使用检索: 主题路径和日期索引
+
+运行时召回由 `MemorySelector` 触发。它会收集输入,使用当前主题树和输入内容提取召回线索,再按线索类型分别查询主题索引或日期索引。
+
+```mermaid
+flowchart TD
+ subgraph Input["输入收集"]
+ A["PartnerRunningFlowContext"] --> B["MemorySelector.collectInputs"]
+ B --> C["collectedInputs"]
+ C --> D["drainMemoryRecall"]
+ end
+
+ subgraph Cue["召回线索抽取"]
+ D --> E["MemoryRuntime.getTopicTree"]
+ D --> F["MemoryRecallCueExtractor"]
+ E --> F
+ F --> G["ExtractorResult.matches"]
+ end
+
+ subgraph Lookup["索引查询"]
+ G --> H{"match.type"}
+ H -- " TOPIC " --> I["MemoryRuntime.queryActivatedMemoryByTopicPath"]
+ H -- " DATE " --> J["MemoryRuntime.queryActivatedMemoryByDate"]
+ I --> K["TopicRecallCollector.collect"]
+ J --> L["DateMemoryIndex.find"]
+ K --> M["SliceRef[]"]
+ L --> M
+ end
+
+ subgraph Materialize["切片还原"]
+ M --> N["MemoryCapability.getMemoryUnit"]
+ M --> O["MemoryCapability.getMemorySlice"]
+ N --> P["sliceMessages"]
+ O --> P
+ P --> Q["ActivatedMemorySlice"]
+ end
+
+ subgraph Evaluate["评估与上下文注入"]
+ Q --> R["MemoryRecallEvaluator"]
+ R --> S["activated_memory_slices ContextBlock"]
+ S --> T["ContextWorkspace"]
+ end
+```
+
+按主题召回时,`TopicRecallCollector` 会从三个来源收集候选:
+
+| 来源 | 含义 |
+|-----------|-----------------------|
+| `PRIMARY` | 当前主题节点直接绑定的 slice |
+| `PARENT` | 父主题节点的近期候选,用于保留上层语境 |
+| `RELATED` | 由当前主题绑定声明的相关主题,用于扩散召回 |
+
+候选会经过 `TopicRecallScorer` 打分。分数综合来源类型、时间新近性、激活权重、上下文独立权重和扩散权重。最终结果会限制数量,并转换成
+`ActivatedMemorySlice`。
+
+`ActivatedMemorySlice` 包含 slice 摘要、日期、时间戳以及对应原始消息片段。`MemorySelector` 会基于这些结果构造
+`activated_memory_slices` 上下文块,使后续 communication、cognition 或 action 模块能够读取被激活的记忆。
diff --git a/doc/memory/memory-storage.md b/doc/memory/memory-storage.md
new file mode 100644
index 00000000..68a60546
--- /dev/null
+++ b/doc/memory/memory-storage.md
@@ -0,0 +1,99 @@
+# 记忆存储
+
+本文说明 Partner 记忆系统的稳定存储模型和原始记忆生成方式。
+
+## MemoryUnit 与 MemorySlice
+
+### 数据模型
+
+存储层由 `MemoryCore`、`MemoryUnit` 和 `MemorySlice` 三层组成。
+
+`MemoryCore` 维护记忆单元集合和当前记忆会话 id;`MemoryUnit` 是可持久化的记忆单元,保存一段对话消息及其摘要切片;
+`MemorySlice` 是对 `MemoryUnit` 中一段消息区间的摘要。
+
+```mermaid
+flowchart TD
+ A["MemoryCore"] --> B["memorySessionId
当前记忆会话"]
+ A --> C["memoryUnits
Map<unitId, MemoryUnit>"]
+ C --> D["MemoryUnit"]
+ D --> E["id"]
+ D --> F["timestamp
最近更新时间"]
+ D --> G["conversationMessages
原始对话消息"]
+ D --> H["slices
List<MemorySlice>"]
+ H --> I["MemorySlice"]
+ I --> J["id"]
+ I --> K["startIndex / endIndex
对应 conversationMessages 区间"]
+ I --> L["summary
该区间摘要"]
+ I --> M["timestamp
切片创建时间"]
+```
+
+`MemoryUnit` 的核心作用是把原始消息和摘要切片绑定在一起。`conversationMessages` 保存完整消息序列,`MemorySlice`
+只记录它覆盖的消息区间和摘要内容。这样,召回层可以先使用摘要切片进行轻量检索,再在需要时回到对应 `MemoryUnit` 读取原始消息。
+
+`MemoryCore` 自身只保存 `memorySessionId` 和 `memory_unit_uuid_set`,每个 `MemoryUnit` 独立持久化到自己的 state
+path。也就是说,`MemoryCore` 负责管理有哪些记忆单元,而具体消息和切片内容保存在 `MemoryUnit` 中。
+
+| 对象 | 作用 |
+|---------------|------------------------------------|
+| `MemoryCore` | 维护当前记忆会话 id、记忆单元集合,并提供读写入口 |
+| `MemoryUnit` | 保存一组原始对话消息及其摘要切片,是稳定落盘单元 |
+| `MemorySlice` | 描述 `MemoryUnit` 中一段消息区间的摘要,可被索引和召回 |
+
+`MemorySlice` 会按创建时间参与排序;`MemoryCore` 在更新记忆时会对 slice 的 id、时间戳和消息区间做规范化,避免索引越界或缺失基础字段。
+
+### 生成方式
+
+`MemoryUnit` 与 `MemorySlice` 的原始材料来自对话轨迹。`CommunicationProducer` 在完成对外回复后,将本轮用户输入和 assistant
+输出写回 `CognitionCapability` 维护的 chat messages;`DialogRolling` 在对话窗口过长或长时间未交互时,基于这些 chat
+messages 生成记忆切片。
+
+```mermaid
+flowchart TD
+ subgraph Communication["CommunicationProducer"]
+ A["PartnerRunningFlowContext
本轮输入"] --> B["生成对外回复"]
+ B --> C["updateChatMessages"]
+ C --> D["CognitionCapability.chatMessages"]
+ end
+
+ subgraph Rolling["DialogRolling"]
+ D --> E{"触发 rolling?"}
+ E -- " 对话数量达到阈值 " --> F["triggerRolling(false)"]
+ E -- " 长时间未交互 " --> G["triggerRolling(true)"]
+ F --> H["snapshotChatMessages"]
+ G --> H
+ H --> I["resolveChatIncrement"]
+ I --> J["MessageCompressor"]
+ J --> K["MessageSummarizer"]
+ K --> L["MemoryCapability.updateMemoryUnit"]
+ L --> M["MemoryUnit"]
+ L --> N["MemorySlice"]
+ end
+
+ subgraph Context["滚动后的上下文处理"]
+ N --> O["dialog_history ContextBlock"]
+ O --> P["ContextWorkspace"]
+ M --> Q["RollingResult"]
+ N --> Q
+ Q --> R["AfterRollingRegistry.trigger"]
+ end
+```
+
+生成流程可以分成两段:
+
+1. **对话轨迹写入**:`CommunicationProducer` 负责把本轮交流结果追加到 `chatMessages`。这里保存的是后续 rolling
+ 能够消费的原始对话轨迹。
+2. **对话滚动入库**:`DialogRolling` 从当前对话快照中计算尚未进入当前 `MemoryUnit` 的增量消息,压缩并总结后调用
+ `MemoryCapability.updateMemoryUnit(chatMessages, summary)`。该调用会把消息增量追加到 `MemoryUnit.conversationMessages`
+ ,并创建一个覆盖这段消息区间的 `MemorySlice`。
+
+`DialogRolling` 有两类触发方式:
+
+| 触发方式 | 含义 |
+|----------|------------------------------------------------|
+| 对话数量达到阈值 | 当前上下文对话过长时触发 rolling,只保留部分近期上下文 |
+| 长时间未交互 | 定时检查发现距离上次交互超过阈值时触发 rolling,并刷新 memory session |
+
+rolling 完成后,系统会把新切片摘要注册为 `dialog_history` 上下文块,并裁剪当前 chat messages。随后 `AfterRollingRegistry`
+会异步触发已注册的 `AfterRolling` consumer。这里的 consumer 只消费 `RollingResult`
+,用于在原始记忆生成后执行额外维护逻辑;具体索引构建与召回组织在 [记忆检索](memory-retrieval.md)
+中说明,扩展点机制见 [AfterRolling](after-rolling.md)。
diff --git a/doc/memory/memory.md b/doc/memory/memory.md
index e69de29b..37d186a3 100644
--- a/doc/memory/memory.md
+++ b/doc/memory/memory.md
@@ -0,0 +1,14 @@
+# 记忆存储与组织
+
+本文是 Partner 记忆系统文档索引。Partner 的记忆系统分为两个层面:
+
+- **存储层**:负责保存稳定的记忆数据。当前核心模型是 `MemoryUnit` 与 `MemorySlice`。
+- **组织层**:负责在存储数据之上建立可替换的召回结构。当前默认实现基于主题路径和日期索引;如果替换召回实现,需要由新实现自行维护对应索引。
+
+这种划分让记忆落盘格式保持稳定,同时允许上层召回策略独立演进。
+
+## 目录
+
+- [`memory-storage.md`](memory-storage.md):说明 `MemoryCore`、`MemoryUnit`、`MemorySlice` 的数据模型,以及原始记忆如何由 `CommunicationProducer` 和 `DialogRolling` 生成。
+- [`memory-retrieval.md`](memory-retrieval.md):说明默认组织层 `MemoryRuntime`,包括主题路径索引、日期索引、索引建立和运行时召回。
+- [`after-rolling.md`](after-rolling.md):说明 `DialogRolling` 后的扩展触发点,以及 memory 侧如何通过 `AfterRolling` consumer 补充索引信息。