| name | coworld-local-run |
| description | Use to run your own built player policy in a LOCAL Coworld episode and watch it — the Gate-1 smoke test ('did my change take, does it connect → play → exit cleanly?'). Triggers: 'smoke test the player locally', 'run a local game', 'run my policy locally and watch it', 'does the build still work', 'open the replay locally'. Game-agnostic; this is correctness only, NOT a competitive matchup (you can't run other users' policies locally). |
Coworld Local Run (Gate-1 smoke test)
Run your own built policy image in a local Coworld episode and watch the result.
This is the Gate-1 check in the improvement loop: confirm the change took and the
player connects → plays → exits cleanly — it is correctness/liveness only, not a
competitive test (you generally can't run other users' policies locally, so all
competitive judgment comes from experience requests; see coworld-experience-requests).
Announce at start: "Running a local Gate-1 smoke test of the built policy."
Two footguns this skill guards (read first)
- Images must be
linux/amd64 — the runner hard-fails on arm64. On Apple Silicon,
build with docker build --platform linux/amd64 -t <tag> .
- Your policy image is the positional argument to
run-episode. Omit it and the
runner silently runs the manifest's reference player — your change isn't under
test even though the run "passes". --run alone does not swap the player; it only
sets the argv for a supplied image.
Workflow
-
Build your policy linux/amd64 (game-specific build; e.g. the player's build.sh
or docker build --platform linux/amd64 -t <tag> .).
-
Smoke test it — the helper does download (if needed) → amd64 check → run-episode
with your image in every slot → a PASS/FAIL verdict + the replay command:
cd /path/to/player_labs
uv run python .claude/skills/coworld-local-run/scripts/smoke.py \
--coworld <cow_id|name> --image <your-tag>:dev
uv run python .claude/skills/coworld-local-run/scripts/smoke.py \
--coworld cow_... --image my:dev --run python --run -m --run my_player --timeout 180
Heads-up — the first run can take several minutes. download pulls the
game's Docker image (often hundreds of MB) and tags it; that's the slow part. It's
cached and idempotent, so later smoke tests against the same game are fast. If a user
is watching, tell them it's pulling the game image and may take a bit — it isn't stuck.
Gate-1 passes when it exits 0: the CLI exited cleanly (no game/player container
crashed), results.json validated, and a replay was written. The default run uses
the package's certification config, which is deliberately degenerate — a score
of 0 there is NOT a failure; this checks liveness/correctness, not gameplay.
-
Watch it — the script prints the exact command; or open the viewer / watch live:
uv run coworld replay <manifest> <out>/replay
uv run coworld play <manifest> <your-tag>:dev
Doing it by hand (what the script runs)
uv run coworld download <cow_id|name>
uv run coworld run-episode ./coworld/<cow_id>/coworld_manifest.json \
<your-tag>:dev --output-dir /tmp/smoke --timeout-seconds 120
uv run coworld replay ./coworld/<cow_id>/coworld_manifest.json /tmp/smoke/replay
run-episode writes results.json, replay (no extension), config.json, and
logs/{game.stdout,game.stderr,policy_agent_<slot>}.log to the output dir. The
positional image is reused for all slots (self-play); pass one image per slot to
mix players (there is no single-slot override — reference players are used only when you
supply zero images).
Notes
run vs play: run-episode is headless and writes the artifacts (the Gate-1
case); play opens the live browser viewer and keeps the session alive — use it to
watch a game in real time.
- Real (non-degenerate) variant:
run-episode has no --variant (only play
does). To smoke a fuller game headlessly, pass an episode_request.json whose
game_config is the variant you want, or use coworld play <manifest> <image> --variant <id>. For competitive numbers, use experience requests, not local runs.
- Auth/network:
download needs softmax login (for a name) + Docker + network to
pull/tag the game image; once the game image and your :dev image are local, the run
is offline. cow_… ids are stable; names resolve to whatever is canonical now.
- Full CLI reference (exact flags, outputs, every gotcha):
references/cli.md.
- Verified against coworld 0.1.20.