Skip to content

Repository cleanup (26 Oct 2026)

The user asked for a whole-repo cleanup that follows the CLAUDE.md code-style guidance: avoid over-engineering, prefer simple and modular code, and do not keep things only for backwards compatibility. Functional correctness had to be preserved. Each pass is its own commit, verified before it landed.

Passes

Pass Commit What changed Verification
Headless tests 4657ce3 tests/conftest.py sets MPLBACKEND=Agg and SDL_VIDEODRIVER=dummy Full change-selected suite
Lint 54b691f Explicit package __init__s with __all__ instead of star imports; unused imports and variables; empty src/opponent_model/visualisation; RecordVideo reuses src/core/wrappers/common.py (its inlined copies and the unused write_video are gone); benchmark_all_mo.py uses notebooks.env_discovery fast suite, marimo check on every changed notebook
Dead code 4d85170 22 unreferenced functions, methods and properties; the modules src/core/utils (commented-out IPython magics) and MSH utils.py git grep -w per name (code, strings, docs), fast suite
Dedup 0bb2017 Chicken and Bertrand on one RepeatedStageGame (src/environments/matrix/stage_game.py), StageGameSafetyModel and StageGameRenderer; MSH's unused AEC env()/raw_env() Byte-for-byte equivalence of rollouts, infos, snapshots, legal graphs, safety labels and rendered frames against the published two-player games and the n-player versions; fast suite
Format 0c122b4 (in .git-blame-ignore-revs) ruff format on 167 files (ruff.toml: 120 columns, double quotes) Every changed file has the same AST as before (docstring whitespace aside); fast suite; marimo check

Full-suite verification (cpucluster, 27 Oct 2026)

scripts/run_tests.py full --include-slow ran on the cleanup HEAD 82dd578, as Slurm job 88036 (amd96, 4 cores, 12 GB). Its worktree was ~/Projects/omsh_tests, with the shared venv. The result was 1,024 passed and 1 failed, in 3.5 min.

  • The failure was in the test, not the code. test_slurm_memory_fallback_uses_job_allocation sets SLURM_CPUS_PER_TASK=3.
  • Inside a real Slurm job, SLURM_JOB_CPUS_PER_NODE=4 is also set. _slurm_job_cpu_count is right to prefer it, so the test got 4 × 4G instead of 3 × 4G.
  • The test now clears that variable too.
  • Checked on the workstation with SLURM_JOB_CPUS_PER_NODE=4 set: the old test fails, and the fixed one passes.
  • It is not a cleanup regression. The test fails this way whenever the suite runs inside a Slurm job.
  • The workstation changed selection after the n-agent readout commit gave 1,017 passed.

Why the popup windows

On a workstation with a display, matplotlib picks TkAgg. Two things then opened windows:

  • test_maybe_save_show_creates_parent_directory calls maybe_save_show(..., show=True);
  • the experiment notebooks' plotting cells call maybe_save_show(..., show=True) when run as scripts.

The conftest fix covers tests and their notebook subprocesses. For local notebook script runs, set MPLBACKEND=Agg. The cluster runners have no display, so they were never affected.

Deliberately left alone

  • Trainers (src/rl) and the shield core (src/shield). They produce the paper's numbers. Restructuring them needs seed-for-seed regression checks on every environment, so only dead code was removed there.
  • Per-game notebook trios. Chicken and Bertrand each have WM, OM, experiments and play notebooks that differ in about 90 of about 1,750 lines.
  • Merging them into one parameterised set (game=chicken|bertrand) is the largest remaining duplication.
  • It moves notebook paths that about 15 launchers, support.bash, the cluster-submission tests and ten docs use. User decision (26 Oct 2026): keep them as separate notebooks.
  • Gridworld renderers. They draw different content and share only pygame boilerplate.
  • Long lines. The 21 that formatting left were split into adjacent string literals or wrapped prose, so ruff check . now passes outright. The only output change is a line break inside the LaTeX header row of summarize_padded_runs.py.