32 KiB
21. Топология ролей перевода: чем платим за второй проход и есть ли ему замена
Полигон-сессия 06.08.2026. Исполнение docs/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT.md
(оркестратор №15, санкция владельца 06.08, D39.108). Зона: eval/role_topology/ + этот файл +
пинг в PROGRESS «Полигон». Потолки предварительные: Ф0 ≤$0.70 · Ф1 ≤$1.00 · Ф2а ≤$2.50 · Ф2б ≤$3.00.
СТАТУС: Ф0 ИСПОЛНЕНА ЧАСТИЧНО, ПЛАТНЫЕ ФАЗЫ НЕ ЗАПУСКАЛИСЬ. Потрачено $0. Разделы §0–§2 — пре-регистрация и результаты бесплатной метрологии. Блокер запуска назван в §0.2.
ИТОГ (для оркестратора)
Заполняется после Ф2. Сейчас закрыты только вопросы метрологии — см. §2.
Что уже решено данными и меняет план пака:
- Детектор «выдуманное слово» построен и работает (§2.1): precision 0.78 / recall 0.70 на
2177 размеченных словотипах против 1.00 / 0.10 у боевых чекеров, вне выборки 6/6. Это не
починка бага, а закрытие дыры, которую движок объявил сам:
sanitizer.go:429дословно — «detection needs a morphology pass (Ф2), so it stays silent here». - Детектор «смысловая инверсия» через QE-ранкер — ОТРИЦАТЕЛЬНЫЙ РЕЗУЛЬТАТ (§2.2), проверенный контрольным декоем. Следствие для плана: арм C фазы 2б в режиме «реальные детекторы» по классу инверсий питать нечем; развилка вынесена владельцу в §0.3.
- Три метрики из шести, которые я построил по букве промта, мерили шум и были сняты замером (§2.3). Это цена, которую платит любая батарея без прогонки на чистом тексте, и она названа числами, а не общими словами.
§0. ПРЕ-РЕГИСТРАЦИЯ
Фриз коммитом ДО первого платного вызова. Изменения после фриза = новый experiment-ID; девиации — явным списком в §5. Amend фриза запрещён.
0.1. Вопрос и что считается ответом
Какая топология целевая — «черновик + переписыватель», «черновик + гейты + точечный ремонт», «однопроходка сильной моделью», гибрид с маршрутизацией — и кто жильцы ролей.
Ответом считается таблица «арм → детерминированная батарея · MQM-lite двух судей · цена за принятую 1000 слов (p50/p95) · дрейф на связном отрезке», где различия названы ОТНОСИТЕЛЬНО порога различимости Ф0.6, а не абсолютно. Ответом НЕ считается ранжирование армов по среднему баллу судьи: эксп-20 §5.4 намерил, что судья согласен сам с собой на идентичном входе в 56% клеток и разниц меньше ~2:1 не разрешает.
Армы равноправны. «Правильного ответа», которого ждут, не существует; при неразличимости дефолт — самый дешёвый и детерминированный арм.
0.2. Материал — ОТКРЫТЫЙ БЛОКЕР
Промт заказывает невиданный срез: свежая zh-вебновелла без опубликованного ru-перевода, рассеянные окна для дисперсии + связный отрезок 8–10 глав для дрейф-метрик.
Такого текста в дереве нет. Инвентарь ~/books с провенансом по докам: gu-zhenren (蛊真人) —
претрейн-канон, ровно тот случай, который строка 55 бэклога объявляет негодным дословно;
jinpingmei — минский байхуа, PD; isekai_majutsushi_jp — ja, не zh (exp11 §41);
fifty_shades_1_en, Empire_of_the_Dawn — en. Каталог eval/data/samples/webnovel/zh/, куда
харнесс webnovel_slice.py:14 ждёт корпус, никогда не создавался — строка 55 висит именно поэтому.
То, что exp07 называл «невиданным вебновелл-текстом», — это само 蛊真人 (07-coverage-precision.md:85),
и его же хвост предписывает «перепроверить на корпусе владельца».
Норма при этом однозначна: корпус кладёт владелец (webnovel_slice.py:1-3 — «запускается по
появлению корпуса владельца»). Полигон текст не добывает.
Развилка передана владельцу 06.08 (варианты: владелец кладёт файлы · санкционирует добычу полигоном · Ф2 идёт на 蛊真人 с объявленной границей). До ответа платные фазы не стартуют. Оговорка о свежести, которую важно не потерять: дата публикации контаминацию не снимает — катофы моделей разные. Чище всего берутся последние главы ИДУЩЕГО сериала (июнь–август 2026), и контаминация всё равно меряется (continuation/cloze + поиск fan-переводов), а не предполагается.
0.3. Армы
Ф2а — «переписывание как класс». Черновики фризятся и подаются идентичными всем армам-редакторам (парный дизайн, McNemar).
| Арм | Что |
|---|---|
| F | do-nothing пол: черновик как есть через гейты. Все редакторские армы мерятся против него |
| A | байт-боевой бейзлайн flash→dspro (без банкноты — объявленная девиация бейзлайна, не чинить) |
| B | связка flash→glm-5-OFF full-regen |
| D | однопроходка сильной модели С мандатом перевёрстки |
| D′ | она же БЕЗ мандата — деконфаунд «модель против мандата» |
Ф2б — ремонт и маршрутизация. Гейт входа: детекторы Ф0.4 валидированы.
| Арм | Что |
|---|---|
| C | черновик (с мандатом перевёрстки) → детекторы+гейты → точечный ремонт дешёвым фиксером; два режима: oracle-флаги (потолок) и реальные детекторы (пол); после каждого фикса полный ре-гейт, кап 2 итерации |
| E | обратная связка: сильный черновик → дешёвый фиксер по флагу |
| G | guarded+routed: QE/гейты скорят все окна → стиль-пасс ТОЛЬКО флагнутым, правка принимается только если внешний гейт видит улучшение (max(draft, edited)) |
⚠ ПОПРАВКА К АРМАМ C и G ПО РЕЗУЛЬТАТУ Ф0.4 (§2.2). QE-ранкер локальную смысловую инверсию не детектирует. Следствия, объявленные ДО запуска:
- арм C гонится в oracle-режиме и в режиме «реальные детекторы», но реальный режим питается ТОЛЬКО детектором выдуманных слов + существующими $0-гейтами; класс «инверсия» в реальном режиме остаётся ненайденным, и разрыв oracle↔реальность печатается как главный результат арма;
- арм G маршрутизирует не по QE-баллу инверсии, а по батарее Ф0.5 + QE как ГРУБОМУ фильтру (декой доказал: рассогласование сегмента ранкер видит, Δ +7.1) — то есть G ловит «сегмент поехал целиком», а не «сегмент поехал в одном слове». Это сужение арма, и оно объявлено здесь.
Reflow-план кодом (Q4c, research/19 §C1.3) — ДИСПОЗИЦИЯ ОТКАЗА. Не гоню. Основание: эксп-20 §5.2 уже проверил гипотезу «мандат в промпте заменяет второй проход» слепым судом и ОПРОВЕРГ её (русский 3:12, вёрстка 5:10 в пользу связки), а деконфаунд мандата в этом паке несёт арм D′ — отдельный кодовый reflow-план добавил бы третий способ спросить то же самое при бюджете, которого нет.
0.4. Метрики и пороги
Порядок первичности задан не вкусом, а измеренным шумом инструментов.
- Детерминированная батарея Ф0.5 — первична. Шума не имеет: повтор даёт то же число. Состав и границы каждой проверки — §2.3.
- MQM-lite двух судей — счёт типизированных ошибок (спан+тип+severity на 1000 слов). Pairwise-преференс — только для стиль-осей. Судья не судит армы своего семейства-жильца; вердикты раскладываются по семействам судей. Агрегация Bradley–Terry с bootstrap-CI.
- Цена за принятую 1000 слов — p50/p95, с кэшем/батчем/ретраями; перезаписанные вызовы тоже деньги (леджер = нижняя граница).
- Дрейф на связном отрезке — швы, ты/вы-стабильность, рост банка.
Порог различимости берётся из Ф0.6 и записывается ДО Ф2. Правило вердикта: «арм X бьёт Y, если перевес по оси больше порога Ф0.6»; средние исходы = «неопределённо»; при неразличимости побеждает самый дешёвый и детерминированный арм.
0.5. Прогнозы (сверка с фактом идёт в отчёт)
Записаны до запуска, чтобы отчёт мог показать, где я ошибся.
| # | Прогноз | На чём основан |
|---|---|---|
| П1 | F (do-nothing) НЕ будет последним; по общему вердикту он в пределах порога от A | эксп-20: на dspro второй проход отрицателен (общий 5:1 в пользу одного прохода) |
| П2 | B (glm-5) выиграет русскую прозу и проиграет верности/термам | эксп-20 §5: у glm свип вёрстки 6:0, у dspro верность 5:1 |
| П3 | D (однопроходка сильной) выиграет качеством и проиграет ценой ≥2× | цена сильного тира против flash |
| П4 | G даст лучшее отношение цена/качество среди всех армов | он единственный не платит за неизменённое |
| П5 | Разрыв oracle↔реальные детекторы в арме C будет БОЛЬШЕ, чем разрыв между армами Ф2а | recall детектора слов 0.70, детектора инверсий нет вовсе |
| П6 | Батарея разведёт армы там, где судья скажет «неразличимо» | у батареи шум ноль, у судьи 56% самосогласия |
0.6. Смета
Ф0 ≤$0.70 (предзамер судей ≤$0.60) · вахта эффорта ≤$0.05 · Ф1 ≤$1.00 · Ф2а ≤$2.50 · Ф2б ≤$3.00. Живые стопы механизмом + проекционный гард. Подъём или пере-нарезка — только словом владельца ДО запуска фазы. Не влезает — стоп и пинг, не резать молча.
0.7. Что считается провалом фазы
Ф0.6 не даёт порога различимости в потолке → СТОП и пинг с расчётом мощности, а не молчаливое уменьшение числа окон. Детекторы Ф0.4 не валидируются → арм C идёт только oracle-режимом, и это записывается как граница, а не как результат.
§1. Что уже стоит на дереве ($0)
| Файл | Что делает | Проверен |
|---|---|---|
eval/role_topology/list_models.py |
живой листинг моделей по 7 ключам; слаги для пре-рега снимаются в день запуска | исполнением, §2.4 |
eval/role_topology/detect_word.py |
детектор «выдуманное слово», 4 накопительных слоя | selfcheck.py, 12 пинов |
eval/role_topology/align.py |
монотонное выравнивание zh↔ru (Гейл–Чёрч), $0, без моделей | selfcheck.py, 5 пинов |
eval/role_topology/qe_bench.py |
обёртка MetricX-24 в reference-free режиме + оконный мини-бенч | selfcheck.py --qe, 3 пина |
eval/role_topology/qe_segment.py |
посегментный QE + контрольный декой | исполнением, §2.2 |
eval/role_topology/battery.py |
детерминированная батарея, 9 проверок | 16 пинов правил + прогон по 91 единице |
eval/role_topology/selfcheck.py |
ревью исполнением всего харнесса; ненулевой код = харнесс не годен | сам |
§2. Ф0 — метрология (исполнено, $0)
2.1. Детектор «выдуманное слово»: построен, базлайн бит
Земля. ~/books/gu-zhenren/labels/labels/k3.jsonl — 2177 размеченных словотипов из шести
реальных прогонов, 10 помечены defect. Разметка сделана ЧУЖОЙ сессией (пакет-6, 26.07) до и вне
этого экспа ⇒ требование «разметка вторым контуром» выполнено построением, а не моей рукой.
Базлайн взят из кода, а не из заголовка. metrics.json того же набора даёт боевым чекерам на
k3 precision 1.0 / recall 0.1. Чтение checks/sanitizer.go:408-436 объясняет почему: боевой
detectBrokenWords ловит ровно два узких класса — невозможные кириллические биграммы с ь/ъ и
кириллично-латинские гомоглифы, — а морфологический проход в нём отложен ЯВНО (:429
«needs a morphology pass (Ф2), so it stays silent here»). ⇒ формулировка «мой детектор бьёт баг»
неверна; верная — он закрывает объявленную дыру.
| Слой | tp | fp | fn | precision | recall |
|---|---|---|---|---|---|
боевые чекеры (их metrics.json) |
1 | 0 | 9 | 1.000 | 0.100 |
| С0 нет в словаре pymorphy3 | 9 | 34 | 1 | 0.209 | 0.900 |
| С1 + вайтлист банка/канона книги | 9 | 28 | 1 | 0.243 | 0.900 |
| С2 + палладиевская форма (со склонением) | 8 | 11 | 2 | 0.421 | 0.800 |
| С3 + разложимость на известные части | 7 | 2 | 3 | 0.778 | 0.700 |
Слои накопительные и печатаются по одному — норма D39.46(а) («у каждого фактора обязан быть арм без него») применена к слоям детектора.
Выделенная валидация: 6/6 на посадках k1 пробы 18 — независимый набор чужой сессии, в настройке не участвовал. ⚠ Набор ЛЕГЧЕ живого: посадки сконструированы заведомо не-словами. Читать как верхнюю границу.
Проверка на подгонку. Свободный параметр слоя С2 (глубина усечения окончания) прогнан по диапазону: k∈{(1,), (1,2), (1,2,3)} при пороге 2 слогов дают ОДНИ И ТЕ ЖЕ 0.778/0.700. Вердикт по параметру не двигается ⇒ подгонки по нему нет.
Ущерб от ложного флага — отдельным числом, как требует промт: из 9 флагов ложных 2 (22%); столько починок арма C правили бы здоровое слово.
Дефекты САМОЙ ЗЕМЛИ, найденные проверкой посылки (пинятся selfcheck.py, чтобы отчёт не считал
recall по номинальным 10 позитивам):
впердиисилённыйвcorpus.jsonlОТСУТСТВУЮТ вовсе, даже подстрокой, хотя README набора объявляет этот файл источником ID («смещения считаны по строкам corpus.jsonl»);ной— валидное русское слово (императив «ныть»); в класс попало из-за разреза токена на границе с иероглифом (伤ной), то есть это дефект утечки, а не выдуманное слово. Один из трёх моих «пропусков» — ошибка класса в метке, а не промах детектора. В классе остаётся 9 позитивов;- два выживших ложных срабатывания (
льшим,льшую) — фантомы сборщика пула: комбинирующий знак ударения U+0301 в «бо́льшим» разрезал токен (51 из 53 вхождений идут после «о», 2 — после ударения).
⚠ Сужение собственного вывода по итогам Go-оверлея. Первая формулировка была «диакритика ломает
любой словный чекер». Проверка исполнением (оверлей вне репозитория, движок read-only) её сузила:
ExportNormalize знак снимает корректно, а SanitizeOutput на тексте с ударением и без даёт
ОДИНАКОВЫЙ вердикт (total=0 в обоих). ⇒ боевой путь не страдает; страдает наивная токенизация в
полигонном коде. Моя батарея нормализует до токенизации (§2.3).
Оставшаяся слепая зона детектора, названная явно: привлеклось = «при» + «влеклось», обе части
настоящие. Класс «валидная приставка + валидное слово, не образующие реального слова» морфологией
не берётся — нужен корпусный или языко-модельный сигнал.
2.2. Детектор «смысловая инверсия» через QE: ОТРИЦАТЕЛЬНЫЙ РЕЗУЛЬТАТ
Инфраструктура поднята с нуля (на машине её не было): CometKiwi / xCOMET / wmt23-cometkiwi-xl —
все gated: auto на HuggingFace, токена у сессии нет; unbabel-comet 2.2.7 не импортируется на
Python 3.14 (functools._HashedSeq удалён). Взята незагейченная google/metricx-24-hybrid-large-v2p6
(mT5-large 1.23B, штатный reference-free режим, CPU-загрузка 7 с). Две несовместимости пойманы
исполнением: protobuf 4.25 против py3.14 и обязательный use_cache=False против transformers 4.57
(с кэшем маска кросс-внимания на токен короче выхода энкодера — падает на любой длине).
Отклонение от буквы промта («CometKiwi/xCOMET») объявлено здесь.
⚠ Шкала MetricX перевёрнута: больше = хуже. Ориентация запинена в selfcheck.py — спутать её
значит получить детектор, флагающий ровно здоровые сегменты.
Замерено на ДВУХ размерах модели — заявлять отрицательный результат по младшей, когда доступна старшая, преждевременно.
| Замер | large (1.23B) | XL (3.7B) | Чтение |
|---|---|---|---|
| уровень окна, 6 окон × 2 класса | Δ +0.035 (4/6) | — | порчу не видит |
| сегмент, k1 выдуманное слово | Δ +0.073 (4/6) | Δ +0.981 (4/6) | чувствительность растёт с моделью |
| сегмент, k2 смысловая инверсия | Δ −0.001 (3/6) | Δ +1.147 (5/6) | то же, но n=6 ⇒ p≈0.11, НЕ установлено |
| абсолютный порог, 81 здоровый сегмент | лучшая precision 0.17 | лучшая precision 0.16 | детектором быть не может НИ НА ОДНОЙ |
| ДЕКОЙ (D39.46б), n=69 | Δ +7.107 (65/69) | Δ +7.000 (59/69) | ранкер на этом материале ЧУВСТВИТЕЛЕН |
Декой — несущая часть замера: без него «не увидел посадку» и «слеп на этом материале» неразличимы,
а это разные вердикты. Он показывает, что модель работает и формат входа верен (сверен с авторским
metricx24/predict.py:_make_input).
Главный вывод — не «ранкер плох», а «два режима расходятся». Абсолютный порог и парное сравнение отвечают на разные вопросы, и это ровно граница между двумя армами фазы 2б:
- арм C ищет дефект в ОДНОМ тексте, образца нет ⇒ ему нужен абсолютный порог. Порога нет: precision ≤0.17 на обеих моделях, баллы здоровых сегментов (медиана 6.1, p90 11.4, макс 16–18) полностью перекрывают баллы испорченных. Арм C по классу «инверсия» не питаем.
- арм G сравнивает ДВЕ версии одного сегмента ⇒ ему нужна парная дельта. Она состоятельна: на механической инверсии полярности (72 пары, построены снятием/вставкой отрицания при личном глаголе) медиана Δ +1.490, направление 66/72 = 92%, знаковый тест p < 1e-5. Арм G питаем.
⚠ Граница парного замера объявлена заранее и остаётся в силе: механическая инверсия ЛЕГЧЕ ручной посадки (голое «не» — сильный поверхностный сигнал, а посадки пробы 18 меняли смысл переписыванием оборота). Поэтому 92% читается как ВЕРХНЯЯ граница парного режима; на реальном классе оценка — те самые 5/6 при p≈0.11, то есть не установлено.
Следствия для пака (внесены в §0.3 ДО запуска): арм C в реальном режиме не покрывает класс инверсий и печатает разрыв oracle↔реальность как главный результат; арм G сохраняет свой QE-гейт, но его пропускная способность обязана быть откалибрована на РЕАЛЬНЫХ правках — §2.5.
2.3. Детерминированная батарея: построена, и три её метрики сняты собственным замером
Девять проверок по спецификациям docs/research/12-failure-modes-ru-target.md (у каждого из 12
режимов отказа русской цели там есть раздел «Детекция» — правила взяты оттуда, а не придуманы).
16 пинов правил на синтетике с известным ответом + прогон по 91 реальной единице.
Главное, что дал прогон по чистому тексту: правила, написанные по букве спецификации, в трёх случаях из шести мерили шум. Числа до и после — на 91 единице, на единицу:
| Метрика | было | стало | что было не так |
|---|---|---|---|
| нарушений типографики | 3.87 | 0.18 | ёлочка в начале строки считалась нарушением (228 срабатываний) — это легитимная цитата/мысль; прописная после атрибуции (119) — в основном имена собственные, которым прописная положена |
| единиц с транслит-междометиями | 0.64 | 0.00 | подстрочный матчинг: 77 «ара» внутри «барабан», 13 «ауч» внутри «паучьей». Чинится границами слова |
| потеряно / появилось величин | 0.70 / 5.56 | 0.25 / 0.27 | не разбирались русские числительные словами («пятьсот»); малые числительные в русском живут местоимениями («один из них»), которым в 一个 нет величины. Пол величины 100 выбран свипом 8 конфигураций |
| не-палладиевских имён | 1.05 | 0.07 | склонённые транскрипции («Чжэна» — 24 срабатывания) и ПЕРЕВЕДЁННЫЕ имена («Первопредок», «Кровавокрылая»), которым палладиевская форма не положена |
| омографов без ё | 1.67 | снята | 130 из 152 — обычное множественное «все», 22 — «небо» в прямом значении. Различить «все/всё» без контекста нельзя; вместо счёта меряется политика ё и её единообразие |
Живые остатки на том же корпусе: ханьцзы в финале 4 знака на 91 единицу (1 единица); не-палладиевских имён 6 срабатываний / 5 различных слов на 2184 кандидата, из них 2 — настоящие сигналы; смешение ты/вы в 0.31 единицы (нижняя граница: смешение между разными собеседниками легитимно); медиана доли слов черновика, доживших до финала, 0.942.
(Расхождение 5↔6 поймано верификатором verify_report.py, а не глазами: в первую редакцию отчёта
попало число РАЗЛИЧНЫХ слов, посчитанное дедуплицирующим путём, при 6 фактических срабатываниях.
Ровно тот класс ошибки, ради которого верификатор и написан.)
Объявленные границы батареи (в отчёт, не в примечание): величины 1–99 вне охвата; «длины предложений против нативного ру-корпуса» не считаются абсолютно — нативного русского референс-корпуса в дереве нет, и подставлять чужую константу нельзя (тот же класс ошибки, что снятый жанровый словарь D39.47), поэтому распределение сравнивается МЕЖДУ АРМАМИ; ты/вы без speaker-ID — сигнал к просмотру, не счёт ошибок; род прош. времени работает только при явной близости имени и глагола.
2.4. Живой листинг моделей
Снят по всем семи ключам, все отвечают. Против 00-provider-quirks.md появились новые жильцы, и
они пойдут в кандидаты Ф1 слагами дня запуска: grok-4.5 · kimi-k3 · glm-5-turbo,
glm-5.2 · gemini-3.5-flash, gemini-3.6-flash. У DeepSeek листинг прежний (два слага) —
но урок календаря D39.61 в силе: «слаг живой ≠ модель та же», и вахта реестра 108 (пере-проба
маппинга эффорта deepseek-v4-pro) остаётся первым платным шагом Ф1.
§3. Девиации от промта
| # | Девиация | Основание |
|---|---|---|
| 1 | QE-ранкер — MetricX-24 вместо CometKiwi/xCOMET | все варианты CometKiwi/xCOMET gated, токена нет; unbabel-comet не встаёт на py3.14 |
| 2 | Reflow-план кодом (Q4c) не гонится | §0.3: гипотеза уже опровергнута эксп-20 §5.2, деконфаунд несёт арм D′ |
| 3 | Арм C реального режима не покрывает класс инверсий; арм G сужен | §2.2, объявлено ДО запуска |
| 4 | Счёт омографов ё снят из метрик | §2.3, снят собственным замером как ложный |
§4. Открыто
- Материал Ф0.2 — на владельце (§0.2). Блокирует все платные фазы.
- Ф0.3 банк среза, Ф0.6 предзамер судей, Ф1, Ф2а, Ф2б — не запускались.