arena
Skill1 starsChanged 2 months agoApache-2.0View on GitHub
Run a judged bakeoff on the Helix Arena board — N candidates answer the same question in their own workspaces, a judge scores them against a ratified rubric, one becomes the base, and the best parts of the losers are grafted in with the rejections recorded. Use when the user says "/helix-arena", "run an arena", "bake this off", or faces a one-way door where one attempt would lock in the wrong shape. Sibling of helix-swarm (slices merged) and helix-loop (build to a bar).
84 other projects use a version of this.
Adopted by
Most recently taken up by
- Yeachan-Heo/oh-my-claude-sisyphustheir own version, first seen Nov 8, 2026
- anorth/agent-skillstheir own version, first seen Nov 8, 2026
- thatmike1/claude-skillstheir own version, first seen Nov 8, 2026
- Yeachan-Heo/oh-my-claudecodetheir own version, first seen Nov 8, 2026
- endqwerty/endstacktheir own version, first seen Nov 8, 2026
- tristanphvn/keeltheir own version, first seen Nov 8, 2026
Used with
Projects with it also use addskill, apply-firmware and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
ryanportfolioSkilladdskill
Create, import, update, or install repo or personal skills: runtime ownership, resources, discovery checks.
Also in 6 projects that use this
ryanportfolioSkillapply-firmware
Bring current folder (plain folder, existing repo, old or partial firmware copy) up to full Harness Firmware in place. Mirror external repo → adopt-repo.
Also in 6 projects that use this
- +10 more from ryanportfolio
Other versions84 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 84
- Yeachan-Heo/oh-my-claude-sisyphus★ 41ksame name
- Yeachan-Heo/oh-my-claudecode★ 41ksame name
- backnotprop/pstack★ 3.8ksame name
- moeru-ai/xsai★ 667same name
- jtaroreh/agystack★ 128same name
- uzairansaruzi/p3-stack★ 126same name
- dsebban/skills★ 71same name
- overextended/skills★ 22same name
- TheOnlyFusionCube/potetos-for-everyone★ 21same name
- creedants/pstack-t3★ 18same name
74 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
Show its rules and text
We split this skill into the rules it gives an agent
14 rules. 0 are common, 5 are distinctive, and 9 are very specific to this project.
0
Common
Most of the 83 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 11
If HELIX_ORCHESTRATOR_RUN_ID or HELIX_SKILL_CREDENTIAL_FILE is set, this skill runs in Helix Console.
- Very specific: line 13
Use the normal helix <surface> up, push, state, and wait commands.
- Very specific: line 14
Do not start local servers or Fleet, open a browser, curl localhost, use --local, log in, or change profiles/projects.
- Distinctive: line 56
Before proposing anything, read the rails that bind this project on this surface:
- Very specific: line 116
Pick the base: Read every candidate end to end first.
- Distinctive: line 121
Read both rationales. A clean disagreement usually means the rubric is missing something — say so, because that is the more valuable …
- Very specific: line 129
All candidates converge → converged.noted.
- Very specific: line 143
Every section carries version and the fields below.
- Very specific: line 164
Every user act — Ratify, Decline, an edit, a gate, a note — is an event with origin:"user".
- Very specific: line 170
Cursor: Every plan and push reply carries cursor.
- Very specific: line 207
Every event on stdin is {"type": "<name>", "payload": {…}} — one object or an array of them.
- Distinctive: line 273
Never ratify or resolve a gate yourself — those come only from the board.
- Distinctive: line 274
Never report a score the judge did not produce.
- Distinctive: line 276
If the arena cannot separate the candidates, that is a finding about the rubric, not a failure to paper over.
“Common” is measured: kept by at least 6 in 10 of the 83 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Helix Arena
Orchestrator cloud context (check before setup)
If HELIX_ORCHESTRATOR_RUN_ID or HELIX_SKILL_CREDENTIAL_FILE is set, this skill runs in Helix Console. This section takes precedence over local setup and browser instructions below.
- First call the plugin's
bin/helix orchestrator-protocol(Windows:bin/helix.cmd orchestrator-protocol). It must print1. Otherwise stop with an actionable request to update the Helix plugin/CLI; never run an older binary's setup commands. - Use the normal
helix <surface> up, push, state, and wait commands. The CLI selects cloud transport and the assigned project automatically. Keep the same slug within this task. - Do not start local servers or Fleet, open a browser, curl localhost, use
--local, log in, or change profiles/projects. Do not read or print the credential file. Do not remove the injected environment variables. upreturns the Console session URL. Use that URL wherever the local instructions request Board/Fleet links. Events go to Console; human responses and gate approvals still come from the person through the normal wait protocol.- On cloud or compatibility errors, report the error. Never fall back to local mode. Outside this context, follow the local behavior below unchanged.
One question, answered N times, judged against a rubric the human ratified before anything spawned. You orchestrate; the board shows every candidate live; the plan and the gates belong to the human.
The arena is expensive on purpose. Four runners plus a judge for one
decision only pays when the decision is a one-way door — a shape every
downstream thing inherits and nobody can revise cheaply. Running one over a
settled shape is an expensive way to agree with yourself. Say so and use
/helix-loop or plain work instead.
Setup
${CLAUDE_PLUGIN_ROOT}/bin/helix arena up --arena <slug> --agent <name> --model <model-id> [--dir <projectDir>] [--no-open]
# --agent: your product name, lowercase (claude, codex, …)
# --model: your exact model id (e.g. claude-fable-5) — Fleet shows and filters by these
${CLAUDE_PLUGIN_ROOT}/bin/helix arena plan --arena <slug> # plan JSON on stdin
${CLAUDE_PLUGIN_ROOT}/bin/helix arena push --arena <slug> # event JSON (single or array) on stdin
${CLAUDE_PLUGIN_ROOT}/bin/helix arena wait --arena <slug> --since <cursor> [--timeout <s>] [--wake-on user]On Windows, ${CLAUDE_PLUGIN_ROOT}\bin\helix.cmd in place of bin/helix; the
rest of the command is the same.
Data: ~/.helix/arena/<project>/<slug>/ — one home for the whole machine,
never inside a repo.
upalso brings up Fleet (mission control) when it is down, and returnsfleet: {url, started}. Hand the user both links in one line —Board: <url> · Fleet: <fleet.url>— so they know the overview is there.upnever opens Fleet in the browser; the user follows the link.
Exit codes: 0 delta, 2 invalid, 3 timeout, 4 no-viewer, 5 down, 6 the plan is not ratified.
Rails first
Before proposing anything, read the rails that bind this project on this surface:
${CLAUDE_PLUGIN_ROOT}/bin/helix rails for --surface arenaWhat comes back is not advice — it is the standard the work is held to. Cite
rail ids when you act on them; full text with helix rails get <id>. Details
in the helix-rails skill.
The gate is real
The server refuses every work event until revision 1 of the plan is ratified on the board. Exit 6 is not a hint you may work around — it means a person has not yet agreed to what this will cost. There is no override.
The run, step by step
- Open:
up. Nothing else yet. Propose the plan. One object, one Ratify, six sections. Two of them cannot be blank:
criteria— 3 to 6 concrete, gradeable criteria derived from what success means for this task. Each carriesdetail(what it means here),checks(what a judge can actually test) andevidence(what the judge must produce).Adds a --dry-run flag that skips writesis a criterion;code is correctis not. The candidates never see the rubric — it is the picker's tool.fanout— how many candidates, on what, how many at once. This is the cost driver.models— one runner per entry. Prefer different model families: the adversarial signal comes from diverse blind spots, not from assigned personas. Same model N times only when the work is generation-bound.selection—first-pass,rank-allorbest-of, declared now. Choosing after the answers are in is the failure this prevents.budget, and that is the plan.
printf '%s' '{"changed":["criteria","budget","fanout","models","selection"], "reason":"one-way door: every context inherits this shape", "sections":{ ... }}' | helix arena plan --arena <slug>- Wait for the ratification —
wait … --wake-on user, as in Waiting on the board below — then read the ratified revision's sections and run from those. On a decline, read the why, revise, propose the next revision. Sections version independently — a budget bump re-ratifies budget alone — and the plan's revision increments on any change, which is what every result cites. - Fan out. One
candidate.createdper runner, each with its own workspace (a git worktree where possible). N candidates writing to one path is the shared mutable state an arena exists to avoid. Spawn them in one message, all in parallel. - Every candidate returns a rationale.
candidate.finishedwithout one is rejected by the server, and rightly: without it there is no way to tell a principled shape from an accidental one, and the graft becomes guesswork. The rationale names what the candidate considered and rejected. - Judge. One read-only judge on a different model family from yours, scoring each criterion for each candidate. It sees the rubric and the candidates by path label. Run it alongside your own reading, never alongside the candidates — a judge spawned while they are still writing sees half-written files and reports them as dropouts.
- Pick the base. Read every candidate end to end first; skimming
surfaces the one whose style looks most familiar. Score criterion by
criterion, then compare with the judge.
base.pickedrequires awhy.- Agreement confirms the pick.
- Disagreement means one of you is biased or a criterion is ambiguous. Read both rationales. A clean disagreement usually means the rubric is missing something — say so, because that is the more valuable finding.
- Graft. Walk each loser once more for the one or two things worth
porting. Fold them in by hand; pasting produces something no single mental
model holds. Push
graft.recordedfor each, andreject.recordedfor what stayed out with its reason — the rejections are the half a future reader learns from. - Two special outcomes, and they lead opposite ways:
- All candidates converge →
converged.noted. Ship the consensus, skip the graft, and record the agreement. - Candidates wildly diverge →
diverged.noted. The framing was too loose. Reframe and re-run; averaging a spread produces a design none of them would defend.
- All candidates converge →
- Verify. The synthesized result faces the same scrutiny as anything else — running an arena does not earn a pass. A fact you cannot prove cheaply is marked unproven with the test that would settle it, never described as safe.
- Report: budget spent, the base and why, grafts with sources, rejections with reasons, dropouts, and whatever is still unproven.
Plan sections — the shape the board reads
Every section carries version and the fields below. budget.maxTokens
and budget.maxWallClockS become the live ceilings on the meter; a budget
sent under another name is a budget nobody enforces.
models.roles.judge is required — set it, on a different family from the
candidates. models.available is the catalogue the board offers when a
person edits the plan: every model id you can actually run, with a label
where the id is not self-explanatory. Every section is editable on the
board; an edit becomes the next revision and waits for its own Ratify.
criteria: {items:[{id, label, detail, checks, evidence, deleted?}]} # deleted:true = retired on the board; judges skip it
budget: {maxTokens:400000, maxWallClockS:900, maxAttempts?}
fanout: {workers:3, unit:"candidate", maxConcurrent:3, task:"..."}
models: {roles:{judge:{model:"…"}, "A":{model:"claude-fable-5",effort:"high"}, "B":{…}},
available:[{id:"claude-fable-5",label:"Fable 5"}, {id:"claude-opus-5"}, …]}
selection: {rule:"first-pass"|"rank-all"|"best-of"}Waiting on the board
Every user act — Ratify, Decline, an edit, a gate, a note — is an event with
origin:"user". You see it only by waiting from the right cursor with the
right flag. This is where runs go wrong: a lead that waits without
--wake-on user wakes on its own pushes and viewer churn, reads "no
ratification yet", and either loops forever or gives up.
- Cursor. Every
planandpushreply carriescursor; wait from the last one you saw. Before waiting for something specific, read the state — the answer may already be in the log:PORT=$(sed -n 's/.*"port": *\([0-9]*\).*/\1/p' ~/.helix/arena/<project>/<slug>/server.json) curl -s "http://127.0.0.1:$PORT/api/state" # .plan, .revision, .ready, .gates, .notes curl -s "http://127.0.0.1:$PORT/api/plan?revision=N" # one revision's exact sections - Always
--wake-on user.
Exit 0: the delta holds a human act — read it. Exit 3: nothing yet; wait again from the returned cursor (and say so in chat every few rounds). Exit 5: the server is down;${CLAUDE_PLUGIN_ROOT}/bin/helix arena wait --arena <slug> --since <cursor> --timeout 600 --wake-on userup, then wait again. Exit 4 only happens without--wake-on user. - What arrives, and what each means.
plan.ratified {revision}— the gate is open. Read the ratified revision and run from its sections, never from what you proposed: the person may have changed models, fan-out, criteria or the selection rule on the board before ratifying.plan.declined {revision, why}— readwhy, revise, propose again.plan.superseded+ a user-originplan.proposed— the person edited the plan; it is a new revision awaiting Ratify. Keep waiting.note.added {text}— steering. Read it, act on it, acknowledge withagent.status.gate.resolved {gateId, action}—continueorstop; honour it.
- Mid-run edits. A user-origin
plan.proposedwhile work is running means a change is coming: finish in-flight units, start nothing new until it is ratified or declined. Once ratified, every later event cites the new revision, and the work that follows runs under its sections. - Drain while working. Between fan-out and merge, wait with a short timeout (60–120s) each time you would otherwise idle, so a note or a gate reaches you before the next expensive step, not after.
Events
Every event on stdin is {"type": "<name>", "payload": {…}} — one object
or an array of them. The fields listed below are the payload.
candidate.created {candidateId, label, runner:{model, effort}, workspace, revision}
candidate.finished {candidateId, summary, rationale} # rationale REQUIRED
candidate.dropped {candidateId, why} # proceed with N-1, on the record
score.added {candidateId, judge, scores:{<critId>:0..3}, notes?, revision}
base.picked {candidateId, revision, judgePick?, agreed, why} # why REQUIRED
graft.recorded {into, from, what, why}
reject.recorded {from, what, why} # why REQUIRED
converged.noted {shape, why}
diverged.noted {why}Plus the shared kit: run.init, agent.status, audit, metrics,
budget.spent, gate.raised.
audit is a read-only evidence card. Pick the kind that fits what you have —
the board renders each properly, and text is markdown (GFM tables work):
audit {agent, unitId?, label?, kind:"markdown"|"text", text}
audit {agent, unitId?, label?, kind:"code", code, lang?, text?}
audit {agent, unitId?, label?, kind:"table", columns:[…], rows:[[…]|{…}], text?}
audit {agent, unitId?, label?, kind:"terminal", command?, output}
audit {agent, unitId?, label?, kind:"diff", diff}
audit {agent, unitId?, label?, kind:"screenshot"|"image", path, caption?} # absolute pathRunners and the judge report for themselves
Give every runner and the judge the CLI line and require, via Bash:
agent.statuson start and on finish —{agent, text, unitId: "<candidateId>"}. Always includeunitId, or the board cannot attribute the work to a candidate.- One
auditper candidate carrying the thing it made:kind:"code"with the key block (≤40 lines) orkind:"screenshot"with an absolutepath. The rationale goes incandidate.finished; the artifact goes here. - One
auditper verdict from the judge —kind:"text", ≤300 chars, naming the criterion and what decided it. A score with no reasoning on the board is a number nobody can argue with. - One
metricsevent on finish from each runner and the judge —{agent, unitId, model, tokens, toolCalls, durationS}, real model id, honest estimates where exact numbers are unavailable. Without it the Stats tab reports zero for a run that cost real money. - The lead pushes
budget.spentdeltas as each runner completes.
Evidence over narration: one entry per step. A run whose Evidence and Stats tabs are empty did not report — it did not do less work.
Server operations
- A stale server restarts on the same port when you run
${CLAUDE_PLUGIN_ROOT}/bin/helix arena upagain; open tabs reconnect. - Kill by pid, never by name.
pkill -f "helix arena serve"matches every arena server on the machine — other projects, other people's sessions, runs in the middle of their work. It looks local and is not. Read the pid instead:kill "$(sed -n 's/.*"pid": *\([0-9]*\).*/\1/p' ~/.helix/arena/<project>/<slug>/server.json)". - The event log survives restarts; state is never in memory only. A server killed
under a live session is survivable — the session sees exit 5 and
upbrings it back — but the work stops until someone notices.
Honesty rules
- Never ratify or resolve a gate yourself — those come only from the board.
- Never report a score the judge did not produce.
- A dropped candidate is reported, not hidden. N-1 is a fact about the run.
- If the arena cannot separate the candidates, that is a finding about the rubric, not a failure to paper over.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

