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/fusioncycle runs end-to-end. It's young — flags and ergonomics will change — but the core mechanism is the point, not a finished product.
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.
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.
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>Point your agent at this and it can install fusion itself:
Clone
https://github.com/malakhov-dmitrii/fusion, run./install.shfrom the repo root, then readREADME.md→ "Providers & auth" and make sure the CLIs for my chosen roster are authenticated. Default roster isclaude codex deepseek. Confirm/fusionis available and report back.
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).
Everything is configured by environment variables — no config files:
| Var | Meaning | Default |
|---|---|---|
FUSION_ROSTER |
participant list | claude codex deepseek |
FUSION_MODEL_DEEPSEEK |
model for the deepseek alias |
opencode-go/deepseek-v4-pro |
FUSION_MODEL_CLAUDE |
--model for claude |
CLI default |
FUSION_TIMEOUT |
per-call timeout (s) | 300 |
FUSION_GUARD_REPO |
repo the write-guard watches | $PWD |
FUSION_SCRATCH |
scratch dir for model writes | /tmp/fusion-scratch |
Set these in your shell profile (~/.zshrc / ~/.bashrc) for a default roster, or prefix one run: FUSION_ROSTER="…" /fusion ….
A participant is claude[:model] · codex · opencode:<model> · deepseek (alias). So you can run a fully opencode-only ensemble of three different families:
export FUSION_ROSTER="opencode:opencode-go/glm-5 opencode:opencode-go/kimi-k2.7-code opencode:opencode-go/deepseek-v4-pro"/fusion <task> --dir <target-repo> [--depth lite|full]
Or drive the harness directly (no host needed):
bash skills/fusion/fusion.sh fan draft prompt.txt runs/r1 claude codex deepseek
bash skills/fusion/fusion.sh cross-verify codex runs/r1/draft/codex.md runs/r1
bash skills/fusion/fusion.sh collect runs/r1
bash skills/fusion/fusion.sh --helpArtifacts land in <target-repo>/.fusion/runs/<timestamp>/: a *-plan.md (the consensus plan, with ranked assumptions and explicit operator-unknowns) and a *-debate.md (the trail).
The harness is plain bash + CLI adapters, so the orchestrator host is interchangeable. install.sh links the skill into ~/.claude/skills/ (Claude Code, invoked as /fusion) and/or ~/.codex/skills/ (Codex reads SKILL.md). The only host-specific step is the operator interview — AskUserQuestion in Claude Code, a plain text question elsewhere.
Claude Code can also load the repo as a plugin (the .claude-plugin/plugin.json manifest) via a plugin marketplace; the install.sh symlink is just the simplest path.
- Plan-only. fusion writes plans, never code. Hand the plan to an executor (e.g.
forge,improve execute). - Batch, not interactive. A full run is multiple models × rounds — expect minutes, not seconds.
- Costs more than one model. Several models × rounds — reach for it when being wrong is expensive (architecture, migrations, irreversible or hard-to-reverse calls), not for quick edits.
- Provider drift. CLI flags and quotas change. Codex in particular has a usage quota and a strict
config.toml(a badservice_tierwill breakcodex exec).
The full design, the decision log, and the implementation plan (themselves produced and reviewed through fusion) live in docs/design/.
MIT © Dmitrii Malakhov