| .. | ||
| minerharness | ||
| termharness | ||
| audit_phaseB.py | ||
| bank_profile.py | ||
| bkrs_lookup.py | ||
| blind_judge.py | ||
| blind_judge2.py | ||
| build_termset.py | ||
| joint_recall.py | ||
| kwic.py | ||
| mine_nonhan.py | ||
| p1_consistency.py | ||
| README.md | ||
| repair_judge.py | ||
| role_probe.py | ||
| rubric_probe.py | ||
| score_b2.py | ||
| score_bws.py | ||
| score_grid.py | ||
| score_probe2.py | ||
| seed_recall.py | ||
| split_book.py | ||
| terminologist_arms.py | ||
eval/pkg7/ — терминологическая ресёрч-программа (полигон, пакет-7)
Инструменты фазы A. Отчёт с цифрами и вердиктами — docs/archive/reports/POLYGON_TERM_RESEARCH_A_2026-07-26.md.
Всё здесь $0: ни одного вызова LLM-провайдера, ни одного чтения ключей.
| Скрипт | Что делает | Заметки |
|---|---|---|
split_book.py |
книга → JSONL-субстрат {chapter, chunk_idx, source} |
правила глав — ДАННЫЕ (RULES), добавить книгу = добавить строку; epub парсится stdlib (bs4/ebooklib в venv нет) и чистится от колонтитулов |
minerharness/ |
вызов БОЕВОГО internal/miner из модуля ВНЕ репо |
build.sh <work-dir> [commit]; replace смотрит в git archive-копию коммита, а НЕ в рабочее дерево |
mine_nonhan.py |
кандидаты-термы для en/ja тремя раздельными каналами | ORTHO · DISP · CONTRAST; кандзи сознательно без контраста (см. шапку) |
kwic.py |
KWIC-контексты вхождения | разметка по тексту, а не по памяти; --stats даёт объём контекстов для сметы |
seed_recall.py |
recall WHICH-канала против подписанного сида | майнер обязан гоняться с ПУСТЫМ сидом, иначе метрика вырождается |
rubric_probe.py |
измеримость критериев рубрики на подписанном сиде | M1 морфология (pymorphy3) · M2 транскрипция · M3 коллизии банка |
Правила, выученные на своих ошибках в этом пакете
- Пин обязателен. Харнесс
replace-ит копию коммита, не рабочее дерево: параллельная бэкенд-сессия правитbackend/под руками, и прогон стал бы невоспроизводимым. Все цифры отчёта — на996bade. - Ссылки
файл:строка— по коммиту пина. В рабочем дереве те же якоря уже уехали; первая редакция отчёта содержала номера строк рабочего дерева. - Порог частоты и алфавит кандидатов — свойство ЯЗЫКА, не движка. Японские названия техник живут на частотах 2–10 и в катакане/руби; ханьский n-граммный канал их не видит вовсе.
- Правило вершины словосочетания зависит от типа терма (у имени вершина последняя, у нарицательного — первая). Морфо-чекер без этого правила меряет не то: первая версия
rubric_probe.pyсклоняла «Вина» в «Монах Цветочного Вина». - Контраст без опоры вырождается в частоту. Ранжирование кандзи против словаря другого языка даёт log частоты, а не над-представленность; канал понижен до инвентаря.
- Отклонение методики — замерять, а не декларировать. Нарезка здесь не боевая; свип целевого размера чанка (800/2000/6000) дал Жаккар 1.000 — только после этого цифры можно было предъявлять.
Фаза B (добавлено 26.07)
| Скрипт | Что делает |
|---|---|
bkrs_lookup.py |
словарные статьи БКРС списком; воспроизводит куки-челлендж ca=<hex>, из-за которого страница считалась JS-рендеримой |
build_termset.py |
набор термов со входом терминолога (KWIC + пары «исходник↔черновик») из реального выровненного корпуса шести прогонов |
terminologist_arms.py |
шесть армов промпта по пре-регистрации §A5; батчи, леджер денег из фактического usage, сырьё сохраняется целиком |
blind_judge.py |
слепая Best-Worst оценка; соль перемешивания по терму, подпись владельца участвует как отдельный кандидат GOLD |
repair_judge.py |
терпимый пере-разбор судейских ответов ИЗ СЫРЬЯ (модель отдаёт JSON с недостающей скобкой) — $0, без повторных вызовов |
score_bws.py |
BWS-счета и вердикты F1–F4 по порогам, названным до трат |
audit_phaseB.py |
адверсариальная ревизия фазы B: пере-счёт объективного слоя, состав промптов по сырью, вырожденные айтемы, пере-скоринг BWS без них, деньги из сырья |
blind_judge2.py |
слепая оценка на ПОЧИНЕННОМ наборе (фаза B′): дедуп кандидатов · только расходящиеся термы · ДЕКОЙ — заведомо неверный вариант, без которого контроль «отличает ли судья годное от случайного» неизмерим |
score_b2.py |
вердикты фазы B′ по порогам §0: T (контроль правила транскрипции) · C1–C3 (годность судьи) · R (разброс прогона) |
Урок фазы B — в редакции ПОСЛЕ ревизии (первая редакция была неверной). Сперва я записал сюда «слепые LLM-судьи не имеют разрешающей способности». Проверка исполнением (audit_phaseB.py) это опровергла: у 35 термов из 80 все семь кандидатов оказались ОДНОЙ И ТОЙ ЖЕ строкой, а на 45 невырожденных судьи ставят арм без контекстов последним — то есть разрыв они видят. Настоящий урок другой и жёстче:
- Айтем без вариативности — не измерение, а шум с ценником. Сравнительный протокол обязан собираться так, чтобы кандидаты РАСХОДИЛИСЬ: дедуплицируй варианты, требуй уникальности эталона (иначе контроль «отличает ли судья подпись» неизмерим по построению), выкидывай термы, где все ответы совпали.
- Фактор, который есть во всех армах, не измеряется ни одним из них. Правило транскрипции лежало в общей части промпта — значит контроля не было, и любые «армы с правилом против армов без» были иллюзией чтения собственного кода.
- Считай улики, а не абзацы. «Три независимых наблюдения» под рекомендацией свелись к одному терму, посчитанному дважды, плюс непроверенная поисковая сводка. Перед словом «сходится» — проверь, не один ли это сигнал в трёх обёртках.
Чем кончилась ревизия (фаза B′, замер за $0.14). Правы оказались обе стороны спора, но каждая наполовину, и без замера этого было не разделить:
- Слепой судья — катастроф-экран, а не ранжировщик. Подложенный декой ловится 43–45 раз из 45 (счёт −0.93/−0.98), подпись владельца не помечена катастрофой ни разу, но ранговое согласие с объективным слоем ничтожно (ρ = +0.43 и −0.11). Грубое видит уверенно, тонкое не разрешает — и роль ему надо давать по этой способности, а не по желаемой.
- Одна строка промпта может стоить канона — и одновременно ничего не менять в среднем. Снятие правила транскрипции вернуло
春秋蝉в точный канон владельца, но агрегатный сдвиг оказался +0.013 при пороге 0.05: правило помогает на антропонимах ровно столько же, сколько вредит на названиях предметов. Единичный яркий пример и агрегат — разные улики, и путать их нельзя даже когда пример красив. - Повторы дёшевы и меняют статус вывода. Три прогона на 19 термах стоили $0.024 и превратили «P0b хуже P1» из одной точки в измерение: разрыв 6 термов против размаха 1. Заодно объяснили аномалию «случайный глоссарий дал 19/19» — 19/19 лежит внутри шума прогона.
Итог пакета (26.07): жанровый словарь ОТМЕНЁН владельцем как класс — решение о переводе принадлежит подписи на банк памяти, а пар-словарь навязывал бы одно видение всем книгам пары. Замеры силы не теряют и перепрогонов не требуют (главный результат P0b↔P1 идёт по армам без словаря; P5↔P2 несут одинаковые инертные строки), беспредметен только арм P0. Отсюда последний и самый дорогой урок:
- Замер может подорвать ПОСЫЛКУ задачи, а не только её исполнение — и тогда деливерабл надо оспорить, а не исполнить. Мы намерили ровно основание для отмены (V0 на центральном терме, ложная сходимость русских глоссариев, покрытие 0/80, четыре строки из шести отсутствуют в книге) — и всё равно принесли «таблицу на подпись», потому что она стояла в промте. Право сессии сказать «этого делать не надо» существует, канал вопросов для этого и заведён; не воспользоваться им дороже, чем не измерить вовсе, потому что так наш вкус едва не стал контрактом пары.
Пакет-8 (пре-замеры перед расширением эмиссии, 26.07)
Отчёт — docs/archive/reports/POLYGON_PREMEASURE_2026-07-26.md. Инструменты живут здесь же по указанию промта пакета-8 (зона записи eval/pkg7/), хотя относятся к следующему пакету.
| Скрипт | Что делает |
|---|---|
termharness/ |
собирает запрос БОЕВОЙ роли терминолога вне репо (Merge→AttachKWIC→ScoreVariants→Batch→RenderCanonAnchor→MessagesWithInjection); режимы build · norm (боевой NormalizeSourceKey) · parse (боевой ParseReply) |
joint_recall.py |
recall майнера · банкноты · объединения против подписанного сида; парсер ⟦TM-BANK-v1⟧ — реплика parseBanknote, сверенная с боевой телеметрией |
bank_profile.py |
цензура инъекцией по парам (терм × глава) + объективный профиль эмиссии банкноты боевыми порогами майнера |
role_probe.py |
драйвер платных вызовов: смета до трат, $0-резюм по уже оплаченным батчам, сырьё с usage/finish_reason, деньги из models.yaml |
score_probe2.py |
доля выдуманных dst по классам разметки, разброс по повторам |
score_grid.py |
сетка kwic × подача: точность против подписи, внутриточечный размах, расходящиеся позиции ПОКАЖДОМУ повтору |
Уроки, купленные пакетом-8:
- «Данные лежат там-то» — проверяй, прежде чем строить на этом замер. Промт сказал, что блоки банкноты лежат в
corpus.jsonlпакета-6. Их там 2 из 91; сырьё жило в трёх базах прогонов, и нашлось только сканированием всех 21 базы стенда. Полминуты проверки против замера, построенного не на том корпусе. - Реплика формата запроса — третья копия и первый кандидат на расхождение. Всё, что можно собрать боевым кодом, надо собирать боевым кодом:
termharnessвызывает те же функции, что рантайм, и вопрос «а точно ли модель видела то же самое» просто не возникает. - Свою же рекомендацию проверяй замером ДО того, как подать её в дизайн. Я предложил дисциплинировать банкноту частотным порогом («$0, снимает 82% лишнего») — и, посчитав частоты по всей книге, обнаружил, что самое частое слово выборки не термин (
少年, 1149), а центральный концепт光阴之河— 15. Порога не существует; рекомендация снята собственной проверкой, а не ревью. - Считай язык ответа, а не только его правильность. Арм без якоря ⟦TM-CANON⟧ в одном прогоне из трёх ответил по-английски (22 строки из 40), и ни парсер, ни эхо-гейт этого не ловят. Находка появилась только потому, что я посчитал скрипт письма по всем 126 вызовам — метрика точности её не показывала.