关于 CommitLore
CommitLore 将仓库决策存储在 Git 中,并向编码 Agent 提供与待编辑路径相关的有效决策。它跟踪决策生命周期和可信度,避免将已被取代的指引当作当前约束。
主要功能
- 01记录约束和被否决的方案
- 02将记录存入 Git trailer 或 notes
- 03跟踪有效、被取代和过期决策
- 04按仓库路径限定上下文
- 05评定记录可信度
适用场景
- 01编辑前向 Agent 提供相关决策
- 02将团队约束与代码一同保存
- 03避免重复提出已否决的方案
- 04审查并维护决策生命周期
MCP 相关
CommitLore 通过 MCP 提供决策流程和按路径筛选的上下文,供 Gemini CLI、Cursor、Windsurf 和 opencode 等宿主使用。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
CommitLore
别再反复审查同一个糟糕想法。
由 Git 持有、供编码 Agent 使用的决策权威记录。
将约束条件、否决的替代方案和警告保存在 Git 中,然后仅交付当前仍然有效的内容,避免把仓库已经推翻的决策再次交给 Agent。
没有托管记忆。记录由仓库持有。
安装一次。然后在要使用它的每个仓库中进行初始化。
curl -fsSL https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.5/install.sh | sh -s v1.7.5
想先查看安装程序吗?
curl -fsSLO https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.5/install.sh
sh install.sh v1.7.5
# Or skip the script: the checkout it makes is one you can make yourself.
git clone --depth 1 --branch v1.7.5 https://github.com/MongLong0214/commitlore
node commitlore/dist/commitlore.mjs --version
它会安装固定版本的源代码检出副本和一个包装脚本,后者运行
node <checkout>/dist/commitlore.mjs——无需下载编译产物,也无需构建步骤。
代码留存。判断却不会。
Agent 提出一种做法。团队因某个不易察觉的约束而否决了它。最终代码保留了结果,却通常没有说明为何否决该替代方案。之后的 Agent 只看到代码,又会提出同一个想法。
CommitLore 将这些判断保存在代码旁边。
CommitLore 的功能
| 行为 | 产品路径 | |
|---|---|---|
| 记录 | 保存差异无法体现的约束条件、否决的替代方案和警告。候选记录会根据会话记录和已暂存的差异进行检查。 | commitlore capture |
| 保留 | 将已接受的记录存储在 Git 提交说明或备注中,而非托管记忆数据库。 | 提交钩子 · refs/notes/commitlore |
| 跟踪生命周期 | 区分有效、已取代和已过期的决策。 | commitlore stale |
| 限定范围 | 根据 Agent 即将编辑的路径选择决策。 | commitlore context |
| 评定可信度 | 将记录作为指令、声明或被暂缓提供的内容交付。 | 默认模式 / 签名模式 |
| 交付 | 在编辑前向受支持的 Agent 提供当前上下文。 | 插件钩子 · MCP |
大多数提交都不应附带记录。CommitLore 用于保存代码无法保留的判断,而不是叙述每一次更改。
60 秒,让 Agent 具备决策意识
1. 安装 CLI
macOS 和 Linux:
curl -fsSL https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.5/install.sh | sh -s v1.7.5
Windows:
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/MongLong0214/commitlore/v1.7.5/install.ps1))) v1.7.5
需要 Node.js 22.23.2+ 和 Git。脚本会在写入任何内容前检查两者。
2. 连接 Agent
Claude Code:
/plugin marketplace add MongLong0214/commitlore
/plugin install commitlore@commitlore
Codex:
commitlore plugin install-codex
插件不会将 commitlore 添加到 PATH,因此还需要安装 CLI 才能运行以下命令。只要能够安全地进行配置,安装程序也会检测并连接受支持的 MCP 宿主;具体支持情况见下方的兼容矩阵。
3. 初始化仓库
cd your-repository
commitlore init
commitlore context .
安装或更新插件后,请启动新的 Agent 会话:正在运行的会话会继续使用已加载的运行时。
然后照常工作并提交。在支持技能集成的环境中,普通提交请求会考虑 CommitLore;没有值得保留的内容时,它会保持静默。无需在每次提交时都提及 CommitLore。
想让已接受的记录无需逐条提示就暂存吗?仓库可以通过一次 commitlore auto on 选择启用。该策略归仓库所有,适用于整个团队,因此本页面不会静默启用它。
Agent 会收到什么
编辑 src/pricing.ts 之前:
commitlore: active records for src/pricing.ts
Limit
[claim] r-price01 a1b2c3d4 calculatePrice owns final checkout pricing only
Ruled-out
[claim] r-price01 a1b2c3d4 Reuse it for admin quotes | eligibility and rounding semantics differ
[claim] 表示“将其作为信息进行权衡”。仓库可以选择启用更严格的签名授权模式。交付会为 Agent 提供上下文,但不会阻止编辑。
为什么选择 Git?
仓库应拥有代码背后的判断依据。
CommitLore 将记录存储在普通的 Git trailers 和 notes 中,因此它们可以随代码分支、合并、克隆和审查,并在更换代码托管平台后继续留存。
SQLite 只是可重建的索引。删除它后,Git 中仍保留着记录。
找到旧决策还不够
通用记忆或检索系统会问:
哪段旧文本看起来相关?
CommitLore 会问:
现在哪些已记录的决策仍适用于此路径?
已被取代的决策可能高度相关,却不再适合作为当前指导。相关性和权威性是两个不同的问题。
工作原理
- 捕获 — Agent 只起草差异无法体现的决策上下文。
- 验证 — CommitLore 根据会话和暂存的差异检查草稿。
- 保留 — 已接受的记录连同身份和生命周期信息一起存入 Git。
- 交付 — 后续编辑前,只会返回该路径的有效记录。
大多数提交都不包含记录。提交钩子会在存在记录时验证它,但不会凭空创建记录。
现有钩子不会被覆盖。commitlore init 会遵循 core.hooksPath,将已安装的钩子移至 <hook>.commitlore-chained,并先调用它;commitlore hooks uninstall 会将其恢复。
哪些操作会自动执行
| 宿主 | 编辑前交付 | 已验证的捕获工作流 | 确定性的每次提交捕获 |
|---|---|---|---|
| Claude Code | 通过插件自动执行 | 可通过插件技能使用 | 未经认证 |
| Codex | 通过插件自动执行 | 可通过插件技能使用 | 未经认证 |
| Hermes | 执行 commitlore hermes install 后可用 | 宿主安装后可用 | 未经认证 |
| Gemini CLI、Cursor、Windsurf、opencode | 宿主使用注册信息时通过 MCP 交付 | 通过 MCP 提供操作流程 | 否 |
AGENTS.md 宿主 | 仅提供操作流程 | 仅提供操作流程 | 否 |
“可用”表示准备 → 验证 → 暂存的工作流已存在。这不表示系统会自动评估每个符合条件的提交。
在受支持技能宿主上使用的用户,无需在每次提交时都说“将此记录到 CommitLore 中”。剩余的限制在于由宿主发起,而不是要求用户逐条发出命令。
压缩合并仓库
压缩合并会将一个分支的提交替换为一个新的提交,而该提交不会携带分支的尾注。如果你的仓库使用压缩按钮进行合并,那么除非有东西将分支上的记录带到压缩后的提交上,否则合并时就会丢失该记录。
有两种方式可以做到这一点,其中一种需要一次性设置:
| 压缩合并的方式 | 携带记录的方式 | 设置 |
|---|---|---|
在本地运行 git merge --squash | 已安装的 prepare-commit-msg 钩子,从 SQUASH_MSG 获取 | 无需设置——commitlore init 已经完成了这项工作 |
| 使用 GitHub 的 Squash and merge 按钮 | action/preserve GitHub Action | 使用下方的工作流 |
GitHub 会在自己的服务器上执行合并,那里根本不会运行本地 git 钩子,所以本地钩子无法发现这种合并。在那个时刻,只有 Action 能获取所需信息:拉取请求、其提交,以及这些提交被压缩合并到的提交。
添加 .github/workflows/commitlore-preserve.yml:
name: CommitLore squash inheritance
# pull_request_target, not pull_request: a pull request from a fork gets a
# read-only token on pull_request, so the job would build the record and then
# fail to publish it.
on:
pull_request_target:
types: [closed]
permissions:
contents: write # the one push to refs/notes/commitlore
concurrency:
group: commitlore-notes
cancel-in-progress: false
jobs:
preserve:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# the merge commit is on the base branch, and a closed pull request
# has no merge ref left to check out
ref: ${{ github.event.pull_request.base.ref }}
fetch-depth: 0
# the mirror this action writes; publishing from a checkout that never
# read it would fork the notes history
- run: git fetch --no-tags origin '+refs/notes/commitlore:refs/notes/commitlore'
# a squash merge usually deletes the branch, and then the pull request's
# own ref is the only one still reaching the commits that carry records
- run: git fetch --no-tags --force origin
'+refs/pull/${{ github.event.pull_request.number }}/head:refs/commitlore/pr-head'
# The action runs CommitLore from a checkout of this repository: the
# package is private, so there is no published npm name to fall back to.
# `dist/` is committed (ADR-0011), so nothing needs building.
- uses: actions/checkout@v4
with:
repository: MongLong0214/commitlore
ref: v1.7.5
path: .commitlore-cli
persist-credentials: false
- uses: MongLong0214/commitlore/action/[email protected]
with:
cli-path: .commitlore-cli/dist/cli.js
由于 pull_request_target 使用具有写入权限的令牌,后续编辑此配置的人必须遵守两条规则:绝不要在这里检出拉取请求的 head,也绝不要执行任何可从 refs/commitlore/pr-head 访问到的内容。来自 fork 的提交只是用于读取尾注的数据,不是要运行的代码。
commitlore doctor 会在 squash inheritance 下报告此功能是否已启用。它会在记录丢失之前报告;squash conservation 这一行报告的是已经丢失的记录。
如果你使用合并提交或变基进行合并,记录会自行保留,无需进行此设置。
一份实地报告,而非测量结果
有人首次安装 v1.2.1 时,在一个无关仓库中进行了一次运行。这里没有任何内容经过测量,也没有任何内容记录在证据日志中。之所以将这段内容放在此处,是因为上文提到了一个本页其他表格未涵盖的循环。
他们让一个 Agent 修复舍入错误,顺带提到之前考虑过并放弃使用一个十进制库,最后以“提交吧”作结。他们从未提到 CommitLore。提交中包含的部分内容:
Ruled-out: adopting a decimal library such as Decimal.js | the backend is a
number contract, so it is meaningless
Warn: do not revert the test file to console.assert: it exits 0 even on
failure, so CI passes silently
Provenance: drafted
这条 Warn 不是 Agent 收到的指令。它在工作时碰到了这个陷阱,并将其留给后来的人。Provenance: drafted 记录了没有人类阅读过这条记录,因此它的等级是 claim——作为一份供人权衡的报告提交,而非命令。
之后的一次会话没有共享历史记录,却被要求最终采用那个十进制库。它没有这么做,并将这条记录列为理由。它也读取了等级:claim 不是指令,因此它在认同之前,根据代码核实了所述理由。
不同于记忆存储
| 通用记忆 / RAG | CommitLore | |
|---|---|---|
| 核心问题 | 哪些旧文本与当前内容相关? | 哪些决策目前仍适用于此处? |
| 权威来源 | 记忆存储或提供方 | Git |
| 范围 | 语义相似度 | 仓库路径 |
| 生命周期 | 通常优先追加 | 有效 · 已被取代 · 已过期 |
| 信任度 | 检索到的文本 | 指令 · 声明 · 已阻止 |
| 捕获方式 | 转录或笔记存储 | 经证据核验的决策记录 |
| 可移植性 | 取决于后端 | 普通 Git |
CommitLore 有意缩小了范围。它不是通用的用户记忆系统、对话存档,也不是向量数据库的替代品。
证据
| 问题 | 测量结果 | 范围限制 |
|---|---|---|
| 在注册研究中,达到声明级别的上下文是否改变了重新提议的情况? | 使用 CommitLore 时为 2.8%(16/580),不使用时为 18.8%(109/579) | 一个模型、一个测试框架、构造的任务 |
| 生命周期筛选是否在测量的活跃投影中返回了已退役记录? | 0 条已退役记录 | 存在已取代的记录;没有过期记录 |
| 索引查找能否扩展? | 100k 次提交时 p50 为 496 ms | 无索引回退方案要慢得多 |
索引构建时间取决于记录数量,而非提交次数:耗时的遍历每条记录只运行一次,因此,记录较少的长历史比记录密集的短历史构建得更快。
路径范围限制了大型历史数据传递给模型的内容。在 #167 语料库中,10,002 条记录中只有 2 条会被传递:
| 路由 | 模型可见记录 | 相关记录 | 模型可见令牌数 |
|---|---|---|---|
| 注入全部内容 | 10,002 | 2/2 | 1,004,554 |
| 词法 top-k | 2 | 1/2 | 190 |
| CommitLore 路径范围 | 2 | 2/2 | 335 |
此测量是在固定两条记录的预算下对暴露量和召回率的测量,不代表令牌成本、计费成本、准确性或 Agent 行为。一个语料库、一个查询、一个固定的嵌入模型。
Agent 研究无法证明普遍适用的模型效果。内容交付并不能证明模型读取或遵循了记录。
限制、信任与隐私
- 捕获是辅助性的,并非确定性的。 支持的技能会考虑常见的提交请求,但没有任何主机经过认证,能够评估所有符合条件的提交。
- 默认指令模式不等于身份验证。 它会匹配提交作者标头,而任何能写入提交的人都能设置该标头——因此,默认模式下的
[directive]是策略元数据,而非身份凭证。签名模式还要求 Git 自身的验证状态为已验证,并且签名者与仓库本地的commitlore.trustedSigner允许列表匹配;签名者允许列表不存在、为空或无法读取时,不会授权任何人,因此该模式会以失败关闭的方式运行。 - Guard 是实验性的参考建议,并非安全网:在包含 417 个决策的语料库中,精确率为 44.8%(95% Wilson CI 为 32.7%–57.5%),召回率为 22.0%。Guard 返回空结果并不代表安全。
- 每次匹配的工具调用都会消耗令牌来传递信息。 编辑前钩子会在
Read以及Edit、Write、MultiEdit和NotebookEdit上触发,因此运行频率远高于编辑型 Agent 提交的频率。每次触发最多消耗载荷预算——默认值为 800 个令牌,可通过--budget更改。没有记录的仓库不会产生任何开销,这意味着这项成本会随着采用而产生,而不是随安装而产生。 - 回答可能不完整。 系统会说明覆盖范围;未出现在部分结果中,并不能证明不存在相关记录。
commitlore coverage会报告扫描覆盖到的范围。 - 提交尾注会随克隆一起传递;注释则不会。 Git 默认不会获取
refs/notes/*,因此refs/notes/commitlore中的记录不会出现在普通克隆中,直到commitlore init配置该镜像。 - 没有托管后端。 但服务器或钩子返回上下文后,主机会根据自身策略处理该上下文;CommitLore 不控制此数据流。
安全与信任模型
记录在评级前均不可信。默认作者匹配属于策略元数据,并非身份验证。签名指令模式要求 Git 验证通过,并要求存在仓库本地的签名者允许列表;允许列表不存在或无法读取时,不会授权任何人。具有注入特征的载荷不会提供给模型可读取的路由。
安装、升级与旧版钩子
CLI 安装程序无法改写它不知道的仓库中的钩子,而正在运行的主机会话会继续使用其已加载的运行时。commitlore doctor 会指出这两种情况及其修复方法,而 commitlore upgrade 会报告是否存在更新版本。
在有历史记录的仓库中试用。
请告诉我们路径范围、生命周期、捕获或安装在哪些方面会出问题。
## 文档
贡献
CONTRIBUTING.md 介绍了本仓库遵循的记录协议、发布门槛,以及如何复现证据。
许可证
MIT — 参见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。