# Пара en→ru: на чём стоит каждое число и решение Носитель провенанса пар-пакета. Промты его не несут: комментариев в промтах нет по слову владельца 17.09 («не нужны ни в каком виде»), а знание обязано жить в репозитории. ## 1. Что пара везёт | файл | что в нём | |---|---| | `prompts/en-ru/translator.md` | рамка двух браков + пять осей, русская и английская стороны | | `prompts/en-ru/translator-banknote.md` | тело переводчика + канал ⟦TM-BANK-v1⟧: та же системная часть плюс ОДНА вставка, различие стережёт пин `TestBanknotePromptIsItsTranslatorPromptPlusOneBlock` — правку веди в ОБА файла | | `prompts/en-ru/editor.md` | шесть осей правки, десять проверок, ДИСКУРС-перевёрстка, два FEWSHOT — ⚠ блок примеров едет только на АРМАХ: `c1`/`c2` держат `few_shot: false` (D38.5, reasoning-редактор), и на боевом пути модель их не видит | | `prompts/en-ru/terminologist.md` | имена по языку происхождения, топонимы по составу, титулы по смыслу | | `prompts/en-ru/classifier.md` | класс × род; cue-слова английские, `they` об одном лице → `none` | | `prompts/en-ru/judge-selector.md` | роль не исполняется фазой 0; ⚠ «выведи только номер» — ЗАГЛУШКА до парсера фазы 2 | | `prompts/en-ru/repair/latin_residue.md` | ⟦TM-NOCHANGE⟧ — главная ветка; имя чинится только при очевидной форме | | `prompts/en-ru/repair/broken_word.md` | целевой класс, копия zh: дефект русского выхода от источника не зависит | | `configs/pairs/en-ru.yaml` | оценка `fertility.other` + коридор | ## 2. Почему промт вообще стоит работы — замер, а не вкус `docs/experiments/23-editor-tier.md:5536` — разрывы в долях собственного порога, панель `p4`, 16 английских глав этой книги, 16 отдельных слепых читателей: ``` удалить ВЕСЬ ролевой промт (RE↔RQ) 1.50 / 1.13 ≈ 1.3 порога ⚠ см. поправку (б) ниже удалить дорогую стадию (Z0↔ZD) 1.38 / 0.85 ≈ 1.6 порога ``` Первичный эндпойнт объявлен ДО чисел (`:5530`): 13 глав из 16 в одну сторону, знаковый p=0.0213. ⇒ ролевой промт по весу сопоставим с целой платной стадией. ## 3. Рамка двух браков — решения ВЛАДЕЛЬЦА, не наши Формулировка взята из `eval/dovodka/rol.py` (второе определение `_BRAK`, после приёмки), её основания: - 16.08, дословно: «штрафовать за вольность нельзя, живой язык — приоритет; штрафовать можно только за перевирания смысла» (`eval/dovodka/prompts/onepass-core.md:13`). Там же: «Ни один боевой промт такого разрешения не давал — оба только ЗАПРЕЩАЛИ». - 20.08, дословно: «присутствие одного языка в другом… полное отсутствие художественности и родного звучания… машинный перевод грубо говоря… перевод это отчасти какое-то но творчество, без перевирания смысла нужно написать текст, чтоб он звучал естественно» (`eval/dovodka/rol.py:187-190`). - Слепое чтение 17.08 забраковало БОЕВОЙ перевод по РЕГИСТРУ: ярость передана словом «шествовала», мат смягчён, вежливое «Пойдёмте» в реплике, которую выплёвывают (`eval/dovodka/prompts/onepass-core.md:15-19`). - Абляция редакций: `RB > Z0 > RC > RN` (`eval/dovodka/SESSION2-LOG.md` §15.21), RN дороже всех по размышлению (28 809 против 23 301, §15.19). ⚠ **Контроль шума КРАСНЫЙ** — порядок при n=3 не разрешим; уцелевает только «RB не хуже продакшена». ⇒ В боевых `prompts/zh-ru/` этих решений НЕТ. Внесение туда — деньги (см. §6), решение оркестратора. ⛔ **И ЧЕГО ЭТА РАМКА МОЖЕТ НЕ ДЕЛАТЬ — назвать обязательно, иначе первый же замер на английском припишет промту то, что сделал ТАРИФ.** Полигон записал механизм победы `RB` прямо (`eval/dovodka/SESSION2-LOG.md:1392`, сверено мной): «`RB` думает 23 301 токен и пишет 94–100% текста в уме — то есть покупает качество той же дорогой монетой. Дешёвый `RC` (11 268) написал хуже. **Качество здесь пропорционально не удачности формулировки, а количеству черновиков, которые модель успела написать про себя.**» Цена клетки: `RB` $0.1050 против ~$0.025 у боевой связки — вчетверо (`:1299-1300`). ⇒ **переносится ФОРМУЛИРОВКА, а работал, возможно, БЮДЖЕТ РАЗМЫШЛЕНИЯ.** На en→ru при другом усилии та же рамка может не дать ничего. Наверняка переносится только одно: это решение ВЛАДЕЛЬЦА. ⚠ Поправка к красному контролю шума, прочитанному мной слабее, чем он есть: читатель НЕ спутал близнецов — он написал, что `ZF` «маскируется под `Z0`», родство опознал и всё равно развёл арма на 2-е и 5-е место ⇒ это разброс АРМА, а не шум читателя. ⛔ **ДВЕ ПОПРАВКИ, КОТОРЫЕ ПРИШЛИ ПОЗЖЕ И ОТМЕНЯЮТ ДВА МОИХ УТВЕРЖДЕНИЯ.** **(а) Механизм дефекта ингеста я назвала НЕВЕРНО ДВА РАЗА, и оба раза со словом «проверено».** Сперва: «движок отдаёт перенос на каждый уровень вложенности `
`» — избыток пустых строк БЕЗВРЕДЕН, `splitParagraphs` (`internal/chunk/chunker.go:470-478`) их отбрасывает, а `blockTags` держит `blockquote` НАМЕРЕННО (без него «a whole chapter collapses into one paragraph»). Затем: «`

` внутри `

` — это строка стиха». ⛔ Пере-снято моим прибором прямо по EPUB (126 документов): **`

` внутри `

` — 0**. Такого механизма нет. ⭐ **Что в книге ЕСТЬ, замер тем же прибором:** цепочек `blockquote` — **88**, пустых 0, **87 из 88 несут ровно ОДНУ строку**, медиана длины **32 знака**; максимальная вложенность 10 и она означает типографский отступ. Шесть подряд: «And so ended the dark year of» · «Empire 676, wherein the Fivefold» · «Throne of Elidaen was beset by» … ⇒ это **прозаический эпиграф, разбитый конвертером на строки по ~32 знака**, каждая своей цепочкой; движок отдаёт каждую отдельным абзацем. Правило промта поэтому ВЕРНО по выводу и пере-формулировано по признаку: «несколько коротких абзацев подряд, каждый продолжает предыдущий» — без опоры на знаки конца предложения (они у пар разные, и такой признак ветвился бы по языку). ⚠ Число «726 абзацев без знака конца предложения» о стихе НЕ говорит: разложение показало заголовки, обрывки оглавления и реплики, оборванные тире. Ряд 499 пере-формулирует оркестратор. **(б) `restore_paragraphs` мне НЕ подходит, и совет взять его отозван его же автором.** Он чинил дефект ПОЛИГОННОГО скрипта (`pair_en.raw_text` сносил теги регексом), а не движка. ⛔ **НО СЛЕДСТВИЕ ТОГО ПОЛИГОННОГО ДЕФЕКТА ОСТАЁТСЯ, И ОНО БЬЁТ ПО ЧИСЛАМ ВЫШЕ.** Их собственная диспозиция «починка экстрактора абзацев — до любого нового английского замера, весь материал искажён нами» (`eval/dovodka/KONSILIUM-22-08.md:141`) НЕ исполнена, арм `RA` НЕ куплен. ⇒ **английские СУДЕЙСКИЕ числа полигона сняты на тексте с потерянными границами абзацев**, и это касается ровно двух чисел, на которые я ссылаюсь: вес ролевого промта (§2) и «редактор на английском покупает» (1.22 против 2.78, §1 таблицы). Оба помечены в тексте. ⚠ Плюс их же оговорка о приборе: разрешение рангового прибора на английской паре **2.15 места против 1.63 на китайской** — на en-стороне «неразличимо» наступает раньше. ⭐ **УТОЧНЕНИЕ ОТ САМОГО ПОЛИГОНА, и оно возвращает основание:** дефект подачи был обойдён ОСОЗНАННО — вход у ВСЕХ армов одинаково плоский (`eval/dovodka/rol.py:110-127`: «`RN / ZP` — эффект ПРОМТА, вход у обоих ОДИНАКОВЫЙ, плоский; `RA / RN` — эффект ПОДАЧИ»), 273 английские клетки, у восстановленного арма `RA` — 0. ⇒ **контрасты промтов между собой ЧИСТЫ**, и порядок `RB > RC > RN` держится. Не держится АБСОЛЮТНЫЙ уровень качества и **всё, что про абзацный строй и оформление диалога**: модель видела сплошной блок вместо 11 447 абзацев. ⚠ Мои правила об абзацах и диалоге на их английских наблюдениях НЕ стоят — они стоят на `docs/research/12-failure-modes-ru-target.md` §10 (норма Розенталя) и на МОИХ замерах прибором движка (2370 из 2532 абзацев, 11 203 абзаца по всем главам). ⚠ **И факт, который надо записать раньше, чем он понадобится:** если бэкенд починит ингест, английские числа полигона и новые станут НЕСОПОСТАВИМЫ (не «неверны», а сняты на разном тексте). Причина, по которой полигон не починил свой экстрактор, — цена: uid единицы = `sha1(source.strip())`, правка пробелов переименовывает все единицы и **289 оплаченных клеток на $2.64 теряют адресата**. ⇒ ЧТО ЭТИМ НЕ ЗАТРОНУТО: подсчёты по тексту книги (`feet` ×161, `François` ×517 и прочие) — это счёт, а не судейство; абляция рамки куплена на ZH (`--buy zh RC RB`), не на английской панели; постинструкция A1 мерена на zh и grok; мои собственные замеры движком (2370 из 2532 абзацев и т. д.). ## 4. Правила русской стороны — носители Все из `docs/research/12-failure-modes-ru-target.md`: ты/вы как событие §2 · вид §3 · рема в конец §4 · деепричастие с общим субъектом §5 · несобственно-прямая речь без бэкшифта §6 · диалект компенсацией §7 · брань §8 · междометия §9 · тире-вёрстка диалога §10. Блок-лист транслит-междометий уже лежит в данных: `internal/lang/data/target-ru.txt`, ключ `translit_interjection`. ⚠ Правило «плотность жестов» у ПЕРЕВОДЧИКА снято: за ним не стоит замера, а прореживание требует сверки с исходником — это работа редактора. У редактора оставлено. ## 5. Английская сторона — числа по этой книге Подсчёты полигона (`docs/experiments/21-role-topology.md`) и мои по EPUB (вхождения, не строки): `François` ×517 · `Fabién` ×180 · `château` ×93 · `Aveléne` ×21 · `Niamh` ×15 · `feet` ×161 · `miles` ×25 · `inch` ×16 · `fathom` ×4 · `fucking` ×136. ⛔ **`stone` ×228 — и ни одного раза МЕРОЙ ВЕСА.** Единственное вхождение с числительным — «five stone bowls», то есть прилагательное. ⇒ правило «отличай stone-меру от stone-камня» снято из переводчика и редактора: оно требовало различения там, где различать нечего, и тем самым ставило под сомнение 228 законных «камней». Это частный случай ратифицированного правила владельца (17.09): данные пары обязаны так же хорошо отрабатывать ТАМ, ГДЕ ЯВЛЕНИЯ НЕТ, — правило либо про КЛАСС без опоры на конкретную меру, либо уходит. Рамочный рассказ: в крупнейшей главе движка 2370 абзацев из 2532 открываются «“», закрывающая «”» стоит у 183 — непарная кавычка есть КОНВЕНЦИЯ, а не ошибка набора. Примеры в промтах ролей, чей ответ становится законом банка (терминолог, классификатор, банкнота), взяты ВНЕ книги. Замер по САМИМ ПРИМЕРАМ, а не по именам вообще: двадцать пять терминов-примеров (`Ashlyn Vale`, `the Ashen Reach`, `the Long Dark`, `the Quiet One`, `Michel du Bois`, `O’Rourke`, `Corwin`, `Highmarch`, `Ravenshire`, `kilnstone`, `wyrmling`, `drakeling`, `Marchwarden`, `Marie-Claire`, `Sévrine`, `Thibault`, `Oisín`, `the Elder`, `Gaspard`, `Lord Marshal`, `Brother Confessor`, `the Ninth Canticle`, `Saint-Aubin`, `Ashlyn`, `Sable`) — в тексте книги **0 вхождений каждый**; прибор прочёл 1 626 475 рун, контроль на том же тексте: `François` **517**. Последние семь нашёл советчик — мой список был на семь короче, и это разница между «посчитала примеры» и «посчитала ВСЕ примеры». ⚠ Отдельные СЛОВА из примеров в книге, разумеется, есть (`Vale` 45, `Reach` 23, `Dark` 29) — законом банка становится строка-термин целиком, и спрашивать надо о ней. ## 6. Цены, которые надо знать прежде, чем править - **Снятие комментариев из промта — $0 ТОЛЬКО ПРИ УСЛОВИИ, и условие стоит одного переноса строки.** `stripPromptComments` (`internal/pipeline/render.go:104-120`) снимает РОВНО `` и оставляет окружающие пробелы; SHA берётся по всей очищенной форме ДО разбора и до `TrimSpace`. Замер функцией движка на `classifier.md`, три операции над одним файлом: снятие ТОЛЬКО тега — `885766fd1e37` (хеш не двигается); тег вместе с ОДНИМ хвостовым переносом — `82759ef35326`; тег вместе с ДВУМЯ — `f7bc660330a3`. ⚠ Первая редакция этого абзаца печатала `f7bc660330a3` под словами «вместе с хвостовым переносом», то есть приписывала число не той операции; пере-снято. ⚠ Хеш промта чувствителен к пробелам, которых модель НЕ ВИДИТ (`System` проходит `TrimSpace`). ⛔ НО ЦЕНА ЭТОГО НЕ ВЕЗДЕ ОДНА, и первая редакция этого раздела сказала шире, чем держится. Потребителей файлового `tpl.SHA256` ровно два: `internal/pipeline/snapshot.go:495` (промты СТАДИЙ) и `:169` (классы РЕМОНТА). Банк-роли туда НЕ входят — они опознаются ОТРЕНДЕРЕННЫМ `tpl.System` (`internal/pipeline/bankbasis.go:209-215`), то есть уже `TrimSpace`-нутым и к пробелам нечувствительным. ⇒ для трёх файлов, где комментарии были (`classifier`, `terminologist`, `editor-mono`), неаккуратная уборка сдвинула бы хеш, но денег бы НЕ стоила; денежной она была бы у стадийных промтов и ремонта, а в них комментариев не было. Ведущие пустые строки в трёх файлах оставлены как гигиена, а не как экономия. - **Правка ТЕКСТА банк-роли — деньги.** `internal/pipeline/bankbasis.go:183-187` хеширует ОТРЕНДЕРЕННЫЙ системный текст терминолога И классификатора в личность продюсера: решённые термины перестают отдаваться из базиса и пере-спрашиваются из ПОЖИЗНЕННОГО бюджета роли. На английской книге сегодня $0 — банка нет. - **Любой файл в `configs/langpacks/en-ru/` делает незапускаемой английскую книгу, ОБЪЯВИВШУЮ `langpack_root`** — и вот условие, при котором вывод перестаёт держаться: книга без этого ключа выходит раньше (`internal/pipeline/runner.go:432`, `if r.Book.LangpackRoot == "" { return nil }`) и каталога не видит вовсе. Дальше загрузчик включается по существованию каталога ПАРЫ (`runner.go:436`) и затем требует у источника `en` либо одиннадцать таблиц КИТАЙСКОЙ морфологии, либо пиньинь. Замер живым движком: с созданным `langpacks/en-ru/` (один `heading.txt`) `tmctl translate` падает `open …/langpacks/en/surnames-single.txt: no such file`, EXIT=1. ⇒ `heading.txt` («Глава {n}») и `terminology.txt` (ширины KWIC) завести НЕЛЬЗЯ до строки бэклога 347. ## 7. Чего пара НЕ может предъявить **Качество этих данных не измерено и в этом заходе измерено не будет.** Размеченного корпуса для en→ru в репозитории нет, человеческого эталона книги в дереве нет. Батарея зелена при любом их содержании. Единственный рубеж — консилиум: сессия плюс советчик Fable 5, шесть кругов. ⚠ И у этого рубежа названа своя граница: обе стороны читают один текст одними приборами, поэтому дефект, невидимый обоим, консилиум не ловит — в этом паке его дважды поймали ТРЕТЬИ читатели (§10). ## 8. Провенанс, переехавший из промтов Из `prompts/zh-ru/` комментарии сняты по слову владельца. ⚠ **Здесь — то, что несло ВЫВОД, а не весь их текст:** перечни нот, цифры и примеры из снятых комментариев сюда не переносились (замер веером: из 19 опрошенных носителей до этого раздела доехали 6). Полный прежний текст берётся одной командой — `git show HEAD:backend/prompts/zh-ru/<файл>`, и это адрес, а не обещание. - `terminologist.md`: третье поле ответа — уверенность 0–100, **НЕ арбитр**, только порядок ручного ревью; ни весов, ни порогов, ни сравнения между моделями (`D39.102`; разбор поля — `internal/terminology/terminology.go:710-738`). - `classifier.md`: третье поле — род; производителя у него не было вовсе (терминолог его не возвращает, майнер брал из сида, на несидированной книге ось мертва), и этот проход читает те же контексты по тем же кандидатам ⇒ род стоит ноль новых вызовов. Значение вне словаря `male|female|neuter|none` движок считает и ОТБРАСЫВАЕТ, класс при этом сохраняется. `hidden` в словарь не входит НАМЕРЕННО: это решение о спойлерной политике книги, а не наблюдение по контекстам, и остаётся ручным, в сиде (`internal/terminology/classify.go:42`). - `editor-mono.md`: **СПИТ.** Монолингвальный вариант редактора (D30.1, подтверждающий арм D13.1). Проверено исполнением: живых ключей, ссылающихся на него, — **0** (все 17 упоминаний в `books/` и `configs/` суть комментарии). Файл держит пин `TestEditorPromptIsBilingual` (`internal/pipeline/runner_memory_test.go:320`, утверждение про `{{text}}` — `:346`): файл обязан существовать у своей пары и НЕ ссылаться на `{{text}}`. ⚠ Пин пере-написан этим паком на цикл по парам, `editor-mono` опционален на пару — прежний адрес `:331` после правки указывает в другую строку. ## 9. Оговорки советчика, взятые дословно - Текст рамки двух браков — ВТОРАЯ редакция `_BRAK`, и это **доказано кодом, а не предположено** (пере-снято полигонной сессией, сверено мной): в `eval/dovodka/rol.py` два присваивания ОДНОМУ имени — `:192` и `:214` — при единственном использовании на `:226`; в Python побеждает последнее, значит первая редакция мертва. Коммит `3075566` («Freeze two ablation variants») добавил ОБА определения сразу ⇒ первая была мёртвым кодом с рождения, а не устаревшей версией. ⚠ Артефактами это недоказуемо: провод в клетках полигона не хранится. Пере-снято на правильной популяции — в `books/dovodka` **1345** JSON и 82 txt (прежняя редакция печатала 5161, это сумма по ЧЕТЫРЁМ корпусам `books/`, то есть контроль был снят не с того предмета). Ключей `prompt`, `system`, `messages` — **0 файлов**; фраза рамки «БРАКУЮТСЯ ДВА ИСХОДА» — **0**. Контроль прибора на той же выдаче: ключ `uid` найден в **1235** файлах ⇒ читались существующие клетки. Доказательство редакции `_BRAK` поэтому механическое, по коду. - `judge-selector.md`: «выведи ТОЛЬКО номер» — **заглушка до парсера фазы 2**. Парсера ответа судьи в движке нет, роль отказывается фазой 0; когда формат определит движок, промт подгоняется под него. - Вес промта (§2) измерен на жильце `gemini-3.1-flash-lite` при вендор-дефолте (`eval/dovodka/rol.py:630`), не на боевом редакторе. Переносится НАПРАВЛЕНИЕ, не величина. ## 10. Как собран пакет Шесть кругов консилиума сессии и советчика Fable 5 (заказ владельца 17.09: «пока вы оба не окните»). Круг 1 — инвентарь механизмов английского. Круг 2 — 19 механизмов, вердикты по каждому правилу, 7 дефектов китайского промтинга. Круг 3 — язык инструкций (решение владельца: русский), три китайских комментария, разбор пере-писанного пакета. Круг 4 — шесть правок переводчику, три редактору, одна классификатору. Круг 5 — одна висящая ссылка и пере-формулировка признака стихотворного блока после того, как полигон отозвал свой же совет. Круг 6 — пакет целиком под ратифицированным правилом владельца «данные обязаны так же хорошо отрабатывать там, где явления нет»: подтверждены чистыми семь правил, найдены НЕ чистыми два (обоснование «в мире книги метрической системы нет» — факт этой книги; признак стихотворного блока ловил оборванные реплики) и досчитаны примеры законодателей с 18 до 25. Восемь ОК с обеих сторон. ⚠ **И то, чего консилиум НЕ даёт:** обе стороны читают один и тот же текст одними и теми же приборами. Дефект, невидимый обоим, консилиум не ловит — в этом паке его дважды ловил ТРЕТИЙ читатель (оркестратор №23: утечка конкретной книги в пар-слой; полигонная сессия: отозванный механизм ингеста). ## 11. Три заказанных замера — результаты (§4.5, §4.6, §4.7 промта пака) Все три сняты кодом САМОГО движка на корпусе из 75 русских переводов ЭТОЙ книги (`books/role-topology/en2-*.json`, 15 исходных чанков × 5 армов), контроли напечатаны рядом. **§4.5 ПОРОГ ЭХА — НЕ ДВИГАТЬ.** Функция `sourceScriptShare` с `lang.LangScripts("en")`, порог `cjkEchoThreshold = 0.15`: | | | |---|---| | доля латиницы в русском выходе | min 0.0000 · медиана 0.0000 · max 0.1211 | | выше порога 0.15 | **0 единиц из 75** | | по 14 прозаическим чанкам из 15 | максимум **0.0136** (запас к порогу 11×) | | единственный чанк у порога | 0.1211 — выходные данные издательства, не проза (запас 1.24×) | | контроль прибора | чистый английский выход = **0.8095**, то есть прибор различает эхо | | контроль данных | `len(LangScripts("en")) = 1` — детектор не мерит пустоту | ⇒ порог трогать нечем: ложных срабатываний на прозе нет, а пере-снапшот стоил бы движения `classifierVersion` (подстрока `echo015`). Ряд бэклога **260** этим замером не закрыт: он про латиницу-тяжёлый русский на ДРУГОЙ паре, и мой корпус его клетку не покрывает. **§4.6 ДЕТЕКТОР ЛАТИНИЦЫ — порог не трогать, лечение аллоу-листом, и у него найден свой дефект.** Боевой путь `checks.RunCheapGates` с чекерами цели `ru` (контроли: `TargetActive()=true`, `TargetScriptNonLatin()=true`, подставная утечка «something» ловится): - сработало **10 единиц из 75**, и по прозе хиты ровно двух родов: французские вставки, которые правило пары велит СОХРАНЯТЬ (`oui` ×3, `gens` ×2, `armes` ×2), и собственное слово книги (`Vampyr`/`VAMPYR`); - остальные хиты — выходные данные издательства на служебной странице (`macmillan`, `newslettersignup`, `jaykristoff`, `New`, `York`, `Times`, `Today`, `USA`, `Aurealis`, `Publishing`, `Group`, `Martin`), то есть не проза. ⛔ **И дефект самого детектора, найденный по ходу:** `isLatinLetterOrDigit` (`internal/checks/checkers.go:596`) — только ASCII, поэтому акцентированное слово дробится на осколки. Замер функцией движка: `Aveléne` → хит **`Avel`**; `Château Impérial` → **ТРИ** хита `Imp`, `rial`, `teau`. ⇒ штатное лечение аллоу-листом (`book.yaml style_allowlist`) на акцентированных именах НЕ РАБОТАЕТ: в список пришлось бы вписывать `teau`. Передано оркестратору рядом; на этой паре экспозиция низкая, потому что правило пары велит имена транслитерировать. **§4.7 КЛЮЧИ БАНКА НА ЛАТИНИЦЕ — подозрение подтверждено и сужено.** Прогон нормализатором движка (`text.NormalizeSourceKey`) по 25 поверхностям реально предложенного банка этой книги (`books/role-topology/bank-en.json`; контроль: 25 из 25 встречаются в книге): | | | |---|---| | ключей со строчным омографом | **3 из 25**: `Dead` 167/143 · `Empire` 11/84 · `Marquis` 155/2 | | чистых (личные имена) | 22 | | `collisionProneKey` | false у всех — все ≥4 значащих рун, короткий-ключевой порог не при чём | | шире по книге, тот же класс | `Silver` 19/177 · `Will` 19/288 · `Faithful` 18/51 · `Dawn` 17/61 · `Forever` 209/76; чисты `Grail` 293/0 и `Almighty` 57/0 | ⇒ дефект реален и узок: он бьёт по заглавным НАРИЦАТЕЛЬНЫМ (фракция «the Dead», держава «the Empire»), а не по личным именам. Лечение БЕЗ правки Go — дисциплина промтов: банкнота и терминолог этой пары велят не канонизировать одиночное заглавное нарицательное. Правка `norm.go` передана оркестратору рядом, с ценой: `bankRoleProducer` делает правку текста банк-роли пере-спросом решённых терминов. ## 12. Нарезка глав (§4.4) — что решено и почему Замер прибором самого движка (`--json`-манифест, 71 запись; сумма `price.source_chars` = 1 601 395 совпадает со сводкой): глав **71**, `heading` НЕПУСТ у **0** из 71, `title_raw` — у 71 из 71; крупных (≥100 тыс. знаков) — **6** (BOOK TWO 392 312 … BOOK SIX 140 022); крошечных (<200) — **64**; средних — **1**. ⛔ 64 крошечные главы — НЕ «страницы-разделители»: это **разрезанная на файлы страница «Contents»**. Замер по EPUB напрямую: navPoint'ов 71, с фрагментом `#` — **ноль**, целей-документов 71 различных; `index_split_058.html` (583 руны) начинается словами «Contents · Title Page … Chapter I. Parting Gifts» и обрывается на 25-й записи, дальше каждая запись оглавления лежит СВОИМ документом. Настоящие главы в TOC не названы вовсе: проза живёт в документах между титулами книг, navPoint'а у них нет, и `groupChapters` приписывает их к предыдущей главе. Заголовок главы ВНУТРИ документа есть, и его форма английская — голая РИМСКАЯ цифра отдельной строкой, под ней название капсом; `

`–`

` нет ни одного. **РЕШЕНИЕ: нарезку EPUB в этом паке НЕ чиню.** (1) Эксперимент она не блокирует: BOOK THREE = 148 782 знака без пробелов ≈ **40 874 токена** при цели 41 027, промах −0.37 %. (2) Починка требует не порога в данных, а нового рода грамматики (безмаркерный заголовок + римские цифры) и разреза ВНУТРИ документа — это тело ряда **283**. (3) Порог «сколько знаков делает главу главой» проблему не решает: он убрал бы 64 крошечные записи и оставил шесть полотен. **Граница ряда 303 названа явно:** не-CJK TXT этим паком НЕ починен. Пере-снято с контролем на второй английской книге: `books/fifty_shades_1_en.txt`, строк `^[[:space:]]*Chapter ` — **26**, а `tmctl manifest` даёт **chapters=1 units=146 chunks=147** и без `en/structure.txt`, и с файлом `marker⇥Chapter`. ⚠ `chapter structure: none` в обоих прогонах НЕ доказывает, что файл не прочли: `structureOf` (`internal/chunk/ingest.go:169-171`) отдаёт `none` при `len(chapters) < 2` независимо от происхождения грамматики. **§4.8 бюджет нарезки** — оценка заведена в `configs/pairs/en-ru.yaml`, названа оценкой (см. §2 того файла).