跳转至

ECC 记忆保险库

功能

操作者可以通过一个人类可读的保险库来保存、检查、搜索和交接持久化上下文;Claude Code、Codex、Hermes、OpenCode 以及其他工具框架可以共享该保险库。项目记忆和团队记忆位于 .ecc/memory/ 之下;用户记忆位于 ~/.ecc/memory/ 之下。相同的 ecc.memory.v1 文档可通过 ecc memory CLI 和可选启用的本地 stdio MCP 服务器获得,因此知识传递不依赖电子邮件、某个供应商的会话记录格式,或某个工具框架的钩子支持。

约束

  • Markdown 文件是唯一事实来源。SQLite 上下文图、嵌入向量和托管系统只是索引或适配器,绝不是唯一副本。
  • 记忆是上下文,不是指令。每个首版保险库条目都是 trust: "unreviewed",不能悄然变成规则、技能或策略。
  • 已评审的项目标准仍应位于仓库的规范规则、决策记录、运行手册或其他受治理文档中。保险库可以链接到这些工件,但不能取代它们。
  • 核心是本地优先、可检查的,并且无需模型、网络、数据库服务器或嵌入提供方即可使用。
  • 写入是仅创建操作。该工具绝不会覆盖现有记忆 ID。取代关系通过带有显式链接的新文档来表示。
  • 在工具写入文件之前,会拒识已知的凭据格式和私钥。此扫描是尽力而为的兜底机制,并非完整的密钥分类器。记忆读取器不会跟随符号链接。
  • 首版中的搜索是有界词汇检索。可选的语义适配器以后可以在不更改文档契约的情况下对结果重新排序。
  • 工具框架适配器保持精简。共享行为属于 scripts/、skills/ 和 MCP 服务器,而不是分开的 Claude/Codex/Hermes 存储。
  • 程序性记忆仍保留在规则和直觉中,并遵守它们现有的提升与验证关卡。

检索完整性与当前状态

有界扫描即使找到了匹配的 ID,仍可能不完整。直接读取会在声明不存在、唯一性或完整反向链接之前,拒绝截断的扫描以及包含无效或不可读记忆文档的扫描。核心错误是 ECC_MEMORY_INCOMPLETE;本地 MCP 返回安全工具错误 MEMORY_READ_INCOMPLETE。在这种情况下不会返回任何部分记忆内容。搜索保留其现有诊断信息,以便调用方可以检查部分结果,而不会将其解释为完整清单。被现有隐藏文件或符号链接策略排除的条目仍会被排除;这不会绕过文件系统安全措施,也不意味着在并发编辑时具有原子快照。

因另一个文档格式错误而导致直接读取失败,是一种刻意的权衡:操作者必须先修复经授权的保险库,才能依赖完整的 ID 查找。使用现有的 doctor 来检查问题。不要扩大范围或权限来让失败的查找通过。

取代链接是引用,不是自动撤销。现有的操作者评审状态字段控制活动搜索;一旦扫描完成,直接读取仍可用于明确的历史检查。证据匹配和词汇相关性并不能确立当前事实、经认证的作者身份或执行操作的权限。这些检查属于消费工作流,并且在事实发生变化时保留原始证据。

威胁边界

首版运行时防御恶意保险库文档、稳定的符号链接/路径逃逸、意外提交项目记忆、跨工具框架 MCP 身份伪造、已知密钥格式、终端控制数据以及有界资源耗尽。保险库根目录必须保持仅操作者可写。它不构成同一操作系统用户下并发进程之间的安全边界:Node.js 并未提供消除所有父目录交换竞态所需的目录文件描述符相对 openat2 保证。需要防范恶意本地进程的操作者必须使用单独的操作系统账户、容器或等效的文件系统隔离。

实现契约

参与者

  • 操作者: 拥有保险库,评审文件,提交团队记忆,并决定被召回的上下文何时成为受治理的项目事实。
  • 工具框架代理: 写入未评审的事实、笔记、经验教训和交接记录;读取面向自身或所有工具框架的活动记忆。
  • ECC CLI: 确定性的本地创建/读取/搜索/doctor 接口。
  • ECC Memory MCP: 暴露相同创建/读取/搜索/doctor 操作的 stdio 适配器。它没有评审或提升工具。
  • ECC2 上下文图: 可选投影,由 Markdown 目录连接器填充,以提供更丰富的关系和会话视图。

存储位置

<repo>/.ecc/memory/
├── project/
│   ├── contexts/
│   ├── decisions/
│   ├── facts/
│   ├── handoffs/
│   ├── lessons/
│   ├── notes/
│   ├── preferences/
│   └── runbooks/
└── team/
    └── <same kind directories>

~/.ecc/memory/
└── <same kind directories>

项目范围是仓库本地的操作者上下文,并拥有自己的失败关闭型 .gitignore:如果保护文件存在且内容不符合预期,初始化和写入将停止。团队范围在提交前应由人工检查,但已提交的保险库条目仍然是未经评审的上下文。用户范围随操作者跨仓库移动,并且仅在明确请求时才会被召回。ECC_MEMORY_PROJECT_ROOT 和 ECC_MEMORY_USER_ROOT 可以显式覆盖这两个保险库位置。

文档契约

每条记忆都是一个 Markdown 文件,带有严格的 JSON 值 YAML frontmatter:

---
schema: "ecc.memory.v1"
id: "mem_20260726_01k123example"
title: "Authentication migration handoff"
kind: "handoff"
scope: "project"
trust: "unreviewed"
status: "active"
source_harness: "codex"
target_harnesses: ["claude"]
tags: ["auth", "migration"]
links: ["mem_20260725_01kolder"]
created_at: "2026-07-26T20:00:00.000Z"
updated_at: "2026-07-26T20:00:00.000Z"
---

The token rotation tests pass. The remaining task is ...

必需字段包括 schema、ID、title、kind、scope、trust、status、source harness、targets、tags、links 和 timestamps。ID、kind、tag 和 harness 名称使用有界的小写 slug 语法。正文为有界的 Markdown 文本。反向链接从其他文档的 links 字段派生。

状态与转换

tool save ──> active + unreviewed
                  │
                  ├── human verifies evidence
                  │      └──> governed rule, decision record, runbook, or doc
                  │
                  └── new memory links with supersedes relation
                         └──> old item may be marked superseded manually

初始运行时仅创建 active、unreviewed 的记忆,常规搜索召回仅返回 active 条目。通过直接 ID 读取仍可能检索到非 active 条目以供检查。人工审核不会更改 vault 条目的 trust 字段;被接受的知识会被提升为受治理的仓库制品。运行时不暴露自动提升转换。这是有意为之:具备 shell 能力的代理不能被当作独立的人工审批边界。

接口

CLI:

ecc memory init [--scope project|team|user]
ecc memory save --title <text> [--body-file <path>|--stdin] [metadata flags]
ecc memory handoff --from <harness> --target <harness> --title <text> ...
ecc memory search <query> [--scope ...] [--target-harness ...] [--json]
ecc memory read <id> [--scope ...] [--json]
ecc memory doctor [--json]

MCP 工具:

memory_save
memory_search
memory_read
memory_doctor

CLI 默认搜索 active 的 project 和 team 记忆。user 召回需要显式指定 --scope user。其 --target-harness 选项是调用方选择的路由过滤器,而不是授权边界。

MCP 服务器在启动时要求小写的 ECC_MEMORY_HARNESS 身份。该服务端身份为写入提供 source_harness,并将搜索/读取限制为面向该 harness 或 all 的记忆;客户端无法在工具参数中覆盖它。除非操作员同时设置 ECC_MEMORY_ALLOW_USER_SCOPE=1,否则 MCP 对 user 范围的访问被禁用;之后客户端仍必须显式请求该范围。MCP 写入始终生成 unreviewed 文档。结构化错误会省略堆栈跟踪和机密值。

故障与恢复

  • 无效元数据、超大输入、重复 ID、疑似机密和路径逃逸会在写入前失败。
  • 格式错误的文件由 doctor 报告并从搜索中排除;它永远不会被自动删除或重写。
  • 重复 ID 和损坏的链接会被显式报告。
  • 符号链接会被跳过并报告。
  • 缺失的 vault 目录等同于空 vault。
  • 失败的 MCP 请求会返回有界错误,并保持现有文件不变。

可观测性

首个版本仅报告操作结果。写入确认会省略原始正文,并使用相对于范围的 vault 路径;只有显式读取才会返回完整正文。后续基于事件溯源的 ECC2 投影可以记录内容哈希和操作元数据,但不得记录原始记忆正文或凭据。

非目标

  • 构建向量数据库、托管同步服务、邮件传输或新的代理框架。
  • 自动导入原始 Claude/Codex/Hermes 转录。
  • 将召回的记忆视为受信任的系统指令。
  • 自动将记忆提升为技能、规则、本能或策略。
  • 替换 ECC2 会话、上下文图、GitHub/Linear 工作项或受治理的项目文档。
  • 在首个版本中解决跨机器无冲突复制。

开放问题

  • 在 ECC2 仅追加事件基座落地后,team 范围是否应获得一个指向受治理制品的签名提升清单。
  • 哪个语义适配器应成为第一个可选重排序器,以及离线评估必须在哪些方面超越词汇搜索,之后它才会被推荐。
  • SessionStart 是否应注入指向受治理项目引用的链接,还是保持所有召回都显式限定任务范围。首个版本保持召回显式。
  • 一旦 conductor fork 生命周期稳定,.context/ worktree 交接应如何从 vault 交接中物化。

交接

本地文件/CLI/MCP 切片在显式 CLI 或 MCP 激活之后实现,并由 core、schema、CLI、protocol、packaging 和 cross-harness 测试覆盖。ECC2 图同步、自动会话捕获、语义适配器、受治理引用召回和事件日志提升属于后续工作流,需在真实世界检索评估之后进行。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC