local-dev — elote onboarding record
Durable record of the LOCAL-DEV onboarding run. Last verified 2026-09-06.
Everything below was executed and observed in the repo sandbox, not inferred.
Environment facts
- Sandbox is Linux; system Python is 3.13 — do not use it for this project. Create the project venv with
uv venv --python=3.11 (uv downloads CPython 3.11.16 automatically; matches make setup).
- uv is not preinstalled —
pip install uv first (uv 0.12.10 verified).
- No Docker, no databases, no services, no env vars, no ports. The "app" is the importable
elote package.
Setup steps (in order)
pip install uv
uv venv --python=3.11
uv pip install -e ".[dev,datasets]"
Notes:
- Do NOT run
make setup verbatim on Linux — its brew install libomp line is macOS-only and fails there. The two uv lines above are the portable equivalent.
- The
datasets extra is required for the full suite (CI installs .[dev,datasets]). make install-dev installs dev only.
Verification ladder (all must pass)
| Step |
Command |
Observed 2026-09-06 |
| Tests |
make test |
612 passed, 2 warnings, ~55s |
| Lint |
make lint |
All checks passed |
| Types |
make typecheck |
Success: no issues in 30 source files |
| Primary flow |
README quickstart (below) |
EloCompetitor: Ada > Grace > Linus, GlickoCompetitor: Ada > Grace > Linus — matches README |
| Serialization |
export_state/initial_state, to_json/from_json |
Round-trips OK |
| Example |
make run-example EXAMPLE=sample_bout.py |
Exit 0 |
Primary-flow smoke script
uv run python - <<'PY'
from elote import EloCompetitor, GlickoCompetitor, LambdaArena
pairs = [("Ada", "Grace"), ("Grace", "Linus"), ("Ada", "Linus"), ("Grace", "Linus")]
for model in (EloCompetitor, GlickoCompetitor):
arena = LambdaArena(lambda w, l: True, base_competitor=model)
for winner, loser in pairs:
arena.matchup(winner, loser)
print(f"{model.__name__}: {' > '.join(r['competitor'] for r in arena.leaderboard())}")
arena = LambdaArena(lambda w, l: True, base_competitor=EloCompetitor)
arena.matchup("a", "b")
restored = LambdaArena(lambda w, l: True, initial_state=arena.export_state())
assert restored.leaderboard()[0]["competitor"] == "a"
print("state round-trip OK")
PY
Serialization gotcha: to_json()/from_json() are competitor methods; arenas use
export_state() + LambdaArena(initial_state=...). LambdaArena has no to_json.
Known side effects (restore before committing)
make test regenerates images/bradley_terry_ratings.png and images/colley_matrix_ratings.png.
uv run may rewrite uv.lock.
- Clean up with:
git checkout -- images/ uv.lock (.venv/ is gitignored).
CI parity
PRs to master run .github/workflows/test-suite.yml (tox py310/py311/py312 with
.[datasets], plus ruff lint) and test-docs-build.yml (Sphinx build). A green local
make test && make lint && make typecheck on 3.11 is a good pre-push proxy.
1---2name: local-dev3description: Stand up a working local dev environment for wdm0006/elote — uv + Python 3.11 venv, full test suite, lint, typecheck, and a primary-flow smoke test4---56# local-dev — elote onboarding record78Durable record of the LOCAL-DEV onboarding run. Last verified 2026-09-06.9Everything below was executed and observed in the repo sandbox, not inferred.1011## Environment facts1213- Sandbox is Linux; system Python is 3.13 — do not use it for this project. Create the project venv with `uv venv --python=3.11` (uv downloads CPython 3.11.16 automatically; matches `make setup`).14- **uv is not preinstalled** — `pip install uv` first (uv 0.12.10 verified).15- No Docker, no databases, no services, no env vars, no ports. The "app" is the importable `elote` package.1617## Setup steps (in order)18191. `pip install uv`202. `uv venv --python=3.11`213. `uv pip install -e ".[dev,datasets]"`2223Notes:24- Do NOT run `make setup` verbatim on Linux — its `brew install libomp` line is macOS-only and fails there. The two uv lines above are the portable equivalent.25- The `datasets` extra is required for the full suite (CI installs `.[dev,datasets]`). `make install-dev` installs dev only.2627## Verification ladder (all must pass)2829| Step | Command | Observed 2026-09-06 |30|---|---|---|31| Tests | `make test` | 612 passed, 2 warnings, ~55s |32| Lint | `make lint` | All checks passed |33| Types | `make typecheck` | Success: no issues in 30 source files |34| Primary flow | README quickstart (below) | `EloCompetitor: Ada > Grace > Linus`, `GlickoCompetitor: Ada > Grace > Linus` — matches README |35| Serialization | `export_state`/`initial_state`, `to_json`/`from_json` | Round-trips OK |36| Example | `make run-example EXAMPLE=sample_bout.py` | Exit 0 |3738## Primary-flow smoke script3940```bash41uv run python - <<'PY'42from elote import EloCompetitor, GlickoCompetitor, LambdaArena4344pairs = [("Ada", "Grace"), ("Grace", "Linus"), ("Ada", "Linus"), ("Grace", "Linus")]45for model in (EloCompetitor, GlickoCompetitor):46 arena = LambdaArena(lambda w, l: True, base_competitor=model)47 for winner, loser in pairs:48 arena.matchup(winner, loser)49 print(f"{model.__name__}: {' > '.join(r['competitor'] for r in arena.leaderboard())}")5051arena = LambdaArena(lambda w, l: True, base_competitor=EloCompetitor)52arena.matchup("a", "b")53restored = LambdaArena(lambda w, l: True, initial_state=arena.export_state())54assert restored.leaderboard()[0]["competitor"] == "a"55print("state round-trip OK")56PY57```5859Serialization gotcha: `to_json()`/`from_json()` are **competitor** methods; arenas use60`export_state()` + `LambdaArena(initial_state=...)`. `LambdaArena` has no `to_json`.6162## Known side effects (restore before committing)6364- `make test` regenerates `images/bradley_terry_ratings.png` and `images/colley_matrix_ratings.png`.65- `uv run` may rewrite `uv.lock`.66- Clean up with: `git checkout -- images/ uv.lock` (`.venv/` is gitignored).6768## CI parity6970PRs to `master` run `.github/workflows/test-suite.yml` (tox py310/py311/py312 with71`.[datasets]`, plus ruff lint) and `test-docs-build.yml` (Sphinx build). A green local72`make test && make lint && make typecheck` on 3.11 is a good pre-push proxy.