| name | run-arena-lab |
| description | This skill should be used when the user asks to spawn or generate an ARENA lab from a spec, run a spec through the pipeline, run several specs in parallel, bring up / start up a generated lab's Docker container for inspection, or find and run a finished run's image. |
| version | 1.0.0 |
Run an ARENA lab
Spawn a vulnerable lab from a spec and bring its container up for inspection. All
commands run from the spawner/ directory.
Spawn one lab
cd spawner
uv sync
uv run arena specs/leaky-query.yaml
- Entry point:
arena = "arena.cli:main" (spawner/pyproject.toml); a bare spec arg
routes to the spawn command (spawner/arena/cli.py).
- Specs live in
spawner/specs/*.yaml. Ad-hoc/showcase specs are conventionally
kept in .context/showcase-specs/ (gitignored) so they don't clutter the repo.
- Logs go to stderr prefixed
[arena] .
Watch for these markers (spawner/arena/cli.py:83-88)
| Marker | Meaning |
|---|
[arena] SUCCESS followed by the manifest JSON | run finished; image built |
[arena] FAILED — reason=<reason> | run failed at a stage |
[arena] workdir preserved at: <path> | inspect this dir to debug a failure |
Failure reasons come from spawner/arena/spawn/errors.py: plan_failed,
skeleton_failed, feature_failed, supporting_failed, usability_failed,
sanity_failed, plus max_turns, wallclock, manifest_missing, image_missing,
goals_mismatch. For why a stage failed, hand off to the logfire skill
(trace triage).
Tuning a run (env vars, spawner/arena/config.py)
| Var | Default | Effect |
|---|
ARENA_MODEL | claude-sonnet-4-6 | planner + sanity model |
ARENA_IMPL_MODEL | claude-opus-4-8 | scaffold + feature model |
ARENA_USABILITY_MODEL | = ARENA_MODEL | usability browser judge |
ARENA_<STAGE>_MAX_TURNS | per-stage | turn cap (e.g. ARENA_SKELETON_MAX_TURNS=50) |
ARENA_<STAGE>_WALLCLOCK_SECONDS | per-stage | wall-clock cap |
ARENA_RUNS_DIR | ~/.arena/runs | where run workdirs land |
ARENA_DOCKER_URI | arena-local | image tag prefix (a dotted host → push to registry) |
ARENA_SKELETON_MAX_TURNS=50 ARENA_IMPL_MODEL=claude-opus-4-8 uv run arena specs/leaky-query.yaml
Run outputs
A run writes to ~/.arena/runs/<spec.id>-<8hex>/ (config.py:38,
spawn/runroot.py). The agent's output is under work/:
~/.arena/runs/<spec.id>-<8hex>/work/
app/ generated app (Dockerfile + source + db init)
exploits/ one runnable exploit per vuln feature
solutions/ human-readable write-ups
plan.json planner output
manifest.json final descriptor (written by sanity)
The workdir is preserved on failure, so a FAILED run is still inspectable.
Run several specs in parallel
There is no built-in batching — run each spawn as its own background task and poll
its log (the pattern used across the edinburgh/tashkent sessions):
cd spawner
mkdir -p ../.context/spawn-logs
for spec in react-shop vue-magazine vanilla-ops php-bank; do
uv run arena "../.context/showcase-specs/$spec.yaml" \
> "../.context/spawn-logs/$spec.log" 2>&1 &
done
wait
grep -lE 'SUCCESS|FAILED' ../.context/spawn-logs/*.log
Prefer the harness's background-task mechanism (it re-invokes you on completion)
over a raw & when driving this interactively.
Bring the container up for inspection
The final image is tagged arena-local:<spec.id>-<8hex> (spawn/image.py:13,
built by verify/docker.py). To run it:
docker images 'arena-local:*'
cid=$(docker run -d --rm -P arena-local:<tag>)
docker port "$cid" 5000
curl -fsS http://127.0.0.1:<host_port>/api/health
/api/health returning any non-5xx (incl. 401/403) means the app booted. Seeded lab
credentials (e.g. admin@ares.local / ArenaAdminPass!1) are deliberately public
lab creds, not secrets.
Note: agent-browser: command not found (exit 127) inside a run is a runtime
packaging concern for the agent, not a problem with bringing up the container.
For local vs prod generation and image destinations, see
agent_docs/environments.md.