From f6346f7ca2d9d2b3d81257e3814e816523c66c80 Mon Sep 17 00:00:00 2001 From: Julien Cornebise Date: Wed, 22 Jul 2026 03:33:12 +0100 Subject: [PATCH] python-math #23: feat(delphi): replay loader resolves private datasets under real_data/.local MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `dataset_dir()` only globbed `real_data/*-`, so the five private datasets (bg2018, pakistan, engage, bg2050, FLI — slugs allowed in code per the 2026-07-05 naming policy; report-id directory names still never appear) were invisible to the replay harness and could not join the certify battery (the dataset × vote-schedule list that `scripts/certify.py` replays through both engines). It now also searches `real_data/.local/*-`, with top-level (public) matches taking priority on a slug collision. Groundwork for extending the battery to all `real_data` datasets (`GOAL_R1_PARITY.md`, Battery section). commit-id:a543ecf1 --- delphi/polismath/replay/real_data.py | 5 +++ delphi/scripts/certify_battery.json | 45 ++++++++++++++++++- delphi/tests/replay_harness/test_certify.py | 8 +++- .../replay_harness/test_real_data_local.py | 39 ++++++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 delphi/tests/replay_harness/test_real_data_local.py diff --git a/delphi/polismath/replay/real_data.py b/delphi/polismath/replay/real_data.py index 1202f4c47..eafbac6b6 100644 --- a/delphi/polismath/replay/real_data.py +++ b/delphi/polismath/replay/real_data.py @@ -23,7 +23,12 @@ def dataset_dir(slug: str) -> Path | None: + """Locate a dataset directory by slug — public (``real_data/*-``) + first, then private (``real_data/.local/*-``, gitignored). A public + match wins a slug collision.""" hits = sorted(REAL_DATA_ROOT.glob(f"*-{slug}")) + if not hits: + hits = sorted(REAL_DATA_ROOT.glob(f".local/*-{slug}")) return hits[0] if hits else None diff --git a/delphi/scripts/certify_battery.json b/delphi/scripts/certify_battery.json index eb5345268..9007a4b32 100644 --- a/delphi/scripts/certify_battery.json +++ b/delphi/scripts/certify_battery.json @@ -11,7 +11,7 @@ "preset": "front-loaded", "n_cuts": 6, "engine_mode": "clojure-legacy", - "notes": "6 front-loaded recomputes — early-conversation warm-start stress" + "notes": "6 front-loaded recomputes \u2014 early-conversation warm-start stress" }, { "dataset": "vw", @@ -25,5 +25,46 @@ "n_cuts": 8, "engine_mode": "clojure-legacy", "notes": "8 evenly-spaced recomputes over the full biodiversity conversation" + }, + { + "dataset": "FLI", + "preset": "uniform", + "n_cuts": 6, + "engine_mode": "clojure-legacy", + "notes": "smallest private dataset (~91k votes) \u2014 pilot for the private-size regime; calibrates clj/py wall-clock before scheduling bg2018/pakistan/engage/bg2050" + }, + { + "dataset": "bg2018", + "preset": "uniform", + "n_cuts": 8, + "engine_mode": "clojure-legacy", + "notes": "~226k votes; revote-rich production conversation" + }, + { + "dataset": "pakistan", + "preset": "uniform", + "n_cuts": 8, + "engine_mode": "clojure-legacy", + "notes": "~400k votes" + }, + { + "dataset": "engage", + "preset": "uniform", + "n_cuts": 8, + "engine_mode": "clojure-legacy", + "notes": "~443k votes" + }, + { + "dataset": "bg2050", + "preset": "uniform", + "n_cuts": 6, + "engine_mode": "clojure-legacy", + "notes": "largest (~1.03M votes) \u2014 6 cuts to bound wall-clock" + }, + { + "dataset": "vw", + "preset": "every-vote", + "engine_mode": "clojure-legacy", + "notes": "densest warm-start chain: one recompute per vote (4683 steps) \u2014 maximal sequential-seam coverage on the smallest dataset" } -] +] \ No newline at end of file diff --git a/delphi/tests/replay_harness/test_certify.py b/delphi/tests/replay_harness/test_certify.py index 868271092..9fd0ca4b5 100644 --- a/delphi/tests/replay_harness/test_certify.py +++ b/delphi/tests/replay_harness/test_certify.py @@ -138,13 +138,19 @@ def test_parse_battery_entry_schedule_form_reads_base_id_from_file(tmp_path): def test_load_battery_starter_file_shape(): + """The committed battery parses, keeps the four original starter entries, + covers the private datasets (session-3 extension), and has no duplicate + (dataset, schedule) pairs. Deliberately NOT pinned to an exact count — + the battery GROWS as the goal's coverage expands (GOAL_R1_PARITY.md).""" entries = cert.load_battery(CERTIFY_BATTERY_PATH) ids = {(e.dataset, e.schedule_id) for e in entries} assert ("vw", "uniform8-clojure-legacy") in ids assert ("vw", "front-loaded6-clojure-legacy") in ids assert ("vw", "single-cut-clojure-legacy") in ids assert ("biodiversity", "uniform8-clojure-legacy") in ids - assert len(entries) == 4 + for private_ds in ("FLI", "bg2018", "pakistan", "engage", "bg2050"): + assert any(e.dataset == private_ds for e in entries), private_ds + assert len(ids) == len(entries), "duplicate (dataset, schedule) entries" assert all(e.engine_mode == "clojure-legacy" for e in entries) diff --git a/delphi/tests/replay_harness/test_real_data_local.py b/delphi/tests/replay_harness/test_real_data_local.py new file mode 100644 index 000000000..cfca6ef96 --- /dev/null +++ b/delphi/tests/replay_harness/test_real_data_local.py @@ -0,0 +1,39 @@ +"""dataset_dir resolves private datasets under real_data/.local/. + +The five private datasets live in ``real_data/.local/*-`` (gitignored); +the public ones at ``real_data/*-``. The battery needs both +(GOAL_R1_PARITY.md: "All real_data datasets"). Slug-only lookups keep +report-id directory names out of code (real_data.py module doc). +""" + +from __future__ import annotations + +import pytest + +from polismath.replay import real_data as rd + + +@pytest.fixture() +def fake_root(tmp_path, monkeypatch): + (tmp_path / "rPUBLIC-pub").mkdir() + (tmp_path / ".local" / "rPRIVATE-priv").mkdir(parents=True) + (tmp_path / ".local" / "rSHADOW-pub").mkdir() # slug collision with public + monkeypatch.setattr(rd, "REAL_DATA_ROOT", tmp_path) + return tmp_path + + +def test_public_dataset_resolves(fake_root): + assert rd.dataset_dir("pub") == fake_root / "rPUBLIC-pub" + + +def test_local_dataset_resolves(fake_root): + assert rd.dataset_dir("priv") == fake_root / ".local" / "rPRIVATE-priv" + + +def test_public_wins_slug_collision(fake_root): + # Top-level (public) match takes priority over a .local shadow. + assert rd.dataset_dir("pub") == fake_root / "rPUBLIC-pub" + + +def test_unknown_slug_returns_none(fake_root): + assert rd.dataset_dir("nope") is None