ouroboros/tests/test_comma_list_sweep.py
Ouroboros af3523466d v7next F3.1-D ABI-10: remove the reviewer comma-list migration read (owner 5.4=A)
The structured OUROBOROS_REVIEWER_SLOTS is the ONE reviewer configuration
surface. The legacy migration-read block (reviewer_slot_config.py:
_shared_session_route_spec / _legacy_rows / _legacy_config — comma-lists,
phase-5 per-row/advisory route envs, global-effort copying) is DELETED; with
no structured value the loader serves the SHIPPED DEFAULT PANEL: api_chat
triad/scope rows over get_review_models()/get_scope_review_models() (the
derived env plane — identical models to the old legacy defaults on every
config class, incl. single-direct-provider adaptation and a bench launcher's
env override), default advisory row, source="default", historical positional
slot ids (receipts keep lining up) and the unchanged legacy fingerprint
identity for the unconfigured panel (skill-review replay authority survives
the upgrade).

Settings vocabulary: OUROBOROS_REVIEW_MODELS / OUROBOROS_SCOPE_REVIEW_MODELS /
OUROBOROS_SCOPE_REVIEW_MODEL plus the phase-5 route envs
(OUROBOROS_REVIEW_ROUTES / OUROBOROS_SCOPE_REVIEW_ROUTES /
OUROBOROS_ADVISORY_REVIEW_ROUTE) leave SETTINGS_DEFAULTS and join
RETIRED_SETTING_KEYS (ghost purge on load; an install that configured
reviewers only through them gets the default panel — the RC auditor names
this migration, per plan). The derived runtime projection
(project_reviewer_slots_into_env) STAYS, floored from
OPENROUTER_REVIEW_DEFAULTS; get_review_models/get_scope_review_models keep
serving the API-pinned surfaces from that env plane. server_runtime's
provider-defaults migration now normalizes a ghost comma value it is FED but
never INTRODUCES a retired key (the direct-provider review adaptation lives
on the read side); the singular→plural promotion in model_slots is gone
(purged before it could run). gateway/settings candidate probes read the
structured candidate else the live derived config.

Bench templates migrated to structured slots with the SAME models
(continual_learning, gaia, swe_bench_pro base/example/probe/profile; comma
keys dropped everywhere incl. osworld/cybergym/programbench which already
carried structured values); run_tb metadata defaults now come from
OPENROUTER_REVIEW_DEFAULTS; manifests record OUROBOROS_REVIEWER_SLOTS.

tests/test_comma_list_sweep.py is the phase CI gate (ABI-10 hook): no
migration-read branches, retired vocabulary pinned, bench templates clean,
prose rewritten, derived projection alive. ARCHITECTURE deltas same commit.

(cherry picked from commit e7578133758f01eac584e8e6522b3f03c4d09818)
2026-08-31 16:54:17 +00:00

114 lines
4.5 KiB
Python

"""ABI 7.0 (ABI-10, owner 5.4=A): the comma-list remnant sweep — the phase CI gate.
Grep-level checker pinning that the legacy reviewer comma-list migration read
stays gone: no migration-read branches, the settings vocabulary carries the
comma keys only as RETIRED, and no bench settings template configures
reviewers through them. The comma ENV spellings legitimately survive as the
derived runtime projection (``project_reviewer_slots_into_env`` + the
API-pinned getters) — the sweep therefore pins SETTINGS-plane and
migration-branch absence, not env-name absence.
"""
from __future__ import annotations
import json
import pathlib
import re
_ROOT = pathlib.Path(__file__).resolve().parents[1]
_COMMA_SETTINGS_KEYS = (
"OUROBOROS_REVIEW_MODELS",
"OUROBOROS_SCOPE_REVIEW_MODELS",
"OUROBOROS_SCOPE_REVIEW_MODEL",
)
_PHASE5_ROUTE_KEYS = (
"OUROBOROS_REVIEW_ROUTES",
"OUROBOROS_SCOPE_REVIEW_ROUTES",
"OUROBOROS_ADVISORY_REVIEW_ROUTE",
)
def _python_files() -> list[pathlib.Path]:
files: list[pathlib.Path] = []
for base in ("ouroboros", "supervisor"):
files.extend((_ROOT / base).rglob("*.py"))
return files
def test_no_migration_read_branches_remain():
"""The reviewer_slot_config legacy block and its helpers stay deleted."""
retired_symbols = ("_legacy_rows", "_legacy_config", "_shared_session_route_spec")
hits: list[str] = []
for path in _python_files():
text = path.read_text(encoding="utf-8", errors="replace")
for symbol in retired_symbols:
if re.search(rf"\b{symbol}\b", text):
hits.append(f"{path.relative_to(_ROOT)}: {symbol}")
assert not hits, f"migration-read remnants: {hits}"
def test_reviewer_config_source_is_never_legacy():
"""`ReviewerSlotConfig.source` vocabulary is structured|default now."""
text = (_ROOT / "ouroboros" / "reviewer_slot_config.py").read_text(encoding="utf-8")
assert 'source="legacy"' not in text
assert 'source="default"' in text and 'source="structured"' in text
def test_settings_vocabulary_retired_the_comma_keys():
from ouroboros.settings_defaults import RETIRED_SETTING_KEYS, SETTINGS_DEFAULTS
for key in (*_COMMA_SETTINGS_KEYS, *_PHASE5_ROUTE_KEYS):
assert key not in SETTINGS_DEFAULTS, f"{key} must not be a settings key"
assert key in RETIRED_SETTING_KEYS, f"{key} must be RETIRED (ghost purge)"
def test_load_settings_purges_a_comma_only_install(tmp_path, monkeypatch):
"""An install that configured reviewers only through comma keys gets them
stripped on load (5.4=A: it runs the shipped default panel; the RC auditor
names this migration)."""
import ouroboros.config as config
settings_path = tmp_path / "settings.json"
settings_path.write_text(json.dumps({
"OUROBOROS_REVIEW_MODELS": "x/custom,y/custom",
"OUROBOROS_SCOPE_REVIEW_MODEL": "z/custom",
}), encoding="utf-8")
monkeypatch.setattr(config, "SETTINGS_PATH", settings_path)
for key in (*_COMMA_SETTINGS_KEYS, *_PHASE5_ROUTE_KEYS):
monkeypatch.delenv(key, raising=False)
loaded = config.load_settings()
for key in _COMMA_SETTINGS_KEYS:
assert key not in loaded, f"retired {key} leaked through load_settings"
def test_no_bench_settings_template_configures_reviewers_via_comma_keys():
"""Bench templates migrated to the structured key with the SAME models."""
hits: list[str] = []
for path in (_ROOT / "devtools" / "benchmarks").rglob("*.json"):
try:
data = json.loads(path.read_text(encoding="utf-8"))
except ValueError:
continue
if not isinstance(data, dict):
continue
for key in _COMMA_SETTINGS_KEYS:
if key in data:
hits.append(f"{path.relative_to(_ROOT)}: {key}")
assert not hits, f"bench templates still carry retired comma keys: {hits}"
def test_prose_no_longer_promises_a_comma_list_migration():
"""The rewritten prose markers stay rewritten (review.py:965 class)."""
for rel in ("ouroboros/tools/review.py", "ouroboros/reviewer_slot_config.py",
"ouroboros/review_model_routes.py"):
text = (_ROOT / rel).read_text(encoding="utf-8")
assert "migrated comma-lists" not in text, rel
assert "старый читается" not in text, rel
def test_derived_projection_survives():
"""5.4=A removes the migration READ; the derived projection STAYS."""
from ouroboros.reviewer_slot_config import project_reviewer_slots_into_env
assert callable(project_reviewer_slots_into_env)