An adversarial build harness. Sparra builds software one work item at a time: each item is negotiated into a checkable "done" contract, implemented by a generator, then graded by an adversarial evaluator that actually runs the artifact — with cross-model judging (Claude builds while Codex judges, or vice versa) and an optional holdout wall of evaluator-only checks the builder can't overfit to.
flowchart LR
contract["Negotiate a<br>'done' contract"] --> generate[Generator<br>implements]
generate --> exercise["Evaluator <b>exercises</b><br>the artifact for real"]
exercise --> grade{Grade}
grade -->|pass| accept[Accept &<br>commit]
grade -->|fail: feedback| generate
grade -->|stuck| pivot[Pivot: discard,<br>restart fresh]
pivot --> generate
Works on new and existing codebases, over pluggable agent backends (Claude and Codex today — the Codex backend also fronts any OpenAI-compatible endpoint). Everything reads and writes the filesystem, so every run is inspectable, diffable, and resumable.
Status: young and still finding its form, but already earning its keep on real projects (and on Sparra itself). Inspired by the Anthropic workshop Build Agents That Run for Hours.
The sparra-loop skill runs the loop above inside Claude Code, with you on the wheel — steer
every step, or let it run in auto mode and step in only when needed. The generator and evaluator
backends remain independently configurable (so Codex still judges what Claude builds, and vice
versa — that cross-model seam is separate from who conducts the loop).
First install Sparra from a clone of this repo. npm link puts the sparra and sparra-run-mcp
package bins on PATH:
npm install && npm link # puts `sparra` + `sparra-run-mcp` on your PATH
npm i @openai/codex-sdk # optional: only for a Codex backend (also needs the `codex` CLI authed)Then register the role-runner MCP tool and the plugin with Claude Code:
claude mcp add sparra-run --scope user -- sparra-run-mcp # the role-runner MCP tool
claude plugin marketplace add "$PWD"
claude plugin install sparra@sparra-skills # gives you /sparra-loop and /sparra(Or let the Makefile drive both steps: make link setup-claude — plus make setup-codex /
make setup-pi for the other conductor hosts. make help lists everything.)
Open Claude Code in your project and type /sparra-loop. The conductor sets the project up
(sparra init, per-role backend/model split, optional holdout) and drives the loop:
sequenceDiagram
participant You
participant CC as Claude Code<br>(sparra-loop)
participant R as Sparra role-runner
You->>CC: sparra-loop "add feature X"
CC->>R: launch contract-generator
CC->>R: launch generator (e.g. Claude)
CC->>R: launch evaluator (e.g. Codex) — sees the holdout, exercises the work
R-->>CC: verdict only (holdout stays redacted)
CC->>You: round summary — accept, iterate, or pivot?
The holdout is passed by path and only the evaluator ever sees it; the runner returns the parsed verdict, never raw output. Details, guarantees, and the CLI equivalents (sparra role run, sparra eval): docs/role-runner.md.
Codex as conductor is experimental (WIP). Codex can also drive
/sparra-loop, but that host path lags Claude Code's and is gated on better Codex capabilities (or an alternative host harness able to run Codex/OpenAI models). Codex as a backend — building or judging individual roles — is fully supported. Setup and current limits: docs/role-runner.md#codex-install-and-run.
Headless conductor (
sparra conduct).sparra conduct "<prompt>"drives the whole conductor pattern from ONE prompt with no.sparra/setup: decompose → per unit contract-negotiate → generate → cross-model evaluate → decide, all through the isolated role-run machinery, writing.sparra/conduct/<runId>/and generating each unit on its own worktree — by default nothing lands on your branch (opt-in--commit/--mergeland on a unit/run branch; the further opt-in, double-gated--landcan fast-forward your default branch itself). Two brain modes (--brain hybrid= deterministic loop + an LLM conductor at the judgment points,--brain llm= the brain drives turn-by-turn) plus a decision engine that parks important decisions for a human (--autoto never park;sparra conduct --decide— or the HTTP bridge'sPOST /jobs/:id/decision— to answer). A crashed or interrupted run is continued in place withsparra conduct --resume <runId>(skips already-accepted units, re-enters the rest at the right stage, appends to the samerun.json), not restarted. Flags + artifacts + safety properties: docs/conduct.md.
Remote conductor (HTTP bridge). Trigger
sparraphases and role-runs on another Mac over Tailscale — Bearer-token auth, a path allowlist, and the same holdout wall over HTTP. Setup + endpoints: docs/http-bridge.md.
Pi as conductor is experimental (WIP). A programmatic conductor for the Pi host — a
sparra_roletool, a/sparra-loopcommand, andsparra/sparra-loopskills, so a Pi (e.g. OpenAI/Codex) session drives the same holdout-safe loop — lives inconductors/. It's built and green with the same cross-model/holdout guarantees, but not yet published (a local-pathpi install ./conductors/piloads it in place).
Just want a second opinion? sparra eval <dir> --contract contract.md --backend codex grades any work-in-progress tree against a contract — no .sparra/ setup required. Add --worktree to evaluate a snapshot without touching your tree.
Prefer to hand off? The same engine runs unattended as a sequence of phases — collaborative planning, a human freeze gate, then the autonomous build loop:
flowchart TB
init["sparra init<br>(+ orient for existing repos)"] --> plan
plan["sparra plan — collaborative<br>interview, co-edits PLAN.md"] <-.-> proto["sparra prototype<br>(throwaway, for learning)"]
plan --> freeze["sparra freeze — <b>your call</b>,<br>locks the plan as build input"]
freeze --> build["sparra build — the autonomous<br>loop, item by item"]
build --> reflect["sparra reflect — proposes prompt<br>edits from build or role-run traces"]
reflect --> new["sparra new / finish —<br>next feature, fresh cycle"]
cd your-project/ # new or existing; Sparra detects which
sparra plan && sparra freeze && sparra build && sparra reflect
sparra status # where am I? what's next?
sparra resume # continue any phase from disksparra build --step pauses at each checkpoint for human steering; sparra help lists everything else (batch, finish, clean, prompts audit, measure, …). → docs/phases.md
- The evaluator runs your code. Grading is evidence-based: it builds, launches, and exercises the artifact (CLI, web, or iOS Simulator with screenshot and animation contact-sheet reading), and won't pass flaky or gamed results. → docs/build-loop.md
- Cross-model on tap. Pick the backend per role — one model family builds while another judges, for a genuinely independent second opinion. → docs/backends.md
- Holdout wall. Evaluator-only acceptance checks the builder never sees, so it can't teach to the test. → docs/role-runner.md
- Bounded & safe by default. Per-item budgets, sandboxed permissions, and a git-worktree boundary — Sparra never commits to your main branch. → docs/build-loop.md
- Filesystem is the source of truth. Contracts, verdicts, traces, and memory all live in
.sparra/on disk — resumable from any point, and it survives provider rate limits unattended. → docs/configuration.md - Self-improving.
sparra reflectreads build traces, or safe ad-hoc role-run trace bundles, and proposes prompt edits you approve. → docs/phases.md - Script hooks. Run your own scripts at phase/run/unit start-and-end lifecycle points (
scriptHooksconfig) — arequiredbefore-hook can gate the step. → docs/configuration.md
Sparra is a harness, not a fixed pipeline. The iOS/macOS support is really one worked example of fitting it to a stack — a custom exerciser plus injected house conventions — and the same hooks let you fit it to yours, in any language:
- Exercise your way —
exercise.mechanism: customruns your own shell recipe to build/run/probe the artifact (cliandwebcover the common cases). → docs/build-loop.md - Your own verify + QA commands —
build.verifyCommandsdrives generator self-checks and lets an isolated Claude contract-evaluator prove proposed gates are runnable;measure.commandis your project's benchmark/QA harness. → docs/configuration.md - Teach it your tooling — hand any role a skill (
roles.<role>.skills, aSKILL.mddescribing your build/test/deploy) and edit the role prompts in.sparra/promptsto inject your conventions. → docs/backends.md
| Phases | orient → plan ⇄ prototype → freeze → build → reflect; greenfield vs brownfield |
| The build loop | contract negotiation, exercising, pivots, budgets, code review, measure, memory |
| Role-runner | the interactive seam: /sparra-loop, MCP run_role, sparra eval, the holdout wall |
| Conduct | sparra conduct "<prompt>" — the headless conductor: decompose → per-unit negotiate/generate/evaluate/decide, run artifacts, safety |
| Agent backends | Claude + Codex, per-role backends, OpenAI-compatible endpoints, skills |
| iOS / macOS | Simulator builds, xcodebuildmcp, XcodeGen, multimodal UI grading |
| Configuration | every knob, the .sparra/ on-disk layout, resuming |
- Node 20+ and
npm install. Interactive-host setup also requiresnpm linkso bothsparraandsparra-run-mcpare onPATH. - At least one agent backend: an Anthropic credential (
ANTHROPIC_API_KEYor a Claude Code login), ornpm i @openai/codex-sdkplus an authenticated Codex CLI. → docs/backends.md - Optional iOS/macOS exercising: macOS + Xcode + a Simulator +
xcodebuildmcp+xcodegen. → docs/ios.md
No build step — the bins run the TypeScript directly via tsx, so a git pull takes effect immediately.
MIT © Kristopher Baker