1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# magi competing on its own repository.
#
# **Only what is peculiar to this checkout lives here.** The roster, the seat
# assignment, the shape of a run and the update policy moved to the machine
# layer (`<config_dir>/magi/config.toml`), because none of them are facts about
# this repository: they are facts about which agent CLIs are installed and what
# the operator is willing to spend. Stating them once there is the point of
# having layers, and it keeps this file to the things a different machine would
# still need to be told.
#
# What that leaves, and why each one has to be here:
#
# - `[verify]` runs `cargo`. A repository that is not Rust cannot inherit it.
# - `[merge] base` names this repository's branch, and is required at all
# because of how this checkout is set up (see below).
# - `[prompts]` are this project's conventions.
#
# Note that an array may be declared in exactly one layer
# (`Config::refuse_split_arrays`), so `[verify]`'s arrays being here is also
# why the roster's arrays are *only* over there.
#
# Rendered by teravars. Tera braces are live everywhere in this file, but
# comments are stripped before Tera sees them (teravars >= 0.2.2), so a comment
# may quote `{{ ... }}` freely.
[]
# Shared build cache for the verification commands. Override per machine with
# MAGI_CACHE. Lives beside its only consumer: `[vars]` is rendered per file, so
# a value used by this file's templates is stated in this file.
= "{{ env.MAGI_CACHE | default(value='/tmp') }}"
[]
# 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.
= ["CARGO_TARGET_DIR={{ vars.cache }}/magi-target cargo test --locked --all-targets"]
# Same gate as CI and the pre-push hook.
= ["CARGO_TARGET_DIR={{ vars.cache }}/magi-target cargo make check"]
[]
= "pr"
# `base` is set explicitly because this is a jj-colocated checkout: jj keeps
# git's HEAD detached at the working-copy commit, so the `git symbolic-ref
# HEAD` fallback in `git::current_branch` would fail here. Teaching magi to
# read the jj bookmark instead is a real feature, not a workaround — tracked
# as its own competition. That fallback only runs when `base` is unset,
# though: with `base` given, `config.merge.base` wins over the fallback no
# matter what `mode` is, so `mode = "pr"` here never reads HEAD at all — the
# `Pr` arm in `land.rs` just pushes the winner's worktree and opens a PR
# against `state.base_branch`. The only mode that depends on HEAD is
# `mode = "local"`, which merges directly in the primary worktree and needs
# to confirm the checked-out branch matches `base` first. Run
# 20260903-134458-ec12 landed this repository's own PR with `--mode pr` as a
# CLI override, confirming this in practice.
= "main"
# This repository's own GitHub ruleset on `main` requires linear history
# ("must not contain merge commits"), so the manual-merge guidance `magi
# show` prints must not be `git merge --no-ff` — that push is rejected for
# anyone without bypass rights. `squash` matches what `[graph] land` already
# runs for `mode = "pr"` (see `land.rs`'s module doc).
= "squash"
[]
# `cargo make check` on this repository takes ~1450s on a warm cache on this
# machine — measured, not guessed — against a `timeout_review` default of
# 1200s, which `timeout_verify` inherits when it is unset. That made the gate
# fail structurally rather than because anything was wrong: run
# 20260915-215701-c1c0 and run 20260915-225246-6805 both reached
# `verify.gate` with two approvals and a green e2e, then timed out at 1200s.
# The e2e leg has the same problem for a different reason: `verify.e2e` is
# `cargo test --all-targets`, which is the same build plus the same suite.
#
# Stated here rather than on the machine layer on purpose: how long this
# repository's own gate takes is a fact about this repository (a Windows box
# building several agent worktrees at once), not about the operator's
# preferences. 2400s is ~1.6x the measured time, which is headroom for a
# busier machine rather than a licence to hang.
= 2400
# 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.
[]
= """
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.
Full verification is parent-owned: magi runs `cargo test --locked --all-targets` \
and `cargo make check` itself, once a round has no blocking findings left and \
again before landing. Do not re-run the full suite or the full gate yourself — \
a focused `cargo check` or a targeted `cargo test <name>` for what you touched \
is enough. Whenever you do build or test locally, set \
`RUSTUP_TOOLCHAIN=stable`: the environment here pins an older toolchain than CI \
uses, so a lint that fails CI is invisible without it.
"""
= """
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.
"""