Files
MemRelay/docs/ai-curation-plan.md

904 lines
96 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MemRelay 无人值守整理与记忆版本管理计划
> 状态:已完成。本文档是功能、接口、可靠性和验收标准的权威说明;计划内能力已通过 Windows AMD64、真实 Responses、真实 Git、备份恢复和物理 Armbian ARM64 验收,并已部署正式实例。AI 整理与记忆 Git 仍是默认关闭、彼此独立的可选增强。
> 2026-08-07 复审:MCP 能力资源与 `capabilities_get` 已统一为实时能力清单,语义搜索会反映 Basic Memory 健康状态;当前隔离实例发现 95 个工具和 3 个资源,MCP 仪表盘与 Web 仪表盘状态字段保持一致。
## 1. 目标
- 为 MemRelay 增加生成式 AI 整理能力,自动整理开发项目、办公资料、学习课程、研究资料、个人笔记和通用工作区,以及全局个人习惯和跨工作区经验。
- 最终运行方式为无人值守:无需依赖用户打开 Web,也不要求每次由用户手动触发。
- 优先使用正在操作本地资料的 Codex、Cursor、Claude Code 和其他 MCP 客户端对源码、文档、笔记、课程或办公文件的理解,通过 MCP 将结论、进度、文档和进度快照同步到 MemRelay。
- 当没有 Agent 同步、同步内容不足或超过配置的新鲜度阈值时,服务器自动读取文件仓储;配置了 Git remote 的工作区再使用受管理的 Git 工作区读取源码和版本化文档。
- 整理结果可被 Web、MCP、Basic Memory、工作区文档导出和 Obsidian 兼容读取共同使用。
- 使用本地 Git 为全部 Markdown 记忆、检查点和整理文档保留真实内容历史,并可选择同步到用户自行注册的专用 Git 账号,实现跨设备备份、差异审计和受控恢复。
## 2. 核心原则
### 2.1 原始记录和整理文档双层并存
- 原始记忆、进度快照、时间线和来源文档继续保留,作为完整事实来源。
- AI 生成独立的“整理文档”,不通过覆盖或删除原始记录来实现整理。
- 整理文档使用稳定 ID 和 revision,每次更新保留来源、模型、提示词版本、时间和变更摘要。
- 冲突内容标记为冲突、过期或已被替代,不自动抹除历史。
- `context_get` 优先返回整理后的当前信息,同时补入该整理文档成功游标之后尚未整理的相关原始变化和最新检查点,并标明整理状态/滞后范围;模型长期不可用时不能只返回陈旧整理文档。其余原始记忆按需要补充,减少上下文长度和重复内容。
### 2.2 MCP 优先,Git 工作区兜底
来源优先级固定为:
1. 本机 Agent 直接读取当前工作区的源码、配置、文档、笔记、课程、办公文件和本地变更。
2. Agent 通过现有 MCP 工具写入规则、事实、决定、经验和进度快照,文档或附件通过文件仓储上传。
3. 整理任务优先消费这些由 Agent 提炼过的内容,避免服务器重复读取全部原始资料。
4. Agent 来源不足时读取 MemRelay 文件仓储;工作区配置了 Git remote 时,再创建或更新受管理的源码工作区作为补充来源。
5. 没有 Git 的办公、学习、个人笔记和通用工作区仍可依靠记忆、进度快照和文件仓储完成全部整理能力,并在任务结果中标记来源覆盖范围。
### 2.3 模型不直接修改任意文件
- 模型读取经过 MemRelay 选择、分段和标注的文本,不获得任意服务器文件路径或 Shell。
- 模型返回结构化整理结果,包括目标文档、Markdown 正文、来源 ID、冲突、替代关系和标签。
- MemRelay 校验任务状态、工作区范围、revision 和输出格式后,通过现有记忆服务写入 Markdown 并触发 Basic Memory 索引。
- 源码 Git 工作区明确作为服务器端整理器的只读来源,不由整理器修改源码、创建提交或推送分支。整理正文统一写入 MemRelay,启用记忆 Git 时再进入独立版本历史;项目仓库中的正式文件仍由有本地源码上下文的 Agent 修改并通过正常 Git 工作流提交。这个职责边界是最终架构,不保留服务器端源码 Git 写回实现。
### 2.4 通用工作区与场景隔离
- 数据层继续保留现有 `Project`/`project_id` 兼容接口,产品语义扩展为“工作区”,避免破坏现有 MCP 客户端和数据。
- 每个工作区增加 `workspace_type`:`development`、`office`、`study`、`research`、`personal`、`general`,并允许自定义整理模板。
- 有 Git remote 的现有项目迁移为 `development`,没有 Git remote 的现有项目迁移为 `general`;管理员可在 Web/MCP 中修改类型。
- 现有项目创建、更新、列表和解析 REST/MCP 接口增加 `workspace_type` 与可空自定义模板字段;旧客户端不传时按 remote 和默认规则自动选择,不破坏兼容性。
- 工作区类型只决定默认文档模板、来源优先级和提示词,不限制用户混合使用文件、笔记、记忆、Git 或进度快照。
- 个人习惯分为全局、场景和工作区三级。开发编码习惯不会自动污染办公或学习场景,只有用户明确声明为全局或跨场景重复成立的偏好才提升到全局。
- 增加轻量 `usage_profile` 做习惯归属和来源标记,不把它扩展成多租户权限系统。实例默认只有 `shared` 团队档案,也可为不同成员建立档案。
- MCP Token 可绑定一个记忆空间;Web 会话可选择当前空间。未指定时使用 `shared`,团队规则继续共享,个人习惯只在对应空间内提升和整理。
- `context_get` 根据当前工作区类型组合对应场景偏好、工作区整理文档、原始记忆和最新进度快照。
### 2.5 记忆 Git 与源码 Git 分离
- Basic Memory Markdown 继续是记忆正文唯一权威来源;启用 Git 后,它只作为版本历史和远程镜像层,不建立第二套记忆写入接口。
- AI 整理启用且工作区配置源码 remote 时,只读源码 Git 工作区位于 `/data/memrelay/workspaces/`;记忆 Git 启用时,仓库位于 `/data/basic-memory/memories/` 对应范围内,由 MemRelay 写入和提交。
- 记忆写入、归档、删除、整理和恢复都先经过 MemRelay 的 revision、引用和索引逻辑,再生成 Git 提交;Agent、Web 用户和远程平台不能绕过 MemRelay 直接改变当前记忆状态。
- 远程仓库默认是 MemRelay 单向推送的镜像。外部提交不会自动 pull 或 merge 到在线记忆;需要使用受控导入/恢复流程,避免 Markdown、SQLite 引用和 Basic Memory 索引分裂。
- Git 只跟踪 Markdown 和必要的非秘密清单,不跟踪 SQLite、索引、模型缓存、文件仓储正文、密码、Token、TOTP、私钥或临时文件。
### 2.6 来源可信边界与秘密过滤
- 来自源码、文档、网页、压缩包、OCR、记忆和 Agent 来源包的正文一律作为不可信数据处理,其中出现的“忽略规则”“执行命令”“读取凭证”等内容不能改变系统提示词、工具权限或整理策略。
- MemRelay 使用结构化边界向模型传递来源,系统指令与来源正文分离;模型不获得 Shell、文件系统、密码库或任意 MCP 工具调用能力,模型输出也继续按不可信数据校验。
- Vaultwarden/Bitwarden 中的密码、Token、TOTP、私钥和隐藏字段绝不进入整理模型请求。来源收集前执行秘密候选检测与脱敏,整理结果写入 Markdown 前再次扫描;命中已知秘密或高置信凭证模式时阻止应用,低置信候选脱敏并给出警告,均返回可定位但不回显秘密值的结果。
- 允许整理文档保存密码库条目名称、用途和非秘密映射,但不得保存其秘密字段。日志、任务错误、模型调用摘要、Git 提交和未覆盖来源报告遵循相同边界。
### 2.7 AI 与 Git 均为可选增强
- AI 整理和 Git 版本管理彼此独立且都不是 MemRelay 基础能力的前置条件。用户可以两者都不配置、只启用其中一个或同时启用。
- 默认安装采用“AI 关闭 + Git 关闭”的零配置基础模式。初始化向导、项目创建/编辑、客户端配置和日常使用不得把模型连接、源码 Git remote 或记忆 Git remote 设为必填项;没有 Git 的工作区同样可以完整使用记忆、检查点、搜索、密码库、文件仓储和 MCP。
- 未配置或未启用 AI 时,不执行模型探测、不创建自动整理任务,也不因缺少模型显示系统故障;记忆、项目、检查点、全文/语义搜索、文件仓储、密码库、Web 和现有 MCP 工具保持当前行为,`context_get` 直接组合原始记忆与检查点。
- 首次启用 AI 时从现有记忆、检查点和文件建立基线并执行一次可观察的初始整理;停用后不再创建任务,重新启用时根据最后成功游标和当前 revision 补齐变化。
- 未配置或未启用 Git 版本管理时,不创建 `.git`、提交任务或远程同步状态,记忆仍按当前 Basic Memory + SQLite 流程读写。启用 Git 后才初始化本地历史,remote 继续可选;停用 Git 不删除已有本地仓库和历史。
- Web 初始化、健康检查、部署和验收必须覆盖“AI 关闭 + Git 关闭”的基础模式,不能用红色错误或阻塞提示迫使用户配置任一增强能力。
- Web 对未配置的 AI/Git 使用中性的“未启用”状态,不计入系统故障、依赖异常或待处理告警;REST/MCP 能力发现返回对应开关状态,并指导客户端继续使用基础工作流,不能要求用户先配置增强能力。
## 3. 内容载体与存放位置
| 内容 | 权威载体 | 存放位置 |
| --- | --- | --- |
| 原始全局/工作区记忆 | Basic Memory Markdown | `/data/basic-memory/memories/` |
| AI 整理文档 | Basic Memory Markdown | `global/curated/`、`projects/<id>/curated/` 逻辑目录 |
| 进度历史 | 进度快照 Markdown | 现有检查点和时间线 |
| 可选记忆本地版本历史 | Git | 启用后位于 Markdown 范围目录内的 `.git/`,由仓库策略决定 |
| 记忆远程镜像 | 标准 Git remote | 用户自行提供的准确 URL 或带 `{repo}` 占位符的 URL 模板 |
| 本机 Agent 上下文副本 | Markdown ZIP | 项目 `aidocs/`,继续加入 `.gitignore` |
| 版本化资料兜底副本 | Git 工作区 | `/data/memrelay/workspaces/<project-id>/` |
| 通用文件、PDF、图片和附件 | MemRelay 文件仓储 | `/data/memrelay/files/` |
| 整理任务、revision、来源关系和模型调用摘要 | SQLite | `/data/memrelay/db/memrelay.sqlite3` |
| 外部模型服务访问 Token | MemRelay 加密设置 | 使用现有部署主密钥加密,不写入 Markdown 或日志 |
| 源码和记忆 Git 凭证 | Vaultwarden/Bitwarden 或 MemRelay 本地加密设置 | 优先保存密码库条目引用;未配置密码库时使用部署主密钥加密,不写入 Markdown 或 Git 配置 |
| 临时分段和模型中间结果 | 临时目录 | `/data/memrelay/tmp/curation/<job-id>/`,任务结束后清理 |
完整整理文档类型按工作区模板组合:
```text
global/curated/profile.md
global/curated/preferences.md
global/curated/workflows.md
global/curated/cross-workspace-experience.md
global/curated/contexts/development.md
global/curated/contexts/office.md
global/curated/contexts/study.md
global/curated/contexts/research.md
global/curated/contexts/personal.md
global/curated/contexts/general.md
projects/<project-id>/curated/overview.md
projects/<project-id>/curated/current-state.md
projects/<project-id>/curated/decisions.md
projects/<project-id>/curated/timeline.md
projects/<project-id>/curated/tasks.md
projects/<project-id>/curated/glossary.md
projects/<project-id>/curated/development/architecture.md
projects/<project-id>/curated/development/troubleshooting.md
projects/<project-id>/curated/development/deployment.md
projects/<project-id>/curated/development/maintenance.md
projects/<project-id>/curated/office/meetings.md
projects/<project-id>/curated/office/action-items.md
projects/<project-id>/curated/office/procedures.md
projects/<project-id>/curated/office/reports.md
projects/<project-id>/curated/study/course-outline.md
projects/<project-id>/curated/study/knowledge-map.md
projects/<project-id>/curated/study/concepts.md
projects/<project-id>/curated/study/exercises-and-mistakes.md
projects/<project-id>/curated/study/review-plan.md
projects/<project-id>/curated/study/references.md
projects/<project-id>/curated/research/literature.md
projects/<project-id>/curated/research/evidence.md
projects/<project-id>/curated/research/hypotheses.md
projects/<project-id>/curated/research/experiments.md
projects/<project-id>/curated/research/citations.md
projects/<project-id>/curated/personal/topics.md
projects/<project-id>/curated/personal/insights.md
projects/<project-id>/curated/personal/goals.md
projects/<project-id>/curated/personal/habits.md
```
整理文档 frontmatter 至少记录:
- `stable_id`
- `scope`
- `project_id`
- `workspace_type`
- `usage_profile_id`
- `preference_context`
- `document_type`
- `revision`
- `source_memory_ids`
- `source_checkpoint_ids`
- `source_file_ids`
- `source_git_commit`
- `model_connection`
- `model_name`
- `prompt_version`
- `curation_job_id`
- `created_at`
- `updated_at`
## 4. 模型接入
### 4.1 通用外部模型服务
- MemRelay 不内置 CLIProxyAPI、Sub2API 或任何模型服务,也不限定服务商。用户自行填写一个 OpenAI-compatible Base URL、可空 Bearer Token、文本模型名称、可空视觉模型名称和协议模式。
- Base URL 可以指向 OpenAI-compatible 官方平台、CLIProxyAPI、Sub2API、团队网关或其他兼容服务;MemRelay 不要求用户声明平台类型,也不编写平台专用分支。
- 模型服务不加入 MemRelay 核心 Compose,由用户自行部署、购买、升级和备份。部署文档只提供通用字段说明和若干可选连接示例,不把任何示例设为必需组件。
- 连接成功后,MemRelay 尝试从规范化 Base URL 的 `/models` 接口发现模型,供 Web/MCP 刷新、搜索、选择和测试;接口不存在或未列出目标模型时仍允许手工填写模型名称。
- 实例保存一个当前启用的模型连接,包括连接名称、Base URL、加密 Token、文本/视觉模型名称、协议模式、探测出的有效协议、请求超时、探测间隔和可空外部管理页面地址。
- Token 由 Web 直接填写并使用现有部署主密钥加密;读取配置时不返回明文,也不写入 Markdown、任务正文或日志。
- 当前 MiniLM/FastEmbed 继续负责本地语义召回,不经过外部生成模型服务,不占用生成模型额度,也不承担归纳和文档生成。
### 4.2 调用与职责边界
- MemRelay 同时实现 OpenAI-compatible Responses API `/responses` 和 Chat Completions API `/chat/completions`,统一转换为内部生成请求和结果,不要求端点同时支持两种协议。
- 协议模式支持 `auto`、`responses` 和 `chat_completions`。显式“连接测试”分别使用最小请求探测 Responses 和 Chat Completions,不能仅依赖 `404/405` 判断协议,因为部分兼容端点会对不支持的协议返回通用 `400`。探测过程逐项记录请求是否真正到达、响应格式和稳定错误,不把普通业务参数错误直接判定为协议不支持。
- `auto` 根据已完成的能力探测优先选择 Responses,Responses 未通过而 Chat Completions 通过时选择后者;探测成功后保存 `effective_protocol`。正式整理任务只调用已确定的协议,不在生成失败后跨协议重放,避免重复生成和计费。手动模式只测试和调用指定协议;管理员可以重新探测或切换,不需要修改 Base URL 和 Token。
- Responses 和 Chat Completions 都支持非流式响应与 SSE 流式响应;端点只支持其中一种传输方式时保存有效模式,后台整理器统一组装完整结果后再校验。
- 两种协议都必须能产生可通过固定 Pydantic schema 校验的 JSON 结果。优先使用端点支持的原生 JSON Schema/structured output;不支持时使用严格 JSON 提示词并执行相同校验和一次结构化修复。
- MemRelay 只记录连接名称、请求模型、响应模型、服务请求 ID、标准响应中可用的输入/输出 Token、耗时和结果,不建立本地月度额度、费用估算或服务端账号用量账本。
- 账号轮询、模型映射、优先级、权重、配额冷却和上游故障切换只在外部服务本身提供时生效;MemRelay 把连接视为一个端点,不假设或管理其内部路由。
- 网关层对同一次外部生成请求最多执行 3 次有界重试,覆盖全部 HTTP 传输层异常(包括远端协议断开、代理断流、连接错误和超时)、408、429、5xx 和流式中断,并遵循 `Retry-After` 或指数退避;流式失败时可降级为非流式,结构化参数不兼容时可移除 schema 重试。整理任务级重试、依赖等待和队列合并仍由上层单独控制,不能形成无界重复调用。
- 模型返回格式无效时,MemRelay 可以基于原响应发起一次明确的结构化修复请求;这属于整理业务校验,不属于上游故障切换。
- 每次调用执行可配置的输入、输出和总上下文预算,每个任务另有最大模型调用轮数和总 Token 预算。来源超出单次预算时先按文档/代码符号等自然边界分批生成带来源引用的中间结果,再在独立预算内分层合并;任务在同一持久化记录内继续分批,全部应处理来源得到明确处置前不能标记成功或推进成功游标。达到任务总预算时以稳定错误进入 `failed` 并保留原游标,调整预算后可显式重试,不能静默截断。
- 外部服务的账号、真实模型映射、路由、额度和详细统计继续在对应服务中维护;MemRelay Web 不复制这些功能,也不调用非标准管理 API。
### 4.3 依赖健康、暂停与自动恢复
- 模型连接状态为 `unconfigured`、`checking`、`available`、`waiting_dependency`、`configuration_error`。
- `unconfigured` 是正常的中性状态:不启动探测、调度或整理 worker,不创建 `waiting_dependency` 任务,也不影响任何非 AI 接口。只有保存并启用完整连接后才进入检查流程。
- 保存配置时立即测试 Base URL、认证、可空 `/models`、Responses、Chat Completions、非流式/流式传输、文本模型最小结构化生成和可空视觉模型;逐项记录 `unknown`、`supported`、`unsupported` 或 `error`。文本生成、选定协议和结构化结果等必需能力失败时标红;未配置视觉模型、不提供 `/models`、标准用量字段缺失等可选能力使用中性或警告状态,不把连接整体误报为故障。
- `/models`、视觉或标准用量字段不受支持时不阻断已通过的文本整理能力;文本生成或结构化结果不可用时连接不能进入 `available`。
- 网络、TLS、远端协议断开、代理断流、超时、`429` 和服务最终返回的 `5xx` 表示模型连接暂不可用。当前执行尝试和模型调用记录必须结束并保存稳定错误码,任务释放运行租约后进入 `waiting_dependency`,自动整理工作进程停止领取新任务;后续自动变化继续合并到各范围唯一的等待任务,不逐条追加队列。记忆、搜索、密码库、文件仓储和 Agent 来源同步继续工作。
- 优先遵循 `Retry-After`;没有时从 5 分钟开始指数退避,最长 1 小时。每次到期先执行最小端到端生成探测,成功后按合并键恢复等待任务,不要求用户手动重试。
- `401/403`、Base URL 无效、文本模型不存在或响应协议不兼容标记为 `configuration_error`。任务继续保留,修正配置并通过测试后自动恢复,不进行高频无效探测。
- 服务重启后从 SQLite 恢复模型连接等待状态和所有等待任务;上个进程遗留的 `running` 模型调用统一结束为 `MODEL_CALL_INTERRUPTED`,未完成整理任务重新排队。依赖故障不会把整理任务标记为永久失败,也不会修改最后成功的整理文档。
### 4.4 当前项目开发测试连接
- Base URL:`https://cc2.cx/v1`
- 文本模型:`gpt-5.6`
- 协议:`responses`
- API Key 由用户在当前执行环境中提供,只通过临时环境变量和 MemRelay 加密运行时配置使用,不写入计划、源码、测试快照、错误响应或部署示例。
- 使用 `POST /responses` 和最小输入完成真实生成验收,再验证结构化输出、流式响应、错误映射、暂停/恢复和任务整理;模型发现接口即使不可用也不阻断手工模型名。
- 开发测试凭证只允许运行时注入或写入隔离的加密测试数据库;生产配置不得包含或复用任何开发测试连接和凭证,凭证到期/撤销由提供方管理。
## 5. 整理任务模型
SQLite 增加以下可迁移、可恢复的数据:
### 5.1 `curation_jobs`
- 任务 ID、范围、项目 ID、触发方式、整理模式、来源策略和目标文档。
- 状态:`queued`、`collecting`、`running`、`waiting_dependency`、`applying`、`completed`、`failed`、`cancelled`。
- 保存稳定的 `coalesce_key`、上次成功整理游标、最新观察游标、有限的目标文档提示、触发次数和聚合摘要。自动任务按“范围或工作区 + 整理模式”生成 `coalesce_key`,同一键最多存在一个等待任务;任务行不累加每次变化的来源 ID 或完整触发正文。
- 来源游标、开始/结束时间、重试次数、下次重试时间、错误码和可读错误;整理起点始终是上次成功游标,终点持续更新为最新观察游标,不能因覆盖等待任务而跳过中间变化。
- 输入来源数量、生成文档数量、跳过数量、模型用量、耗时、覆盖范围和未覆盖来源摘要。每个来源最终处置为 `processed`、`unchanged` 或带稳定原因的 `unsupported/skipped`;没有处置的来源仍属于待处理范围。
- 每次执行尝试领取时快照非秘密的模型连接 revision、有效协议、模型名、提示词版本、结构化 schema 版本和整理预算;Token 仍从加密连接配置按 revision 解析,不复制到任务。运行中的一次尝试固定使用该快照;进入 `waiting_dependency` 后原尝试已经结束,恢复时建立新尝试并使用当前已验证配置。
### 5.2 `curation_attempts`
- 每次实际执行保存任务 ID、尝试序号、模型配置 revision、有效协议、模型、提示词/schema 版本、预算、状态和错误。
- `curation_retry` 默认使用当前已验证配置;只有原配置仍存在且凭证可用时,管理员才可明确选择原配置。历史任务展示实际使用的快照,避免配置变化后无法复盘。
### 5.3 `curated_documents`
- 稳定文档 ID、范围、项目、文档类型、Markdown 路径和当前 revision。
- 最新任务 ID、来源摘要哈希、模型和提示词版本、更新时间。
- SQLite 只保存可重建引用,正文仍由 Basic Memory Markdown 保存。
### 5.4 `curation_sources`
- 任务与记忆、检查点、文件、Git commit 的来源关系。
- 保存来源 ID、来源 revision、内容哈希、`origin`、是否实际送入模型及最终处置。处置为 `processed`、`unchanged`、`unsupported` 或 `skipped`,后两者必须保存稳定原因;`origin` 至少区分 `user`、`agent`、`external`、`curation`、`index`、`git` 和 `system`。
- 用于增量整理、追溯来源、跳过未变化内容和判断是否需要重新整理。
### 5.5 `curation_change_log`
- 每个用户、Agent 和外部来源变化分配单调递增序号,保存范围、来源引用、变更类型、revision/内容哈希、目标提示、`origin` 和时间;删除使用 tombstone,确保游标范围查询不会漏掉已删除来源。
- 等待任务只保存起止序号,执行时查询 `(last_success_cursor, latest_observed_cursor]` 的变化并解析当前来源内容,不把事件清单复制进任务行。
- 所有受影响合并键的成功游标越过某段变化且任务历史不再需要逐事件追溯后,才按保留策略压缩旧变更日志;任务实际使用的来源关系继续保存在 `curation_sources`。
### 5.6 `curation_settings`
- 实例只有一份当前启用的外部模型连接;Base URL、加密 Token、文本/视觉模型名称、配置协议、有效协议、流式模式、请求超时、探测间隔和可空管理页面地址按 revision 保存。被任务尝试引用的历史 revision 和提示词/schema 版本按历史保留策略保存,未被引用的旧配置可清理。
- 实例时区只保留一份全局配置;新鲜度阈值、重试策略、场景模板、最大并发、单次输入/输出 Token 预算、每任务最大调用轮数/总 Token 预算、分批大小和合并层级可按全局、场景类型和工作区配置,工作区未覆盖时依次继承场景和全局值。
### 5.7 `curation_model_calls`
- 任务 ID、用途、连接名称、有效协议、流式模式、请求模型、响应模型、服务请求 ID、提示词版本、开始/结束时间和结果。
- 输入/输出 Token、延迟和稳定错误码;只用于任务追踪,不维护上游账号额度或费用账本。
### 5.8 `curation_dependency_state`
- 外部模型连接当前状态、能力矩阵、最后检查/成功/失败时间、HTTP 状态、稳定错误码、可读原因和下次探测时间。
- 状态在服务重启后恢复;不保存外部服务内部的账号、上游 Token、真实额度、路由或凭证冷却明细。
### 5.9 `curation_schedules`
- 规则 ID、名称、触发类型、作用范围、可空工作区 ID、启用状态、继承方式、时区模式、IANA 时区和 recurrence 配置。
- 触发类型为 `workspace_quiet`、`workspace_fallback` 或 `global_curation`。前两类支持实例默认和工作区覆盖;全局整理只使用实例级规则。
- `workspace_quiet` 保存静默时长和可空最大延迟;其余规则支持 `interval`、`daily`、`weekly` 和 `cron`。
- `interval` 保存正整数、`minutes/hours/days` 单位和锚点;`daily` 保存本地时间;`weekly` 保存一个或多个星期和本地时间;`cron` 保存标准五段表达式。
- 保存上次计划时间、上次实际触发时间、下次触发时间、错过执行策略、最近状态和可读错误。默认错过策略为恢复后合并执行一次,不回放每个错过周期。
### 5.10 `usage_profiles`
- 档案 ID、名称、说明、启用状态和时间;默认创建不可删除的 `shared` 团队档案。
- MCP Token 和来源包可关联档案,记忆与整理文档 frontmatter 保存档案引用。
- 档案只用于习惯归属、上下文选择和来源追溯,不改变现有单管理员、共享工作区和 Token 权限模型。
### 5.11 `git_connections`
- 连接名称、准确 remote URL 或带 `{repo}` 占位符的 URL 模板、用户名、传输方式、凭证存储方式及引用、默认分支、本地提交身份、允许写入测试、允许 push-to-create 和启用状态。
- 用户自行选择任意 Git 服务、注册专用于 MemRelay 的账号,并在 MemRelay 的 Git 连接页面填写 URL、用户名以及 Token、账号密码或 SSH 私钥;MemRelay 不识别或绑定具体平台,也不注册平台账号。
- Web 接收凭证明文但不回显;凭证存储支持外部 Vaultwarden/Bitwarden 条目或使用部署主密钥进行本地 AES-GCM 加密。已连接密码库时默认保存到密码库,否则允许使用本地加密存储,Git remote 不因密码库未配置而失效。
- 能力探测只使用标准 Git CLI,分别记录 URL 解析、`ls-remote`、clone/fetch、push、删除临时探测 ref 和服务端 push-to-create 的 `unknown/supported/unsupported/error` 状态。
- 标准 Git 协议没有远程仓库列表、创建、改名、归档和删除接口;只有服务端支持 push-to-create 时才能通过首次 push 创建仓库,其余能力明确标红且不伪装可用。
### 5.12 `memory_repositories`
- 仓库 ID、模式、范围、工作区 ID、本地根目录、解析后的远程 URL、默认分支和状态。
- 保存当前本地 commit、最后成功 push、远程可达性、落后提交数、工作树状态和可空归档时间。
- 全局仓库和工作区仓库使用稳定 ID 绑定;工作区改名不改变本地目录和远程仓库标识,避免 URL 漂移。
### 5.13 `git_sync_jobs`
- 操作 ID、仓库 ID、记忆/检查点/整理任务引用、动作、目标 commit、状态、尝试次数、下次重试和错误。
- 状态为 `pending`、`committing`、`pushing`、`completed`、`waiting_remote`、`failed`、`cancelled`。
- 同一逻辑写入只生成一个本地提交;服务重启、网络中断和重复事件通过操作 ID 幂等恢复。
## 6. 无人值守工作流
```mermaid
flowchart TD
Trigger["定时 / 进度快照 / 记忆或文件变化 / 手动触发"] --> Merge["按范围与模式合并自动变化"]
Merge --> Queue["持久化整理任务"]
Queue --> Fresh{"MCP 来源是否足够且新鲜"}
Fresh -->|是| McpSource["读取 Agent 已同步的记忆、进度和文档"]
Fresh -->|否| Repository["读取文件仓储与原始笔记"]
Repository --> HasGit{"工作区是否配置 Git"}
HasGit -->|是| GitSource["更新受管理的 Git 工作区"]
HasGit -->|否| Collect["合并记忆、进度、文档和文件来源"]
GitSource --> Collect
McpSource --> Collect
Collect --> Retrieve["语义召回、去重、分段和来源标注"]
Retrieve --> Gateway{"外部模型连接是否可用"}
Gateway -->|否| Wait["任务等待依赖并暂停自动领取"]
Wait --> Probe["按 Retry-After / 退避执行端到端探测"]
Probe -->|恢复| Gateway
Gateway -->|是| Model["调用已配置文本模型生成结构化结果"]
Model --> Validate["校验 schema、范围、来源和 revision"]
Validate --> Write["写入整理 Markdown 新 revision"]
Write --> Index["Basic Memory 重新索引"]
Index --> GitEnabled{"记忆 Git 是否启用"}
GitEnabled -->|否| Finish["记录历史、调用摘要和下次增量游标"]
GitEnabled -->|是| GitCommit["生成记忆 Git 提交"]
GitCommit --> Finish
GitCommit -.异步.-> GitPush["推送远程记忆仓库"]
```
执行步骤:
1. 触发器先把真实来源变化写入带单调序号的变更日志,再按范围和整理模式查找可合并任务。自动触发存在等待任务时只推进其最新游标并合并有限目标提示与触发摘要;不存在时才创建持久化任务。手动强制任务遵循调用方明确选择的拒绝或替换策略,不被静默合并。
2. 工作进程领取任务并记录租约,服务重启后可恢复未完成任务。
3. 根据最后 Agent 同步时间、来源数量、文件变化和目标文档判断来源覆盖是否完整。
4. 先读取记忆、进度快照和文件仓储;配置 Git remote 的工作区再使用目标分支和所选凭证存储中的 Git 凭证执行 clone/fetch/checkout。
5. 根据工作区类型读取源码、项目文档、办公资料、课程、笔记、研究材料和版本历史;二进制附件通过文件提取适配器处理。
6. 使用 MiniLM 和元数据分层检索与目标文档相关的来源,增量任务覆盖上次成功游标到最新观察游标之间的全部变化。超过配置的输入预算时在同一任务内按来源边界分批整理,再执行有预算上限的层级合并;每个来源记录明确处置,任务结果列出不支持或跳过的来源,不能静默截断。
7. 领取任务时固定本次尝试使用的模型连接 revision、有效协议、模型、提示词/schema 版本和输入/输出预算,再调用配置的文本模型;账号轮询、配额冷却和故障切换仅在所连接服务自身支持时由其完成。
8. 生成模型返回固定 JSON schema,MemRelay 按工作区模板渲染为 Markdown。
9. 写入前检查整理文档 revision;冲突时重新读取最新版本后执行一次受控重整,不直接覆盖。
10. 写入成功后更新 Basic Memory 索引;记忆 Git 已启用时再为本次逻辑变更生成一个本地提交,配置 remote 时异步 push。Git 未启用或 remote 未配置都不阻塞整理结果使用。
11. 更新上下文优先级、任务历史、模型调用摘要和成功来源游标;Git 提交记录任务 ID、来源范围、操作者和变更摘要。只有完整应用成功,且游标范围内每个变化都已有 `processed/unchanged/unsupported/skipped` 明确处置后才推进成功游标;未处置来源使任务保持未完成。
12. 任务临时文件清理;外部模型连接不可用时保留每个合并键唯一的等待任务并暂停自动整理,后续变化继续合并。端到端探测恢复后,每个合并键只执行一次即可覆盖故障期间全部变化。
## 7. 自动触发
- 自动触发器只有在 AI 整理已配置并启用时才创建或合并任务;未配置 AI 时不排队。AI 从关闭切换为启用时先比较现有 revision 与最后成功游标,没有基线则创建一个初始全量任务,已有基线则把停用期间变化合并为一个增量任务。
- AI 整理启用后,用户、Agent 或外部来源产生的 `memory_save`、`checkpoint_save`、`curation_source_submit`、文件上传和文件元数据变化只记录“需要整理”,不为每次写入立即调用模型。AI 整理写回、Basic Memory 索引、Git 提交/推送、扫描缓存和其他内部事件标记对应 `origin`,不得再次设置“需要整理”,避免形成递归整理循环。
- 工作区静默增量整理具有独立开关。启用后在最后一次变化达到配置的静默时长时合并变化并运行一次增量整理;静默时长可自定义,可空最大延迟用于避免持续变化导致任务永远不触发。
- 保存重要进度快照后按工作区模板优先刷新当前状态、决定、任务,以及开发故障、办公行动项、学习知识点等场景文档。
- 工作区兜底整理和全局习惯/跨工作区经验整理分别具有独立开关和 recurrence 规则,可选择每隔若干分钟、小时或天,每日指定时间,每周选择一个或多个星期并指定时间,或使用高级五段 Cron。
- 每条规则的时区默认继承实例时区,也可单独选择 IANA 时区;实例时区本身可在 Web/MCP 中修改。所有状态、预览和任务历史同时显示时区与带偏移的实际时间。
- 实例规则可作为工作区默认值;工作区可以选择继承、完全覆盖或关闭自己的静默增量和兜底整理,不影响其他工作区。
- 保存规则前校验时区、间隔、星期、时间和 Cron,并返回未来至少 5 次执行时间预览;配置生效后原子重算 `next_run_at`,无需重启服务。
- 服务重启或停机错过周期时默认只合并补跑一次,不为每个错过时间创建任务;管理员也可选择跳过错过执行。夏令时不存在的本地时间顺延到下一个有效时刻,重复的本地时间只触发一次。
- 同一工作区的静默和周期触发按来源游标合并;模型长期不可用时,每个“范围或工作区 + 整理模式”最多保留一个等待的自动任务,新变化只更新该任务的最新游标、有限目标文档提示、计数和聚合摘要,不复制来源正文或逐事件 ID。若任务正在运行,最多保留一个合并后的自动后继任务。
- 手动非强制触发可复用相同范围的等待任务并返回其任务 ID;手动强制任务不被静默丢弃或合并。同一范围已有待执行的强制任务时默认返回冲突,调用方只有显式指定替换后才取消旧任务并创建新任务,防止手动操作绕过队列上限。
- 全量整理只在首次启用、模型/提示词重大升级、索引重建或用户明确触发时运行。
- 同一工作区默认只允许一个整理任务运行;不同工作区可按配置并发。
- 关闭任一自动规则只停止对应触发器;关闭全部调度时仍保留手动 Web、REST 和 MCP 触发能力。
## 8. MCP 工具
- 现有 `capabilities_get` 同步返回工作区类型、记忆空间、整理文档类型、来源适配器、外部模型连接健康和全部整理工具能力;不返回 Token。
- `capabilities_get` 分别返回 `curation_enabled` 和 `memory_git_enabled`。能力关闭时工具仍可被客户端发现,但运行类工具返回稳定的 `FEATURE_DISABLED` 和配置入口信息,不创建后台任务;读取既有整理文档或既有 Git 历史的工具在数据存在时仍可用。
### 8.1 `curation_run`
创建整理任务并立即返回,不等待模型执行完成。
建议参数:
- `scope`: `global` 或 `project`
- `project_id`: 工作区范围必填,沿用兼容字段名
- `mode`: `incremental` 或 `full`
- `source_strategy`: `auto`、`mcp`、`repository`、`git` 或 `all`
- `document_types`: 可空,空值表示按范围使用默认文档集合
- `reason`: 可空,记录本次触发原因
- `force`: 是否忽略未变化判断
- `pending_policy`: 手动任务遇到同范围待执行任务时使用 `reuse`、`reject` 或 `replace`;非强制默认 `reuse`,强制默认 `reject`,`replace` 必须由调用方明确指定
`replace` 只替换待执行任务身份和调用参数,新任务必须继承旧任务尚未成功覆盖的最早游标并合并当前最新游标,不能因替换而丢失已积累变化。
返回任务 ID、初始状态、来源策略和预计目标文档,不返回整理正文。
### 8.2 `curation_status`
查询整理服务和任务状态。
- 传入 `job_id` 时返回单个任务的阶段、进度、来源统计、重试、错误和时间。
- 不传 `job_id` 时返回工作进程状态、队列长度、当前任务、模型可用性,以及各启用规则的时区和下一次计划执行时间。
- 队列统计同时返回实际等待任务数、被合并的触发次数、各合并任务覆盖的起止游标和运行任务的后继任务状态,不能把触发计数误报为队列长度。
- 状态查询不泄露模型凭证或 Git 凭证。
### 8.3 `curation_history`
分页查询整理历史。
建议筛选:
- `scope`
- `project_id`
- `status`
- `trigger`
- `started_after`
- `limit`
- `cursor`
每条历史返回任务、来源范围、生成/更新文档、实际使用的模型配置/提示词/schema revision、合并触发摘要、覆盖与未覆盖来源、用量、耗时、错误和变更摘要。
### 8.4 `curated_document_get`
读取当前整理文档或指定历史 revision。
支持两种定位方式:
- `document_id`
- `scope + project_id + document_type`
建议参数:
- `revision`: 可空,默认返回最新版本
- `include_sources`: 是否返回来源引用,默认只返回正文和核心元数据
返回 Markdown 正文、revision、更新时间、来源摘要、模型和最新任务 ID。
### 8.5 `curation_source_submit`
让具有本地工作区上下文的 Agent 一次提交完整来源包,减少多次 MCP 往返并为无人值守整理提供明确来源边界。
参数包括:
- `request_id`:整个来源包的幂等键。
- `project_id`:目标工作区,沿用兼容字段名。
- `usage_profile_id`:可空;默认从调用该工具的 MCP Token 获取,未绑定时使用 `shared`。
- `workspace_type`:开发、办公、学习、研究、个人或通用场景。
- `git_remote`、`branch`、`commit`、`dirty`:可空,仅在 Agent 实际读取 Git 工作区时提交。
- `changed_resources`:文件 ID 或路径、变更类型、内容哈希、资源类型和可空摘要。
- `memories`:规则、事实、决定和经验数组,每项包含标题、正文和标签。
- `documents`:已通过文件仓储上传的文件 ID、工作区相对路径、用途和摘要。
- `checkpoint`:可空的进度快照,包含完成内容、原因、关键变化、验证/证据、问题、解决方案和下一步;字段适用于开发、办公、学习和个人任务。
- `observed_at`:Agent 完成本次观察的时间。
服务端先校验整个来源包,再为各项派生稳定请求 ID,复用现有记忆、检查点和文件服务写入。中途失败时任务保持可恢复状态,重试从未完成项继续且不重复已成功项;只有全部写入完成后才返回来源包成功状态。
返回来源包 ID、各类写入结果、可空来源 commit、完成状态和是否触发增量整理。
### 8.6 配套工具
同时提供完成工作流必需的工具:
- `curated_document_list`:列出全局或工作区整理文档及更新时间。
- `curation_cancel`:取消仍在排队或尚未写入的任务。
- `curation_retry`:使用原任务来源和目标重新执行失败或已取消任务并建立新的尝试记录;默认使用当前已验证模型配置,可在原配置仍可用时明确选择原配置。
- `curation_settings_get`:读取模型、调度、来源、场景和工作区覆盖配置。
- `curation_settings_update`:更新实例时区、无人值守来源、场景和并发配置。
- `curation_schedule_list`:按触发类型和工作区列出规则、继承关系、最终时区、上次/下次执行时间和状态。
- `curation_schedule_save`:创建或更新静默、间隔、每日、每周或 Cron 规则,立即重算下一次执行时间。
- `curation_schedule_delete`:删除自定义规则或工作区覆盖并恢复继承;内置默认规则只允许关闭或修改,不物理删除。
- `curation_schedule_preview`:不保存配置,校验候选规则并返回指定时区下未来至少 5 次执行时间。
- `curation_model_connection_status`:返回外部模型连接配置状态、Responses/Chat Completions 和流式能力矩阵、配置/有效协议、当前可用性、文本/视觉模型、最后成功/失败、等待任务数和下次探测时间,不返回 Token。
- `curation_model_list`:通过规范化 Base URL 的可空 `/models` 刷新并返回模型名称、显示名称和服务提供的能力元数据;接口不可用时返回 `unsupported` 并继续允许手工模型名。
- `curation_model_connection_test`:立即执行连接、认证、模型发现、Responses、Chat Completions、流式/非流式、最小结构化文本生成和可空视觉测试;成功时保存有效协议并恢复等待队列,失败时返回逐项状态、稳定错误码和可读原因。
- `usage_profile_list`:列出记忆空间及关联 Token、记忆和整理状态。
- `usage_profile_save`:创建或更新档案,并可把 MCP Token 绑定到该档案。
- `usage_profile_token_bind`:把一个或多个已有 MCP Token 重新绑定到指定档案,可选择替换该档案的现有绑定。
- `usage_profile_delete`:删除没有正式来源引用的非 `shared` 档案,或把来源迁移到指定档案后删除。
- `curated_document_revert`:把指定历史 revision 作为新的最新 revision 写回,保留完整回滚记录并重新索引。
### 8.7 记忆 Git 工具
- `memory_repository_status` 在功能从未启用时返回中性 `disabled`;创建、同步和恢复类工具要求管理员先明确启用记忆 Git,不因缺少 remote 或凭证自动启用。
- `git_connection_get/save/test/delete`:配置准确 remote URL 或 URL 模板及用户自行准备的凭证,使用 Git CLI 测试读写能力;秘密值优先写入 Vaultwarden,未配置密码库时由部署主密钥本地加密,读取时不返回明文。
- `memory_repository_list/status/create/sync`:列出本地记忆仓库、查看本地/远程状态、按 URL 模板初始化映射并立即提交或推送待同步内容;远程不存在且不支持 push-to-create 时返回明确待处理状态。
- `memory_repository_history`:按全局/工作区、时间、操作者、操作类型和记忆 ID 查询提交历史。
- `memory_repository_diff`:查看两个 commit 或指定 commit 与当前版本之间的 Markdown 差异。
- `memory_version_get`:读取某条记忆、检查点或整理文档在指定 commit 的内容和元数据。
- `memory_version_restore`:通过正常记忆服务恢复单个文档历史版本,增加 revision、重新索引并生成新的恢复提交,不重写既有 Git 历史。
- `memory_snapshot_restore`:在正确范围的写锁下恢复一个记忆仓库的历史快照;`single` 仓库使用全局记忆写锁,`per_workspace` 使用目标范围写锁。校验 Markdown 后重建 SQLite 可重建引用和 Basic Memory 索引,再生成新的恢复提交。
- `memory_remote_inspect`:clone/fetch 到隔离暂存区,只读检查远程分支、commit、Markdown 树、稳定 ID、模式兼容性和与本地历史的关系,不改变在线记忆。
- `memory_remote_import`:从已检查的远程 commit 选择单文档、工作区或仓库范围,通过正常记忆服务导入为新的 revision 和本地提交;用于处理 `remote_diverged`,不执行自动 pull/merge 或历史重写。
- `memory_remote_bootstrap`:在空实例或明确的恢复模式中从 remote 建立本地记忆仓库,校验全部 Markdown,重建 SQLite 可重建引用和 Basic Memory 索引,再绑定远程状态。该工具不恢复部署主密钥、会话、Token、文件正文或密码库数据。
- `memory_repository_archive_purge`:永久清除已删除工作区对应的独立本地 Git 历史;必须与普通项目删除分离并由管理员明确执行。
- `memory_repository_unbind`:解除 remote 绑定但保留本地仓库和历史;标准 Git CLI 不提供远程仓库归档或删除能力。
Agent 同步本地资料和结论继续复用现有工具:
- `project_resolve_or_create`
- `context_get`
- `memory_save`
- `checkpoint_save`
- `file_upload_prepare`
- `file_metadata_update`
- `curation_source_submit`
`curation_source_submit` 是对一次工作区上下文同步的编排入口,不替代单条 `memory_save`、`checkpoint_save` 和文件上传;Agent 可按任务规模选择批量同步或单项写入。
## 9. REST 接口
REST 统一放在 `/api/v1/curation`:
- `POST /jobs`
- `POST /sources`
- `GET /status`
- `GET /jobs/{job_id}`
- `POST /jobs/{job_id}/cancel`
- `POST /jobs/{job_id}/retry`
- `GET /history`
- `GET /documents`
- `GET /documents/{document_id}`
- `PATCH /documents/{document_id}`
- `GET /documents/{document_id}/history`
- `GET /documents/{document_id}/diff`
- `POST /documents/{document_id}/revert`
- `GET /settings`
- `PATCH /settings`
- `GET /schedules`
- `POST /schedules`
- `PATCH /schedules/{schedule_id}`
- `DELETE /schedules/{schedule_id}`
- `POST /schedules/reset-defaults`
- `POST /schedules/preview`
- `GET /model-connection/status`
- `GET /model-connection/models`
- `POST /model-connection/test`
- `GET /profiles`
- `POST /profiles`
- `PATCH /profiles/{profile_id}`
- `PUT /profiles/{profile_id}/tokens`
- `DELETE /profiles/{profile_id}`
MCP 与 Web 复用同一服务层,不建立并行整理逻辑。
记忆 Git REST 接口统一放在 `/api/v1/git`:
- `GET/POST/PATCH/DELETE /connections`
- `POST /connections/test`
- `GET /mode-migration`
- `POST /mode-migration`
- `GET /repositories`
- `POST /repositories`
- `GET /repositories/{repository_id}/status`
- `POST /repositories/{repository_id}/sync`
- `POST /repositories/{repository_id}/remote/inspect`
- `POST /repositories/{repository_id}/remote/import`
- `POST /repositories/bootstrap`
- `GET /repositories/{repository_id}/history`,支持时间、提交者、操作类型、工作区和资源 ID 筛选
- `GET /repositories/{repository_id}/diff`
- `POST /repositories/{repository_id}/restore`
- `DELETE /repositories/{repository_id}/archive`
- `DELETE /repositories/{repository_id}/remote`
- `GET /versions/{resource_id}`
- `POST /versions/{resource_id}/restore`
## 10. Web 页面
### 10.1 AI 整理总览
- 外部模型连接状态、能力矩阵、队列长度、等待依赖任务、运行中任务、最近成功/失败和下一次计划运行。
- 未配置 AI 时显示中性的“未启用”空状态和配置入口,不显示等待依赖、失败告警或待处理任务;其他页面和导航保持可用。
- 支持编辑连接名称、Base URL、可空 Token、协议模式、请求超时、探测间隔、输入/输出 Token 预算、分批/合并预算和可空管理界面地址;自动刷新可搜索模型列表并选择文本/视觉模型,也可手工输入,然后分别执行真实能力测试。
- 协议使用 `auto/responses/chat_completions` 分段选择;能力矩阵分别显示 Responses、Chat Completions、流式、非流式、结构化输出、视觉和用量字段,`auto` 旁显示当前探测出的有效协议。必需能力失败标红,暂时不可用显示警告,可选能力未配置或不支持使用中性状态。
- 页面不出现平台类型选择,也不内置 CLIProxyAPI、Sub2API 或官方平台配置;只按 OpenAI-compatible 接口探测 Base URL 和实际能力。
- 页面显示最近模型调用摘要和可空外部管理页面链接;外部服务内部的账号、上游 Token、路由、额度和详细用量仍由该服务维护。
- 全局立即整理、全量整理和暂停/恢复自动整理。
- 队列区域按合并键显示上次成功游标、最新观察游标、合并触发次数和后继任务;模型不可用期间队列数量保持有界,同时可观察积累的变化范围。
### 10.2 工作区整理
- 工作区类型、整理模板、启用状态、来源策略、Agent 最后同步时间和来源覆盖情况。
- 整理文档列表、最后更新时间、revision、来源数量和立即整理按钮。
- 文件仓储来源、新鲜度阈值和场景偏好配置;配置 Git remote 时再显示分支、凭证条目和最后抓取 commit。
### 10.3 记忆空间
- 管理 `shared` 团队档案和可选成员档案,显示各档案的场景偏好、来源数量和最后活动时间。
- MCP Token 可绑定档案;Web 会话可切换当前档案。档案切换只影响习惯归属和上下文,不改变工作区访问权限。
### 10.4 整理历史
- 按工作区、范围、状态和时间筛选。
- 查看任务阶段、来源、模型用量、错误、生成文档和前后 revision 差异。
- 对失败任务重新运行,对排队任务取消。
### 10.5 整理文档
- 使用现有 Markdown 编辑/预览组件。
- 查看当前正文、历史 revision、来源引用、变更摘要和相关原始记忆。
- 人工编辑仍通过现有 revision 冲突检查,后续 AI 整理以最新人工版本为基线。
### 10.6 记忆版本管理
- 页面首先提供独立的记忆 Git 启用开关。关闭且从未启用时显示中性的功能说明和启用操作,不初始化仓库、不要求凭证或 remote;关闭已有配置时明确说明历史会保留但停止产生新提交。
- 不区分 Gitea、GitHub、GitLab、Gitee 或其他服务,也不内置 Git 平台;用户填写准确 remote URL 或带 `{repo}` 的 URL 模板、用户名、Token/密码或 SSH 私钥、默认分支、本地提交身份和仓库策略。凭证可选择外部密码库或 MemRelay 本地加密存储。
- 提供“允许写入测试”和“允许自动创建远程仓库”开关。保存后立即使用 Git CLI 测试;新建工作区时自动初始化本地仓库、生成初始提交,并在允许时通过首次 push 尝试由服务端创建远程仓库。
- 使用 Git CLI 展示 URL、读取、写入、临时 ref 清理和 push-to-create 能力矩阵;`unsupported` 或 `error` 项标红并显示原始 Git 错误的可读摘要。
- 显示本地仓库列表、当前 commit、远程同步状态、待推送数量、最后成功时间和可读错误。
- 支持初始化/绑定本地仓库、立即同步、查看提交历史和 Markdown 差异、恢复单个文档或整个仓库快照、检查/导入远程历史、从远程冷启动重建,以及解除 remote 绑定。
- 仓库策略切换先执行只读预检并展示迁移计划;确认后在全局写锁下完成,失败则保持原策略。禁止在已有仓库内部生成嵌套 `.git`,完整 URL 不能选择多仓库模式,URL 模板不能选择单仓库模式。
- 工作区创建后按策略解析目标 URL 并尝试首次 push;服务端不支持 push-to-create 时标记 `remote_repository_missing`,展示应由用户自行创建的完整仓库 URL,创建后可一键重试。
- remote 不可达不影响本地 Git 提交;页面持续显示 `waiting_remote`,网络或服务恢复后自动补推。
### 10.7 自动整理调度
- 顶部提供可搜索的 IANA 实例时区选择器,默认使用部署实例时区;每条规则可以继承实例时区或单独覆盖,并显示当前 UTC 偏移。
- 静默增量、工作区兜底和全局整理分开显示,每项都有启用开关。工作区页面可选择继承实例默认、覆盖配置或对当前工作区关闭。
- 静默规则使用时长输入并支持可空最大延迟;周期规则使用模式选择器切换“每隔一段时间”“每日”“每周”和“高级 Cron”。
- 间隔模式可选分钟、小时或天并填写正整数和锚点;每周模式允许多选星期;Cron 提供五段输入、格式校验和字段说明。
- 编辑过程中实时显示未来至少 5 次执行时间、最终时区和带偏移时间;保存后显示上次计划、上次实际运行、下一次运行、错过执行策略和最近错误。
- 默认调度可一键恢复,但恢复前显示将被改动的三类规则;关闭自动调度不隐藏或禁用“立即整理”。
## 11. Agent 提示词更新
生成的中英文 Agent 提示词增加以下工作流:
- 会话开始先解析工作区并读取 `workspace_type`,按开发、办公、学习、研究、个人或通用场景使用对应的记忆和整理策略。
- 会话同时读取 MCP Token 绑定的 `usage_profile`;个人偏好写入该档案,团队约定明确写入 `shared`。
- Agent 有本地资料访问能力时,优先由 Agent 理解源码、文档、笔记、课程和办公文件,不要求服务端重复下载。
- 工作过程中持续通过 `memory_save` 保存规则、事实、决定和经验,通过 `checkpoint_save` 保存结构化进度快照。
- 需要保留完整文档或附件时使用文件仓储,不把大文件正文塞进普通记忆。
- 会话结束前确保当前进度、关键原因、验证或证据、未解决问题和下一步已经同步;没有 Git 的场景不得省略同步。
- Agent 不需要等待整理任务;无人值守整理器会在静默期或计划时间自动消费已同步内容。
- 需要立即得到整理结果时调用 `curation_run`,随后使用 `curation_status` 查询,完成后通过 `curated_document_get` 读取。
- 新会话首先读取场景匹配的整理文档、当前上下文和最新进度快照,再按需要读取原始记忆,降低 Token 消耗。
- Agent 只能通过 MemRelay MCP 查询差异和执行受控恢复,不直接操作服务端记忆仓库或向其 remote 推送。
## 12. Git 兜底工作区
- 工作区以项目 ID 隔离,路径固定为 `/data/memrelay/workspaces/<project-id>/`。
- 使用项目 Git remote 和 Vaultwarden 中映射的 Git 凭证,无需再次询问账号密码。
- 分支优先使用项目配置,其次读取远端默认分支,最后依次尝试 `main` 和 `master`;每次任务记录 remote、分支和实际 commit。
- HTTPS 和 SSH remote 均可读取;凭证按规范化主机、仓库 URI 和项目映射从 Vaultwarden 唯一解析。
- fetch 失败时保留上次成功工作区并标记为缓存来源;网络恢复后自动刷新。
- 读取 `.gitignore`、源码、Markdown、配置、提交历史和工作区状态;跳过 `.git` 对象、依赖目录、构建输出和二进制构建产物。
- 工作区只作为整理来源,不执行依赖安装、构建脚本、项目代码或任意项目 Shell,也不创建提交或推送远端。
- 工作区不放入 MemRelay 文件仓储,也不混入项目文档导出。
## 13. 记忆 Git 版本管理
### 13.1 本地仓库布局
- 记忆 Git 版本管理默认关闭。管理员明确启用后才初始化本地仓库和提交队列;启用后即使没有配置 remote 也持续提交,保证误修改、归档和删除可以回看与恢复。
- 首次启用时先在记忆写锁下为当前 Markdown 建立基线提交,不追溯伪造启用前的逐次历史。关闭后停止创建新提交和同步任务,但保留已有 `.git`、映射和可查询历史;重新启用时把关闭期间的当前差异生成一个恢复提交。
- 仓库策略支持 `single` 和 `per_workspace`。`single` 以 `/data/basic-memory/memories/` 为仓库根目录;`per_workspace` 分别以 `global/` 和 `projects/<id>/` 为仓库根目录。
- 使用完整 remote URL 时只允许 `single`;使用且必须包含 `{repo}` 占位符的 URL 模板时只允许 `per_workspace`。保存时拒绝不匹配的组合,避免多个工作区意外推入同一仓库或模板无法展开。
- 仓库策略切换属于受控迁移:先检查现有 `.git`、目标目录、remote 和未提交状态,生成可预览计划;确认后获取全局记忆写锁,提交当前状态、迁移历史并重建映射。任何目标路径已位于其他 Git 工作树内时拒绝执行,禁止嵌套仓库。
- 多仓库模式中全局仓库名默认为 `memrelay-global`,工作区仓库名默认为 `memrelay-<slug>-<short-id>`;稳定 ID 防止同名冲突,工作区改名不自动改变既有 remote URL。
- 归档 Markdown 保持在原范围仓库内,例如 `global/archive/` 和 `projects/<id>/archive/`,避免归档操作跨 Git 仓库丢失历史。
- Basic Memory 扫描和索引必须排除所有 `.git/` 内容;Git `.gitignore` 排除索引、缓存、SQLite、锁、临时文件和秘密值。
- 初始化仓库时生成 `.gitattributes`,至少固定 `*.md text eol=lf`,并统一清单类文本的行尾,避免 Windows/Linux 间产生无意义差异。
### 13.2 通用 remote 与能力探测
- MemRelay 只调用系统 Git CLI,不使用 Gitea、GitHub、GitLab、Gitee 或其他平台专用 API,也不随 Compose 内置任何 Git 服务。
- HTTPS 支持用户名加 Token/密码,SSH 支持私钥和可空口令;秘密值从 Vaultwarden 或 MemRelay 本地加密设置临时注入 `GIT_ASKPASS` 或 SSH 命令环境,不嵌入 remote URL、`.git/config`、进程参数和日志。
- 保存连接时先规范化 URL 并执行无副作用的 `git ls-remote` 与 fetch 测试;对已存在且用户允许写测试的 remote,推送唯一临时 ref 后立即删除,以判断 push 和 ref 删除能力。
- push-to-create 不能在不产生远程仓库的前提下通用探测,因此初始状态为 `unknown`;首次向真实目标仓库 push 后更新为 `supported` 或 `unsupported`,不创建额外测试仓库。
- URL 模板只替换 `{repo}`,不拼接平台特有 API 路径。远程仓库不存在且 push-to-create 不可用时,返回 `remote_repository_missing` 并显示完整目标 URL,等待用户自行创建后重试。
- 能力矩阵逐项显示 `unknown`、`supported`、`unsupported` 或 `error`;不支持项标红,但不会阻断本地 Git 历史、记忆读取和其他可用能力。
### 13.3 新工作区自动建仓
- 配置 per-workspace URL 模板后,新建工作区自动计算稳定仓库名和完整 remote URL,初始化本地仓库,并把初始 Markdown 与非秘密清单生成第一个提交。
- “允许自动创建远程仓库”默认启用。MemRelay 在目标 remote 不存在时执行首次 push;服务端支持 push-to-create 且当前凭证具有权限时,该 push 同时完成远程建仓和初始同步。
- 首次 push 成功后记录 `push_to_create=supported`、远程默认分支和最后同步 commit,后续使用普通 push。
- 首次 push 失败时不撤销本地仓库和提交:确认远程不存在且不支持 push-to-create 时进入 `remote_repository_missing`;URL 或凭证错误时进入 `configuration_error`;网络或远端暂时不可用时进入 `waiting_remote`。对应能力标红并展示可读原因和完整目标 URL。
- 用户在任意 Git 服务上自行创建空仓库或修正权限后,可以执行重新测试/立即同步;MemRelay 不要求更换平台,也不调用平台 API。
### 13.4 提交与远程同步
- 每个成功的单条记忆/检查点写入生成一个逻辑提交;`curation_source_submit`、批量导入和一次 AI 整理中的多文档变更各自合并成一个提交,不按文件制造碎片提交。
- 提交作者使用配置的 MemRelay Git 身份,提交信息保存操作类型和可读摘要,并使用 trailers 记录操作 ID、工作区 ID、记忆 ID、整理任务 ID 和调用方类型,不记录秘密值。
- SQLite 在保存记忆引用时同步写入 `git_sync_jobs`;提交工作进程按仓库加锁并立即尝试提交,失败后通过脏工作树扫描和操作 ID 幂等补交,服务重启不会丢失版本事件。
- 本地提交完成后异步 push;remote 不可达、认证失败或网络中断进入 `waiting_remote`,不回滚已生效记忆,恢复后按提交顺序自动补推。
- 禁止自动 force push。远程分支出现非 MemRelay 提交或历史分叉时状态变为 `remote_diverged`,停止自动 push 并要求管理员选择重新绑定空仓库、受控导入远程版本或继续使用本地历史。
- 远程仓库仅作镜像和恢复来源,不自动 pull/merge 到在线 Markdown。解绑 remote 不删除本地仓库,也不尝试删除服务器上的仓库。
### 13.5 历史与恢复
- Web、REST 和 MCP 可以按时间、操作者、操作类型、工作区和资源 ID 查询提交,并查看 Markdown 级差异。
- 单文档恢复从指定 commit 读取正文和 frontmatter,通过正常记忆服务写成新 revision,重新索引并生成新的恢复提交;不执行 `git reset` 或重写历史。
- 仓库快照恢复先获取与仓库范围匹配的写锁:`single` 模式获取全局记忆写锁,`per_workspace` 获取目标工作区或全局范围写锁。恢复期间暂停对应范围的 Basic Memory 写入和索引,校验目标树中所有 Markdown 和稳定 ID,再恢复文件、重建 SQLite 可重建引用、重建 Basic Memory 索引并生成新提交。
- 删除项目之前先通过正常记忆服务删除其 Markdown 并生成 Git 删除提交。`per_workspace` 仓库随后移入 `/data/memrelay/git-archive/<repository-id>/` 保留独立历史;`single` 仓库继续由删除提交保留历史。普通项目删除不物理清除 Git 历史,永久清除归档仓库必须使用单独的管理员操作。
- remote 冷启动或灾难恢复先 clone 到隔离暂存区,校验仓库模式、路径、Markdown frontmatter、稳定 ID 和重复项,再在恢复锁下导入,重建 SQLite 可重建引用和 Basic Memory 索引。远程镜像不能恢复未纳入 Git 的数据,完成后仍需显示缺失范围。
- `remote_diverged` 的“受控导入”使用同一暂存和校验流程,把选定远程版本通过正常记忆服务写为新的 revision 和提交;不得把远程分支直接覆盖在线工作树。
- 永久删除产生 Git 删除提交;只要本地仓库或 remote 历史存在,就可通过受控恢复重新建立引用和索引。
- Git 历史不能替代完整 `/data` 备份:它不包含 MemRelay 会话、Token、凭证映射、文件仓储正文、Basic Memory 索引或部署主密钥。
## 14. 文件内容提取与分段
- 源码和文本不依赖固定扩展名列表,结合 MIME、内容探测、编码识别和二进制检测读取;保留文件路径、语言、行号范围和 Git commit 来源。
- 原生支持 Markdown、纯文本、常见编程语言、JSON、YAML、TOML、XML、HTML、INI、Properties、CSV 和日志。
- PDF 先提取文本层,扫描版页面自动进入 OCR;结果保留页码。
- DOCX 提取标题、段落、列表和表格;XLSX/XLS/ODS 提取工作表、单元格区域和公式显示值;PPTX/ODP 提取页面标题、正文、备注和表格。
- PNG、JPEG、WebP、TIFF 等图片执行 OCR;配置了视觉模型时可同时生成图片内容说明,并保留原文件引用。
- ZIP、TAR 和常见压缩包按安全路径和展开上限读取目录及其中受支持文件,不执行归档内程序。
- 提取器采用统一接口并缓存结果,缓存键由文件 SHA-256、提取器版本和配置组成;文件未变化时不重复提取。
- 长文档按标题、段落、代码符号、页码、工作表或幻灯片边界分段,不在固定字符位置粗暴截断。
- 单个文本/源码文件默认直接读取上限为 2 MiB,Office/PDF/图片默认原文件上限为 50 MiB,每个任务默认最多处理 1,000 个文件和 2,000 万提取字符;超过范围时按工作区核心文档、最近变更、入口文件、语义相关度排序,并在结果中报告未覆盖部分。所有上限可配置。
- OCR、Office、PDF 和压缩包依赖同时进入 AMD64/ARM64 镜像、许可清单、健康检查和验收,不允许只在开发机存在。
## 15. 个人习惯与场景记忆整理规则
- 用户明确表达为“任何场景都适用”的长期规则和偏好进入当前记忆空间的全局整理文档;明确属于团队的规则进入 `shared`。
- 用户在某一场景表达的习惯先进入 `development`、`office`、`study`、`research`、`personal` 或 `general` 场景偏好,不默认提升为全局。
- 从行为归纳的偏好记录来源工作区、场景、出现次数、最近时间、反例和置信度;默认至少在 3 次独立任务中重复才形成场景偏好。
- 场景偏好只有在同一记忆空间的至少 2 种场景中重复成立且没有反例时才自动提升为该空间的全局偏好,不要求逐条确认。
- 工作区专用做法保留在工作区范围,办公格式、学习复习方式、编码规范和个人笔记习惯互不污染。
- 不同记忆空间的个人习惯不互相提升;团队共享规则和跨成员协作约定单独整理到 `shared`。
- 新的明确规则与旧规则冲突时,在相同范围内以最新明确表达为当前结论,旧内容标记为已被替代并保留来源;不同场景的差异可以同时有效。
- 办公场景重点整理会议、行动项、流程、报告和沟通偏好;学习场景重点整理课程结构、知识点、错题、复习计划和引用;个人笔记重点整理主题、洞见、目标和习惯;开发场景保留架构、决定、故障、部署和维护。
- 密码、Token、TOTP 和私钥不进入整理正文;整理文档只保留 Vaultwarden 条目名称和用途。
## 16. 数据库容量与并发决策
- MemRelay 继续使用 SQLite,不切换 MySQL,也不同时维护 PostgreSQL 适配;这是本次完整交付的确定架构。
- 记忆正文由 Basic Memory Markdown 保存,文件正文位于文件仓储,源码 Git 内容位于只读工作区,记忆 Git 历史位于 Markdown 仓库,提取缓存位于独立目录;SQLite 只保存用户会话、项目/工作区、引用、任务、来源、Git 连接/仓库/同步任务、外部模型连接状态、模型调用摘要和设置,数据量与写入频率可控。
- Basic Memory 仍有自己的本地数据库和索引边界,只把 MemRelay 元数据切换到 MySQL/PostgreSQL 并不能消除整个系统中的本地数据库,因此不为形式上的“生产数据库”增加额外服务。
- SQLite 启用 WAL、foreign keys、合理的 `busy_timeout` 和自动 checkpoint;所有 Web/MCP 写事务保持短小。
- 模型请求、外部模型连接探测、OCR、文件提取、Git 操作和 Basic Memory 网络调用期间不得持有 SQLite 事务;任务先提交状态,再执行外部操作,完成后用短事务写入结果。
- 整理任务通过原子领取、租约和幂等键串行化同一工作区写入;模型调用摘要按请求追加,不为模型流式输出逐 Token 写数据库。
- 调度器使用 SQLite 租约选出唯一活动调度者,并对“规则 ID + 计划时间”建立唯一触发键;即使运行多个 Uvicorn worker 或服务重启,同一计划时间也只能创建或合并一次任务。
- 读取接口继续允许并发,写入遇到短暂锁竞争执行有上限的 SQLite busy retry;写操作本身不做不受控业务重试。
- 定期清理过期会话、依赖探测明细、临时任务和可重建缓存;任务历史、文档 revision 和模型调用摘要按管理员配置保留或归档。
- 仪表盘和健康接口暴露数据库大小、WAL 大小、checkpoint 时间、锁等待/重试次数、事务延迟和完整性检查结果,便于在真实使用中直接判断容量与并发是否健康。
- 备份前执行 WAL checkpoint,并把 SQLite 主文件、WAL/SHM、部署主密钥和 Markdown/文件数据作为一致性整体处理。
- MySQL 不提供该场景需要的额外价值;PostgreSQL 适用于多应用节点、高持续写 QPS 和数据库级多租户隔离,而当前单实例、共享团队和低频整理任务不具备这些必要条件。
- 验收必须覆盖 20 个并发 Web/MCP 客户端、记忆/文件/进度写入与后台整理混合运行,连续任务期间不得出现未处理的 `database is locked`、重复领取、丢任务或损坏;同时验证异常退出、WAL 恢复和完整备份恢复。
## 17. 可靠性与恢复
- 整理任务写入 SQLite 后才进入队列,服务重启不会丢失任务。
- 工作进程使用任务租约和心跳;超时任务可重新领取。单实例服务启动时会立即将上次进程中断的 `collecting`、`running` 或 `applying` 任务重新排队,不等待旧租约自然过期;来源游标、合并键和历史尝试记录保持不变。
- worker 池必须动态遵循整理开关和实例最大并发。并发降低或停用整理时,不取消正在安全执行的任务,超出目标的 worker 在当前任务结束后退休;再次启用或提高并发时按槽位补充 worker,不能长期残留旧并发规模。
- 一个整理任务需要生成多个稳定文档时,最终文档生成按每批最多 4 个目标拆分;每批模型输出上限按目标数收紧到 4,096 至 8,192 Token,避免单个超大结构化请求长期占用 worker 或反复触发上游超时,来源、revision 和应用顺序保持不变。
- 同一个变化游标范围、目标文档、模型配置 revision 和提示词/schema 版本计算尝试幂等键,避免重复执行和重复 revision;等待任务推进最新游标后生成新的尝试键。
- 自动任务使用稳定 `coalesce_key` 做有界背压:每个范围和整理模式最多一个等待任务;新变化只推进最新观察游标并合并有限目标提示、计数和摘要,起点保持上次成功游标。运行中任务最多拥有一个合并后继,模型恢复后一次执行即可覆盖故障期间全部变化。
- 手动强制任务不静默丢弃;同范围已有待执行强制任务时默认拒绝,只有调用方明确选择替换才取消旧任务。已完成、失败和取消历史不参与合并并按保留策略归档。
- 写回使用现有 optimistic revision;冲突不静默覆盖。
- 模型输出必须通过 Pydantic schema 校验,格式错误可在同一任务中进行一次修复请求。
- 整理结果验证通过后自动应用,不设置依赖人工批准的阻塞流程;Web 和 MCP 提供差异查看与 `curated_document_revert` 完整回滚。
- 外部模型服务最终返回暂时不可用错误时,任务进入 `waiting_dependency`,自动整理停止领取新任务;连接恢复后按合并键继续,不丢失来源、游标或目标文档,也不按故障期间每次触发回放任务洪峰。
- Basic Memory 超时或暂时不可用时,只把当前任务按策略中的初始/最大重试间隔做有界指数退避并重新排队;不永久失败任务,不暂停全部模型队列,也不修改外部模型依赖状态。
- 流式请求的网络类临时故障继续使用流式重试,只有端点明确拒绝流式参数或协议时才降级为非流式;配置超时直接作为单次流式读取超时。每个模型调用每 60 秒产生一次受控等待事件,完成后保存底层请求尝试次数和端到端总耗时,服务取消时立即收尾调用记录。
- 任务失败不影响原始记忆和当前整理文档,Web/MCP 明确显示最后成功时间和失败原因。
- 所有变化事件携带 `origin`;只有用户、Agent 和外部来源可触发自动整理。整理写回、索引、Git 同步和扫描缓存等内部事件不得再次触发,防止无人值守递归循环。
- Basic Memory 只挂载其所需的 `/data/basic-memory` 子目录且服务端口不直接暴露给非 MemRelay 客户端。普通写入由 MemRelay 获取范围写租约后调用 Basic Memory;Basic Memory 确认 Markdown 写入完成后,Git worker 才获取仓库锁提交。恢复和仓库策略迁移期间暂停对应范围的 Basic Memory 写入与索引,完成引用/索引重建后再解除。
- 范围写租约和仓库锁不能持有 SQLite 事务;租约状态先短事务落库,再执行 Basic Memory 或 Git 操作。租约超时可恢复,但操作 ID 和 revision 校验必须阻止重复写入。
- 来源正文始终视为不可信数据,不能覆盖系统指令或获得工具权限;模型请求前和 Markdown 应用前都执行秘密检测。疑似密码、Token、TOTP 或私钥时阻止写入,且错误与日志不得回显秘密值。
- 记忆 Git 提交和 push 任务持久化后再执行;服务重启时扫描未完成任务和脏工作树,按操作 ID 补交或补推,不能重复生成逻辑提交。
- remote 断网、认证失败或服务不可用不阻塞记忆写入;本地历史保持可用,恢复后按提交顺序补推。远程分叉不自动 force push、pull 或 merge。
- 备份脚本继续备份整个 `/data`,必须包含记忆 Markdown、已存在的本地记忆 Git `.git/` 历史、任务、连接元数据、凭证引用和来源引用;仅 `/data/memrelay/workspaces/` 下可重新 fetch 的只读源码工作区允许从备份排除。
- 恢复后校验 SQLite、Markdown、本地 Git 对象和索引的一致性;remote 未配置或暂时不可达时仍能完成本地恢复,联网后再补推。
## 18. 实施阶段
以下阶段只表示依赖顺序,不表示分版本交付。所有阶段、工具、文件提取器、Web 页面、调度和验收全部完成后,AI 整理功能才可标记为完成并部署正式实例。
### 阶段一:契约和数据
- 锁定通用工作区类型、场景模板、整理文档、frontmatter、结构化模型输出和 MCP/REST schema。
- 增加 `workspace_type` 兼容迁移、整理数据表、单调变化日志/tombstone、任务状态机、成功/观察游标和分层配置模型。
- 增加通用外部模型连接的加密配置、能力矩阵、依赖状态、模型调用摘要、配置 revision/尝试快照、上下文预算和 `waiting_dependency` 任务状态。
- 增加 `curation_schedules`、实例/规则时区、工作区继承覆盖、recurrence 联合类型、错过执行策略和 `next_run_at` 迁移。
- 增加 `git_connections`、`memory_repositories`、`git_sync_jobs` 迁移、状态机、幂等键及 Git 凭证的 Vaultwarden 引用/本地加密存储。
### 阶段二:整理引擎
- 实现任务领取、合并背压、运行中单一后继、恢复、重试、取消、状态和历史。
- 实现记忆、进度快照、文件仓储、Git 和语义检索来源收集。
- 实现 OpenAI-compatible 模型发现、手工模型名、Responses/Chat Completions 独立能力探测与适配器、SSE/非流式解析、有效协议缓存、结构化输出回退、依赖暂停/恢复、配置快照、分层预算整理、场景模板渲染、自动应用、revision 回滚和重新索引。
- 实现带唯一调度租约的可热更新调度器、静默防抖、间隔/每日/每周/Cron 计算、IANA 时区、工作区继承、停机补跑、触发合并、内部事件过滤和服务重启恢复。
- 落实 SQLite WAL、短事务、任务租约、busy retry、用量批量更新和异常恢复约束。
- 把记忆、检查点、归档、删除、整理和恢复统一接入本地 Git 提交队列,保证一个逻辑操作对应一个可追溯提交。
### 阶段三:MCP 优先工作流
- 完成四个核心整理 MCP 工具、`curation_source_submit`、文档列表/回滚、任务取消/重试、记忆 Git 连接/仓库/历史/差异/恢复和配置工具。
- 更新通用 Agent 提示词,让本机 Agent 按工作区类型持续同步本地资料、结论、进度和文档。
- 验证开发、办公、学习、研究、个人笔记和通用工作区的新建、持续工作、新会话恢复和无人值守增量整理。
### 阶段四:Git、记忆版本与文件来源
- 实现只读源码工作区管理、凭证解析、clone/fetch、分支/commit 记录和缓存读取。
- 实现通用 Git CLI 连接、完整 URL/URL 模板严格模式、双凭证存储、凭证临时注入、能力探测、本地记忆仓库、新工作区首次提交、push-to-create、异步 push、断网补推、分叉停止、删除归档、远程检查/导入/冷启动和受控恢复。
- 实现文本/源码、PDF、Office、图片 OCR、压缩包提取、智能分段、缓存、限制和来源哈希。
- 验证没有 Agent、没有 Git 以及同时具有文件仓储和 Git 的不同来源组合都能完成整理。
### 阶段五:Web 和调度
- 完成整理总览、工作区类型/模板、历史、文档、通用外部模型连接设置/健康、记忆版本管理和调度设置页面。
- 调度页面完整支持实例时区、规则时区覆盖、三类独立开关、静默时长、可空最大延迟、分钟/小时/天间隔、每日、每周多选、五段 Cron、错过执行策略和未来执行预览。
- 模型能力矩阵必须分别显示 Responses、Chat Completions、SSE/非流式和结构化输出;必需能力的 `unsupported/error` 标红,暂时错误显示警告,可选能力缺失显示中性状态,并提供可读原因。`/models` 不可用时允许手工输入模型,不把未选择协议或可选视觉能力缺失误判为文本整理整体故障。
- Git 能力矩阵必须把 `unsupported` 和 `error` 标红,并显示受影响能力、可读原因、目标 URL 和重试操作;未配置 remote 时明确显示“仅本地版本历史”,不显示为故障。
- 接入静默期、进度快照、每日工作区和每周全局触发。
- 加入仪表盘任务状态和依赖健康。
- 验证 AI/Git 未配置时使用中性状态,基础页面、MCP 和健康检查不降级;增强能力只有在用户明确启用后才出现相应任务和状态。
### 阶段六:验收与部署
- 完成单元、集成、MCP、Web、通用 OpenAI-compatible 连接与不可用恢复、调度/时区/停机恢复、非 Git 场景、SQLite 并发、Git CLI 能力探测、断网/分叉、服务重启和备份恢复测试。
- 在 Windows Docker Desktop AMD64 和现有 Armbian ARM64 实机验证。
- 更新 README、Mermaid、Agent 提示词、MCP 工具表、部署变量和第三方许可。
- 清理临时任务与测试数据,更新项目记忆,提交独立中文 Git commit 后部署正式实例。
## 19. 验收标准
- 全新实例不配置 AI 且不启用 Git 时,不执行模型探测、不创建整理/Git 任务和 `.git` 目录;现有记忆、项目、检查点、搜索、文件仓储、密码库、Web、MCP、导出和备份行为保持可用,健康状态为正常而非降级。
- 分别验证“仅 AI”“仅本地 Git”“Git + remote”“AI + Git”和“两者关闭”五种组合,任一未启用增强能力都不能阻塞另一能力或基础服务。
- 有本机 Agent 时,整理任务优先使用 MCP 已同步内容,不重复扫描 Git。
- 没有 Agent 时先使用记忆和文件仓储;配置 Git 的工作区可自动补充 Git 来源,没有 Git 的办公、学习和个人工作区仍能完整整理。
- `curation_source_submit` 能一次同步可空 Git 状态、变更资源、结构化记忆、文档引用和进度快照,部分失败后可幂等续传且不会产生重复记录。
- 服务重启后排队和运行中的任务可恢复,不丢失来源游标。
- 模拟模型长期不可用并连续产生至少 10,000 次自动变化后,每个“范围或工作区 + 整理模式”仍最多只有一个等待任务,任务行大小不随事件正文线性增长;任务的起点保持上次成功游标、终点等于最新观察游标,通过变更日志查询覆盖中间全部创建、更新和删除事件。模型恢复后只运行一次且结果覆盖完整范围。
- 变更日志只有在所有受影响成功游标越过后才允许压缩;压缩前后的增量结果一致,删除 tombstone 不会因来源正文已不存在而漏掉整理更新。
- 任务运行期间继续产生变化时最多创建一个合并后继;前一任务成功后,后继从新的成功游标处理剩余变化,不重复或漏掉边界事件。
- 手动强制任务遇到同范围待执行强制任务时默认返回冲突;明确 `replace` 后旧任务变为已取消且保留历史,新任务完整继承要求的来源范围。手动重复操作不能让队列无界增长。
- 整理写回、Basic Memory 索引、Git 提交/推送和缓存扫描不会再次创建整理任务;用户、Agent 和外部来源的真实后续变化仍能正常触发。
- 实例时区默认取部署时区,可通过 Web/MCP 改为任意受支持的 IANA 时区;规则继承和单独覆盖后的下一次执行时间、UTC 偏移与实际触发一致。
- 静默增量可以独立启用/关闭并修改时长;启用最大延迟时持续写入最终会触发一次合并任务,关闭后变化只记录待整理状态而不自动创建增量任务。
- 工作区兜底和全局整理分别验证每 N 分钟/小时/天、每日指定时间、每周多选星期和五段 Cron;无效数字、时间、时区和 Cron 必须拒绝保存并返回字段级错误。
- `curation_schedule_preview`、Web 预览和调度器对未来至少 5 次执行时间的计算一致;修改规则后无需重启即可使用新的 `next_run_at`。
- 工作区继承、覆盖和关闭只影响目标工作区;删除覆盖后恢复实例默认,不改变其他工作区或全局整理规则。
- 服务停机跨过多个周期后,`run_once` 只合并补跑一次,`skip` 不补跑;两种策略都不回放任务洪峰。夏令时跳时和重复时刻按计划规则各验证一次。
- 静默、周期和手动触发同时命中同一来源范围时只执行一次有效整理;无来源变化时不调用模型、不创建空 revision。
- 增量整理只处理变化内容;无变化时不调用生成模型、不创建空 revision。
- 来源超过单次模型上下文时能在同一任务中按配置预算分批和层级合并;任务历史准确记录每个来源处置、输入/输出用量和实际预算。未处置来源时成功游标不推进;达到任务总预算时返回稳定错误并可在调整预算后续跑,任何超限内容都不得被静默截断。
- 模型配置在任务排队期间发生变化时,尚未领取任务使用新配置;运行中的尝试保持领取时快照。暂时故障使当前尝试结束并进入等待,恢复后的新尝试使用当前已验证配置。显式重试默认使用当前配置,明确选择仍存在的原配置时才复用原 revision,任务历史可完整复盘。
- 整理文档正文为标准 Markdown,可通过 Web、MCP、Basic Memory 和工作区 ZIP 读取。
- `curation_run`、`curation_status`、`curation_history`、`curated_document_get` 及全部配套工具完成真实 Streamable HTTP MCP 验收。
- 文本/源码、PDF、扫描 PDF、DOCX、表格、PPTX、图片 OCR 和压缩包来源在 AMD64/ARM64 都能提取、分段、追溯和缓存。
- 整理结果自动应用,历史 revision、差异和回滚完整可用。
- 明确启用记忆 Git 但不配置 remote 时,本地历史仍能提交、查询、查看差异,并通过 MemRelay 恢复单文档和仓库快照;未启用 Git 时不产生这些操作且基础记忆行为不受影响。
- 使用任意标准 Git remote URL 和用户输入的 HTTPS Token/账号密码或 SSH 私钥后,`git ls-remote`、fetch、临时 ref push/delete 分别给出真实能力状态;不可用项在 Web 标红,其他能力继续工作。
- 开启写入测试时,临时 ref 使用唯一名称并在成功与失败路径尽力清理,不污染默认分支和正式历史。
- 新建工作区在本地自动建仓并生成初始提交;测试服务支持 push-to-create 且凭证有权限时,自动完成远程建仓和首次 push;不支持时准确返回 `remote_repository_missing` 并可在用户手工建仓后重试成功。
- remote 断网或不可达时,多次记忆变更继续形成有序本地提交并进入 `waiting_remote`;网络恢复和服务重启后自动补推且不重复、不丢提交。
- 人为制造 remote 分叉后必须进入 `remote_diverged` 并停止自动 push,不得 force push、静默 pull 或覆盖任一侧历史。
- 单文档恢复会生成新 revision、新索引和新 Git 提交;仓库快照恢复会校验 Markdown、重建可重建引用与索引并生成新提交,两者都不重写既有历史。
- 完整 remote URL 只能保存为 `single`,包含 `{repo}` 的模板只能保存为 `per_workspace`;两种模式的受控迁移不会生成嵌套仓库,失败时原仓库、映射和在线记忆保持可用。
- 未连接 Vaultwarden/Bitwarden 时,HTTPS 和 SSH Git 凭证可通过部署主密钥本地加密后完成 `ls-remote`、fetch 和 push;连接密码库后可切换为密码库条目且日志、进程参数和 Git 配置均不泄露秘密。
- 删除 `per_workspace` 项目会先生成删除提交并把仓库移入独立归档区,普通项目删除后历史仍可查看和恢复;只有单独的管理员永久清除操作才删除归档 Git 历史。
- 在空的恢复实例中可从 remote 冷启动,校验 Markdown 后重建 SQLite 可重建引用和 Basic Memory 索引;结果明确报告 Git 无法恢复的部署主密钥、Token、文件正文和其他范围。
- `memory_remote_inspect/import` 能处理 `remote_diverged`:远程内容先在隔离暂存区检查,再作为新 revision 导入并形成新提交,不直接覆盖工作树或改写本地/远程历史。
- Windows 与 Linux 对同一 Markdown 仓库往返同步时,`.gitattributes` 保持 LF 且不产生仅行尾变化的提交。
- 相同的 Base URL、Token、模型和协议字段可以连接 OpenAI-compatible 官方平台、CLIProxyAPI、Sub2API 或其他兼容服务,服务端代码不根据平台名称分支;至少使用不同类别的真实端点或协议测试替身完成契约验收。
- Responses-only、Chat-Completions-only 和两者都支持的端点分别通过真实调用或协议测试替身验收;三种协议模式都必须选择正确端点且生成相同内部结构化结果。
- 显式连接测试能分别探测 Responses 与 Chat Completions,包括把通用 `400 Invalid request` 与协议不支持、业务参数错误区分记录;`auto` 从已通过的能力中优先选择 Responses。保存后的正式任务只使用 `effective_protocol`,超时、`429`、`5xx` 和连接中断不得触发跨协议重复生成。
- Responses 和 Chat Completions 的流式 SSE、非流式响应、服务请求 ID、响应模型、Token 用量和错误映射分别验证;流中断不得应用半截文档。
- 原生 JSON Schema 可用时优先使用;不支持时通过严格 JSON 提示词仍能得到同一 Pydantic schema,格式错误只允许一次明确修复请求。
- `/models` 自动发现、模型搜索/选择、手工模型名和文本/视觉能力测试在 Web、REST 与 MCP 中结果一致;模型列表仅用于发现,真实可用性以端到端结构化生成测试为准。
- 不提供 `/models` 但支持有效文本生成的端点可通过手工模型名进入 `available`;模型发现显示 `unsupported`,不得阻断整理任务。
- 外部服务停止、网络中断、上游额度耗尽或最终返回 `429/5xx` 时,任务进入 `waiting_dependency`,新自动变化继续合并到有界等待任务;连接恢复后无需人工操作即可完成故障期间全部变化。
- Base URL、Token 或文本模型名错误时 Web/MCP 明确显示 `configuration_error`;修正并测试成功后自动恢复等待任务,且错误页面不泄露 Token。
- 使用具备内部多账号、模型路由和故障切换能力的外部服务时,MemRelay 能透明使用最终结果但不依赖这些扩展;直连不具备路由能力的官方端点时,基础整理、暂停和恢复仍完整可用。
- 开发、办公、学习、研究、个人和通用工作区分别生成匹配场景的完整整理文档,不要求具备 Git 或开发术语。
- 全局习惯能够从明确规则和跨场景重复行为中自动整理;场景和工作区习惯互不污染,并保留来源和替代关系。
- `shared` 与成员记忆空间能通过 Web/MCP Token 正确归属来源;个人习惯不跨空间污染,团队规则仍可共享。
- 20 个并发 Web/MCP 客户端与后台整理混合运行时 SQLite 不得出现未处理锁错误、重复任务、丢失写入或损坏,异常退出和备份恢复必须通过。
- 使用至少两个 Uvicorn worker 同时运行调度器时,同一规则和计划时间只创建或合并一次任务;租约持有者异常退出后其他 worker 能接管且不重复触发。
- Basic Memory 写入完成后才允许对应 Git 提交;恢复期间对相同范围的写入会等待或返回稳定忙碌错误,不会与索引重建交叉。Compose 中 Basic Memory 仅能访问自己的数据子目录,不能读写 MemRelay 数据库、文件仓储或部署主密钥。
- 在来源文件中放入提示注入文本、测试密码、Token、TOTP 和私钥后,模型不能获得额外工具或改变系统规则,秘密值不会出现在模型请求、Markdown、Git、日志和任务错误中;被拦截内容有不含秘密值的可定位报告。
- 模型、Git 或网络故障不会破坏现有记忆和最后成功的整理文档。
- 正式部署可连续无人值守运行,Web 能看到最后成功、当前任务、失败原因和下一次计划时间。
- 不发布缺少任一计划能力的中间整理版本;全部验收通过后统一交付。
## 20. 已锁定默认值
- 本计划中的全部能力属于同一次完整交付,实施阶段不是产品版本拆分。
- AI 整理默认未配置且不启用;MemRelay 不内置或限定模型服务。用户明确配置后,实例保存一个当前启用的 OpenAI-compatible 连接,由用户自行填写 Base URL、可空加密 Token、文本模型名、可空视觉模型名和协议模式。
- CLIProxyAPI、Sub2API、官方平台和其他兼容服务地位相同;MemRelay 不调用平台专用管理 API,也不管理端点内部的账号、优先级、权重、额度或路由。
- Responses API 和 Chat Completions API 同时实现;协议默认 `auto` 并优先探测 Responses,也可手动固定。模型列表自动发现是可选能力,允许手工填写未公开的模型名;文本结构化生成是整理功能进入 `available` 的必要能力,视觉模型保持可选。
- 已启用的外部模型连接默认每 5 分钟探测;未配置或关闭时不探测。暂时不可用时任务进入 `waiting_dependency` 并暂停自动领取,遵循 `Retry-After` 或 5 分钟至 1 小时退避,端到端探测成功后自动继续。
- 实例时区默认继承部署时区并可修改;每条调度规则可继承实例时区或选择独立 IANA 时区。
- AI 整理启用后,静默增量规则默认启用并设为 15 分钟;工作区可继承、覆盖或关闭。最大延迟默认为空,由管理员按持续写入场景配置。
- AI 整理启用后,工作区兜底规则默认启用并设为实例时区每日 `02:30`;全局习惯和跨工作区经验整理规则默认启用并设为实例时区每周日 `03:30`。
- 周期规则同时支持每 N 分钟/小时/天、每日、每周多选和高级五段 Cron;错过执行默认合并补跑一次,可改为跳过。
- Agent 来源默认新鲜度为 24 小时;来源不完整、超过 24 小时或用户强制全量时读取文件仓储,配置 Git 的工作区同时启用 Git 兜底。
- 工作区类型固定支持 `development`、`office`、`study`、`research`、`personal`、`general` 和自定义模板;现有有 Git 项目迁移为开发类型,其余迁移为通用类型。
- 默认创建 `shared` 记忆空间;未绑定 MCP Token 和未选择空间的 Web 会话都归属 `shared`,成员空间不改变现有权限模型。
- 源码 Git 分支按项目配置、远端默认分支、`main`、`master` 的顺序解析;`/data/memrelay/workspaces/` 下的源码工作区永久保持来源只读,不创建提交或推送。
- 记忆 Git 默认关闭;用户明确启用后建立本地历史,remote 仍可选并按用户提供的完整 URL 或 `{repo}` 模板连接,不内置 Git 服务、不限定平台、不调用平台专用 API。
- 记忆 Git 和 remote 都已启用时,默认允许新工作区通过首次 push 尝试 push-to-create;成功时自动完成远程建仓与同步,不支持时标红并等待用户自行创建空仓库。
- HTTPS Token/账号密码和 SSH 私钥都从 Git 设置页面接收;已连接 Vaultwarden/Bitwarden 时默认保存为密码库条目,否则使用部署主密钥本地加密。Git CLI 运行时临时注入,配置和日志只保留非秘密引用。
- 记忆 remote 只接受 MemRelay 单向普通 push,禁止自动 force push 和自动 pull/merge;断网时保留本地提交并自动补推。
- `curation_source_submit` 与四个核心整理工具及全部配套工具同时交付。
- 文本、源码、PDF、扫描件、DOCX、电子表格、PPTX、图片 OCR 和压缩包提取全部纳入交付及双架构验收。
- 整理结果验证后自动应用;所有修改都生成 revision,并支持 Web/MCP 差异查看和回滚。
- MemRelay 只记录任务级连接名称、请求/响应模型、服务请求 ID、标准响应提供的 Token 用量、耗时和结果;额度、费用、账号健康及详细用量由外部模型服务负责。
- MemRelay 数据库继续使用 SQLite WAL,不引入 MySQL/PostgreSQL;所有外部 AI、Git、OCR、文件和 Basic Memory 操作不得占用数据库事务。
- 同一工作区最大整理并发默认为 1,全局任务最大并发默认为 1,失败默认重试 3 次并指数退避;均可配置。
- AI 整理启用后,自动队列默认使用按范围和模式合并的有界背压,运行中任务最多一个自动后继;手动强制任务默认拒绝同范围重复排队,只有显式替换才能取代旧任务。
- 模型输入/输出预算、每任务最大调用轮数/总 Token 预算、分批大小和合并层级可配置;默认值由所选模型配置提供的上下文能力与 MemRelay 保守上限共同决定,未知上下文能力时使用保守上限。预算耗尽不推进成功游标,调整后可继续同一来源范围。
## 21. 实施与验收结果
- 完成工作区类型、来源策略、MCP 优先/Git 兜底、来源墓碑、稳定 `source_key`、结构化输出 schema v2、冲突/替代关系、场景偏好和 revision 元数据。
- 完成 Responses 与 Chat Completions、流式/非流式、原生 JSON Schema、能力探测、错误分类、依赖等待、自动恢复、有界合并队列、并发租约、调度继承和可配置来源限制。
- 完成默认关闭的记忆 Git、本地历史、可选 remote、模式迁移、断网补推、分叉检测、push-to-create、历史/差异/恢复、远程导入与冷启动。
- 完成 REST、95 个 MCP 工具、3 个 MCP Resources、中文/英文桌面 Web、动态 Agent 提示词、备份恢复和部署文档。
- 真实 Responses 已覆盖非流式、SSE、JSON Schema、全局整理、项目连续增量、历史、差异、回滚和暂时断网恢复;永久模型输出错误进入 `failed`,只有可恢复依赖错误进入 `waiting_dependency`。
- 生产长任务已覆盖流式远端断线后的请求内恢复和 Basic Memory 并发超时;正式全局与两个项目范围的最新重试均完成。自动测试覆盖动态并发缩减、任务级本地依赖退避、长调用进度、端到端耗时、请求尝试次数和取消收尾;ARM64 正式发布后运行时 worker 为 `1 / 1`,队列和运行中调用为 0。受控停止 Basic Memory 后,重试任务按预期以本地依赖错误重新排队且不改变模型依赖状态,取消测试任务并恢复依赖后 LAN/公网服务均正常。
- Windows Docker Desktop AMD64、物理 Armbian ARM64、Alembic `0001 -> 0009`、SQLite 并发、正式数据迁移、公网 HTTPS/MCP 和重启自动恢复全部通过。
- 零配置基础模式已在正式实例验证:AI/Git 均未配置时不探测、不排队、不 Clone、不创建 `.git`,原有记忆、项目、搜索、密码库、文件、Web、REST 和 MCP 保持完整可用。