textmachine/docs/archive/reports/POLYGON_PREMEASURE_2026-07-26.md

92 KiB
Raw Permalink Blame History

Полигон, пакет-8: три пре-замера перед дизайном расширения эмиссии

Санкция: D39.49 (владелец, 26.07.2026), база D39.48. Бюджет ≈$0.14, потолок $0.30.

Ревью-шапка (оркестратор №8, 26.07): ПРИНЯТ, D39.50 — 8/8 CONFIRMED. Приёмка исполнением из сохранённого сырья (147 вызовов): деньги $0.11313 пересчитаны по usage до токена и цента; множества каналов (13/67/2/78) пере-раном joint_recall на read-only копиях БД; цензура 49/51 и правомерность пре-рег стопа — пересчётом; разметка замера 2 зафиксирована ДО прогона (mtime-цепочка), выдумки 77/80/78 из 100 — пере-раном скорера; сетка §3.1 — все клетки, латиница 22/40 без якоря — боевым ParseReply; дефект нарезки пакета-7 — строкой кода (split_book.py:210-211) и пере-раном непрерывного среза (0.255); частоты §5.1 — grep по полной книге, все 23 числа. Ниты: (а) типы строк банкноты в §1.3 посчитаны по ТРЁМ прогонам при «67 поверхностях» основного — популяция сменена без оговорки (по основному: 57/9/3/2); (б) mtime-довод §2 доказывает «не правлено после», сильнее артефактного доказательства не существует. Пре-регистрационная дисциплина (сработавший стоп §1.2 вместо подгонки, снятая собственная рекомендация §5.1) — образцовая. Зона: eval/pkg7/ (инструменты) + этот отчёт. backend/ — только чтение, сессия не коммитит.


Эхо-блок (что я услышал, ДО работы)

  1. Три пре-замера перед дизайном расширения эмиссии. Словарь отменён; ось — «что банкуется без подписи ≠ что кладётся на подпись».
  2. З1 ($0): recall майнера · банкноты · их объединения против guzhenren-seed-v2.yaml, по классам, плюс доля сида, которую банкнота уже покрывает. Майнер — на объявленном коммит-пине через minerharness.
  3. З2 (~$0.01): ~100 кандидатов из хвоста варианта C, боевой промпт роли с HEAD, дешёвая модель, один прогон; критерий «выдумала dst мусору» и порог провала — названы ДО трат. При провале фолбэк D39.46 констатирую, не строю.
  4. З3 (~$0.12): сетка kwic×подача, минимум 3×40 · 8×120 · промежуточные, 3 повтора, мера против подписанного сида; прямой ответ на развилку «широкая подача × узкий контекст vs узкая × широкий».
  5. Смета до вызовов, деньги из usage до цента; превышение потолка = стоп и пинг.
  6. Нормы D39.46/47: арм без фактора · сравнение на расходящихся позициях · декой · пре-регистрация с критерием провала · критик полноты на КАЖДУЮ фазу · самопроверка исполнением.
  7. Право сказать «этого делать не надо» сохраняю: замер, подрывающий посылку, = стоп и канал вопросов.
  8. После отчёта — СТОП; итоги уходят в дизайн расширения (бэкенд, пак-20).

§0 Пре-регистрация — написана ДО прогонов и до единого платного вызова

Разделы §1§3 заполняются ПОСЛЕ. Всё, что ниже этой черты, зафиксировано заранее; любое отклонение от плана помечается в теле отчёта явно, с причиной.

§0.1 Общие правила

  • Пин. Майнер и сборка запроса роли гоняются из копии бэкенда, извлечённой git archive <commit>, а не из рабочего дерева. Коммит объявляется в теле замера.
  • Деньги. Всякая цифра стоимости — из фактического usage ответа провайдера, пересчитанного по backend/configs/models.yaml. Смета публикуется ДО прогона; расхождение смета↔факт называется.
  • Сырьё. Каждый платный вызов сохраняется целиком (запрос, ответ, usage, finish_reason) в скретчпаде сессии; выводы пересчитываются ИЗ сырья отдельным скриптом, а не из памяти прогона.
  • Провал замера — тоже результат. Если критерий не даёт разделения, это пишется как «неизмеримо на этих данных», а не подгоняется под ожидание.

§0.2 Замер 1 — совместный recall (майнер банкнота)

Вопрос. Какую долю ПОДПИСАННОГО банка книги два канала эмиссии находят вместе, и сколько из этого даёт банкнота, которой в recall-программе пакета-7 не было вовсе.

Знаменатель. Термы guzhenren-seed-v2.yaml, физически встречающиеся в срезе (та же дисциплина, что в seed_recall.py: иначе меряется длина среза, а не recall).

Срез. Тот, на котором реально гонялась банкнота, — minirun-banknote/guzhenren-ch1-10.gb18030.txt. Оба канала меряются на ОДНОМ тексте, иначе объединение бессмысленно.

Каналы.

  • Майнер: minerharness, сид ПУСТОЙ (иначе miner_emit.go исключает засеянное по построению и recall выходит 0 по определению).
  • Банкнота: блоки ⟦TM-BANK-v1⟧ из сырья прогонов, разобранные репликой parseBanknote.

Пре-названная угроза достоверности (главная). Прогон банкноты шёл с НЕПУСТЫМ банком: промпт роли переводчика просит «НОВЫЕ … которых НЕТ в приложенном глоссарии». Значит терм сида, попавший в инъекцию чанка, банкнота не могла предложить ПО ПОСТРОЕНИЮ — ровно та же ловушка, из-за которой майнер обязан гоняться с пустым сидом. Поэтому заранее фиксирую разбиение знаменателя:

  • цензурированные — термы сида, инъектированные хотя бы в один чанк (у банкноты не было шанса);
  • со свободным шансом — термы сида, не инъектированные нигде. Recall банкноты считается ОТДЕЛЬНО на второй группе; сырая цифра «по всему знаменателю» публикуется, но помечается как нижняя граница, а не как оценка способности канала.

Критерий «замер не состоялся»: если группа «со свободным шансом» меньше 10 термов, совместный recall против подписанного сида объявляется НЕИЗМЕРИМЫМ на существующих артефактах, и вместо подгонки пишется, чего стоит его измерить (холодный прогон с пустым банком).

Второй выход, не зависящий от цензуры (страховка, названа заранее): пересечение и разности множеств эмиссии двух каналов на одном срезе — сколько поверхностей даёт только майнер, только банкнота, оба. Этот вопрос («что банкуется без подписи ≠ что кладётся на подпись») цензурой не затрагивается, потому что не опирается на сид.

Что считается основанием для расширения эмиссии: если объединение по классу term остаётся ниже 0.20 — расширение оправдано; если объединение ≥0.50 — выигрыш расширения кратно меньше того, что показала абляция, и это надо сказать вслух.

§0.3 Замер 2 — доля отказов роли на мусоре

Вопрос. Отвечает ли терминолог сентинелом ⟦TM-NO-DST⟧ на кандидатов, которым перевода не существует, — или выдумывает dst грамматическим огрызкам. Правило проверяется впервые (0 пустых консолидаций из 875 в живом прогоне).

Материал. ~100 кандидатов из ХВОСТА расширенной эмиссии варианта C (снят потолок emitRankCap + снят фильтр типа) — ровно та популяция, которую расширение эмиссии впустит в вход роли.

Промпт. Боевой backend/prompts/zh-ru/terminologist.md на HEAD (без жанрового блока), запрос собирается боевым кодом (terminology.RenderBatch + RenderCanonAnchor + MessagesWithInjection), не моей репликой. Модель — дешёвая, один прогон.

Разметка (названа ДО прогона). Каждый кандидат раскладывается на три класса ПО ИСХОДНИКУ, до того как я увижу ответ:

  • МУСОР — строка не является языковой единицей (грамматический огрызок: 便是, 的关, 则是一);
  • ГОДНЫЙ — самостоятельная именуемая сущность или доменное понятие;
  • СЕРЫЙ — обычное слово/словосочетание языка, не термин книги (明日, 议论声). Разметка одного разметчика, фиксируется файлом ДО отправки запроса и не правится после.

Метрика. Доля МУСОРНЫХ кандидатов, на которые роль вернула непустой dst («выдумала»).

Пороги, названные заранее.

  • Провал — выдумывает >50% мусора: сентинел не работает как фильтр, расширение эмиссии без внешнего экрана пустит выдумки в карту подписи. Фолбэк уже ратифицирован (D39.46, судья-с-декоем); строить его не моя задача — констатировать.
  • Годно — выдумывает <20%: сентинел несёт свою функцию, расширение можно проектировать без дополнительного экрана.
  • Серая зона 2050% — вывод «нужен экран или нужна правка промпта», без выбора между ними.

Контроль (арм без фактора). Та же батча с ДОБАВЛЕННЫМИ 10 заведомо ГОДНЫМИ кандидатами из подписанного сида. Без него неизмеримо, отличает ли роль мусор от годного вообще: 100% отказов на чистом мусоре и 100% отказов на всём — разные вещи, а по одной батче они неразличимы.

Что НЕ измеряет. Качество dst у годных кандидатов (это З3) и поведение на других парах.

§0.4 Замер 3 — сетка kwic × подача

Вопрос. Боевой дефолт 3×40 не покрыт ни одним замером (весь пакет-7 мерил ~8×120). Где на кривой цена/качество стоит дефолт и есть ли между точками разрыв, ради которого его стоит двигать.

Точки сетки (kwic_per × kwic_width): 3×40 (боевой дефолт) · 5×80 · 8×120 (точка пакета-7) · 3×120 и 8×40 — последние две есть ответ на развилку владельца «широкая подача × узкий контекст vs узкая × широкий»: они несут сопоставимый объём контекста при противоположной форме подачи.

Арм без фактора (обязателен по D39.46): 0×0 — кандидаты вообще без строк ctx:. Без него «контексты — главный рычаг» на боевом промпте не измерено, а перенесено из другого харнесса.

Выборка. Термы подписанного сида, физически встречающиеся в срезе, — мера верности есть совпадение с подписью владельца. Выборка типа S1 пакета-7 (термы с расхождением, не вырожденные).

Повторы. 3 прогона каждой точки. Разрыв между точками засчитывается ТОЛЬКО если он больше внутриточечного размаха — правило, купленное фазой B пакета-7 за $0.024.

Метрика. Доля термов выборки, где консолидированный dst совпадает с подписью владельца (нормализация: регистр, ё/е, пробелы). Плюс стоимость точки из фактического usage.

Пороги, названные заранее.

  • Дефолт 3×40 признаётся достаточным, если его точность не ниже точности 8×120 минус внутриточечный размах.
  • Дефолт признаётся заниженным, если существует точка с точностью выше 3×40 больше чем на размах, и её цена на терм ниже удвоенной цены 3×40.
  • Развилка решается ТОЛЬКО если 3×120 и 8×40 расходятся больше чем на размах; иначе вывод — «форма подачи при равном объёме контекста не различима на этой выборке».

Что НЕ измеряет. Одна книга, одна пара, одна модель. Перенос на другие пары — гипотеза.


§1 Замер 1 — совместный recall (майнер банкнота). $0

Пин: 0a7fa5b (HEAD). Эмиссия майнера на этом пине побайтно совпадает с пином пакета-7 996bade (cmp чист) — проверено исполнением, а не принято по диффу: между коммитами в miner_emit.go добавлены счётчики EmissionStats, поле Term.Dst и режим draft в DeltaYAML, и надо было убедиться, что ни одно из этого не сдвинуло эмиссию. Цифры пакета-7 и пакета-8 сравнимы.

Срез: minirun-banknote/guzhenren-ch1-10.gb18030.txt — 10 节 тома 1, 27 322 знака, 20 чанков. Это тот же файл, на котором гонялся прогон с банкнотой, поэтому оба канала меряются на одном тексте.

§1.1 Отклонение от посылки промта — сказано вслух

Промт говорит: «блоки ⟦TM-BANK-v1⟧ уже лежат в черновиках corpus.jsonl пакета-6 (91 юнит, 6 прогонов)». Это не так, и я проверил все артефакты стенда, а не только названный. В corpus.jsonl блок несут 2 юнита из 91 (обаverify2), и пакет-6 честно классифицировал их как утечку служебного блока в текст черновика. Прогоны acceptance, minirun, rerun2-* шли с каналом ВЫКЛЮЧЕННЫМ — блоков там нет вовсе.

Сырьё банкноты живёт не там: в трёх базах прогонов (сканированы все 21 база стенда).

База Блоков Строк Срез
minirun-banknote/guzhenren-banknote.db 9 71 гл. 110 (основной)
minirun-verify/guzhenren-verify.db 2 10 гл. 12
minirun-verify2/guzhenren-verify2.db 2 6 гл. 45

Парсер сверен с боевой телеметрией, а не объявлен верным: моя реплика parseBanknote даёт пер-чанково те же числа, что движок записал в retrieval_state.n_banknote_lines, включая banknote_parse_fail=1 на гл.3 — совпадение полное, 71 = 71.

§1.2 Пре-зарегистрированный стоп СРАБОТАЛ: совместный recall против сида неизмерим

Критерий §0.2 («если группа со свободным шансом < 10 термов — замер объявляется несостоявшимся») выполнился с запасом.

Термов recall
Знаменатель: термы сида, встречающиеся в срезе 51
Майнер (как терм) 12 0.235
Майнер (терм алиас) 14 0.275
Банкнота (сырая) 2 0.039 ← нижняя граница
Объединение 14 0.275

Цензура: 49 из 51 термов сида были инъектированы в промт черновика, а промт просит «новые, которых НЕТ в приложенном глоссарии». Свободных от инъекции — 2 терма. Уточнение до уровня ГЛАВЫ (инъекция пер-чанковая, а не книжная, поэтому пар «терм × глава» больше) даёт 21 свободную пару из 217 — и на всех 21 банкнота не предложила ничего.

И этот знаменатель ещё и структурно смещён: все свободные пары дают ровно три поверхности — , , 古月. Они не инъектировались не случайно, а потому что коротки (см. §1.5). То есть «свободный шанс» и «короткая поверхность» на этих данных — одно и то же множество, и вывода о способности канала из него не извлечь никакого.

Вывод: совместный recall против ПОДПИСАННОГО сида на существующих артефактах не измеряется. Чтобы измерить, нужен холодный прогон черновой волны с ПУСТЫМ банком и включённой банкнотой — это не $0. Подгонять цифру под ожидание я не стал.

§1.3 Страховочный выход (пре-зарегистрирован, цензурой не затронут): множества каналов

Поверхностей
Майнер 13
Банкнота (основной прогон) 67
Пересечение 2
Только майнер 11
Только банкнота 65
Объединение 78

Каналы почти не пересекаются: 2 общие поверхности из 78. Разъезд в 3%, названный в D39.42, на уровне множеств выглядит как разъезд в 97%. И объём даёт банкнота: 67 против 13, то есть пять шестых кандидатов в карту подписи приходит не от майнера.

По типам строк банкноты в ТОМ ЖЕ основном прогоне (71 строка): term 57 · title 9 · name 3 · place 2. (Первая редакция давала здесь 67/13/4/3 — счёт по ТРЁМ прогонам рядом с числом поверхностей одного; смена популяции без оговорки, поймано ревью оркестратора D39.50, исправлено.) То есть банкнота эмитирует ровно тот класс, который майнер не эмитирует НИКОГДА (фильтр типа name|place|title). Среди её предложений — 光阴之河 (Река времени), 十大奇蛊, 九转境界, 力量蛊, 智慧蛊, 青铜真元, 紫府, 秘法, 遗藏, 蛊室, 性命交修, 开窍大典.

§1.4 Но объём банкноты — не покрытие: два объективных дефекта канала

Разметку «годный/мусор» я здесь сознательно НЕ применяю (это был бы мой вкус). Беру пороги, которые движок уже применяет к другому каналу, — emitMinFreq=5 и runeLen≥2 из miner_emit.go:

Свойство предложений банкноты (67 поверхностей) Доля
Прошли бы боевые пороги майнера (частота ≥5 и длина ≥2) 11 = 0.164
Встречаются в ≥2 главах среза 18 = 0.269
Встречаются в срезе ≤1 раза 32 = 0.478

Почти половина предложений — разовые фразы (三天三夜 «три дня и три ночи», 六块 «шесть штук, 白银盘子«серебряная тарелка»,雨声 «звук дождя, 中年/少年/老年). Это не терминология книги, это обычные слова, которые модель приняла за термины.

Второй дефект — повторяемость. Главы 12 прогонялись ДВАЖДЫ, побайтно тем же промтом (prompt_sha256 = d1dc7a3a2675…), той же моделью deepseek-v4-flash, при temperature 0.3:

Поверхностей Пересечение Жаккар
Прогон A vs прогон B, как есть 5 vs 9 1 0.077
То же, после снятия книжных кавычек 《》 5 vs 9 4 0.400

Эмиссия банкноты — лотерея прогона. Что попадёт в карту подписи, зависит от сэмплирования, а не от книги. Для дизайна расширения это значит: канал, дающий 5/6 объёма, невоспроизводим, и опираться на него как на измеритель покрытия нельзя без агрегации по нескольким прогонам.

Третий дефект, мелкий, но он стоит строк владельцу. Три поверхности приходят в книжных кавычках (《咏梅》, 《将敬酒》, 《江城子》), и тот же прогон эмитирует их же без кавычек (咏梅, 将敬酒, 江城子) с другим переводом. NormalizeSourceKey кавычки не снимает, значит это ЧЕТЫРЕ разные строки в карте подписи вместо двух, и ни одна из них не сойдётся с ханьским n-граммным пространством майнера.

§1.5 Побочная находка: подписанный терм не доезжает до модели вообще

— заглавное понятие книги, 188 вхождений в срезе, владельцем подписан (蛊 → гу, status: approved). Он не доезжает до модели ни одним путём:

  • майнер не эмитируетruneLen(c.Src) < 2 (miner_emit.go);
  • инъекция не показываетSignificantLen=1 < minKeyLenHan=2 при allow_short=0 (membank/memory.go:276), то есть подписанная строка выбрасывается из индекса инъекции;
  • банкнота не предлагает — 0 из 21 свободной пары.

То же у («ранг», 61×). Это НЕ вопрос расширения эмиссии: терм уже подписан, его не надо находить — его надо доставлять. Механизм отключения известен и у него есть штатный обход: allow_short: true в строке сида. Правка — ДАННЫЕ, Go не трогается.

Не раздуваю severity: на этой книге промах компенсируется косвенно — «гу» приезжает в модель внутри инъектированных 蛊师 → гу-мастер и 蛊虫 → гу-червь, и черновики действительно пишут «гу» (видно в самих банкнотах: 力量蛊 → гу Силы, 第三蛊 → третья гу). То есть замер показывает дыру в доставке, а не доказанный дефект перевода.

§1.6 Методологическая находка про срезы пакета-7 (самопроверка исполнением)

Проверяя, почему мой срез «10 глав» в 7 раз короче одноимённого среза пакета-7, я нашёл дефект нарезки в собственном инструменте пакета-7. В 蛊真人 нумерация 节 перезапускается в каждом из 6 томов, а split_book.py --max-chapters N фильтрует по НОМЕРУ (c[0] <= max_ch). Поэтому «gu 10 глав» пакета-7 — это не первые 10 节, а все 节 с номерами 110 из шести томов: рассеянная выборка по всей книге (и с коллизией ключей (chapter, chunk_idx)).

Что это ломает и что нет — измерено, а не оценено:

Срез Знаков Термов сида recall (терм∪алиас) term name title place
пакет-7, «gu 25гл» (рассеянный) 471 496 56 0.089 0.043 0.231 0.077 0.000
пакет-8, 25 节 ПОДРЯД 70 708 55 0.255 0.091 0.308 0.462 0.400

Абсолютные recall пакета-7 занижены нарезкой втрое (потолок emitRankCap=200 на длинном тексте режет сильнее). Структурный вывод пакета-7 устоял целиком: класс term и на непрерывном срезе остаётся кратно ниже остальных (0.091 против 0.310.46), а оба «попадания» в классе term元海 и 元石 — попали не как термины, а случайностью паттерна ( читается как фамилия, как топо-суффикс). Ни одного доменного понятия майнер по-прежнему не эмитирует.

Влияние на internal/miner — нулевое: ChunkIdx майнер не читает вовсе, а Chapter использует только для рассеяния (miner_substrate.go:116), так что склейка томов рассеяние занижала, а не завышала.

Чувствительность к нарезке пере-проверена и на этом срезе: свип целевого размера чанка 800/2000/6000 даёт побайтно одну и ту же эмиссию (Жаккар 1.000). Цифры §1 не артефакт субстрата.

§1.7 Ответ на вопрос, ради которого замер заказан

Пре-регистрация §0.2 назвала порог: объединение по классу term ниже 0.20 = расширение оправдано. Измеренное объединение по term = 0.105 (2 из 19, и оба — случайность паттерна).

Но главный итог замера не в этой цифре, а в переформулировке:

  1. Расширять эмиссию майнера — не единственная и не первая опция. Канал, который уже сегодня даёт 5/6 кандидатов и умеет класс term вместе с dst, — это банкнота, а не майнер.
  2. Банкнота при этом непригодна как измеритель покрытия в нынешнем виде: 48% предложений разовые, 16% прошли бы боевые пороги, Жаккар между двумя прогонами одних и тех же глав 0.0770.40.
  3. Значит вопрос дизайна — не «поднять ли emitRankCap», а «чем дисциплинировать банкноту»: частотный порог по тексту книги (он у движка уже есть для майнера), нормализация книжных кавычек, агрегация по прогонам. Всё три — дешёвые, детерминированные и $0 в проде.

Чего замер не покрывает. Холодного старта (банк пуст) не мерил никто; сколько банкнота предложит, когда её не глушит инъекция, неизвестно, и это ровно та цифра, на которой стоит цена расширения. Одна книга, одна пара, одна модель, 10 глав.

§1.8 Критик полноты фазы 1

Что проверено дополнительно по итогам критика и что осталось непокрытым:

Проверка Итог
Парность пинов 0a7fa5b / 996bade эмиссия побайтно одна (cmp)
Мой парсер банкноты против боевой телеметрии пер-чанково совпадает, 71 = 71, parse_fail тоже
Все ли источники банкноты найдены просканирована 21 база стенда; блоки только в 3
Одинаковы ли промты двух прогонов гл.12 prompt_sha256 совпадает — сравнение честно
Чувствительность к нарезке Жаккар 1.000 на 800/2000/6000
Молчание канала 11 из 20 чанков не выдали блок вовсе, truncated=0 — это молчание, не обрезка
Круговая порука сида все 53 подписанные строки имеют source='seed' (не промоушен из майнинга); но собирал ли владелец сид, глядя на дельты прошлых паков, из артефакта не восстановить — остаётся угрозой достоверности
НЕ покрыто холодный старт; вторая книга; вторая пара; вторая модель

§2 Замер 2 — доля отказов роли на мусоре. Факт $0.0064 (смета ≤$0.0183)

Как собран запрос. Не моей репликой: Go-харнесс eval/pkg7/termharness собирает батчи БОЕВЫМ кодом — terminology.MergeAttachKWICScoreVariantsBatchRenderCanonAnchorpipeline.MessagesWithInjection, промт backend/prompts/zh-ru/terminologist.md с HEAD. Пин 0a7fa5b. Ответы разбираются боевым terminology.ParseReply (тот же харнесс, -mode parse) — он и решает, что считается ответом, что отказом, а что «плохой строкой». Модель deepseek-v4-flash, max_tokens=8000 (пол min_max_tokens из models.yaml, к которому боевой terminologyCallBudget батч такого размера и приводит), thinking не отключался.

Материал. 100 кандидатов из хвоста РАНГА варианта C (потолок emitRankCap снят + снят фильтр типа; ранг записан самим движком в пин-копии, так что «хвост» определён порядком движка, а не моим вкусом) + 10 контрольных заведомо годных строк подписанного сида. Контрольные строки исключены из якоря ⟦TM-CANON⟧ — иначе контроль выродился бы в списывание из якоря. 7 батчей.

Разметка зафиксирована файлом ДО отправки: МУСОР 16 · СЕРЫЙ 84 · ГОДНЫХ в хвосте 0.

§2.1 Результат

Класс Кандидатов Выдумала dst ⟦TM-NO-DST⟧ Промолчала
МУСОР (огрызки и «числительное+счётное») 16 9 = 0.562 7 = 0.438 0
СЕРЫЙ (обычные слова, не термины книги) 84 68 = 0.810 0 16
КОНТРОЛЬ (подписанные термы) 10 9 = 0.900 0 1

Плохих строк парсера — 0.

Вердикт по пре-зарегистрированному порогу §0.3: доля выдумок на МУСОРЕ 0.562 > 0.50 → ПРОВАЛ.

§2.2 Но провал не там, где я ждал — структура ответов её объясняет

Разбиение класса МУСОР по ответам оказалось идеальным и не случайным (это разбиение ПОСТ-ХОК, оно не было пре-зарегистрировано, и я это помечаю):

Подкласс МУСОРА Строки Ответ роли
Разрез поперёк границы слова 了上 了不 人一 人不 人是 他在 在大 ⟦TM-NO-DST⟧ — 7 из 7
«Числительное + счётное слово» 一人 一句 一天 一年 一座 一番 一面 三年 перевод — 8 из 8 («один день», «три года»)
Прочее 是为 «являться»

Сентинел различает НЕ «терм / не терм», а «переводимо / непереводимо». Это ровно то, о чём промт роли и просит («если не можешь выбрать перевод уверенно»), — и значит на своей задаче правило работает безупречно, а на задаче «отсеять не-терминологию» не работает вовсе: 一天 переводится уверенно и правильно, термином книги от этого не становясь.

Подтверждение с другой стороны — контроль: на подписанных термах роль отвечает 9 из 10, и 8 из 9 ответов совпадают с подписью владельца буквально (方源→Фан Юань, 蛊→гу, 蛊师→гу-мастер, 古月→Гуюэ, 方正→Фан Чжэн, 资质→талант, 家老→старейшина, 酒虫→винный червь — регистр иной). Расходится один: 转 → «поворот» против подписанного «ранг». То есть роль умеет давать нужный ответ на годном материале и не умеет отказываться от негодного.

§2.3 Цена вопроса для дизайна расширения

Из 100 кандидатов хвоста роль выдумала перевод 77. По §C2-7 консолидированный dst переводит строку в режим status: draft — то есть в инъекцию редактора с пометкой ⟨проверить⟩. Значит расширение эмиссии до варианта C без внешнего экрана кладёт в рабочий канон книги строки вида «люди», «различный», «один день» — помеченные, неподписанные, но уже влияющие на редактуру.

Фолбэк на этот случай ратифицирован заранее (D39.46: слепой судья с декоем как катастроф-экран). Строить его не моя задача — констатирую, что условие его применения наступило. И называю то, чего в фолбэке нет: судья-экран стоит денег на каждый кандидат, а 82% лишних кандидатов отсекаются БЕСПЛАТНО частотным порогом, который у движка уже есть (см. §1.4 и §2.4).

§2.4 Побочный результат, который меняет постановку задачи

Я пересёк эмиссию варианта C с поверхностями банкноты на одном срезе (гл. 110, $0):

Поверхностей
Вариант C (потолок и фильтр типа сняты) 559
Банкнота, все три прогона (в §1.3 бралcя один — там 67) 74
Пересечение 8
Банкнота ВНЕ варианта C 66

Расширение эмиссии майнера НЕ достаёт того, что находит банкнота. Причина измерена, а не предположена: 82% поверхностей банкноты встречаются в срезе реже 5 раз (55 из 67 в основном прогоне) и потому лежат ниже порога emitMinFreq, то есть вне кандидатного алфавита майнера — независимо от потолка ранга и фильтра типа. Из 11 поверхностей банкноты, проходящих боевые пороги, вариант C содержит 8; три остальные срезаны другими правилами (古月方源 поглощён алиас-кластером подписанного 古月, 力量蛊/智慧蛊 — субсумпцией).

Так что 光阴之河, 十大奇蛊, 九转境界, 元气, 力量蛊 снятием двух констант не появятся. Их приносит только банкнота — тот канал, который §1.4 показал невоспроизводимым.

Оговорка, которую надо держать рядом с этой цифрой. «Ниже порога частоты» здесь — свойство СРЕЗА в 10 глав, а не книги: во всём тексте 元气 встречается 101 раз, 遗藏 143, 智慧蛊 634 (§5.1). Боевой терминолог работает после полной черновой волны, то есть на полной книге, и там эти поверхности в кандидатный алфавит майнера войдут. Вывода о расширении это не меняет: войдут они вместе с 少年 (1149) и 中年 (244), а порога, разделяющего эти два множества, не существует (§5.1).

§2.5 Критик полноты фазы 2

Проверка Итог
Сборка запроса — боевая, не реплика да: termharness на пине, промт с HEAD
Разбор ответа — боевой ParseReply да; плохих строк 0
Контроль (арм с заведомо годным материалом) есть, 10 строк, вне якоря канона
Повторы 3 прогона, разброс — §2.6
Есть ли ответы, которые парсер обязан был отсечь нашлось: 是为 → «is» (r2) — английское слово в zh→ru роли проходит wellFormedLemma и банкуется
Разметка зафиксирована до вызова да, отдельным файлом
НЕ покрыто одна модель; ГОДНЫХ строк в самом хвосте нет, поэтому precision роли на «расширенном, но осмысленном» материале не измерена; разметчик один

§2.6 Повторы (3 прогона, $0.0168 суммарно) — и они меняют формулировку вывода

Класс r0 r1 r2 Размах
МУСОР 0.562 0.938 0.562 0.375
СЕРЫЙ 0.810 0.774 0.821 0.048
КОНТРОЛЬ 0.900 0.900 1.000 0.100

Пер-строчная картина показывает, что именно скачет:

Терм r0 r1 r2
了上 ⟦TM-NO-DST⟧ «наверх» ⟦TM-NO-DST⟧
人不 ⟦TM-NO-DST⟧ «люди» ⟦TM-NO-DST⟧
他在 ⟦TM-NO-DST⟧ «он» ⟦TM-NO-DST⟧
是为 «являться» «является» «is»

Вывод правится по факту: сентинел не просто «не фильтр не-терминологии» — он нестабилен и на своей собственной задаче. В двух прогонах из трёх непереводимые огрызки отклоняются полностью, в третьем переводятся все. Размах 0.375 при разрыве от порога 0.06 — то есть по одному прогону вывод «роль отклоняет огрызки» был бы куплен случайностью сэмплирования. Устойчиво здесь только одно, и это самое важное для дизайна: на классе СЕРЫЙ, который и составляет 84% расширенной эмиссии, роль выдумывает перевод в 7782% случаев в каждом прогоне.

Отдельная улика: 是为 → «is» — англоязычный ответ в zh→ru роли. Он проходит wellFormedLemma, не является эхом исходника и потому банкуется как рабочий канон книги. Продолжение этой ниточки — в §3.4, где она оказалась не случайностью.


§3 Замер 3 — сетка kwic × подача. Факт $0.0963 (126 вызовов)

Выборка: 40 подписанных термов сида, встречающихся в непрерывном срезе 25 节 (отбор детерминированный: вхождения вниз, порог ≥3). Эталон — подпись владельца. Все 40 исключены из якоря ⟦TM-CANON⟧ (в якоре осталось 13 не пересекающихся строк), иначе замер мерил бы списывание. Черновых вариантов (drafts:) у кандидатов нет — значит измеряемый фактор один: контексты.

Сборка запроса — боевая (termharness на пине 0a7fa5b, промт с HEAD), разбор — боевой ParseReply, модель deepseek-v4-flash, 3 повтора на точку.

§3.1 Результат сетки

Точка Вызовов $ r0 r1 r2 Средняя Размах $/1000 термов·прогон
0×0 (арм без фактора) 3 0.00530 0.625 0.650 0.625 0.633 0.025 0.044
3×40 (боевой дефолт) 9 0.00935 0.575 0.600 0.675 0.617 0.100 0.078
3×120 18 0.01495 0.550 0.575 0.575 0.567 0.025 0.125
5×80 21 0.01682 0.550 0.625 0.625 0.600 0.075 0.140
8×40 18 0.01568 0.550 0.600 0.450 0.533 0.150 0.131
8×120 (точка пакета-7) 48 0.02562 0.475 0.550 0.650 0.558 0.175 0.214

Максимальный внутриточечный размах — 0.175. Разброс СРЕДНИХ по всем шести точкам — 0.100. То есть по пре-зарегистрированному правилу чтения ни одна точка не отличима ни от одной другой.

То же на расходящихся позициях (норма D39.46; подмножество считается ЗАНОВО в каждом повторе, иначе подмножество, выбранное по одному прогону, само есть выбор по случайности):

Точка r0 r1 r2 Средняя
0×0 0.464 0.409 0.462 0.445
3×40 0.393 0.318 0.538 0.417
5×80 0.357 0.364 0.462 0.394
3×120 0.357 0.273 0.385 0.338
8×120 0.250 0.227 0.500 0.326
8×40 0.357 0.318 0.192 0.289

Расходящихся позиций 28/22/26 из 40. Внутриточечный размах здесь 0.273, разброс средних 0.156 — снова неотличимо.

§3.2 Вердикты по пре-зарегистрированным порогам §0.4

  1. Боевой дефолт 3×40 — ДОСТАТОЧЕН. Его точность 0.617 против 8×120 = 0.558; порог «не ниже 8×120 минус размах» выполнен с большим запасом. Двигать дефолт вверх оснований НЕТ.
  2. Дефолт НЕ занижен. Лучшая точка (0×0) выше него на +0.017 при размахе 0.175.
  3. Развилка владельца «широкая подача × узкий контекст vs узкая × широкий» — НЕРАЗЛИЧИМА на этой выборке. 8×40 = 0.533 против 3×120 = 0.567, разница 0.033 при размахе 0.175. Форма подачи при сопоставимом объёме контекста ничего не решает; решает, по-видимому, вообще не объём.
  4. Кривая цена/качество монотонна ТОЛЬКО по цене. От 0×0 к 8×120 стоимость растёт в 4.9 раза ($0.044 → $0.214 на 1000 термов за прогон), точность не растёт вовсе.

§3.3 Напряжение с ратифицированным D39.46 — называю прямо, за отмену НЕ выдаю

D39.46 ратифицировал: «контексты — главный рычаг качества терминолога» (арм без KWIC терял 67 совпадений из 19 при внутриармовом размахе 1). Мой замер этого не воспроизводит: на боевом промте арм без контекстов оказался не хуже всех остальных.

Я НЕ утверждаю, что D39.46 неверен. Три различия постановки, любое из которых объясняет расхождение, и ни одно из которых я не устранял:

  1. Другая выборка. Пакет-7 брал 19 термов С РАСХОЖДЕНИЕМ черновиков — то есть заведомо трудные. Здесь — 40 подписанных термов по частоте вниз, среди них половина простых (方源, 方正, 古月赤城), где модель права и без единого контекста.
  2. Другой промт. Пакет-7 гонял собственную сборку без якоря ⟦TM-CANON⟧; здесь — боевая сборка с якорем. Якорь может работать заменой контекстов (см. §3.4 — он оказался не безобиден).
  3. Нет строки drafts:. В бою кандидат несёт варианты черновиков; здесь их нет ни у одной точки. Контексты могли быть рычагом именно в связке «контексты + разноголосица черновиков».

Что из этого следует практически, независимо от того, кто прав: поднимать kwic_per_term и kwic_width над боевым дефолтом 3×40 нечем обосновать. На лёгком материале контексты не помогают, на трудном — вопрос открыт, и закрывает его пере-замер на выборке пакета-7 с боевой сборкой запроса, чего я НЕ делал.

§3.4 Побочный результат, самый тяжёлый в пакете: якорь держит ЯЗЫК ответа

Контрольный арм (не был в плане промта; добавлен как арм-без-фактора для якоря): 3×40 без блока ⟦TM-CANON⟧, 3 повтора, $0.0086.

Арм r0 r1 r2 Средняя
3×40 с якорем 0.575 0.600 0.675 0.617
3×40 без якоря 0.550 0.525 0.250 0.442

Провал в r2 не шум разметки. Вот что роль вернула:

一转	Rank 1          丙等	Grade C        修行	cultivation
元海	Primordial Sea  古月	Gu Yue         资质	talent
酒虫	Wine Bug        转	realm          青茅山	Qingmao Mountain

Роль ответила по-английски — 22 строки из 40 в одном прогоне из трёх. Счёт по всем 126 вызовам замера (латиница без единой кириллицы в ответе):

Арм r0 r1 r2
0×0 · 3×40 · 3×120 · 5×80 · 8×40 0/40 0/40 0/40
8×120 3/39 2/39 0/40
без якоря 0/40 0/40 22/40

Два вывода, и оба про дизайн расширения:

  1. Блок ⟦TM-CANON⟧ — де-факто якорь ЦЕЛЕВОГО ЯЗЫКА, а не только канона. Его кириллические строки удерживают модель в русском. Промт роли объявляет язык через {{target_lang}}, и одного этого объявления не хватает.
  2. Это ровно сценарий расширения. Якорь пуст или короток именно на книге, где подписано мало строк, — то есть на холодном старте и сразу после расширения эмиссии, когда кандидатов много, а подписей мало. Соотношение «много кандидатов / пустой якорь» — та самая точка, где замер показал срыв в английский.
  3. Ничто в конвейере этого не ловит. ParseReply пропускает латиницу (wellFormedLemma её допускает — она нужна для латинских имён), эхо-гейт не срабатывает (ответ не равен исходнику), и строка уезжает в карту подписи как status: draft — то есть в инъекцию редактора с ⟨проверить⟩. В §2.6 то же самое поймано отдельно (是为 → «is»), там я счёл это единичным.

§3.5 Критик полноты фазы 3

Проверка Итог
Арм без фактора (0×0) есть, и он оказался лучшей точкой
Повторы и правило «разрыв > размаха» 3 повтора на точку; правило применено, разрывов нет
Сравнение на расходящихся позициях посчитано ПОКАЖДОМУ повтору, не по одному
Батчи не роняли термы «молчание» ≤2 термов на прогон; все ответы finish=stop
Утечка эталона через якорь 40 термов выборки из якоря исключены; проверено по файлу канона
Язык ответа посчитан по всем 126 вызовам — так и нашлась находка §3.4
Ошибки вызовов 0
НЕ покрыто выборка пакета-7 (трудные термы) на боевой сборке; строка drafts:; вторая модель; вторая пара; влияние batch_runes (фиксирован 6000 во всех точках)

§4 Деньги — из фактического usage, до цента

Арм / проба Вызовов Вход (в т.ч. кэш) Выход $
Замер 2, probe2 ×3 21 90 015 (67 072) 47 959 0.01683
Замер 3, 0×0 3 7 581 (6 016) 18 091 0.00530
Замер 3, 3×40 9 35 307 (26 624) 28 785 0.00935
Замер 3, 3×120 18 81 954 (60 672) 42 128 0.01495
Замер 3, 5×80 21 93 684 (69 504) 47 278 0.01682
Замер 3, 8×40 18 80 571 (59 904) 45 067 0.01568
Замер 3, 8×120 48 210 399 (156 672) 63 073 0.02562
Замер 3, без якоря 9 34 617 (27 008) 26 601 0.00859
ИТОГО 147 634 128 (473 472) 318 982 $0.11313

Бюджет $0.14, потолок $0.30. Факт $0.11313 — 81% плана. Замер 1 бесплатен целиком. Цены — deepseek-v4-flash $0.14/$0.28 за 1M, кэш $0.0028 (backend/configs/models.yaml, read-only). 75% входных токенов пришли из кэша — это и есть причина, по которой шесть точек сетки поместились в смету одной.


§5 Итог: что эти три замера говорят дизайну расширения эмиссии

  1. Вопрос «поднимать ли emitRankCap» закрыт отрицательно, и не порогом, а механизмом. Расширение майнера не достаёт того, ради чего затевалось: 66 из 74 поверхностей банкноты лежат ВНЕ варианта C, и не из-за потолка ранга или фильтра типа, а потому что 82% из них не входят в кандидатный алфавит по ЧАСТОТЕ. На полной книге частоты выше и часть этих поверхностей в алфавит вернётся — вместе с 少年 (1149 вхождений) и 中年 (244), см. §5.1. Снятие двух констант ни в одном из двух случаев не даёт того, ради чего его предлагали.
  2. Зато расширение дорого стоит в другую сторону. На хвосте варианта C роль выдумывает перевод для 77 кандидатов из 100 — и это устойчиво (77 · 80 · 78 из 100 в трёх прогонах). Сентинел ⟦TM-NO-DST⟧ различает «переводимо / непереводимо», а не «терм / не терм», и даже на своей задаче нестабилен (размах 0.375).
  3. Настоящий носитель покрытия — банкнота, и её надо не расширять, а дисциплинировать. Она даёт 5/6 кандидатов и умеет класс term вместе с dst. Но 48% её предложений встречаются в срезе один раз, Жаккар между двумя прогонами одних и тех же глав 0.0770.40, и она эмитирует 《咏梅》 и 咏梅 как две разные строки. Из дешёвых детерминированных лечений выдерживают проверку два: нормализация книжных кавычек и агрегация по прогонам. Третье — частотный порог — я предложил и сам же опроверг замером, см. §5.1.

§5.1 Рекомендация, которую я снял собственной проверкой

Первая редакция §5 предлагала дисциплинировать банкноту частотным порогом — тем самым emitMinFreq, который у движка уже есть для майнера, «$0 в проде, снимает 82% лишнего». Прежде чем подавать это в дизайн, я посчитал частоты обеих популяций во всей книге (7.78 млн знаков, $0):

Настоящие термы книги В книге Не-термы из той же эмиссии В книге
智慧蛊 «гу Мудрости» 634 少年 «юность» 1149
遗藏 «забытое сокровище» 143 中年 «средний возраст» 244
元气 «первичная ци» 101 三天三夜 «три дня и три ночи» 72
家主 «глава клана» 95 六成 «шесть десятых» 69
力量蛊 «гу Силы» 48 停息 «прекратиться» 39
光阴之河 «Река времени» 15 地下溶洞 «подземная пещера» 25
九转境界 12 早智 11
紫府 «Пурпурный дворец» 7 八分 9
十大奇蛊 5 雨声 «звук дождя» 4
古月先祖 «предок Гуюэ» 2 参茶 · 白银盘子 · 方格子 · 乏闷 1

Порога, разделяющего эти два столбца, не существует. Самое частое слово всей выборки — не термин (少年, 1149), а настоящий центральный концепт 光阴之河 («Река времени», 15) лежит НИЖЕ пяти не-терминов. Частота снимает объём, но не тот: единственное, что она отсекает надёжно, — строки с одним вхождением, и вместе с 参茶 она убивает 古月先祖.

Вывод для дизайна — отрицательный и от этого не менее полезный: дешёвого частотного экрана для банкноты не существует, и планировать расширение в расчёте на него нельзя. Отбор здесь семантический, а значит либо стоит вызова модели (судья-с-декоем D39.46), либо остаётся владельцу.

Отдельно: та же таблица объясняет, почему emitMinFreq=5 не «настроен плохо». Он не разделяет термы и не-термы ни при каком значении — он лишь бюджетирует объём, и именно так его и надо читать. 4. kwic-дефолты трогать нечем. 3×40 не отличим ни от одной точки сетки, включая 8×120 за 5-кратную цену; развилка «широкая подача vs широкий контекст» неразличима. 5. Перед любым расширением надо закрыть язык ответа. Пустой или короткий якорь ⟦TM-CANON⟧ — состояние книги, у которой мало подписей, то есть состояние ровно после расширения — дал 22 английских ответа из 40 в одном прогоне из трёх, и конвейер их не ловит. 6. Мелочь, которая чинится данными: и подписаны владельцем, но не доезжают до модели ни одним каналом (allow_short: false при SignificantLen=1). Правка — строка в сиде.

Чего эти замеры не покрывают (сведено в одно место): холодный старт с пустым банком — не мерил никто, и именно там стоит цена расширения · вторая книга, вторая пара, вторая модель · выборка трудных термов пакета-7 на боевой сборке запроса · строка drafts: в кандидате · batch_runes как ось · разметчик в замере 2 один.

СТОП. Итоги уходят в дизайн расширения эмиссии (продолжение пака-20, бэкенд). Ни строки в backend/ эта сессия не написала и не коммитила.


§6 Добор по вопросу владельца: «хватает ли экспов по одной книге?» ($0, после СТОПа)

Владелец спросил (26.07), достаточно ли одной книги, раз движок строится универсальным, и не надо ли гонять на английском Кристоффе. Проверил на стенде боевым майнером из того же пина. Ответ — не надо, и не потому что «и так ясно», а потому что гонять пока нечего: на латинице канал WHICH не слабый, а мёртвый, а на японском — активно неверный.

§6.1 Три измеренных факта

1. en→ru сегодня не запускается вовсе. Пары en/en-ru в backend/configs/langpacks/ не существует, и загрузчик отказывается работать ЛОУДНО, как и задумано (D39.15: «language data is required, never silently empty»). Это гардрейл общности, работающий правильно: недостающее — ДАННЫЕ, и движок об этом кричит, а не деградирует молча.

2. Когда загрузчик удовлетворён, канал WHICH на латинице даёт НОЛЬ. Зеркалю zh-пак в en (только в пин-копии скретчпада — цель не оценить таблицы, а увидеть кандидатный алфавит):

Книга Знаков Эмитировано
Kristoff, Empire of the Dawn (25 глав) 814 674 0
Fifty Shades (26 глав) 814 756 0

Механизм — не тюнинг: кандидатный алфавит есть hanRuns (miner_substrate.go:46-48), максимальные пробеги ханьских иероглифов, а паттерны (miner_patterns.go) строятся поверх них. В латинском тексте ханьских пробегов нет, поэтому пусто не «почти», а точно.

3. На японском канал не молчит, а ошибается. Тот же приём (zh-пак зеркалом в ja), 異世界魔術師, 25 глав, 134 204 знака → эмитировано 10 строк, все типа name, и все десять — ложные срабатывания китайских фамильных паттернов на японских composites:

何故 «почему» 44×  ← surname:何      王国 «королевство» 35×  ← surname:王
何人 «сколько человек» 22×           王女 «принцесса» 27×    ← surname:王|formant_suffix:女
马鹿 «дурак» 21×  ← surname:马       元々 «изначально» 14×   ← surname:元
何処 «где» 13×                       范囲 «диапазон» 14×
危険 «опасность» 6×                  解呪 «снятие проклятия» 8×

Precision 0/10. Оговорка, обязательная: я подставил КИТАЙСКИЕ фамильные таблицы японской книге, поэтому ложняки — свойство подставленных данных, а не приговор японской паре. Но вывод от этого только жёстче: настоящий ja-пак убрал бы эти десять, и не добавил бы ничего, потому что имена собственные этой книги живут в катакане и руби (замерено пакетом-7, §A4.5), а hanRuns катакану не видит по построению.

§6.2 Что из пакета-8 переносится на другие пары, а что нет

Вывод Статус переносимости
Роль выдумывает dst 7780% на мусоре; сентинел различает «переводимо», а не «терм» вероятно пар-слепой — свойство модели и промта, но популяция мусора на латинице другая (не n-граммные огрызки, а словосочетания); не проверено
Якорь ⟦TM-CANON⟧ держит язык ответа вероятно пар-слепой и ХУЖЕ для en→ru: срыв в английский на английском исходнике неотличим от нормальной работы глазом
Частотного порога, разделяющего термы и не-термы, не существует пар-слепой по механизму, но конкретные числа — этой книги
Каналы почти не пересекаются; 5/6 объёма даёт банкнота усиливается: на en/ja доля майнера не 1/6, а ноль
kwic-дефолт 3×40 достаточен ТОЛЬКО zh. См. §6.3
Все recall-цифры, профиль банкноты, allow_short этой книги и этой пары

§6.3 Дефект общности, найденный этим добором: kwic_width меряется в РУНАХ

window() (terminology.go:332-349) режет окно в рунах, и дефолт terminologyDefaultKWICWidth = 40 живёт в Go как одна константа на все пары. Что она означает физически:

[zh] 方源:    «“方源,乖乖地交出春秋蝉,我给你个痛快!”…»        43 знака ≈ 43 морфемы ≈ 2 реплики
[zh] 开窍大典: 84 знака ≈ два полных предложения с окружением
[en] Gabriel: «offers reminder of these, our players:\nGabriel de León—The Last Silversaint, the Black»
              13 СЛОВ, обрезано с обеих сторон посреди фразы

Одна и та же цифра даёт две реплики диалога на китайском и обрубок фразы на английском. Это ровно тот класс, который CLAUDE.md называет утечкой: Go не ветвится по паре (и правильно), но смысл константы по паре различается, значит её место — пар-данные (internal/lang/langpack), а не инженерный дефолт. И мой собственный вердикт §3.2 «3×40 достаточен» надо читать как «4384 морфемы контекста достаточно», а не как «числа 3 и 40 достаточно».

§6.4 Что делать (предложение, НЕ исполнение — санкции не было)

  1. Гонять эксперименты на Кристоффе сейчас преждевременно. Мерить нечего: WHICH-канала для латиницы не существует, а терминолог без кандидатов не запускается. Второй КНИГИ мало — нужен второй ДЕТЕКТОР.
  2. Дешёвый и честный первый шаг — не эксперимент, а решение: признать, что internal/miner — детектор ханьской пары, и назвать, чем ловятся кандидаты на латинице. Прототип уже есть и замерен пакетом-7: eval/pkg7/mine_nonhan.py, каналы ORTHO/DISP/CONTRAST; на Кристоффе он достал Ashdrinker, Silversaint, San Michon, Forever King — то, что боевой канал не производит в принципе.
  3. Что стоит перепроверить на второй паре ДО расширения (когда детектор будет): срыв языка ответа без якоря (§3.4) — на en→ru он опаснее всего; и kwic_width как пар-данные (§6.3).
  4. Чего второй книгой не купить: цену расширения эмиссии. Она упирается в холодный старт с пустым банком на ЛЮБОЙ паре, и это по-прежнему единственная неизмеренная цифра.

§7 Добор по D39.51: два замера. ПРЕ-РЕГИСТРАЦИЯ (написана ДО трат и ДО счёта)

Санкция D39.51 (26.07): (а) пример формата в промпте роли — арм «3×40 без якоря + строка примера на целевом письме», 3 повтора, ≈$0.009; (б) P1 consistency — $0 из сохранённых артефактов.

§7.1 Замер (а): помогает ли строка примера удержать язык ответа

Фактор ровно один, проверено диффом, а не глазом. Вариант промпта собран копией backend/prompts/zh-ru/terminologist.md в скретчпад (репозиторий не тронут); единственное отличие — три строки после спецификации формата:

Пример строки ответа:

师父	наставник

Батчи, ключи и user-часть запроса побайтно те же, что у контрольного арма gNOANCHOR (проверено сравнением построенных запросов). Пример-терм 师父 не входит ни в выборку, ни в якорь, ни в сид и не встречается в срезе ни разу — подсказать эталон он не может по построению.

Арм без фактора — существующий gNOANCHOR (3×40, без якоря, без примера, 3 повтора, 120 строк ответа, из них 22 не на целевом письме).

Предикат «не-целевая строка» (тот же, которым отвечал бэкендерам): в принятом парсером ответе нет ни одной руны кириллицы. Смешанные строки (кириллица + латиница) считаются отдельно и в критерий не входят — предикат их по построению пропускает.

Критерий, названный ДО прогона: арм с примером проходит, если даёт 0 не-целевых строк из 120. Любая не-целевая строка = фактор не сработал.

Мощность — называю ДО прогона, потому что после будет поздно. Срыв в контроле случался не в каждом прогоне: 1 прогон из 3, 2 батча из 9, 22 строки из 120. Если считать батч независимой попыткой, то при НУЛЕВОМ эффекте вероятность получить 0 срывов на 9 батчах равна (7/9)⁹ = 0.104. То есть даже чистый проход — это «согласуется с починкой» с одним шансом из десяти на совпадение, а не доказательство. Провал же (хоть одна не-целевая строка) — сильная улика против фактора. Усиление до 6 повторов уронило бы ложный проход до ~0.011 и стоило бы ещё ≈$0.009; санкция названа на 3 повтора, поэтому гоню 3 и цифру ложного прохода публикую рядом с результатом.

§7.2 Замер (б): P1 consistency как разделитель термов и мусора

Метрика. Для каждой из 74 поверхностей банкноты: Σ единиц, где чтец объявил строку термином, делить на Σ единиц, где строка физически встречается.

Отклонение от формулировки санкции, названное заранее. Санкция говорит «чанков». Тексты боевых чанков прогона не сохранены (в БД лежат хеши и вердикты, не исходник чанка), поэтому единицей взята ГЛАВА — атрибуция главы у чекпойнта банкноты есть точная. Цена отклонения измерена, а не оценена: доля поверхностей, встречающихся в ≤1 единице, составляет 0.743 по главам и 0.730 по чанкам моей нарезки — то есть более мелкая единица метрику не спасает, а вырожденность есть свойство десятиглавного среза, не единицы.

Разметка. 74 поверхности размечены на TERM/JUNK тремя независимыми разметчиками вслепую: им дана строка исходника, предложенный черновиком перевод и до двух контекстов — и НЕ даны ни частота, ни главы, ни сама метрика (иначе метка коррелировала бы с арм-без-фактора). Метка — большинство из трёх; согласие публикуется; расхождения решаю сам по контекстам и помечаю. Это прямой ответ на слабость, записанную мной же в §2.5 как непокрытую («разметчик один»).

Критерий, названный ДО счёта (из санкции): P1 засчитывается как разделитель, если существует порог, при котором выше него оказывается ≥80% TERM, а ниже — ≥60% JUNK.

Арм без фактора: голая частота на том же наборе и том же критерии. Она обязана провалиться — иначе P1 не несёт информации сверх частоты, и вся конструкция беспредметна (§5.1 уже показал, что частота термы и не-термы не разделяет; здесь это проверяется на ДРУГОМ наборе и другой разметке).

Заранее названный стоп. Если вырожденных поверхностей (встречаются в ≤1 главе, поэтому P1 = 1.0 по построению) окажется больше половины набора, критерий §7.2 объявляется неприменимым на этих артефактах: на такой популяции «≥80% TERM выше порога» достигается тривиально и ничего не значит. В этом случае пишется, чего стоит измерить P1 по-настоящему, а цифра не подгоняется.

§7.3 Результат (а): пример формата язык УДЕРЖИВАЕТ — критерий выполнен

Факт $0.00960 (смета ≤$0.0232, названная до трат), 9 вызовов, 120 принятых строк ответа.

Арм Строк НЕ на целевом письме Смешанных (кир.+лат.)
3×40 без якоря, без примера (контроль) 120 22 3
3×40 без якоря, со строкой примера 120 0 7

Критерий §7.1 (0 не-целевых строк) ВЫПОЛНЕН. Три строки промпта — Пример строки ответа: 师父 наставник — сняли полный срыв в английский там, где его не удержал ни якорь (его нет), ни объявление {{target_lang}}, ни весь русскоязычный промпт.

Мощность, названная ДО прогона, и она же ограничение вывода. Срыв в контроле происходил не в каждом прогоне: 2 батча из 9. Значит при НУЛЕВОМ эффекте шанс получить 0 срывов на 9 батчах равен (7/9)⁹ = 0.104. Читать результат следует как «согласуется с починкой, один шанс из десяти на совпадение», а не как доказательство. Удвоение повторов уронило бы эту цифру до ~0.011 и стоило бы ещё ≈$0.010 — решение не моё, но цифра названа.

§7.4 Побочный результат (а): пример НЕ чинит утечку алфавита, и экран её не поймает

Смешанных строк стало не меньше, а больше (7 против 3), и все они — одно и то же место:

Терм Подпись владельца Арм с примером Контроль
甲等 «класс А» (кириллица) «категория A» (латиница) «Ранг A»
乙等 «класс Б» «Класс B» · «уровень B» «Категория B»
丙等 «класс В» «Класс C» · «уровень C» «Категория C»

Сравнение 7 против 3 причинным считать нельзя: в контроле те же самые термы в прогоне r2 уехали целиком в английский («Grade C», «Grade B») и попали в колонку «не на целевом письме», а не «смешанных». То есть поведение одно и то же в обоих армах — модель берёт буквенные обозначения из ЛАТИНСКОГО алфавита, — а пример лишь перевёл окружающее слово на русский.

Значение для стройки: предикат «в ответе есть руны целевого письма» пропускает все семь. «категория A» с латинской A от подписанного «класс А» с кириллической А отличается байтом и не сойдётся с каноном никогда, а языковой экран промолчит. Ни один подписанный dst сида (53 строки) латинских букв не содержит вовсе — то есть эталон здесь однозначен, и правило «в целевой строке латиница допустима только внутри латинского имени собственного» проверяемо. Это не возражение против экрана: это второй дефект, который экран по построению не покрывает, и теперь он измерен дважды.

§7.5 Результат (б): P1 consistency НЕ разделяет термы и мусор

Разметка — три независимых слепых разметчика, попарное согласие 0.973 · 0.986 · 0.986, единогласно 72 из 74; расхождения ровно два (第三蛊, 镇族蛊虫), взято большинство. Метка: 37 TERM · 37 JUNK — набор сбалансирован сам собой, подгонки не потребовалось.

Заранее названный стоп сработал. Вырожденных поверхностей (встречаются в ≤1 главе среза, поэтому P1 = 1.0 по построению) — 54 из 73 = 0.740, что больше половины. И вырожденность бесполезна не «в среднем», а адресно: среди этих 54 ровно 27 TERM и 27 JUNK. Обе метки получают одинаковый максимум, разделять там нечем.

Набор Метрика Лучший порог TERM выше JUNK ниже Критерий ≥0.80/≥0.60
весь (73) P1 1.000 0.000 НЕ ВЫПОЛНЕН
весь (73) частота (арм-без-фактора) >4 0.189 0.861 НЕ ВЫПОЛНЕН
невырожденные (19) P1 >0.5 0.200 1.000 НЕ ВЫПОЛНЕН
невырожденные (19) частота (арм-без-фактора) >7 0.300 0.778 НЕ ВЫПОЛНЕН

Порог — не единственный способ прочитать метрику, поэтому считаю и площадь под кривой (вероятность, что случайный TERM получит балл выше случайного JUNK; 0.5 = ноль информации):

Весь набор Невырожденные (19)
P1 consistency 0.438 0.583
Частота (арм-без-фактора) 0.500 0.433

P1 на полном наборе ниже случайного угадывания. Арм-без-фактора отработал ровно как обязан был: голая частота даёт 0.500 — ноль информации, независимое подтверждение §5.1 на ДРУГОМ наборе и ДРУГОЙ разметке. На 19 невырожденных P1 даёт 0.583 — формально выше монетки, фактически 10 против 9 объектов, и лучшее, чего метрика достигает, это 2 TERM из 10 выше порога.

Вердикт: положительного P1 нет. Права на порядок подачи метрика не заработала. Внутри среза видно и почему: два верхних места по P1 действительно заняты термами (灵泉 1.00, 学堂家老 0.75), но на самом дне рядом с (0.10, JUNK) и 少年 (0.14, JUNK) стоит 魔道巨擘 (0.00, TERM), а вся середина 0.50 — ровная смесь.

Отклонение от формулировки санкции, названное в §7.2 и подтверждённое замером. Единица — глава, а не чанк: тексты боевых чанков не сохранены. Цена отклонения измерена: доля вырожденных 0.740 по главам против 0.730 по чанкам моей нарезки — более мелкая единица метрику не спасает.

Чего стоит измерить P1 по-настоящему: данных банкноты существует только на 10 глав, а метрика требует, чтобы поверхность встречалась во МНОГИХ единицах. Нужен прогон черновой волны с включённой банкнотой на объёме, где типичная поверхность попадает в 510 единиц, — то есть та же полная книга, что и для холодного старта. Отдельного замера P1 при этом не потребуется: он считается $0 из чекпойнтов того же прогона.

§7.6 Деньги добора и критик полноты

Замер Вызовов $
(а) арм с примером формата 9 0.00960
(б) P1 consistency 0 0
Добор итого 9 0.00960
Пакет-8 нарастающим итогом 156 $0.12273
Проверка критика Итог
Фактор в (а) ровно один доказано диффом собранных запросов: ключи и user-часть побайтно те же, отличие — три строки
Пример не подсказывает эталон 师父 нет ни в выборке, ни в каноне, ни в сиде, и не встречается в срезе ни разу
Мощность (а) названа ДО прогона да, 0.104 при нулевом эффекте
Разметчик в (б) не один три независимых, слепых, согласие 0.9730.986
Разметка не видела метрику да: разметчикам не давали ни частоту, ни главы, ни P1
Арм-без-фактора в (б) провалился, как обязан да, AUC 0.500
НЕ покрыто (а) одна модель, 3 повтора, одна пара; разметчики (б) — модели, а не люди, и их согласие 0.98 может отражать общий системный вкус, а не истину

Ревью-приписка к §7 (оркестратор №8, 26.07): ОБА ЗАМЕРА ПРИНЯТЫ, D39.52. Воспроизведено: (а) арм с примером — 0 из 120 строк не на целевом письме (независимый пересчёт по raw_example своим кодом); (б) ре-ран p1_consistency.py на сохранённых артефактах d51 — вырожденность 54/73 = 0.740, критерий не выполнен на полном и невырожденном наборах, частотный арм-без-фактора нулевой. Оговорка мощности (а) — 0.104 — принята как названная честно; удвоение повторов НЕ берём: гарантия — экран п.1, живой монитор — счётчик OffLanguage холодного прогона. Побочная находка «утечка алфавита» (7 строк вида «категория A»; предикат п.1 их пропускает, подписанные dst латиницы не содержат) — записана хвостом в пак-21 (кандидаты: банк-линт по латинице в dst / строгая форма §2.2-Б).