magi-cli 0.4.0

Blind multi-agent implementation competition: N agents implement, M judges rank blind, deliberate, vote privately, winner survives double review + E2E gate
Documentation
# magi competing on its own repository.
#
# Rendered by teravars. Note that Tera braces are live everywhere in this file,
# comments included.
#
# Gemini CLI is absent on purpose: Google retired the standalone client for
# individual accounts, so the roster is claude (two models) plus opencode. Add
# an `agy` entry once Antigravity's plan is worth a seat here.

[vars]
# Shared build cache for the verification commands. Override per machine with
# MAGI_CACHE.
cache = "{{ env.MAGI_CACHE | default(value='/tmp') }}"

[[agents]]
id = "opus"
kind = "claude"
model = "opus"

[[agents]]
id = "sonnet"
kind = "claude"
model = "sonnet"

[[agents]]
id = "oc"
kind = "opencode"

[[agents]]
id = "agy"
kind = "antigravity"

# Seat assignment is a cost decision, and the numbers are measured, not guessed.
# One implement seat on this repo cost $12.09 on opus against $6.95 on sonnet
# for the same task — 1.7x — while `oc` reported $0.00. The driver is internal
# tool-loop iterations (111 and 134 turns respectively): every turn re-reads the
# cached context, so cache_read ends up ~= turns * context size, and the
# implement node is where the turns are.
#
# Hence: the expensive model never implements. opus judges instead, which is a
# handful of turns, and the free CLIs carry the implementation load.
[roles]
# `agy` implements here, and the reason is worth writing down because it was
# twice diagnosed wrongly. It routinely uses the whole 3600s implement budget
# while its own process shows almost no CPU, and `impl-*.out` comes back empty -
# which reads exactly like a hung agent that produced nothing. It is not. The
# work happens in child processes, and the seat leaves a finished implementation
# in its worktree without committing it or reporting a usable JSON reply: run
# 01c2's candidate A was 7 files and a 35 KB patch, recorded as "rescued an
# uncommitted tree". What agy fails at is finishing the conversation, not the
# task.
#
# The cost is real - the wave ends up as slow as the timeout rather than as slow
# as its slowest reporting seat - but the candidate competes, so dropping the
# seat would throw away a working implementation. Fix the reporting, not the
# roster.
implementers = ["oc", "agy", "sonnet"]
# Rotated so no judge sits on its own candidate: opus/oc/agy against oc/agy/sonnet.
judges = ["opus", "oc", "agy"]
reviewers = ["sonnet", "oc"]
# Not the winner's own author by default: the fixer would inherit the
# implementer's 100-turn session, and with it the whole accumulated cache-read
# bill.
fixer = "sonnet"

[graph]
candidates = 3
judges = 3
deliberate_rounds = 1
reviewers = 2
review_rounds = 3
max_parallel = 3
language = "ja"
sessions = true

[verify]
# The real-machine leg, run in the winner's worktree once per review round.
#
# CARGO_TARGET_DIR is shared on purpose: each candidate worktree would otherwise
# compile this crate from scratch, which is by far the slowest thing in a run on
# a Rust repo (minutes, against ~90 s of agent latency per node). Only the
# winner's worktree runs these commands, and only one at a time, so nothing
# contends on cargo's lock.
e2e = ["CARGO_TARGET_DIR={{ vars.cache }}/magi-target cargo test --locked --all-targets"]
# Same gate as CI and the pre-push hook.
gate = ["CARGO_TARGET_DIR={{ vars.cache }}/magi-target cargo make check"]

[merge]
mode = "none"
# Required here, and in every jj-colocated repo: jj keeps git's HEAD detached at
# the working-copy commit, so magi cannot infer the base branch from
# `git symbolic-ref HEAD`. Teaching magi to read the jj bookmark instead is a
# real feature, not a workaround — tracked as its own competition.
base = "main"

[update]
mode = "notify"

# Project conventions appended to the node prompts, never merged into them.
# Repository-wide context lives in AGENTS.md, which every agent already reads
# from the checkout; these are the things a magi *node* needs to know.
[prompts]
all = """
This repository uses jj (Jujutsu) with a colocated git repo. `git commit` works \
in a candidate worktree and is what magi expects, but never run `jj` commands \
and never touch the main working copy.
Verify with `RUSTUP_TOOLCHAIN=stable cargo make check`: the environment here \
pins an older toolchain than CI uses, so a lint that fails CI is invisible \
without it.
"""
review = """
Formatting is not a finding: `cargo fmt` runs in the gate. Spend the round on \
correctness, on invariants the code claims and does not keep, and on tests that \
assert plumbing rather than behaviour.
"""