#!/usr/bin/env python3 """ГЕЙТ ПАРИТЕТА СУДЕЙСКИХ ОБВЯЗОК. $0. Норма Д0.13 П-4. Единственный неустранимый конфаунд прохода `tier` пака 23: промт харнесса Sol нёс правила плотности счёта («две одинаковые ошибки — это два», «4 задания за сессию»), которых у обвязки Claude не было. Значит часть расхождения семейств в РАЗЫ могла быть куплена ИНСТРУКЦИЕЙ, а не моделью, и разделить это постфактум нечем. Отсюда норма: обвязки обоих семейств обязаны совпадать ВЕЗДЕ, кроме путей, и совпадение проверяется механически ДО прогона, а не обещанием. Приём тот же, что у `promptdiff.py` для пар-промтов: нормализуем объявленное различие и требуем побайтного совпадения остального. Запуск: eval/.venv/bin/python eval/dovodka/paritet.py """ from __future__ import annotations import re import sys from pathlib import Path P = Path(__file__).resolve().parent / "judge-prompts" # ЕДИНСТВЕННОЕ объявленное различие — каталоги. Всё прочее обязано совпасть. PATHS = ("sud-d4", "sol-d4-work") def body(f: Path) -> str: t = re.sub(r"", "", f.read_text(encoding="utf-8"), flags=re.S) for p in PATHS: t = t.replace(p, "ПУТЬ") return "\n".join(x.rstrip() for x in t.strip().splitlines()) def main() -> int: bad = 0 def ck(n: str, ok: bool, d: str = "") -> None: nonlocal bad bad += not ok print(f"[{'OK ' if ok else 'ПРОВАЛ'}] {n}" + (f" {d}" if d else "")) core, cl, sol = P / "core.md", P / "claude.md", P / "sol.md" for f in (core, cl, sol): ck(f"файл обвязки есть: {f.name}", f.exists()) if bad: return bad a, b = body(cl), body(sol) ck("обвязки совпадают ВЕЗДЕ, кроме путей", a == b, f"первое расхождение: {next((i for i, (x, y) in enumerate(zip(a.splitlines(), b.splitlines(), strict=False)) if x != y), '—')}") c = core.read_text(encoding="utf-8").strip() norm = lambda t: re.sub(r"\s+", " ", t) # noqa: E731 перенос строки не различие for f in (cl, sol): ck(f"{f.name} несёт общее ядро дословно", norm(c) in norm(f.read_text(encoding="utf-8"))) # ядро обязано нести правила, купленные дорого прошлыми паками must = ["ОТДЕЛЬНО против исходника", "требует обоснования ЦИТАТОЙ", "Ноль — это утверждение", "потерянное отрицание", "Не ищи и не открывай ничего другого", # решение владельца 16.08, меняющее шкалу: см. `zsud.RUBRIC_*` и эрратy Д18 "переврать смысл исходника — ошибка; обойтись с его буквой вольно — нет"] for m in must: ck(f"ядро несёт правило: «{m[:44]}»", norm(m) in norm(c)) print(f"\n{'ПАРИТЕТ ОБВЯЗОК СОБЛЮДЁН' if not bad else f'ПРОВАЛОВ: {bad}'}") return bad if __name__ == "__main__": sys.exit(1 if main() else 0)