关于 Foremerge
Foremerge 是供编码 Agent 使用的开源协调协议,适用于各自在 Git worktree 中工作的场景。它记录声明的意图与语义范围,并在代码变更落地前确定性地提示潜在冲突。
主要功能
- 01共享 Agent 意图与语义声明
- 02编码前检测提示性冲突
- 03协调隔离的 Git worktree
- 04追踪 ChangeSet、验证与来源记录
- 05依据已配置检查门控验收
适用场景
- 01发现并行 Agent 之间的跨文件冲突
- 02协调多个 Git worktree 中的工作
- 03核查 Agent 变更是否通过可信检查
MCP 相关
Foremerge 除 CLI 和 JSON API 外还提供 MCP 服务。MCP 客户端可使用同一协调服务与本地存储。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Foremerge
Foremerge 是面向编码 Agent 的开源协作协议,构建于 Git 之上。Agent 在各自隔离的工作树中工作,同时共享意图、语义声明、依赖关系、临时 ChangeSet、决策、验证结果和来源信息。
| 让你的 Agent 安装 | → | 完成 | → | 在变更落地前查看冲突 |
|---|---|---|---|---|
| 将一行内容粘贴到 Claude Code、Codex 或 Cursor 中 | 它会安装 Foremerge 并完成自身配置 | 每个 Agent 都能看到其他 Agent 即将进行的变更,即使它们在不同的工作树中 |
状态: Foremerge
0.6.0是一个 1.0 之前、以本地为先的 MVP。CLI、JSON API、MCP 服务、SQLite 存储、确定性冲突检测器以及受验证流程控制的生命周期均已实现。公开的架构仍可能变更。目前尚无已发布的基准测试结果,机器间协作也不在本项目的范围内。
工作原理
假设你有两个 AI Agent 同时处理同一个项目。它们各自拥有一份代码副本,因此不会争抢文件。它们都完成了工作,结果看起来也都正确。之后你却发现,它们的工作相互抵消了。
Git 无法对此发出警告,因为 Git 比较的是文本,而不是意图。如果两个 Agent 编辑同一文件的同一部分,Git 会阻止你。但如果两处编辑各自看来都完全合理,却落在不同的文件中,Git 就看不到问题。比如,一个 Agent 将所有调用方迁移到新的 StripePaymentService,另一个 Agent 则为旧的 PaymentService 添加 PayPal 支持;两边没有任何重叠,因此 Git 会毫无异议地合并两项变更,而 PayPal 相关工作最终会留在一个再也没有任何代码调用的类中。
Foremerge 通过让 Agent 在动手之前先声明即将进行的工作来解决这个问题。
- 每个 Agent 都说明自己打算改动什么。 不是代码本身,而是目标,例如“我准备修改
sendEmail函数”。 - 所有 Agent 都从同一份共享清单中读取信息。 它是存储在项目
.git文件夹中的小型数据库,因此你机器上的每个 Agent,无论是 Claude、Codex 还是 Cursor,都能看到相同的信息。 - 如果两个计划冲突,你会立即收到通知。 Foremerge 会指出涉及的两个 Agent,解释计划冲突的原因,并建议如何拆分工作。此时两个工作树都仍然干净,因此不必丢弃任何工作。
可以把它想象成一块共享白板。Agent 开始工作前,会先记下自己准备做什么,并查看其他人已经写下的内容。
Foremerge 有两件事刻意不做。它绝不会锁定文件或阻止 Agent,因为一个 Agent 崩溃就可能拖住整个团队,所以警告仅供参考,决定权仍在你手中。它也绝不会让模型来判断冲突,因此相同输入总会得到相同答案。
Git 尚未发现的冲突
Agent A: Replace PaymentService with StripePaymentService
Agent B: Add PayPal support to PaymentService
这些 Agent 可以在不同的工作树中工作,而不会改动同一行。但计划仍会冲突:一方移除了扩展点,另一方却依赖它。
两个 Agent 都声明了相同的 symbol:PaymentService 范围,一个表示将对其执行 replace,另一个表示将对其执行 extend。Foremerge 会在双方写入代码前比较这两项声明,发出 HIGH 级别的提示,并建议围绕 PaymentProvider 之类的稳定抽象进行协调。这个建议是可解释的依据,并非自动作出的架构决策,也不会形成硬性锁定。
由于这里声明的是操作,而不是从摘要中读取,因此 Agent 如何措辞计划并不重要。“将支付整合到 Stripe”与“用 Stripe 替换 PaymentService”会得到相同的判定。
Git 仍是持久化的代码仓库。Foremerge 在此之上补足了缺失的共享认知。

内容根据 0.1.0 发布二进制的运行中捕获的实际冲突字段渲染,见
examples/terminal-session.txt。显示的
命令使用了图中所示的 jq 筛选器;输出经过删节,以便阅读。
快速入门:不到五分钟发现第一个冲突
让编码 Agent 帮你完成
在你想要协调的代码仓库中,将以下内容粘贴到 Claude Code、Codex 或 Cursor:
Set up Foremerge in this repository so we can coordinate parallel agents.
1. Install it: curl -fsSL https://foremerge.com/install.sh | sh
2. Initialize: foremerge init
3. Wire this client and any others in use: foremerge setup all
4. Register the check I should be validated against, for example:
foremerge checks set test -- cargo test --all-targets
5. Confirm: foremerge doctor --client all
Then read the Foremerge skill that step 3 installed for this client and follow
it from now on: publish your intent with semantic scopes before editing, claim
the scope, and check for conflicts before you start.
将步骤 4 调整为此代码仓库实际使用的测试命令。步骤 3 会请求客户端启用 MCP 服务,因此启用前会提示你。Codex 注册是用户级的,但一次注册即可用于所有代码仓库:在你想要协调的代码仓库中启动 Codex。
或者自行操作
你需要较新版本的 Git 和 jq。安装预构建且经过校验和验证的发布二进制(适用于 macOS 和 Linux;脚本会将其安装到 ~/.local/bin):
curl -fsSL https://foremerge.com/install.sh | sh
提示
两个命令,一个程序。 这会安装
foremerge和fmg,二者是同一二进制的完整名称和短名称,因此fmg status与foremerge status的作用相同。以下示例均使用完整名称foremerge;你可以任选其一。
也可以通过 npm 安装(适用于 macOS、Linux with glibc 和 Windows x64)。软件包包含相同的发布二进制,因此安装时不会编译或下载任何内容:
npm install -g foremerge
也可以使用 Rust 1.85+ 从源代码构建:运行 cargo install --locked --git https://github.com/naw103/foremerge foremerge,或在检出目录中运行 cargo install --locked --path .。Windows 二进制文件可在发布页面获取。要更新,请使用与安装时相同的方式升级,然后重新运行 foremerge setup 并重启 Agent 客户端;升级 Foremerge 说明了每个步骤的重要性。然后,在你想要协调的代码仓库中:
foremerge init
foremerge doctor
从 0.4.0 起,安装程序、发布压缩包和 cargo install 都会包含这两个名称。如果 PATH 中已有其他程序响应 fmg,安装程序会保留它,并说明原因,而不会覆盖它。
为此代码仓库使用的任何客户端安装原生技能和 MCP 条目,然后定义 Agent 可以按名称请求的可信检查:
foremerge setup all
foremerge checks set test -- cargo test --all-targets
foremerge doctor --client all
验收必须通过验证:Foremerge 会自行运行检查,而不是轻信 Agent 的说法。选择一项运行速度快且确实能发现交接问题的检查,例如构建或类型检查,而不是完整的 CI 测试套件;此门禁决定其他 Agent 是否可以将工作视为已完成,但不能替代 CI。如果此代码仓库没有有意义的验证方式,只需说明一次,不要注册一个永远通过的检查:
foremerge checks policy advisory
以这种方式被接受的工作会记录为 UNVERIFIED,并附上原因,因此审计记录绝不会让人误以为执行过实际上并未执行的检查。foremerge doctor 会报告已注册的检查能否在此处实际运行。这在 Agent 工作树中很重要,因为依赖目录通常会被 gitignore 忽略,而 git worktree add 不会创建这些目录。
使用 setup codex、setup claude 或 setup cursor 为单个客户端进行设置。设置会保留无关配置(包括项目 MCP JSON 中的键顺序)。升级 Foremerge 时,会原地刷新自身未编辑的技能文件;但除非你明确传入 --force,否则已编辑的技能文件或与 Foremerge 不同的 MCP 条目都不会被替换。setup all 会尝试设置每个客户端并报告各自的结果;只要有任一项失败,就会以非零状态退出。Codex MCP 注册为用户级配置,适用于所有仓库,并根据启动 Codex 时所在的目录解析;参见Agent 客户端设置。
init 会在仓库的 Git 公共目录下创建本地协作状态,不会更改已跟踪的文件。以下无需工作树的会话足以验证编码前检测;实际的编码 Agent 应注册各自隔离的工作树和实际模型标识符。
STRIPE_AGENT=$(
foremerge --json agent register \
--name stripe-agent \
--no-worktree |
jq -er '.data.id'
)
STRIPE_RESULT=$(
foremerge --json intent publish \
--agent "$STRIPE_AGENT" \
--task "modernize-payments" \
--summary "Replace PaymentService with StripePaymentService" \
--scope symbol:PaymentService=replace
)
STRIPE_INTENT=$(printf '%s\n' "$STRIPE_RESULT" | jq -er '.data.intent.id')
PAYPAL_AGENT=$(
foremerge --json agent register \
--name paypal-agent \
--no-worktree |
jq -er '.data.id'
)
PAYPAL_RESULT=$(
foremerge --json intent publish \
--agent "$PAYPAL_AGENT" \
--task "add-paypal" \
--summary "Add PayPal support to PaymentService" \
--scope symbol:PaymentService=extend
)
PAYPAL_INTENT=$(printf '%s\n' "$PAYPAL_RESULT" | jq -er '.data.intent.id')
printf '%s\n' "$PAYPAL_RESULT" |
jq '.data.conflicts[] | {kind, severity, scope, explanation, suggestion}'
printf '%s\n' "$PAYPAL_RESULT" |
jq '.data.related_work[] | {agent, summary, asserted, overlap}'
第一条命令会打印本地运行中发现的问题。第二条命令会打印 related_work:另一位 Agent 的意图,以及所有重叠范围和双方声明的操作。Foremerge 会指出重叠之处;由你判断其含义,并使用 foremerge assess record 记录结论。无需先更改任何文件。查看捕获的、带有清晰标注的会话记录:examples/terminal-session.txt。
声明可添加所有权上下文,但不会阻止任何一位 Agent:
foremerge --json work claim \
--agent "$STRIPE_AGENT" \
--intent "$STRIPE_INTENT" \
--scope symbol:PaymentService \
--reason "Changing the provider boundary" >/dev/null
foremerge --json work claim \
--agent "$PAYPAL_AGENT" \
--intent "$PAYPAL_INTENT" \
--scope symbol:PaymentService \
--reason "Adding another provider" |
jq '.data | {advisory_only, warnings}'
foremerge --json work query --scope symbol:PaymentService |
jq '.data[] | {agent: .agent.name, intent: .intent.summary, open_conflicts}'
两项声明都成功。第二条响应包含重叠警告,因为声明只是带租期的建议,并非排他性所有权。

录制时使用的是已发布的 0.4.0 二进制;每条命令及其输出都是真实的。
它如何构建在 Git 之上
coding agent A coding agent B
| |
isolated worktree A isolated worktree B
| |
+--------- semantic events, not edits ----------+
|
CLI / MCP / JSON API
|
Foremerge service
/ | \
SQLite coordination git CLI validation argv
in <git-common-dir> | |
\ Git repository /
durable commits and refs
所有前端都使用同一服务和存储。语义图如下:
Agent → Task → Intent → Claim → Symbol → Dependency
→ ChangeSet → Test → Result → Decision → Provenance
变更会在一个事务中更新类型化的 SQLite 投影、生成图边,并追加经过哈希链处理的语义事件。日志可用作防篡改证据;它不是远程身份签名,也不提供分布式共识。
Git 工作树:文件隔离,状态互通
Foremerge 会解析 Git 公共目录,并将默认数据库存储在:
<git-common-dir>/foremerge/state.sqlite3
尽管关联工作树中的检出文件彼此独立,但它们共享同一个公共目录。使用 Foremerge 对原生 Git 的轻量封装创建工作树:
foremerge worktree create \
--branch agent/paypal \
--path ../payments-paypal \
--base HEAD
foremerge --cwd ../payments-paypal --json agent register \
--name paypal-agent \
--model "$ACTUAL_MODEL_ID"
同一仓库中的其他工作树会立即看到已注册的 Agent 及其意图。你可以使用 --database PATH 或 FOREMERGE_DB 覆盖存储位置,但所有本地 Agent 必须指向同一个数据库才能共享状态。MVP 不会在多台机器之间复制 SQLite;不要因为数据库挂载在网络上就推断它具备分布式安全性。
Foremerge 会为 ChangeSet 指纹和已接受的引用创建 Git 状态快照。它不会自动合并、变基、拣选提交、推送或更新目标分支。
语义工作流
INTENT ─claim→ CLAIMED ─start→ IN_PROGRESS ─publish→ PROVISIONAL
─validate current fingerprint→ VALIDATED
─accept gates→ ACCEPTED ─record Git ref→ COMMITTED
支持的范围类型:
symbol api schema config infra test migration env file component contract domain
发布最小且有用的语义范围。仅使用文件路径会遗漏 API、配置、架构、基础设施和跨语言冲突。
常用命令:
| 边界 | 命令 |
|---|---|
| 注册来源信息 | foremerge agent register --name NAME --model MODEL |
| 发布意图 | foremerge intent publish --agent ID --task TASK --summary TEXT --scope KIND:KEY=OPERATION |
| 声明范围 | foremerge work claim --agent ID --intent ID --scope KIND:KEY |
| 开始实现 | foremerge work start INTENT_ID --agent AGENT_ID |
| 询问谁正在修改 | foremerge work query --scope KIND:KEY |
| 查看每个 Agent 正在做什么 | foremerge status |
| 预检计划 | foremerge conflicts check --intent TEXT --scope KIND:KEY=OPERATION |
| 记录结论 | foremerge assess record --agent ID --intent ID --related-intent-id ID --verdict V --rationale TEXT --action A |
| 发送协调信息 | foremerge coordinate send --from ID --to ID --message TEXT |
| 监视语义事件 | foremerge work watch --after-seq 0 |
运行 foremerge <command> --help 查看完整的当前标志。全局标志(如 --json、--cwd 和 --database)可以放在子命令之前或之后。
ChangeSet 与验证门槛
ChangeSet 会记录 Agent/模型、任务和意图、受影响的文件/符号/契约、依赖项、实现摘要、报告的测试、决策、来源信息、工作树、指纹、状态和 Git 引用。已接受的候选版本及其后续落地提交会分别保留为 accepted_commit 和 integration_commit。
规范的集成顺序如下:
- 发布意图、声明语义范围,并将实现标记为进行中。
- 在隔离的 Agent 分支上工作并提交。
- 为干净的候选版本发布 ChangeSet。
- 让 Foremerge 针对其确切指纹执行验证。
- 解决高优先级冲突,然后接受仍然干净且已验证的引用。
- 使用常规 Git 操作或拉取请求进行集成。
- 在 Foremerge 中记录持久化的集成提交。
foremerge work claim \
--agent "$AGENT_ID" \
--intent "$INTENT_ID" \
--scope component:payments
foremerge work start "$INTENT_ID" --agent "$AGENT_ID"
# Implement the change and commit it on this isolated branch before publishing.
CHANGESET_ID=$(
foremerge --json changeset publish \
--agent "$AGENT_ID" \
--intent "$INTENT_ID" \
--summary "Introduce PaymentProvider and StripePaymentProvider" \
--file src/payments.rs \
--symbol PaymentProvider \
--symbol StripePaymentProvider \
--contract payment-provider \
--provenance-json '{"source":"coding-agent"}' \
--git-ref HEAD \
--worktree "$PWD" |
jq -er '.data.id'
)
foremerge changeset validate "$CHANGESET_ID" \
--worktree "$PWD" \
-- cargo test --all-targets
foremerge changeset accept "$CHANGESET_ID" --git-ref HEAD
# Integrate with ordinary Git, then record the commit that actually landed.
foremerge changeset commit "$CHANGESET_ID" --git-ref main
Agent 报告的 --reported-test COMMAND=STATUS 值仅用于记录来源信息,不满足验收要求。由 Foremerge 执行的验证会记录命令参数向量、退出状态、输出、耗时和候选版本指纹。验证后检测到的任何更改都会使该次尝试失去权威性,但仍可通过 changeset attempts 查询其输出和更改路径诊断信息。
对于会生成一次性未跟踪输出的可信检查,操作员可以设置精确规则或目录前缀规则,而无需更改已跟踪文件:
foremerge validation-exclusions set \
--path coverage.log \
--path target/validation-reports/
规范化策略摘要属于候选版本指纹的一部分;已跟踪的更改永远不能排除;MCP 无法更改该策略;生成的文件仍必须在验收前移除。请参阅 ADR 0001。
验收还要求工作树干净,且没有尚未解决的 HIGH 冲突,除非调用方刻意同时使用可见的 --allow-high-conflicts 覆盖选项和 --override-reason "..."。建议通过明确说明理由来解决冲突。验收会创建 refs/foremerge/accepted/<changeset-id>;它不会合并代码。
验证命令会以可信的本地代码身份运行,并拥有你的操作系统权限。Foremerge 不会对其进行沙盒隔离。
Agent 客户端与 MCP:完整生命周期工具
通过 stdio 运行 foremerge mcp。MCP 无需 HTTP 守护进程;两者都是同一数据库的适配器。
| 工具 | 用途 |
|---|---|
register_agent | 记录 Agent、模型、能力和 worktree 来源信息 |
publish_intent | 发布计划中的工作,声明其对每个范围的影响,并获取冲突及相关工作以供评估 |
record_assessment | 记录你对某个相关意图的结论以及你将采取的行动 |
claim_work | 创建针对语义范围的租约式建议声明 |
query_work | 查找 Agent、意图、声明、ChangeSet 和冲突 |
check_conflicts | 在代码更改前检查已发布或临时意图 |
publish_changeset | 记录实现、测试、决策和 Git 来源信息 |
coordinate_with_agent | 发送与冲突或 ChangeSet 关联的持久消息 |
start_work | 将已声明的工作推进到实现阶段 |
resolve_conflict | 记录经审计的持久冲突解决方案 |
run_verification | 按名称运行受信任的仓库检查,不接受原始 MCP argv |
accept_changeset | 执行最终冲突、依赖、验证和 Git 门禁检查 |
record_commit | 记录实际的 Git 集成提交 |
discard_work | 关闭已放弃的工作,或未经过接受流程但已合并的工作,并释放声明和阻塞项 |
list_agents | 读取已注册 Agent 的来源信息 |
get_intent | 读取一个意图及当前冲突快照 |
get_changeset | 读取一个 ChangeSet 及 Git/来源状态 |
status | 读取一致的协调器状态快照 |
请从有效的最小配置
examples/mcp-config.json 开始。该配置假定客户端以仓库为工作目录启动 foremerge。没有仓库工作目录设置的客户端应在 mcp 前传入绝对路径的 --database;请从 Git 公共目录推导,而不要假定链接 worktree 的 .git 是一个目录。
请参阅Agent 客户端设置,了解安装程序、原生技能位置、特定客户端的 MCP 文件、诊断和安全替换规则。请参阅MCP 设置,了解传输行为、架构、命名检查、示例输入和多 worktree 配置。
源码克隆包含位于 .codex/skills、.claude/skills、.cursor/skills、可移植的 .agents/skills 位置以及 Claude Code 插件中的等效技能,此外还包括可移植的 Claude 和 Cursor MCP 模板。Cargo 安装会嵌入规范技能,因此 foremerge setup 可以将其安装到另一个仓库,无需复制此源码树。
本地 JSON API
守护进程默认通过经过身份验证的环回 HTTP 运行,地址为
http://127.0.0.1:47811。init 会创建一个 bearer 令牌,并在平台支持时设置私有文件权限。
在一个终端中:
foremerge daemon
在另一个终端中,请从 Foremerge 读取令牌路径,而不要猜测:
export FOREMERGE_URL=http://127.0.0.1:47811
TOKEN_FILE=$(foremerge --json init | jq -er '.data.token_file')
FOREMERGE_TOKEN=$(tr -d '\r\n' < "$TOKEN_FILE")
curl --fail --silent --show-error \
--header "Authorization: Bearer $FOREMERGE_TOKEN" \
--get "$FOREMERGE_URL/v1/work" \
--data-urlencode 'scope=symbol:PaymentService' |
jq .
不要打印、提交或分享令牌。/healthz 用于检查无需数据库的进程存活状态,/readyz 用于执行有界且不等待的存储探测;两者均公开。除非守护进程是为可信的本地测试而有意使用 --no-auth 启动,否则每个 /v1 路由(包括分页事件链审计)都需要令牌。MVP 会拒绝非环回绑定,并非经过加固的多租户服务。
命令行的备用方式 foremerge request 会自动读取本地身份验证信息。可运行的 curl 操作指南见
examples/api-requests.sh;完整的路由和错误参考见 JSON API。
MVP 有意不作出的承诺
- 冲突检测是确定且可解释的,但基于启发式规则。它可能会漏掉同义概念,也可能对兼容的工作发出警告。
- 声明只会发出警告;绝不会锁定文件、符号或 Agent。
- 验证通过仅能证明记录的命令针对记录的指纹通过了验证,并不能证明测试计划完整。
- Git 引用和进程结果比模型、提示词或测试说明中的自我报告更可靠。
- 事件链可以检测保留链中的更改;它不是签名、远程证明或外部检查点。
- 本地 SQLite 不提供共享模式下的共识,环回承载令牌也不是面向公开部署的安全模型。
- 我们提供了可执行的基准测试装置、可复现的查询测试工具和基准测试计划,但尚未发布 协调与非协调运行之间的性能对比结果。
- Foremerge 不能取代代码审查、架构所有权、CI、安全扫描、Git 托管规则或备份。
将 Foremerge 用作集成门禁前,请阅读完整的限制和信任模型。
文档
| 文档 | 解答的问题 |
|---|---|
| 架构 | 为什么采用一个 Rust 二进制文件、SQLite、Git CLI 和共享的 common-dir 状态? |
| 协议 | Agent 会发布什么,以及何时发布? |
| 状态模型 | 哪些状态转换和不变量会决定工作是否通过? |
| 冲突检测 | 哪些确定性规则会生成发现和建议? |
| Git 集成 | 指纹、工作树和已接受的引用如何运作? |
| Agent 客户端 | Codex、Claude Code 和 Cursor 如何发现技能和 MCP 服务? |
| MCP 设置 | 客户端如何配置和调用 18 种生命周期/读取工具? |
| JSON API | 提供了哪些路由、请求正文、身份验证和错误? |
| OpenAPI 架构 | 机器可读的 HTTP 契约是什么? |
| 基准测试计划 | 将如何比较协调与非协调运行? |
| 验证排除 ADR | 验证可以忽略哪些生成路径,为什么? |
| 路线图 | 哪些内容属于当前、下一步、以后或非目标? |
| 限制 | MVP 不保证什么? |
| 品牌 | Foremerge 的各类展示界面应遵循哪些标志、颜色、字体、图标和 CLI 输出规则? |
链接
- 网站:foremerge.com
- Crate:crates.io/crates/foremerge
- MCP 注册表名称:mcp-name: io.github.naw103/foremerge
贡献与许可证
欢迎贡献,尤其是关于范围词汇、冲突证据、ChangeSet 来源和验证策略的协议反馈。请阅读 CONTRIBUTING.md,然后运行完整的本地检查:
make verify
Foremerge 根据 Apache License 2.0 授权。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。