From 969ad2f8dca445a7e60648819f4beed25a32256a Mon Sep 17 00:00:00 2001 From: heaven Date: Fri, 14 Aug 2026 17:37:53 +0300 Subject: [PATCH] Make the noise floor and judge audit belong to the axis so the en panel gets its own threshold and cannot read any axis raw cells --- eval/dovodka/contour.py | 30 ++++++++++++++++++++---------- eval/dovodka/sud.py | 6 +++++- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/eval/dovodka/contour.py b/eval/dovodka/contour.py index 5ba9edc0..3459e180 100644 --- a/eval/dovodka/contour.py +++ b/eval/dovodka/contour.py @@ -84,6 +84,14 @@ ARM_KIND = {"A1": "flags", "A1B": "flags", "A6F": "flags", "A4": "canonfix", "J2": "onepass"} +def phase_letter(arm: str) -> str: + """Буква фазы в теге. Одна на все теги оси — включая половины шумового пола.""" + P = pair() + if P.key == "zh-ru": + return "f" if arm.startswith("A6") else "a" + return "g" if arm == "E6" else {"en-ru": "b", "ja-ru": "c"}[P.key] + + def phase_of(arm: str) -> str: """Фаза кассы арма. Должна совпадать с буквой в `tag`, иначе трата уедет мимо потолка.""" P = pair() @@ -412,11 +420,7 @@ def tag(arm: str, uid: str, part: str = "") -> str: # Буква в теге — ФАЗА КАССЫ, а не пара: глоб `dv-b-*` покрывает ФД-B, `dv-a-*` — ФД-A. # Пар-префикс, стоявший здесь до 14.08, давал `dv-en-…`, который не покрыт ни одним глобом, # и покупка отверглась бы гейтом кассы — лучше так, чем мимо потолка, но работать нельзя. - P = pair() - if P.key == "zh-ru": - ph = "f" if arm.startswith("A6") else "a" - else: - ph = "g" if arm == "E6" else {"en-ru": "b", "ja-ru": "c"}[P.key] + ph = phase_letter(arm) return f"dv-{ph}-{arm.lower()}{('-' + part) if part else ''}-{uid}" @@ -711,19 +715,25 @@ def cmd_floor() -> None: эксп-23 `CTRLfloorA` совпал с армом `T1` побайтно в 16/16, и контроль оказался пуст. Половины судят РАЗНЫЕ сессии (это забота судейского рига, здесь — только генерация). """ - led = MONEY.Guarded("ФД-A") - old = [u for u in P22.M.units_zh() if u["uid"] not in EXCLUDED] - for u in old: + # ⚠ Пол принадлежит ОСИ, а не китайскому паку: касса, буква тега и состав единиц берутся + # у текущей пары. Прежняя редакция звала `ФД-A` и `units_zh()` безусловно, то есть на + # английской оси купила бы китайский пол в китайскую кассу — и порог оси считался бы по + # чужому шуму. Критик-арм передаётся, потому что у осей он называется по-разному. + crit_arm = "A3" if pair().key == "zh-ru" else "E3" + led = MONEY.Guarded(phase_of(crit_arm)) + src_units = ([u for u in P22.M.units_zh() if u["uid"] not in EXCLUDED] + if pair().key == "zh-ru" else units_ok()) + for u in src_units: uid, src = u["uid"], u["source"] draft = base_draft(uid) if not draft.strip(): continue - places, _ = critic_places("A3", uid) + places, _ = critic_places(crit_arm, uid) if not places: print(f" {uid}: мест нет — единица в пол не идёт") continue for half in ("flo1", "flo2"): - tg = f"dv-a-{half}-{uid}" + tg = f"dv-{phase_letter(crit_arm)}-{half}-{uid}" if (OUT / f"{tg}.json").exists(): continue _buy(led, tg, fix_msgs(src, draft, places), diff --git a/eval/dovodka/sud.py b/eval/dovodka/sud.py index bc6bf139..da20d878 100644 --- a/eval/dovodka/sud.py +++ b/eval/dovodka/sud.py @@ -239,7 +239,11 @@ def emit(half: int) -> None: f"ключ → {KEYS} (судье НЕ давать)") -FORBIDDEN = ("blind-keys", "dv-a-", "dv-f-", "/books/dovodka", "contour.py", "sud.py") +# ⚠ Список запретов — ПО ВСЕМ осям, а не по своей. Судья английской оси, заглянувший в `dv-a-`, +# так же скомпрометирован, как заглянувший в `dv-b-`: он увидит сырьё с полем `arm` и перестанет +# быть слепым. Перечисляем все префиксы фазы, а не только свой. +FORBIDDEN = ("blind-keys", "dv-a-", "dv-b-", "dv-c-", "dv-f-", "dv-g-", + "/books/dovodka", "contour.py", "sud.py", "en_axis.py", "ja_axis.py") def audit(tr_dir: Path) -> int: