A woman reviewing a wall of green terminal checkmarks beside a heavy bag in magenta haze.

Ringer.

Multi-agent swarms are the most powerful pattern in AI right now — and the way most people run them, every worker burns frontier tokens doing mechanical work. Ringer splits the roles: your best model writes the specs and reviews the results, while a swarm of inexpensive workers does the implementation in parallel. It ships with three worker lanes — Codex CLI, Grok Build CLI, and OpenCode running any OpenRouter model — and anything else with a CLI is a config block, not a migration.

You won't type any of it: every step in this guide is a prompt you hand to Claude Code — the agent Ringer was designed to be run from, with a frontier Claude model in the orchestrator seat. The first prompt alone carries the whole setup: the demo swarm, the cheap worker lanes, your first real manifest, all watched live in Ringside. Your frontier budget goes back to thinking.

July 7, 2026 Last verified3 minutes To a verified swarmExit codes Decide what passed
01First verified swarm in about three minutes. Your agent does the typing.One prompt to Claude Code sets up everything this guide covers — the demo swarm, the cheap worker lanes, your first real manifest, the agent integration — one phase at a time, proving each step before the next.

Every copyable block in this guide is a prompt for Claude Code — Ringer is designed to run from it, with a frontier Claude model in the orchestrator seat while cheap workers do the typing. Other terminal agents can run these prompts, but never make your orchestrator its own worker lane: orchestrating from Codex CLI just to spawn Codex CLI workers defeats the entire split. Ringer runs on macOS and Linux (Windows works inside WSL) and needs Python 3.11+ plus one worker CLI signed in; your agent checks both and fixes what's missing.

Hand your agent the whole setup — it proves each step as it goes

You don't install Ringer — your agent does, and proves it the Ringer way: three demo workers build in parallel, every artifact is verified by executing it, and a verdict table prints. Then the same prompt keeps going: the cheap worker lanes, your first real manifest on your own work, and the agent integration, one phase at a time, asking before each. Paste it once; everything below this section is the why, not a checklist you have to come back for.

You do

Paste the prompt, approve commands as they go by, complete any sign-ins yourself, and answer the interview questions between phases.

The AI does

Checks prerequisites, clones and configures, runs the demo, wires the lanes you want, drafts and runs your first real manifest, and installs the agent integration — proving every step with an executed check.

Show the full prompt
<prompt>
  <task>
    Set up Ringer on this machine end to end: prove it works by running its built-in
    demo swarm, then walk me through the rest of the setup — cheap worker lanes,
    my first real manifest, the agent integration — pacing each step with me.
  </task>
  <context>
    Ringer is a single-file Python orchestrator that fans tasks out to cheap parallel
    worker agents and verifies every result by executing a check command. It is
    designed to be run from Claude Code: you are the orchestrator, and inexpensive
    worker CLIs do the typing.
    Repo: https://github.com/NateBJones-Projects/ringer — the README documents every
    manifest field, engine, and config option, and templates/ ships manifest
    skeletons. Read them as you go; they are the source of truth for anything this
    prompt doesn't carry.
    Treat this prompt as the whole setup guide: assume I will not read anything else.
    After each phase, tell me what I now have, what's possible next, and ask whether
    to continue.
  </context>
  <phases>
    <phase>1 — Prove it. Check python3 is 3.11 or newer (install a current Python via
    Homebrew if not — stock macOS is usually old). Check a worker CLI is installed and
    signed in — try codex --version (Codex is the demo's default worker); if none is
    present, install one and hand me the sign-in. Clone the repo, copy
    config.sample.toml to ~/.config/ringer/config.toml, and run ./ringer.py demo.
    Show me the verdict table and confirm Ringside opened in my browser, with its URL.</phase>
    <phase>2 — Cheap lanes. Offer to wire the worker lanes: OpenCode + OpenRouter
    (one key in front of virtually every pay-per-token model — I paste it into
    opencode auth login myself), and Grok Build if I hold a SuperGrok or X Premium
    Plus plan (browser OAuth, cost reported as included-in-plan). Prove every lane
    you set up with a one-task manifest whose check executes a real artifact.</phase>
    <phase>3 — Real work. Interview me: what small batch of real work do I want done?
    Draft swarm.json — 2-4 independent tasks, each with a self-contained spec, a
    check that verifies the artifact by executing it and prints WHY it fails when it
    fails, expect_files, and a one-sentence verified line saying what the check
    proves. Run ./ringer.py lint swarm.json and fix what it flags, then run it and
    walk me through the results in Ringside.</phase>
    <phase>4 — Make it stick. Run ./ringer.py install-agent so you reach for Ringer
    on your own when work is swarm-shaped, and tell me about ./ringer.py models —
    the scoreboard that turns my own pass rates into routing once history
    accumulates.</phase>
  </phases>
  <constraints>
    <constraint>Sign-ins are mine: pause and hand me the terminal or browser — never
    ask me to paste keys or credentials into chat, and never read them from files.</constraint>
    <constraint>One phase at a time. After each, summarize what I have, then ask
    before starting the next. If I stop early, tell me exactly what remains and that
    pasting this prompt again resumes from wherever we left off.</constraint>
  </constraints>
</prompt>
A stopwatch on a desk reflecting rows of green terminal checkmarks
02The check is the contract.Everything about a Ringer manifest is designed around one idea: you define done as an executable test, and the swarm has to earn it. Parallel agents report "done" with total confidence whether or not the thing works — so Ringer never reads the worker's summary. It runs your check against the artifact, and exit code zero is the only thing it believes.

The fields that matter

key names the task and its working directory. spec is the worker's prompt — write it as a self-contained brief, because it's also what anyone watching the dashboard reads as "what this agent was asked to do." check is a shell command run after the worker exits — exit 0 is PASS, anything else is FAIL. expect_files must exist and be non-empty for the task to pass — they're judged after the check runs, so a check is free to generate or export a deliverable itself — and they're harvested into the results page as clickable deliverables. verified is one plain-English sentence saying what the check proves. timeout_s kills runaways (default 900s). engine routes the task to a harness, and model picks which model that harness runs (next section). task_type tags what kind of work it is — that's the bucket the scoreboard in section 05 accumulates pass rates under. full_access unlocks nested sub-workers — a flagged worker can spawn its own parallel crew on cheap tokens — and must also be enabled in config, so nobody trips into it.

Have your agent write your next manifest

A manifest is just JSON: a name, a working directory, and a list of tasks — each one a spec (the worker's prompt), a check (any shell command — exit 0 means pass), the files you expect to exist, and one plain-English sentence saying what the check proves. The craft is in the checks: a check that prints WHY it fails is what makes the retry prompt smart. Your agent knows all of this once it reads the README — so point it at real work and let it draft.

You do

Tell it what small batch of real work you want done, and read the results page with it.

The AI does

Drafts the manifest, writes checks that fail loudly, lints it, runs it, and walks you through what passed and why.

<prompt>
  <task>
    Write my next Ringer manifest and run it.

1. Read README.md in my ringer clone for the manifest schema and check-writing guidance.
2. Interview me briefly: what small batch of real work do I want done? Aim for 2-4 independent tasks.
3. Write swarm.json: for each task, a self-contained spec, a check that verifies the artifact by executing it and prints WHY it fails when it fails, expect_files, and a one-sentence "verified" line saying what the check proves.
4. Run ./ringer.py lint swarm.json and fix everything it flags before spending a token.
5. Run ./ringer.py run swarm.json, then walk me through the results page in Ringside: what passed, how each check proved it, and what any retry did with the failure output.
  </task>
</prompt>

The full quickstart prompt already walked you through your first one — this is the standalone brief for every batch after.

Failures get one honest second chance

When a check fails or a worker times out, Ringer retries once — and injects the failure output into the retry prompt, so the worker sees exactly what broke instead of guessing. One retry, not an endless loop: if a task can't pass in two informed attempts, you want to know, because the spec is usually what's broken.

Parallel workers on one repo, without the collisions

Turn on worktrees mode and every task gets its own isolated git worktree of your repo — ten workers editing the same codebase with zero stepped-on toes. One footgun to respect: passing tasks get their worktrees removed, including anything written inside them. Write deliverables outside the worktree, or have your check copy artifacts out before it exits 0.

A row of identical heavy bags in a dark gym, each lit by its own overhead light
03Ships with Codex CLI, OpenCode, and Grok Build CLI. Anything else is one config block away.Ringer is deliberately not married to any worker model. Three worker lanes come ready out of the box — Codex CLI on your ChatGPT plan, Grok Build CLI on a SuperGrok or X Premium Plus plan, and OpenCode + OpenRouter for every pay-per-token model on the market. Wiring a lane up is your agent's job; the only steps it can't do for you are the sign-ins that belong to each tool.

An engine is a config block

Codex ships built in. Any other harness is a few lines of TOML in your config — the binary, an argument template, and optionally a regex that parses token usage out of its output. The shipped config.sample.toml carries verified blocks for Grok Build CLI and OpenCode, ready to uncomment — and OpenCode is the universal one: a single engine block with a {model} placeholder runs virtually any model behind one CLI. Set model_default in the config, override per task in the manifest.

Hand the lane setup to your agent

OpenRouter is one account and one API key in front of virtually every model on the market — GLM, Kimi, DeepSeek, whatever drops next week — and a few dollars of prepaid credit goes a long way at these rates. Grok Build is xAI's coding-agent CLI: if you already hold a SuperGrok or X Premium Plus plan, it's a worker lane with no per-token bill at all, and Ringer reports its cost as included in plan. Your agent wires up both lanes end to end. One rule survives the delegation: credentials never travel through the agent — each tool's own sign-in holds them (OpenCode keeps the key in its own auth store; Grok is browser OAuth), and you're the one who completes it.

You do

Paste your OpenRouter key into opencode auth login when the agent hands you the terminal, and finish Grok's browser OAuth if you hold the plan.

The AI does

Installs the CLIs, wires the engine blocks into your config, and proves each lane with a real verified run.

Show the full prompt
<prompt>
  <task>
    Set up Ringer's cheap worker lanes on this machine: OpenCode + OpenRouter, plus Grok Build if I have the plan for it.
  </task>
  <inputs_to_collect>
    <input>Whether I already have an OpenRouter account and API key.</input>
    <input>Whether I hold a SuperGrok or X Premium Plus plan.</input>
    <input>The absolute path of my ringer clone.</input>
  </inputs_to_collect>
  <requirements>
    <requirement>Install the OpenCode CLI if it's missing — pick the official method that fits this system and tell me which you chose before running it.</requirement>
    <requirement>Run opencode auth login, select OpenRouter, then pause and hand me the terminal so I can paste my API key myself. I'll create it at openrouter.ai/settings/keys.</requirement>
    <requirement>In ~/.config/ringer/config.toml, uncomment [engines.opencode] and set bin to the ABSOLUTE path of engines/opencode-sandboxed.sh inside my ringer clone. On Linux or WSL, point bin at the opencode binary itself instead — the sandbox wrapper is macOS-only.</requirement>
    <requirement>If I hold a SuperGrok or X Premium Plus plan: install Grok Build, run grok login, let me finish the OAuth in the browser, then uncomment [engines.grok].</requirement>
    <requirement>Prove every lane you set up: for each, write a one-task manifest whose check verifies a real artifact by executing it, run ./ringer.py run on it, and show me the PASS.</requirement>
  </requirements>
  <constraints>
    <constraint>Never ask me to paste an API key or credential into chat, and never read one out of a file. Sign-ins are mine; everything around them is yours.</constraint>
  </constraints>
</prompt>

Two models ride the Grok lane: grok-build for heavier work, and grok-composer-2.5-fast — the speed pick — as the default. The quickstart prompt offers this same setup in its phase 2.

Mix models inside a single swarm

engine and model are per-task fields. That means one manifest can send the gnarly refactor to your strongest worker, the test-writing sweep to the cheapest one, and a genuine bakeoff can run three different models on the same task — in the same run, on the same dashboard, under the same verification. The dashboard shows which model actually did each task's typing, so a bakeoff can't quietly run one model under three names. Cross-model isn't a migration project; it's a JSON field.

The safety rails travel with every engine

The invariants that make headless agents behave — stdin closed so they can't hang waiting for a keyboard, explicit sandbox flags so writes don't silently fail, process-group kills so timeouts actually kill, raw output in every log — are enforced by the orchestrator, not by the engine. Plug in a new model and it inherits all of them on day one.

Ringside in the browser: a finished demo run's results page showing three workers, each finished and checked, with deliverables and how each was verified
04Mission control, one tab over.A swarm you can't see is a swarm you don't trust. Ringside is a local web page — no install, no account, nothing leaves your machine — that your first run opens automatically and every later run reuses, instead of burying you in new tabs. One page shows the live results document, every agent working, and the full history of what past runs produced.

What you're looking at

The top of the page is the run's results document, updating live: what the job is, a progress bar of green and red rounds, and "The work" — every deliverable each worker has filed, with a plain-English line saying what the check proved and the check's raw output one click away. Below it, the agents: expand a round, click a worker, and you see the exact brief it was handed, which engine and model are doing the typing, and its live work stream — the agent actually thinking and working, not a spinner. Past runs stay in the library with every round versioned, so "what did the swarm make last Tuesday" is a dropdown, not an archaeology dig.

The state every other dashboard forgets

Finished and running are easy. Ringside also knows died — a swarm whose orchestrator vanished without finishing, detected by checking whether the process is actually still alive. Silent orchestrator death is the failure mode that turns "I thought it was running" into an hour of lost time, and it gets its own unmissable state.

Open it

There's nothing to install and nothing to do: the first run starts Ringside and opens the tab for you, and every run after that streams into the same tab instead of popping a new one. It's a local page served from your machine on 127.0.0.1; your specs, logs, and results never leave the building. (A native desktop build of Ringside exists as a v0.1.1 prototype for Windows and Linux on the release page, but the web dashboard is currently ahead of it — start there.)

Tab gone? ./ringer.py hud brings the page back any time, at http://127.0.0.1:8700 — or just ask your agent to open Ringside.

05Every attempt is data. The swarm gets better on evidence, not vibes.Ringer logs every worker attempt — pass, fail, timeout, retry — with its spec, engine, model, task type, duration, token count, and the raw check output. That log is the difference between a toy and a system that improves — and your agent can read it back to you on demand.

Everything lands in one local file

Out of the box, every attempt lands in a JSONL file on your machine — zero setup, no accounts, nothing leaves the building. Each row records which model did the typing, what kind of task it was, whether it passed on the first try, and what it cost in time and tokens. Failure rows are deliberately the most detailed: a failed attempt with its raw check output tells you which spec styles, engines, and task shapes actually work.

The scoreboard: your own pass rates, turned into routing

./ringer.py models turns that log into a per-model, per-task-type scoreboard, and first-try pass rate is the routing signal: which model to hand which kind of work, answered from your machine's own verified history instead of a leaderboard built on someone else's workload. Don't read it like a report — have your agent read it and hand you a policy.

<prompt>
  <task>
    Read my Ringer scoreboard and turn it into a routing policy.

1. In my ringer clone, run ./ringer.py models — and ./ringer.py models --open so I get the rendered page too.
2. For each task_type with real history, tell me which model should own it and why. First-try pass rate is the signal; cost is the tiebreaker.
3. Flag any bucket where the data is too thin to call, and what kind of run would fill it.
4. Finish with the exact "engine" and "model" lines to put in my next manifest.
  </task>
</prompt>

It watches the market and auditions the rookies

./ringer.py catalog keeps a local snapshot of every model on OpenRouter — prices, context sizes, and a change log of what arrived, what got cheaper, and what just went free (models genuinely do). Runs refresh it quietly in the background, at most once a day. Then models --explore splits your history into tiers — proven, on probation, and cheap untested candidates worth a look. The habit that compounds: hand one low-stakes task per swarm to a promising unknown, and let the receipts decide whether it gets promoted.

<prompt>
  <task>
    Find me a rookie worth auditioning.

1. In my ringer clone, run ./ringer.py catalog --changes and ./ringer.py catalog --free: what's new, what got cheaper, what's free right now.
2. Run ./ringer.py models --explore: which cheap models are proven, on probation, or untested in MY log.
3. Pick one promising untested model and make the case for it in two sentences.
4. Add one low-stakes task routed to it in my next manifest — the receipts decide whether it gets promoted.
  </task>
</prompt>

The flywheel this unlocks

When a new cheap model drops, you don't argue about whether it's ready — you audition it and read the pass rates. When a task class keeps failing, the eval rows show whether the spec, the engine, or the check is at fault. And because the log is yours, the answers are too: every user's workload is different, and a model that's proven in someone else's log is untested in yours until you've run it. Model choice stops being a debate and becomes a query. That's the quiet superpower: the expensive part of cross-model isn't wiring, it's knowing — and the log knows.

An empty boxing ring at night, a laptop glowing with terminal text on the apron
06Built by the pattern it implements.Ringer's origin story is its best proof. The specs were written and reviewed by one orchestrating model; the implementation was built by swarms of inexpensive workers; and the verification loop caught its own bugs before any human did.

One day, zero hand-written implementation

The orchestrator, the dashboard, and the native HUD were all implemented by cheap parallel workers from written specs, reviewed by a frontier model, in a single day. The tool's own verify stage caught its first three real bugs — a sandbox that silently blocked writes, a run-ID collision between same-second swarms, a state field that never serialized. Same-day field testing by an agent on a second machine produced four more fixes, merged within the hour. Every one of those lessons is now baked in, and nobody who downloads it pays that tuition again.

The four rules that cost real debugging hours

One: stdin is always closed — headless CLI agents hang forever waiting on a keyboard that isn't there. Two: sandbox mode is always explicit — defaults silently resolve to read-only in temp directories and every write fails without an error you'll see. Three: verification executes the artifact — an agent's own "done" is not evidence. Four: raw output only — logs carry verbatim worker output, never a summary, because anything that needs judgment should read the real data. You get all four for free, on every engine.

07Point your agent at the repo, keep your frontier budget for thinking.Ringer and Ringside are free to use, modify, and share — including inside your own commercial work. The one thing the license reserves is selling Ringer itself or a competing derivative; that right belongs to Nate Jones Media.

Everything is on GitHub — and it ships its own playbook

The repo is public, the README documents every manifest field and config option, and templates/ ships ready-made manifest skeletons for the patterns that work: review swarms, fix swarms, focus groups, model bakeoffs, research-with-proof. If you ran the quickstart, you already have all of it. The move that makes it stick: have your agent match those templates to the work you actually do — the first time a swarm of cheap workers hands you a stack of verified PASSes on your own backlog, the economics stop being an argument and start being your default.

<prompt>
  <task>
    Open templates/ in my ringer clone and walk me through the manifest skeletons it ships — review swarm, fix swarm, focus group, model bakeoff, research-with-proof.

Then interview me about the work I actually do most weeks, recommend the one template that fits it best, and adapt it into a manifest I could run this week. Lint it with ./ringer.py lint before you hand it to me.
  </task>
</prompt>

The repo: github.com/NateBJones-Projects/ringer — clone and demo are covered by the quickstart prompt in section 01.

Make your agent reach for it on its own

If an AI agent does your orchestrating, one more step matters: between swarms, agents drift back to invisible inline work, and reminders decay. install-agent ships the enforcement with the product — it installs the orchestrator playbook as a skill in Claude Code, the seat this guide has assumed all along, and registers two gentle hooks that notice swarm-shaped work happening outside a run and point the agent back at Ringer, once per session. Nothing is ever blocked; telling your agent "just do it inline" still works. Fittingly, the agent installs its own leash.

<prompt>
  <task>
    Install Ringer's agent integration on yourself.

1. Run ./ringer.py install-agent in my ringer clone.
2. Show me what it installed: the orchestrator-playbook skill, the session hooks, and where each lives on disk.
3. Explain in three sentences what you'll now do differently when you see swarm-shaped work in our sessions.
  </task>
</prompt>

Undo any time: ./ringer.py uninstall-agent. The quickstart prompt runs this as its final phase.