---
name: llm-round-robin-ipd-runner
description: Run and inspect LLM-vs-LLM round robin iterated prisoner's dilemma simulations in web/scratch using the Bun runner and historical viewer UI.
compatibility: Created for Zo Computer
metadata:
  author: rob.zo.computer
  version: "0.1"
---

# llm-round-robin-ipd-runner

Run LLM-vs-LLM round robin iterated prisoner's dilemma simulations from soft natural-language parameters, persist them into SQLite, and inspect the completed run in the scratch site viewer.

## When to use

Use this skill when Rob asks for things like:
- "run round robin ipd with all registered models"
- "run a round robin tournament for 40 generations"
- "simulate GPT-5.4 vs Sonnet vs Gemini in round robin"
- "run another LLM round robin prisoner's dilemma and give me the run id"

## What this is

This skill operates the round robin IPD setup in `file 'web/scratch'`.

Core pieces:
- Runner: `file 'web/scratch/scripts/llm_round_robin_ipd.ts'`
- Default config: `file 'web/scratch/data/llm-spatial-ipd/default-round-robin-config.json'`
- DB: `file 'web/scratch/data/llm-spatial-ipd/runs.sqlite'`
- Schema: `file 'web/scratch/data/llm-spatial-ipd/schema.sql'`
- Historical viewer page: `file 'web/scratch/src/pages/LlmRoundRobinIpd.tsx'`
- Historical viewer route: `/llm-round-robin-ipd?runId=<RUN_ID>`

The runner uses the AI SDK with Vercel AI Gateway string-model routing. Each active model gets one fixed seat in the tournament and plays every other active model repeatedly across generations.

## Registered models

Current registered model keys:
- `GPT5_3_CODEX_MC`
- `GPT5_4_MC`
- `OPUS_4_6_MC`
- `KIMI_K2_5_MC`
- `GLM_5_MC`
- `MINIMAX_2_5_MC`
- `GEMINI_3_MC`
- `SONNET_4_5_MC`

"all registered models" means all of the above with equal weight unless specified otherwise.

## Default interpretation of soft params

Map common language to config fields like this:
- "40 steps" / "40 generations" → `generations: 40`
- "8 rounds" / "8 rounds per step" → `roundsPerGeneration: 8`
- "all registered models" → all model weights set to `1`
- "just GPT-5.4 and Sonnet" → those model weights set to `1`, all others `0`
- "noise 1%" → `noiseRate: 0.01`
- "seed 42" → `seed: 42`
- "temptation 5 reward 3 punishment 1 sucker 0" → payoff matrix fields

Reasonable defaults if not specified:
- `generations: 24`
- `roundsPerGeneration: 8`
- `temptation: 5`
- `reward: 3`
- `punishment: 1`
- `sucker: 0`
- `noiseRate: 0.01`
- all model weights = 1

## How to run it

### 1. Translate the request into a config

Write a temporary JSON config in the conversation workspace and keep the canonical DB at:
- `file 'web/scratch/data/llm-spatial-ipd/runs.sqlite'`

Use the current default config at `file 'web/scratch/data/llm-spatial-ipd/default-round-robin-config.json'` as a baseline, then override only the requested parameters.

Recommended pattern:
```bash
bun scripts/llm_round_robin_ipd.ts run --config /absolute/path/to/temp-config.json
```

You may also initialize the canonical files if needed:
```bash
bun scripts/llm_round_robin_ipd.ts init
```

### 2. Execute from the scratch site root

Always use cwd:
```bash
/home/workspace/web/scratch
```

### 3. Verify persistence

Optionally confirm the run landed in SQLite:
```bash
sqlite3 /home/workspace/web/scratch/data/llm-spatial-ipd/runs.sqlite \
  "select id,status,name,generations from runs where neighborhood='round_robin' order by created_at desc limit 5;"
```

## How to view results

Primary viewer:
- `file 'web/scratch'`
- route: `/llm-round-robin-ipd?runId=<RUN_ID>`

The page is designed to show:
- run metadata
- model roster
- score-over-generation chart
- ranking table for each generation
- sample interactions for a selected generation

API endpoints behind the viewer:
- `GET /api/llm-round-robin-ipd/runs`
- `GET /api/llm-round-robin-ipd/runs/:runId`

## Output schema summary

The run is persisted in SQLite tables:
- `runs` — one row per simulation run
- `run_models` — participating models and gateway IDs
- `run_population` — per-generation normalized score shares by model
- `run_round_robin_scores` — per-generation raw and cumulative scores plus rank by seat
- `run_round_robin_matches` — pairwise actions and payoffs by round

## Execution checklist

1. Read the user's request.
2. Read `file 'web/scratch/data/llm-spatial-ipd/default-round-robin-config.json'` if useful for inheritance.
3. Translate the request into an explicit JSON config.
4. Save the config into the conversation workspace.
5. Run the Bun script from `file 'web/scratch'`.
6. Capture the `runId`.
7. Verify the run status in SQLite or via `/api/llm-round-robin-ipd/runs/<runId>`.
8. Return the run id and the viewer route.
