fusion

A multi-model consensus planner for coding agents. Claude, Codex, and DeepSeek (or any models you reach through opencode — GLM, Kimi, MiniMax…) each draft a plan independently, cross-verify one another ("idiot-test"), and must reach consensus before a single plan is emitted. The output is a plan — fusion never touches your code.
Status: v0.1, experimental. The harness (fan / cross-verify / collect / cleanup) is verified working across Claude, Codex, and opencode (incl. an opencode-only roster of GLM + Kimi + DeepSeek), and the full /fusion cycle runs end-to-end. It's young — flags and ergonomics will change — but the core mechanism is the point, not a finished product.
Why
One frontier model has one set of blind spots. Three different model families, forced to debate and agree, cover for each other — the "fusion beats frontier" idea, applied to planning instead of answers. fusion makes the disagreement explicit and refuses to emit a plan until the models actually converge (or escalates the fork to you).
This is not a marginal quality bump. A single agent routinely hallucinates specifics — a flag, an API, a cost number — believes its own fiction, and ships something that does not work. The cross-verify rotation and the hard consensus gate exist to catch exactly that. fusion's own design and plan (in docs/) were built this way, and the process caught real errors a solo agent had already written down as fact: a fabricated cost figure, a transport that did not survive a spike, a "read-only writes" contradiction, a missing .gitignore. That gap — between a grounded plan and confident fiction — is the whole point.
How it works
brief (raw repo context, not a Claude summary)
│
▼
fan ──► claude ┐
codex │ each drafts a full plan, independently, challenging
deepseek ┘ "don't build it / simpler / depends on future / scenarios"
│
▼
cross-verify (rotation — nobody grades themselves)
claude → codex's plan, codex → deepseek's, deepseek → claude's
each re-checks every claim INSTRUMENTALLY (grep/read/counter-example)
│
▼
consensus gate (hard: all agree on material axes, no majority override)
split survives → spike the assumption → re-discuss → operator breaks the tie
│
▼
synthesize → plan.md (+ debate.md: who proposed what, how it resolved)
Two invariants make it trustworthy:
- Hard consensus gate. No plan is emitted until every available model agrees on the material axes (architecture, approach, key assumptions). A 2-of-3 majority never overrides a dissenter; an unresolved fork goes to you (
decision: operator_decision), never silently averaged.
- Write isolation. Planning is read-only. A git guard snapshots your repo before and after every fan; if a model mutates a tracked file, the run stops (
write_leak: true).
See a real run in examples/selftest-plan.md.
Quickstart
git clone https://github.com/malakhov-dmitrii/fusion fusion && cd fusion
./install.sh # detects Claude Code / Codex, links the skill
# authenticate the providers in your roster (below), then:
/fusion <task> --dir <path-to-your-repo>
Installing with your coding agent
Point your agent at this and it can install fusion itself:
Clone https://github.com/malakhov-dmitrii/fusion, run ./install.sh from the repo root, then read README.md →
"Providers & auth" and make sure the CLIs for my chosen roster are authenticated.
Default roster is claude codex deepseek. Confirm /fusion is available and report back.
Requirements & providers
You only need the CLIs for the models in your roster.
| Participant | CLI | Auth | Smoke test |
|---|
| Claude | claude | Claude Code login or ANTHROPIC_API_KEY | claude -p "say OK" |
| Codex / GPT | codex | codex login (ChatGPT) or OPENAI_API_KEY | codex exec "say OK" |
| GLM / Kimi / DeepSeek / MiniMax… | opencode | opencode auth login (OpenCode Go / OpenRouter) | opencode run -m opencode-go/glm-5 "say OK" |
git, bash, shasum are assumed. If a participant's CLI is missing or unauthenticated, fusion drops it and runs degraded (and labels the output as such — it won't pretend two models are three).
Models & rosters
Everything is configured by environment variables — no config files: