{"slug": "foremerge", "title": "Foremerge", "summary": "Foremerge 0.4.0, an open-source coordination protocol for coding agents built above Git, lets agents announce their intended changes in a shared SQLite store inside the project's .git folder, detecting semantic collisions before code is written. The protocol, which is local-first and pre-1.0, compares declared operations rather than text, so it can flag conflicts like one agent replacing PaymentService while another extends it, without locking files or using model judgment.", "body_md": "Foremerge is the open-source coordination protocol for coding agents, built above Git. Agents keep isolated worktrees while sharing intent, semantic claims, dependencies, provisional ChangeSets, decisions, validation, and provenance.\n\nTell your agent to install |\n|---|\n\n**Done**\n\n**See collisions before they land**\n\nStatus:Foremerge`0.4.0`\n\nis a pre-1.0, local-first MVP. The CLI, JSON API, MCP server, SQLite store, deterministic conflict detector, and verification-gated lifecycle are implemented. Public schemas may still change. Shared multi-machine mode and published benchmark results do not yet exist.\n\nSay you have two AI agents working on the same project at the same time. Each one gets its own copy of the code, so they never fight over files. Both finish. Both look correct. Then you find they undid each other's work.\n\nGit cannot warn you about that, because Git compares text and not intent. It\nwill stop you when two agents edit the same part of the same file. What it\ncannot see is two edits that are each perfectly reasonable on their own and\nland in different files. If one agent moves every caller onto a new\n`StripePaymentService`\n\nwhile another adds PayPal support to the old\n`PaymentService`\n\n, nothing overlaps, so Git merges both without complaint and\nthe PayPal work is left stranded on a class nothing calls any more.\n\nForemerge fixes this by having agents announce what they are about to do, before they do it.\n\n**Each agent says what it is about to touch.** Not the code, just the target, like \"I am going to change the`sendEmail`\n\nfunction.\"**Every agent reads from one shared list.** It is a small database inside your project's`.git`\n\nfolder, so every agent on your machine sees the same picture, whether it is Claude, Codex, or Cursor.**If two plans collide, you hear about it right away.** Foremerge names the two agents, explains why their plans clash, and suggests how to split the work. Both worktrees are still clean at that point, so no work has to be thrown away.\n\nThink of it as a shared whiteboard. Before an agent starts, it writes down what it is about to work on, and it reads what everyone else already wrote.\n\nTwo things Foremerge deliberately does not do. It never locks a file or blocks an agent, because a single crashed agent would then stall the whole fleet, so the warnings are advisory and you stay in charge. And it never asks a model to judge conflicts, so the same inputs always produce the same answer.\n\n```\nAgent A: Replace PaymentService with StripePaymentService\nAgent B: Add PayPal support to PaymentService\n```\n\nThese agents can work in different trees without touching the same line. The plans still collide: one removes the extension point while the other depends on it.\n\nBoth agents declare the same `symbol:PaymentService`\n\nscope, one saying it will\n`replace`\n\nit and the other that it will `extend`\n\nit. Foremerge compares those\ntwo declarations before either writes code, raises a `HIGH`\n\nadvisory, and\nsuggests coordinating on a stable abstraction such as `PaymentProvider`\n\n. That\nsuggestion is explainable evidence, not an automatic architecture decision or a\nhard lock.\n\nBecause the operation is declared rather than read out of the summary, it does not matter how either agent phrased its plan. \"Consolidate payments onto Stripe\" and \"Replace PaymentService with Stripe\" reach the same verdict.\n\nGit remains the durable repository. Foremerge supplies the missing shared awareness above it.\n\n*Rendered from the actual conflict fields captured by the 0.1.0\nrelease-binary run in\nexamples/terminal-session.txt. The displayed\ncommand uses the shown jq filter; output is abridged for readability.*\n\nPaste this into Claude Code, Codex, or Cursor from inside the repository you want to coordinate:\n\n```\nSet up Foremerge in this repository so we can coordinate parallel agents.\n\n1. Install it:      curl -fsSL https://foremerge.com/install.sh | sh\n2. Initialize:      foremerge init\n3. Wire this client and any others in use: foremerge setup all\n4. Register the check I should be validated against, for example:\n                    foremerge checks set test -- cargo test --all-targets\n5. Confirm:         foremerge doctor --client all\n\nThen read the Foremerge skill that step 3 installed for this client and follow\nit from now on: publish your intent with semantic scopes before editing, claim\nthe scope, and check for conflicts before you start.\n```\n\nAdjust step 4 to whatever this repository's real test command is. Step 3 asks the client to enable an MCP server, so it will prompt you before doing so. The Codex registration is user level, but one registration serves every repository: start Codex inside the repository you want it to coordinate.\n\nYou need a recent Git and `jq`\n\n. Install a prebuilt, checksum-verified release\nbinary (macOS and Linux; the script installs to `~/.local/bin`\n\n):\n\n```\ncurl -fsSL https://foremerge.com/install.sh | sh\n```\n\nTip\n\n**Two commands, one program.** This installs `foremerge`\n\nand `fmg`\n\n, the same\nbinary under a shorter name, so `fmg status`\n\nand `foremerge status`\n\ndo the\nsame thing. Examples below spell out `foremerge`\n\n; type whichever you prefer.\n\nOr build from source with Rust 1.85+: `cargo install --locked --git https://github.com/naw103/foremerge foremerge`\n\n, or `cargo install --locked --path .`\n\nfrom a checkout. Windows binaries are on the\n[releases page](https://github.com/naw103/foremerge/releases). To update,\nre-run the installer. Then, inside the repository you want to coordinate:\n\n```\nforemerge init\nforemerge doctor\n```\n\nThe installer, the release archives and `cargo install`\n\nall carry both names\nfrom 0.4.0 onward. If something else on your PATH already answers to `fmg`\n\n, the\ninstaller leaves it alone and says so rather than shadowing it.\n\nInstall the native skill and MCP entry for any clients used in this repository, then define the trusted checks agents may request by name:\n\n```\nforemerge setup all\nforemerge checks set test -- cargo test --all-targets\nforemerge doctor --client all\n```\n\nAcceptance is verification-gated: Foremerge runs the check itself rather than taking an agent's word for it. Pick a check that is fast and that would actually catch a broken handoff, such as a build or a typecheck, rather than a full CI suite; this gate decides whether other agents may treat the work as done, and it does not replace CI. If this repository has nothing meaningful to verify, say so once rather than registering a check that always passes:\n\n```\nforemerge checks policy advisory\n```\n\nWork accepted that way is recorded as `UNVERIFIED`\n\nwith the reason, so the audit\ntrail never implies a check ran when none did. `foremerge doctor`\n\nreports\nwhether the registered checks can actually run here, which matters in agent\nworktrees, because dependency directories are usually gitignored and\n`git worktree add`\n\nwill not create them.\n\nUse `setup codex`\n\n, `setup claude`\n\n, or `setup cursor`\n\nfor one client. Setup\npreserves unrelated configuration (including key order in project MCP JSON).\nUpgrading Foremerge refreshes its own unedited skill file in place, but a skill\nfile you edited, or a differing Foremerge MCP entry, is never replaced unless\nyou explicitly pass `--force`\n\n. `setup all`\n\nattempts every client and reports each\nresult, exiting nonzero if any failed. The Codex MCP registration is user-level\nand serves every repository, resolved from the directory Codex is started in;\nsee [agent client setup](/naw103/foremerge/blob/main/docs/agent-clients.md).\n\n`init`\n\ncreates local coordination state under the repository's Git common\ndirectory. It does not change tracked files. The following no-worktree sessions\nare enough to exercise pre-code detection; real coding agents should register\ntheir isolated worktrees and actual model identifiers.\n\n```\nSTRIPE_AGENT=$(\n  foremerge --json agent register \\\n    --name stripe-agent \\\n    --no-worktree |\n  jq -er '.data.id'\n)\n\nSTRIPE_RESULT=$(\n  foremerge --json intent publish \\\n    --agent \"$STRIPE_AGENT\" \\\n    --task \"modernize-payments\" \\\n    --summary \"Replace PaymentService with StripePaymentService\" \\\n    --scope symbol:PaymentService=replace\n)\nSTRIPE_INTENT=$(printf '%s\\n' \"$STRIPE_RESULT\" | jq -er '.data.intent.id')\n\nPAYPAL_AGENT=$(\n  foremerge --json agent register \\\n    --name paypal-agent \\\n    --no-worktree |\n  jq -er '.data.id'\n)\n\nPAYPAL_RESULT=$(\n  foremerge --json intent publish \\\n    --agent \"$PAYPAL_AGENT\" \\\n    --task \"add-paypal\" \\\n    --summary \"Add PayPal support to PaymentService\" \\\n    --scope symbol:PaymentService=extend\n)\nPAYPAL_INTENT=$(printf '%s\\n' \"$PAYPAL_RESULT\" | jq -er '.data.intent.id')\n\nprintf '%s\\n' \"$PAYPAL_RESULT\" |\n  jq '.data.conflicts[] | {kind, severity, scope, explanation, suggestion}'\n\nprintf '%s\\n' \"$PAYPAL_RESULT\" |\n  jq '.data.related_work[] | {agent, summary, asserted, overlap}'\n```\n\nThe first command prints the live finding from your local run. The second\nprints `related_work`\n\n: the other agent's intent and every overlapping scope\nwith both declared operations. Foremerge states what overlaps; you decide what\nit means and record that with `foremerge assess record`\n\n. No files need to\nchange first. Inspect the captured, clearly labeled transcript in\n[ examples/terminal-session.txt](/naw103/foremerge/blob/main/examples/terminal-session.txt).\n\nClaims add ownership context without blocking either agent:\n\n```\nforemerge --json work claim \\\n  --agent \"$STRIPE_AGENT\" \\\n  --intent \"$STRIPE_INTENT\" \\\n  --scope symbol:PaymentService \\\n  --reason \"Changing the provider boundary\" >/dev/null\n\nforemerge --json work claim \\\n  --agent \"$PAYPAL_AGENT\" \\\n  --intent \"$PAYPAL_INTENT\" \\\n  --scope symbol:PaymentService \\\n  --reason \"Adding another provider\" |\n  jq '.data | {advisory_only, warnings}'\n\nforemerge --json work query --scope symbol:PaymentService |\n  jq '.data[] | {agent: .agent.name, intent: .intent.summary, open_conflicts}'\n```\n\nBoth claims succeed. The second response includes an overlap warning because a claim is a leased advisory, never exclusive ownership.\n\n```\n  coding agent A                                  coding agent B\n        |                                               |\n  isolated worktree A                            isolated worktree B\n        |                                               |\n        +--------- semantic events, not edits ----------+\n                              |\n                    CLI / MCP / JSON API\n                              |\n                     Foremerge service\n                    /        |        \\\n       SQLite coordination   git CLI   validation argv\n       in <git-common-dir>       |           |\n                    \\         Git repository /\n                     durable commits and refs\n```\n\nEvery frontend uses the same service and store. The semantic graph is:\n\n```\nAgent → Task → Intent → Claim → Symbol → Dependency\n      → ChangeSet → Test → Result → Decision → Provenance\n```\n\nMutations update typed SQLite projections, materialize graph edges, and append a hash-chained semantic event in one transaction. The log is useful tamper evidence; it is not a remote identity signature or distributed consensus.\n\nForemerge resolves the Git common directory and stores its default database at:\n\n```\n<git-common-dir>/foremerge/state.sqlite3\n```\n\nLinked worktrees share that common directory even though their checked-out files are separate. Create a worktree with Foremerge's thin wrapper around stock Git:\n\n```\nforemerge worktree create \\\n  --branch agent/paypal \\\n  --path ../payments-paypal \\\n  --base HEAD\n\nforemerge --cwd ../payments-paypal --json agent register \\\n  --name paypal-agent \\\n  --model \"$ACTUAL_MODEL_ID\"\n```\n\nAnother worktree in the same repository sees the registered agent and its\nintents immediately. You can override storage with `--database PATH`\n\nor\n`FOREMERGE_DB`\n\n, but every local agent must point at the same database to share\nstate. The MVP does not replicate SQLite across machines; do not infer\ndistributed safety from a network-mounted database.\n\nForemerge snapshots Git state for ChangeSet fingerprints and accepted refs. It does not automatically merge, rebase, cherry-pick, push, or update a target branch.\n\n```\nINTENT ─claim→ CLAIMED ─start→ IN_PROGRESS ─publish→ PROVISIONAL\n       ─validate current fingerprint→ VALIDATED\n       ─accept gates→ ACCEPTED ─record Git ref→ COMMITTED\n```\n\nSupported scope kinds are:\n\n```\nsymbol api schema config infra test migration env file component contract domain\n```\n\nPublish the narrowest useful semantic scope. File paths alone miss API, configuration, schema, infrastructure, and cross-language collisions.\n\nCommon commands:\n\n| Boundary | Command |\n|---|---|\n| Register provenance | `foremerge agent register --name NAME --model MODEL` |\n| Publish intent | `foremerge intent publish --agent ID --task TASK --summary TEXT --scope KIND:KEY=OPERATION` |\n| Claim scope | `foremerge work claim --agent ID --intent ID --scope KIND:KEY` |\n| Start implementation | `foremerge work start INTENT_ID --agent AGENT_ID` |\n| Ask who is changing it | `foremerge work query --scope KIND:KEY` |\n| See what every agent is doing | `foremerge status` |\n| Preflight a plan | `foremerge conflicts check --intent TEXT --scope KIND:KEY=OPERATION` |\n| Record what you concluded | `foremerge assess record --agent ID --intent ID --related-intent-id ID --verdict V --rationale TEXT --action A` |\n| Send coordination | `foremerge coordinate send --from ID --to ID --message TEXT` |\n| Watch semantic events | `foremerge work watch --after-seq 0` |\n\nRun `foremerge <command> --help`\n\nfor the complete current flags. Global flags\nsuch as `--json`\n\n, `--cwd`\n\n, and `--database`\n\nmay appear before or after\nsubcommands.\n\nA ChangeSet captures the agent/model, task and intent, affected\nfiles/symbols/contracts, dependencies, implementation summary, reported tests,\ndecisions, provenance, worktree, fingerprint, status, and Git ref.\nThe accepted candidate and its later landing commit are retained separately as\n`accepted_commit`\n\nand `integration_commit`\n\n.\n\nThe honest integration order is:\n\n- Publish intent, claim semantic scope, and mark implementation in progress.\n- Work and commit on the isolated agent branch.\n- Publish a ChangeSet for that clean candidate.\n- Ask Foremerge to execute validation against its exact fingerprint.\n- Resolve high conflicts, then accept the still-clean, still-validated ref.\n- Integrate with ordinary Git or a pull request.\n- Record the durable integration commit in Foremerge.\n\n```\nforemerge work claim \\\n  --agent \"$AGENT_ID\" \\\n  --intent \"$INTENT_ID\" \\\n  --scope component:payments\nforemerge work start \"$INTENT_ID\" --agent \"$AGENT_ID\"\n\n# Implement the change and commit it on this isolated branch before publishing.\nCHANGESET_ID=$(\n  foremerge --json changeset publish \\\n    --agent \"$AGENT_ID\" \\\n    --intent \"$INTENT_ID\" \\\n    --summary \"Introduce PaymentProvider and StripePaymentProvider\" \\\n    --file src/payments.rs \\\n    --symbol PaymentProvider \\\n    --symbol StripePaymentProvider \\\n    --contract payment-provider \\\n    --provenance-json '{\"source\":\"coding-agent\"}' \\\n    --git-ref HEAD \\\n    --worktree \"$PWD\" |\n  jq -er '.data.id'\n)\n\nforemerge changeset validate \"$CHANGESET_ID\" \\\n  --worktree \"$PWD\" \\\n  -- cargo test --all-targets\n\nforemerge changeset accept \"$CHANGESET_ID\" --git-ref HEAD\n\n# Integrate with ordinary Git, then record the commit that actually landed.\nforemerge changeset commit \"$CHANGESET_ID\" --git-ref main\n```\n\nAgent-reported `--reported-test COMMAND=STATUS`\n\nvalues are provenance only.\nThey do not satisfy acceptance. Foremerge-owned validation records the command\nargument vector, exit status, output, duration, and candidate fingerprint. Any\ndetected change after validation makes that attempt non-authoritative, but its\noutput and changed-path diagnostic remain queryable with `changeset attempts`\n\n.\n\nFor trusted checks that generate disposable untracked output, an operator may set exact or directory-prefix rules without changing tracked files:\n\n```\nforemerge validation-exclusions set \\\n  --path coverage.log \\\n  --path target/validation-reports/\n```\n\nThe normalized policy digest is part of the candidate fingerprint, tracked\nchanges are never excludable, MCP cannot change the policy, and generated files\nmust still be removed before acceptance. See\n[ADR 0001](/naw103/foremerge/blob/main/docs/adr/0001-validation-exclusion-rules.md).\n\nAcceptance also requires a clean worktree and no unresolved `HIGH`\n\nconflict,\nunless the caller deliberately uses the visible `--allow-high-conflicts`\n\noverride together with `--override-reason \"...\"`\n\n. Prefer resolving a conflict\nwith an explicit rationale. Acceptance creates\n`refs/foremerge/accepted/<changeset-id>`\n\n; it does not merge code.\n\nValidation commands run as trusted local code with your operating-system permissions. Foremerge does not sandbox them.\n\nRun `foremerge mcp`\n\nover stdio. MCP does not require the HTTP daemon; both are\nadapters over the same database.\n\n| Tool | Purpose |\n|---|---|\n`register_agent` |\nRecord agent, model, capabilities, and worktree provenance |\n`publish_intent` |\nAnnounce planned work, declare what it does to each scope, and receive conflicts plus related work to assess |\n`record_assessment` |\nRecord what you concluded about one related intent and what you will do |\n`claim_work` |\nCreate leased advisory claims on semantic scopes |\n`query_work` |\nFind agents, intents, claims, ChangeSets, and conflicts |\n`check_conflicts` |\nCheck a published or provisional intent before code changes |\n`publish_changeset` |\nRecord implementation, tests, decisions, and Git provenance |\n`coordinate_with_agent` |\nSend a durable message linked to a conflict or ChangeSet |\n`start_work` |\nAdvance claimed work into implementation |\n`resolve_conflict` |\nRecord an audited resolution for a durable conflict |\n`run_verification` |\nRun a trusted repository check by name, never raw MCP argv |\n`accept_changeset` |\nApply final conflict, dependency, validation, and Git gates |\n`record_commit` |\nRecord the actual Git integration commit |\n`discard_work` |\nPreserve abandoned work while releasing claims and blockers |\n`list_agents` |\nRead registered agent provenance |\n`get_intent` |\nRead one intent and current conflict snapshot |\n`get_changeset` |\nRead one ChangeSet and Git/provenance state |\n`status` |\nRead one consistent coordinator status snapshot |\n\nStart from the valid minimal config in\n[ examples/mcp-config.json](/naw103/foremerge/blob/main/examples/mcp-config.json). It assumes the client\nlaunches\n\n`foremerge`\n\nwith the repository as its working directory. Clients\nwithout a repository working-directory setting should pass an absolute\n`--database`\n\nbefore `mcp`\n\n; derive the Git common directory instead of assuming\nthat a linked worktree's `.git`\n\nis a directory.See [agent client setup](/naw103/foremerge/blob/main/docs/agent-clients.md) for the installer, native skill\nlocations, client-specific MCP files, diagnostics, and safe replacement rules.\nSee [MCP setup](/naw103/foremerge/blob/main/docs/mcp-setup.md) for transport behavior, schemas, named checks,\nexample inputs, and multi-worktree configuration.\n\nSource clones include equivalent skills in `.codex/skills`\n\n, `.claude/skills`\n\n,\nand `.cursor/skills`\n\n, plus portable Claude and Cursor MCP templates. A Cargo\ninstallation embeds the canonical skill so `foremerge setup`\n\ncan install it\ninto another repository without copying this source tree.\n\nThe daemon defaults to authenticated loopback HTTP on\n`http://127.0.0.1:47811`\n\n. `init`\n\ncreates a bearer token with private file\npermissions where the platform supports them.\n\nIn one terminal:\n\n```\nforemerge daemon\n```\n\nIn another terminal, read the token path from Foremerge rather than guessing it:\n\n```\nexport FOREMERGE_URL=http://127.0.0.1:47811\nTOKEN_FILE=$(foremerge --json init | jq -er '.data.token_file')\nFOREMERGE_TOKEN=$(tr -d '\\r\\n' < \"$TOKEN_FILE\")\n\ncurl --fail --silent --show-error \\\n  --header \"Authorization: Bearer $FOREMERGE_TOKEN\" \\\n  --get \"$FOREMERGE_URL/v1/work\" \\\n  --data-urlencode 'scope=symbol:PaymentService' |\n  jq .\n```\n\nDo not print, commit, or share the token. `/healthz`\n\nis database-free process\nliveness and `/readyz`\n\nis a bounded non-waiting store probe; both are public.\nEvery `/v1`\n\nroute, including the paged event-chain audit, requires the token unless\nthe daemon was deliberately started with `--no-auth`\n\nfor a trusted local test.\nThe MVP refuses non-loopback binds and is not a hardened multi-tenant service.\n\nThe CLI escape hatch `foremerge request`\n\nreads local auth automatically. A\nrunnable curl walkthrough is in\n[ examples/api-requests.sh](/naw103/foremerge/blob/main/examples/api-requests.sh); the full route and error\nreference is\n\n[JSON API](/naw103/foremerge/blob/main/docs/json-api.md).\n\n- Conflict detection is deterministic and explainable, but heuristic. It can miss synonymous concepts and warn on compatible work.\n- Claims warn; they never lock files, symbols, or agents.\n- Passing validation proves only that the recorded command passed for the recorded fingerprint, not that the test plan was complete.\n- Git refs and process results are stronger evidence than self-reported model, prompt, or test prose.\n- The event chain detects changes inside the retained chain; it is not a signature, remote attestation, or external checkpoint.\n- Local SQLite is not shared-mode consensus, and the loopback bearer token is not a public deployment security model.\n- There are executable benchmark fixtures, a reproducible query harness, and a benchmark plan, but no published coordinated-vs-uncoordinated performance results yet.\n- Foremerge does not replace code review, architecture ownership, CI, security scanning, Git hosting rules, or backups.\n\nRead the complete [limitations and trust model](/naw103/foremerge/blob/main/docs/limitations.md) before\nusing Foremerge as an integration gate.\n\n| Document | What it answers |\n|---|---|\n|\n\n[Protocol](/naw103/foremerge/blob/main/docs/protocol.md)[State model](/naw103/foremerge/blob/main/docs/state-model.md)[Conflict detection](/naw103/foremerge/blob/main/docs/conflict-detection.md)[Git integration](/naw103/foremerge/blob/main/docs/git-integration.md)[Agent clients](/naw103/foremerge/blob/main/docs/agent-clients.md)[MCP setup](/naw103/foremerge/blob/main/docs/mcp-setup.md)[JSON API](/naw103/foremerge/blob/main/docs/json-api.md)[OpenAPI schema](/naw103/foremerge/blob/main/docs/openapi.yaml)[Benchmark plan](/naw103/foremerge/blob/main/docs/benchmark-plan.md)[Validation exclusion ADR](/naw103/foremerge/blob/main/docs/adr/0001-validation-exclusion-rules.md)[Roadmap](/naw103/foremerge/blob/main/docs/roadmap.md)[Limitations](/naw103/foremerge/blob/main/docs/limitations.md)[Brand](/naw103/foremerge/blob/main/docs/brand.md)Also see the [changelog](/naw103/foremerge/blob/main/CHANGELOG.md), [security policy](/naw103/foremerge/blob/main/SECURITY.md), and\n[code of conduct](/naw103/foremerge/blob/main/CODE_OF_CONDUCT.md).\n\nContributions are welcome, especially protocol feedback on scope vocabulary,\nconflict evidence, ChangeSet provenance, and verification policy. Read\n[CONTRIBUTING.md](/naw103/foremerge/blob/main/CONTRIBUTING.md), then run the complete local gate:\n\n```\nmake verify\n```\n\nForemerge is licensed under the [Apache License 2.0](/naw103/foremerge/blob/main/LICENSE).", "url": "https://wpnews.pro/news/foremerge", "canonical_source": "https://github.com/naw103/foremerge", "published_at": "2026-08-28 19:34:36+00:00", "updated_at": "2026-08-28 19:48:46.539940+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents"], "entities": ["Foremerge", "Git", "Claude Code", "Codex", "Cursor", "StripePaymentService", "PaymentService"], "alternates": {"html": "https://wpnews.pro/news/foremerge", "markdown": "https://wpnews.pro/news/foremerge.md", "text": "https://wpnews.pro/news/foremerge.txt", "jsonld": "https://wpnews.pro/news/foremerge.jsonld"}}