Land the generality research phase one as D39.60: debt is 149 sites with a clean book axis, rewrite plan P0-P5 ratified as the map, five section-12 questions stop on the owner

This commit is contained in:
Claude (backend session) 2026-07-31 23:21:35 +03:00
parent 2b75c2cce7
commit 4eb0b3d1ed
4 changed files with 469 additions and 7 deletions

View file

@ -15,6 +15,8 @@
3. **Пересборка входа пака-21 «чекеры»:** какие из 12 дефектов и существующих чекеров — общие КЛАССЫ с пар-данными (числовые масштабы, битые формы, эхо, латиница-резидю), а какие — zh-привязка в Go, требующая перепроекта, а не фикса. Вопросы разметки Р1Р4 пере-оценить: какие переживают генерализацию, какие были вопросами про конкретную книгу.
4. **План переписывания пакетами:** порядок · оценка объёма · ЦЕНЫ (какие оси снапшота двигает каждый пакет — что перекупается, что нет; прецеденты условных фолдов) · риски · **приёмочный критерий каждого пакета = «пара, которой нет в репо (ja→ru / en→ru), проходит этот слой без правки Go»**.
5. **Счёт масштаба:** файлы/сайты/строки по вёдрам — чтобы владелец видел размер долга числом, а не ощущением.
6. Опциональное исследование алгоритмов, возможные предложения по улучшению текущей кодовой базы.
7. Синк с документацией, в коде бэкенда много кода, которое отсылает к каким-то решениям, возможно полезно понимать их контекст, прежде чем переписывать
## НЕ делать

View file

@ -1,7 +1,7 @@
# Журнал прогресса
> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-07-26: пак-20 закрыт ЦЕЛИКОМ D39.4153 — терминолог · флаговый стоп · двухсекционная инъекция · точечная ре-редактура · языковой экран; жанровый словарь отменён D39.47; полигон-пакеты 6/7/8 закрыты). **Источник истины по РЕШЕНИЯМ — `architecture/05-decisions-log.md` (D1D39.53); этот файл — ЖУРНАЛ.**
> - **Фазы/курс:** Ф0 ✅ · Ф1-инфра ✅ (D20D28; golden = инвариант №8) · арка «качество-первым» D26→D38.5 закрыта · **арх-ресет D39 исполнен ЦЕЛИКОМ** (7 слоёв → программа D39.1D39.10 → паки 1116, D39.13D39.24; статус слоёв — шапка-таблица `architecture/09-target-architecture.md`) · пере-прогон rerun2 прочитан (D39.20: операционка живьём, $0-резюм ×3 арма, $6.63<$15; планка ≤2 НЕ пройдена; анти-корреляция гладкость↔верность ×3 → mistral-редактор вон) · эксп ЗАКРЫТ (D39.22), итерация №2 отложена · **курс = разработка бэкенда: пак-17 «канал B вживую» ЗАКРЫТ ЦЕЛИКОМ (дизайн D39.26 · стройка D39.27 · дельта `allow` D39.28, 25.07); вокабуляр = ПАРА `violence`/`sexually-explicit`, остаток — ФАКТЫ ToS в зоне полигона (fail-closed до них)** (D39.25: в движке НЕТ понятия «18+» — generic content-labels × provider-capabilities; лейблы вне хешей · резолв до валидации · один хоп `chain[0]` · гранулярность = книга) → **КУРС АМЕНДИРОВАН ВЛАДЕЛЬЦЕМ 25.07 (D39.33): МАСШТАБ — ПОСЛЕДНИМ, после достройки алгоритмического идеала; доказательство эффективности крупных изменений — МИНИ-ПРОГОНЫ ~10 глав (детерминированные чекеры и скан остатка первыми, судья — только когда от него зависит решение).** **ОЧЕРЕДЬ (D39.40/51/53, актуализация 31.07):** пак-19 «голос/состояние» ЗАКРЫТ ЦЕЛИКОМ (D39.5456, вкл. малую пачку 14а+14б) → ХОЛОДНЫЙ мини-прогон ИСПОЛНЕН ДОСТАТОЧНО (D39.58, Р7 владельца: recall банка 0.918/0.980, банк приходит переведённым; хвосты 16/21/22/24/13бсо следующим живым прогоном или полигон-пакетом) → **ПАРАЛЛЕЛЬ (D39.59): бэкенд — ресёрч общности (инвентаризация языковой привязки; пак-21 ОТЛОЖЕН до его карты, Р1Р4 заморожены с ним) ∥ полигон — Р6 «язык промптов» + fidelity-хвост P4 анти-эхо** → арка АВТОНОМНОСТИ банка (веб-фетч пере-замер + 36а/36б/36в; премиса «решение = подпись» амендирована D39.59) → rewrite-пакеты общности → свип гипотез → добор идеала → МАСШТАБ целой книги (7,78 млн симв., ~2284 раздела) → пилот Ф2.5. Хроника треков A/B, exp15/16 и стройки паков — архивы ниже + D-лог.
> - **Фазы/курс:** Ф0 ✅ · Ф1-инфра ✅ (D20D28; golden = инвариант №8) · арка «качество-первым» D26→D38.5 закрыта · **арх-ресет D39 исполнен ЦЕЛИКОМ** (7 слоёв → программа D39.1D39.10 → паки 1116, D39.13D39.24; статус слоёв — шапка-таблица `architecture/09-target-architecture.md`) · пере-прогон rerun2 прочитан (D39.20: операционка живьём, $0-резюм ×3 арма, $6.63<$15; планка ≤2 НЕ пройдена; анти-корреляция гладкость↔верность ×3 → mistral-редактор вон) · эксп ЗАКРЫТ (D39.22), итерация №2 отложена · **курс = разработка бэкенда: пак-17 «канал B вживую» ЗАКРЫТ ЦЕЛИКОМ (дизайн D39.26 · стройка D39.27 · дельта `allow` D39.28, 25.07); вокабуляр = ПАРА `violence`/`sexually-explicit`, остаток — ФАКТЫ ToS в зоне полигона (fail-closed до них)** (D39.25: в движке НЕТ понятия «18+» — generic content-labels × provider-capabilities; лейблы вне хешей · резолв до валидации · один хоп `chain[0]` · гранулярность = книга) → **КУРС АМЕНДИРОВАН ВЛАДЕЛЬЦЕМ 25.07 (D39.33): МАСШТАБ — ПОСЛЕДНИМ, после достройки алгоритмического идеала; доказательство эффективности крупных изменений — МИНИ-ПРОГОНЫ ~10 глав (детерминированные чекеры и скан остатка первыми, судья — только когда от него зависит решение).** **ОЧЕРЕДЬ (D39.40/51/53, актуализация 31.07):** пак-19 «голос/состояние» ЗАКРЫТ ЦЕЛИКОМ (D39.5456, вкл. малую пачку 14а+14б) → ХОЛОДНЫЙ мини-прогон ИСПОЛНЕН ДОСТАТОЧНО (D39.58, Р7 владельца: recall банка 0.918/0.980, банк приходит переведённым; хвосты 16/21/22/24/13бсо следующим живым прогоном или полигон-пакетом) → **ПАРАЛЛЕЛЬ D39.59: бэкенд-ресёрч общности фаза 1 ПРИНЯТ (D39.60 — долг 149 сайтов/45 файлов, книго-ось чиста: 4 сайта; ja→ru безопасно без Go, en→ru нет; план П0П5; СТОП — 5 вопросов §12 у владельца, строка 72) ∥ полигон Р6+P4 — отчёт пришёл, приёмка D39.61** → фаза 2 общности по ответам ($0-части П1 → общий resnapshot-батч П0+П1+П2+П3+П4+дешёвая шестёрка пака-21 → П5 гейтится второй книгой) → арка АВТОНОМНОСТИ банка (веб-фетч пере-замер + 36а/36б/36в; премиса «решение = подпись» амендирована D39.59) → rewrite-пакеты общности → свип гипотез → добор идеала → МАСШТАБ целой книги (7,78 млн симв., ~2284 раздела) → пилот Ф2.5. Хроника треков A/B, exp15/16 и стройки паков — архивы ниже + D-лог.
> - **Стек:** draft deepseek-v4-flash (thinking ON, +банкнота `translator-banknote.md`) → **терминолог** (роль пар-пака, deepseek-v4-flash, батчи, языковой экран `target_script` — D39.42/45/51/53) → **editor deepseek-v4-pro БИЛИНГВ ИНТЕРИМ (D39.22; glm-5 резерв)**, промпт v3-discourse, инъекция двухсекционная (D39.45) → судья gemini-3.1-pro-preview (Ф2, полигон); канал B Mistral+grok; 7 ключей; ~$0.85/ранобэ (D30.4).
> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже (введён 26.07 по решению владельца: одна таблица вместо наслоений; ревью-пасс оркестратора сверил её с коммитами и обсуждённым, добавил 7 строк). Норма прежняя: каждая петля обязана иметь диспозицию (решено / отложено-с-записью / отклонено); ведёт оркестратор. Историческая развёртка петель до 26.07 — в git-истории этого файла и в D-логе.**
> - Архивы хроники: `archive/PROGRESS-2026-07-04-10.md` (D31) · `archive/PROGRESS-2026-07-10-13.md` (D39.6-гигиена) · `archive/PROGRESS-2026-07-13-25.md` (слайс 25.07: стройка паков 1116, rerun2). Записи ниже — живой хвост.
@ -13,7 +13,7 @@
| ID | Хвост (одной фразой) | Зона | Вес | Чем закрывается | Источник |
|---|---|---|---|---|---|
| **— ВИСИТ НА ВЛАДЕЛЬЦЕ —** | | | | | |
| 1 | Ответы на вопросы разметки Р1Р4 (гипербола 千万 · дефект в 成 · сокращённая форма · неразрешимая речь/мысль) — ЗАМОРОЖЕНЫ с паком-21 (D39.59): общность-ресёрч пере-оценит, какие переживают генерализацию | владелец | отложено-с-записью | пак-21 после общность-ресёрча | D39.39(г), D39.44 Q4, D39.59 |
| 1 | Ответы на вопросы разметки Р1Р4 — пере-оценка D39.60 (Q4): на владельце остаются ДВА — **Р2-расширенный** («детекторы единиц/шкал судят ЗНАЧЕНИЕ рендера или ФОРМУ?» — один ответ на семейство) + **Р4-норма** (потолок recall by construction пишется в контракт правила); Р3 закрыт D39.44 Q4 (остаток-работа → строка 73), Р1 расщеплён (данные→пар-пак · политикаР2 · книжный остаток снят) | владелец | ждёт подтверждения Q4 | ответ владельца | D39.39(г), D39.44 Q4, D39.60 |
| 2 | Четыре вопроса границы «алгоритмического идеала» (Annotator · семантический судья · ja→ru §B5 · ru-target до/после) | владелец | скоро (гейт «добора идеала» перед МАСШТАБОМ) | отдельное решение | D39.33, D39.38 |
| 3 | Одноразовый `--resnapshot` стендовых книг с auto-строками | владелец | скоро | отдельное решение | D39.45(4) |
| 4 | Ре-чек ToS по триггерам — первый ИСПОЛНЕН 31.07, дельт вердиктов нет (D39.57); предмет Google-мониторинга перевешен на цепочку договора (PUP · Additional ToS · Google APIs ToS); следующие: квартал 25.10.2026 · первая лейблованная книга · любая правка `accepts_labels` | владелец/полигон | скоро (следующий триггер 25.10.2026) | отдельное решение (правило) | D39.32, D39.57 |
@ -30,14 +30,16 @@
| 13б | `speech-cue.txt` zh НЕ шипить до замера голос-флаггера на холодном прогоне (данные для недоказанного детектора = инерция; вывод обсуждения 31.07): оси пустые → файл не нужен, оси ловят → решение владельца о шипе (байты двигают `LangpackVersion`) | владелец | отложено-до-замера | холодный мини-прогон → отдельное решение | D39.56, PACK19_BUILD §7.2, чат 31.07 |
| **— ХВОСТЫ ХОЛОДНОГО ПРОГОНА (исполнен достаточно, D39.58; Р7 владельца) —** | | | | | |
| 16 | Полная цена холодного старта: edit-волна не гонялась (Р7); измерено всё ДО редактуры (драфт+банкнота $0.0247/волна · терминолог $0.0060.013/проход) | бэкенд | когда-нибудь (следующий живой прогон) | следующий прогон | D39.58 |
| 18 | `蛊` не приходит НИ ОДНИМ каналом (модель объявляет составные, майнер режет по длине) — структурная дыра эмиссии на голове частотного понятия; доставка подписанной короткой строки проверена $0-пином | бэкенд | когда-нибудь | отдельное решение (рядом с 36а) | D39.58 |
| 18 | `蛊` не приходит НИ ОДНИМ каналом (модель объявляет составные, майнер режет по длине) — структурная дыра эмиссии на голове частотного понятия; доставка подписанной короткой строки проверена $0-пином; третий сайт того же порога — алиас-канал `miner_alias.go:44,93` (D39.60) | бэкенд | когда-нибудь | отдельное решение (рядом с 36а) | D39.58, D39.60 |
| 21 | Пере-замер P1 consistency — сырьё снято холодным прогоном (4 сэмпла, 150 термов, без цензуры), метод полигонский | полигон | скоро | полигон-пакет | D39.52, D39.58 |
| 22 | Пере-мер весов консолидации §C2-3 при n≥2 — сырьё то же | полигон | скоро | полигон-пакет | D39.45, D39.58 |
| 24 | Остаток: авто-режим флага (проект Б не гонялся) · оси голоса AD (профили не подписаны; черновик готов — `coldrun-a/SIGN-PACKAGE.md` §3) | бэкенд | когда-нибудь (следующий живой прогон) | следующий прогон | D39.40, D39.58 |
| **— ТЕКУЩАЯ ОЧЕРЕДЬ (D39.59) —** | | | | | |
| 72 | Ресёрч общности: инвентаризация языковой привязки движка (полный скан → пять вёдер → пересборка пака-21 → план rewrite с критерием «вторая пара без правки Go») — промт выдан | бэкенд | блокер-очереди | ресёрч-пак (фаза 1 → СТОП) | D39.59 |
| 73 | Арка АВТОНОМНОСТИ банка (курс владельца: подпись опциональна): пере-замер веб-фетча под АВТОНОМНЫМ критерием (пакет-7 мерил не то — аддитив к KWIC против подписи) + механизмы 36а/36б/36в; дизайн после общность-ресёрча и Р6 | бэкенд/полигон | скоро | дизайн-арка → ратификация | D39.59 |
| **— ПАК-21 «чекеры» (ОТЛОЖЕН до карты общность-ресёрча, D39.59) —** | | | | | |
| 72 | Ресёрч общности: фаза 1 ИСПОЛНЕНА и ПРИНЯТА (D39.60; карта = рабочая истина: 149 сайтов/45 файлов, книго-ось чиста, план П0П5) — **СТОП: 5 вопросов §12 у владельца** (П1-санкция · resnapshot-фигура · П6 · Р1Р4 · судьба пака-21); фаза 2 по ответам | владелец → бэкенд | блокер-очереди | ответы → фаза-2 директива | D39.59, D39.60 |
| 73 | Арка АВТОНОМНОСТИ банка (курс владельца: подпись опциональна): пере-замер веб-фетча под АВТОНОМНЫМ критерием (пакет-7 мерил не то — аддитив к KWIC против подписи) + механизмы 36а/36б/36в + Decl-шов (майненая сторона не пишет склонённых форм — пост-чек не примет 149 авто-строк; D39.60, бывший дефект #9 пака-21) + Р3-остаток; дизайн после ответов по общности | бэкенд/полигон | скоро | дизайн-арка → ратификация | D39.59, D39.60 |
| 75 | Живой баг: `isCJKLang` числит ko, а `cjkShare`/CJK-leak/гард ремонта Hangul не содержат — движок считает ko-нарезку как CJK, печатает эхо-предупреждение и при этом эхо УВИДЕТЬ НЕ МОЖЕТ | бэкенд | скоро (носитель П2) | П2 скрипт-шов | D39.60, GENERALITY_RESEARCH §3.3 |
| 76 | Эмбед-плоскость `internal/lang/data/*.txt` НЕ хешируется (а `injection.txt` едет на провод, `target-ru.txt` даёт вердикты санитайзера) = канал тихой пере-оплаты вне контура Р6 — П0 «байты есть версия» ПЕРВЫМ в любой фазе 2 | бэкенд | скоро (П0, предусловие) | П0 | D39.60, GENERALITY_RESEARCH §6.1 |
| **— ПАК-21 «чекеры» (карта готова; предложение D39.60/Q5: РАСТВОРИТЬ — дешёвая шестёрка батчем в общий resnapshot, 6 дефектов в П1/П2/П3, #9 → строка 73, #12/K4a снять; якоря D39.39 устарели — актуальные в GENERALITY_RESEARCH §8) —** | | | | | |
| 25 | 12 дефектов чекеров с file:line (супрессор K5c · атрибуция K4b · inner_marker на тире · предохранитель K5a · заглавные/гомоглифы K2 · 两 в cheng_re · U+0301 в TokenizeCyrillic · мн.число в сид-тулинге · однознаковые ключи пост-чека) — приёмка против набора пакета-6 за $0 | бэкенд | скоро | пак-21 | D39.39(в), D39.40 |
| 26 | Переезд `translitInterjections` из Go в данные (`cheapgates.go:367`, улов владельца) | бэкенд | скоро | пак-21 | D39.40 |
| 27 | Пост-чек обязан принимать сокращённую форму терма как поле записи (Р3/Q4) | бэкенд | скоро | пак-21 | D39.44 Q4 |
@ -50,7 +52,7 @@
| 30в | Идеи START_PROMT не разобраны: V4 п.45 (сборка глоссария — частично закрыта паком-20; ЯЗЫК промпт-запросов по паре) → в свип; V5 (фронт веб-первый, SEO) → Ф3; эксперимент «язык промптов» ОФОРМЛЕН (D39.58 §6.4: армы ru/en при неизменных инъекциях, детерминированные счётчики формата, ≈$0.020.05) — к выдаче полигону по слову владельца | оркестратор/владелец | скоро | свип гипотез + полигон-пакет + Ф3 | START_PROMT.MD V4/V5, D39.58 |
| **— ОТДЕЛЬНЫЕ ПАКИ/РЕШЕНИЯ (бэкенд, добор идеала) —** | | | | | |
| 31 | Слой-2: извлечение дискурс-норм/few-shot из ТЕЛ промтов (форсинг = ja→ru) | бэкенд | когда-нибудь | отдельный пак (идеал D39.33) | CURRENT-STATE, D39.33 |
| 32 | ru-target долг слоя 7 (`isRuTarget`×11 · `TokenizeCyrillic`×6 · ключ «ru» в санитайзере) — ждёт своего дизайн-пака | бэкенд | когда-нибудь | отдельный пак (идеал) | CURRENT-STATE, D39.34 |
| 32 | ru-target долг слоя 7 — факт D39.60: боевых call-site `isRuTarget` **6** и `TokenizeCyrillic` **2** (счёт «×11/×6» был грепом по комментариям); класс ~18 сайтов, гейты молчат-а-не-лгут (исключение: `isCyrLetter` checkers.go:393 — ложные срабатывания на не-кириллице) | бэкенд | скоро (носитель П1) | П1 цель-шов (ждёт санкции Q1 D39.60 — амендмент заморозки D39.24) | D39.34, D39.60 |
| 33 | native-Gemini судья (Ф2-механизм) | бэкенд | когда-нибудь | отдельный пак (идеал) | CURRENT-STATE, D39.33 |
| 34 | Генеральность нарезки: кана/ханьцзи один класс (`est_out` ja завышен ~1.7× МОЛЧА) + `EstimateTokens` недосчитывает кириллицу (резервации занижены) | бэкенд | когда-нибудь | отдельный пак (с ja→ru) | D39.37(5) |
| 34а | Экран кодировки не видит `<meta charset>` без XML-объявления (епаб с gb18030-метой прочтётся как UTF-8) — до-паковая дыра, сознательно не тронута пачкой 14а (паритет со старым ридером) | бэкенд | когда-нибудь | отдельное решение | D39.54, SMALLPACK §8 |
@ -101,6 +103,10 @@
| 69 | Gemini API «под-18» обязательство на конечный продукт (независимо от лейблов) | владелец | когда-нибудь | Ф3 / отдельное решение | D39.32, D39.34(7) |
| 70 | Action-security gate перед выдачей tools/webfetch (D25 п.5) | бэкенд | когда-нибудь | Ф3 | D39.34(7) |
| 71 | Планы research/22: epub-tag-rewrite · Q7-леджер | бэкенд | когда-нибудь | Ф3 | D39.34(7) |
## Оркестратор №9 — РЕСЁРЧ ОБЩНОСТИ ФАЗА 1 ПРИНЯТ (D39.60): долг 149 сайтов/45 файлов, книго-ось чиста, план П0П5; СТОП — пять вопросов владельцу, 31.07
Короткая приёмка по норме 30.07: отчёт (запись сессии — ниже, `### РЕСЁРЧ ОБЩНОСТИ фаза 1 ИСПОЛНЕН`) прочитан целиком, восемь несущих утверждений пере-проверены исполнением — все сошлись (вкл. побайтный повтор хеша пака `a28ed743c99c` и счёт 27/12 живых CJK-строк); два нита некритичны (счёт сайтов `ExportNormalize`, атрибуция Ш-1). Ратифицировано как карта (D39.60): вёдра A27/B6/C104/D12/E106 · заморозки З1З9 · актуальные якоря пака-21 (§8 отчёта — ссылки D39.39 устарели) · правило условного фолда §6.2. Новые строки: 75 (живой баг ko/Hangul → П2) · 76 (эмбед-плоскость без хеша → П0 первым). Строка 32 исправлена фактом (боевых call-site 6 и 2), Decl-находка уехала в арку банка (73). **На владельце пять вопросов §12 с моими рекомендациями (в D39.60): П1 в арку = ДА · один общий resnapshot = ДА (но после развилки DeepSeek, D39.61) · П6 = не сейчас · Р1Р4 = сократить до Р2+Р4 · пак-21 = растворить.** Фаза 2 не начинается до ответов.
## Полигон — РЕ-ЧЕК ToS ПО КАЛЕНДАРНОМУ ТРИГГЕРУ ИСПОЛНЕН ($0): дельт вердиктов НЕТ, но триггер стоит не на том документе, 31.07
Отчёт: `archive/reports/TOS_RECHECK_2026-07-31.md`; факты — секция «Право по ToS/AUP» в `experiments/00-provider-quirks.md` (помечена датой ре-чека). **Триггер сработал буквально** — головной Google ToS сменил ревизию `May 22, 2024`**`Effective July 30, 2026`**, — **но по нашей оси он пуст:** свой байтовый диф архивной и живой US-версий даёт 72 строки, все потребительско-правовые (сетевые расходы, дисклеймеры, калифорнийское право), а счётчики `violen*` = 0 и `sexual*` = 0 в ОБЕИХ ревизиях. Единственная контентная вставка — `Some content may not be suitable for everyone.` в разделе о генерируемом контенте: дисклеймер о ВЫХОДЕ Google, по D39.29 права не даёт, и специально помечена, чтобы её не приняли за сдвиг. **Пере-сняты пять вендоров цепочки — `gemini` · `mistral` · `xai` · `deepseek` · `zai`, все на ПРЕЖНИХ объявленных ревизиях, 34 цитаты подтверждены счётом = 1, дельт вердиктов ноль.** `kimi`/`openai` (403 Cloudflare, JS-шелл) вне названного промтом фокуса — помечены непере-проверенными. **Три находки сверх задачи.** (1) **Триггер поставлен на косвенно привязанный документ:** договор Gemini API — это `Google APIs ToS` (*Last modified: November 9, 2021*, прежде в записи ОТСУТСТВОВАЛ) + `Additional ToS` (*March 23, 2026*) → PUP; потребительский ToS цепляется лишь через API ToS §b `You will not violate any other terms of service with Google`. Предложение: мониторить три документа цепочки, а не `policies.google.com/terms`. (2) **Метод верификации цитат дефектен:** `grep -c -F` по стриппнутому тексту дал ЛОЖНЫЕ НУЛИ на трёх верных цитатах DeepSeek (жёсткие переносы + кавычки в отдельных тегах) — без поправки ре-чек показал бы фантомную дельту вендора; рабочая форма (сверка по копии без пробелов) вписана в quirks. Там же: **`r.jina.ai` как второй путь МЁРТВ (403)**, заменён двумя независимыми снимками Wayback с честной оговоркой «оба в прошлом»; **`ai.google.dev` больше не требует Wayback** — петля была на cookie `signin=autosignin`, лечится cookie-jar. (3) **Рассинхрон:** клетка `gemini` × `sexually-explicit` в quirks стояла `FORBIDDEN` против ратифицированного D39.32 п.2 `UNCLEAR` — помечена ссылкой на амендмент, молча не переписана. **Рекомендация по строке 6 (Gemini в `accepts_labels`): не подписывать сейчас**ре-чек не дал новой фактуры ни за, ни против, а главное: подпись даст ПРАВО, но не даст судью 18+, потому что по оси ПОВЕДЕНИЯ Gemini fail-closed на графичной эротике (D22.6, 8× wire-verified, фильтр неконфигурируем), а Additional ToS теперь ещё и прямо запрещает обход фильтра (`You may not attempt to bypass these protective measures`). Строка стоит дешевле, чем выглядит: ничего не блокирует и почти ничего не открывает. Следующий триггер — квартальный **25.10.2026**, без изменений. Сессия не коммитила; `accepts_labels` не трогала; бэклог не правила (зона оркестратора).
@ -235,6 +241,10 @@
*(Хроника бэкенд-паков 1116 (1925.07, вкл. отчёт-запись пака-15) — в [archive/PROGRESS-2026-07-13-25.md](archive/PROGRESS-2026-07-13-25.md); отчёты паков — `archive/reports/`.)*
### РЕСЁРЧ ОБЩНОСТИ фаза 1 ИСПОЛНЕН ($0, read-only, кода не тронуто) — СТОП на ратификацию, 31.07
Отчёт: [`archive/reports/GENERALITY_RESEARCH_2026-07-31.md`](archive/reports/GENERALITY_RESEARCH_2026-07-31.md). Промт D39.59 отработан целиком: полный скан → пять вёдер → пересборка пака-21 → план пакетов с ценами → счёт масштаба → критик полноты. Метод: 8 срезов кода, каждый адверсариально перепроверен вторым проходом с прогоном чужих grep; 5 сквозных разборов (цены снапшота · синк с D-логом · пересборка пака-21 · сухой прогон второй пары · алгоритмы), каждый кросс-чекнут; несущие числа пере-мерены сессией лично. **Долг = 149 сайтов в 45 файлах** (133 в `.go`), 111 из них НЕ забуканы; вёдра A=27 · B=6 · C=104 · D=12 · легитимно E=106. **Ось: источник/пара 63% · ЦЕЛЬ (ru) 30% · КНИГА 3% (4 сайта поимённо)** — по книжной оси движок практически чист. **Долг меньше бэклога:** строка 32 пишет «isRuTarget×11 · TokenizeCyrillic×6» — это счёт грепа, боевых call-site **6 и 2**; живых CJK-литералов в исполняемом Go — 27 строк в 12 файлах из 201 (87% — комментарии). **Вторая пара:** golden-фикстура уже ja→ru (скелет доказан), но через `prompt_override`, без langpack и пар-конфига; ja→ru проходит безопасно без правки Go, **en→ru — небезопасно** (молча спят детектор эха `cjkShare`=0 и майнер `hanRuns`=0). Данными лечится 11 позиций, Go требуют 5 (+2 латентных), ни одна не блокирует запуск. **Цены:** сдвиг любой из 20 осей снапшота = перепокупка книги, ре-пинуема ровно одна (`memory_version`); вынос в `configs/langpacks/` двигает `LangpackVersion` включая КОММЕНТАРИИ (хеш над сырыми байтами), вынос в `internal/lang/data/` — $0; новая пара — $0 для существующих книг. Рецепт воспроизведения хеша пака без запуска Go проверен: даёт `a28ed743c99c`. **Две находки сверх задачи.** (1) `internal/lang/data/*.txt` (6 файлов, из них `injection.txt` едет на провод, `target-ru.txt` определяет вердикты санитайзера) **не хешируются ничем** — механизма «байты ЕСТЬ версия» на эмбед-плоскости НЕТ, правка байта без ручного бампа константы = тихая пере-оплата вне контура Р6 (`rebill.go:137-139`). (2) **Живой баг:** `isCJKLang` числит `ko`, а `cjkShare`/CJK-leak/гард ремонта Hangul не содержат — корейское эхо невидимо и не эскалируется. **Пак-21 пересобран:** все якоря D39.39 устарели (пак-19 их сдвинул) — даны актуальные; из 12 дефектов собственно zh-привязок ТРИ, остальное — ось ЦЕЛИ; Р3 закрыт D39.44 Q4, Р1 расщепляется ⇒ на владельце остаются ДВА вопроса вместо четырёх. **План — 6 пакетов** (П0 «байты есть версия» предусловием → П1 цель-шов → П2 скрипт-шов источника → П3 нарезка/оценка → П4 пак как механизм → П5 майнер, гейт на реальную вторую пару), приёмочный критерий каждого — «пара, которой нет в репо, проходит слой без правки Go». **Несущая рекомендация: один общий `--resnapshot` сейчас** — оплаченный корпус = два мини-прогона по $0.130.23, после МАСШТАБА тот же дифф стоит порядки. **Пять вопросов владельцу в §12 отчёта**, главный бьёт по посылке: больший и замороженный (D39.24 «НЕ чинить») кусок долга лежит на оси ЦЕЛИ, а директива названа по оси ПАРЫ. Сессия не коммитила; `backend/` не тронут ни строкой.
### Пак-18 «долги контракта» ОТРАБОТАН и ПРИНЯТ (D39.31, приёмка оркестратора №8), 25.07
Отчёт: [`archive/reports/PACK18_DEBTS_REPORT_2026-07-25.md`](archive/reports/PACK18_DEBTS_REPORT_2026-07-25.md). **П.1 `--accept-rebill[=usd]` ПОСТРОЕН** на снапшотной гранулярности (`internal/pipeline/rebill.go`): проекция = Σ хранимых `cost_usd` оплаченных строк под устаревшим снапшотом ЕГО ВОЛНЫ, порог `min($0.50, 5%×ProjectedBookUSD)` + флор $0.50 + переопределение книгой `rebill_consent_usd`; гейт стоит ДО денег в `TranslateBook` и ДО деструктивного сброса в `Redrive`; read-only пути ($0-контракт D20.4) не тронуты. `ProjectedBookUSD` вынесен в общий `projectBookUSD` — порог и `status` считают ОДНО число. **Развилка на ратификацию:** оговорка спеки «`--resnapshot` = алиас-синоним согласия» СОЗНАТЕЛЬНО не перенесена — флаги ортогональны (иначе ратифицированный порог = мёртвый код); 4 существующих теста получили строку согласия. Каскад §7.1-бис зафиксирован как ВЫРОЖДЕННЫЙ, ветка `EstimateUSD` — без предмета на этой гранулярности; `guard_hash` не строился. **П.2 `escalation_model` = АВТОРИТЕТНАЯ модель ПОСТРОЕН**; пере-капчер golden `f7641993…``211c9013…` проверен машинно: сдвинулись ровно 4 строки `ch3/0 draft`, дельта ТОЛЬКО в колонке `esc_model`, оба волновых снапшота/`brief_hash`/`memory_version` байт-идентичны ⇒ пере-оплаты нет; миграции нет, смешанная семантика записана в доккоммент `store.ChunkStatus`. **П.3 (два нита общности) ОТЛОЖЕН с замером:** одна новая строка в `configs/langpacks/zh-ru/dc-checkers.txt` двигает `pack.Version()` `a7d4be2c0465``133d71e8d132` и ОБА волновых снапшота (проба исполнением), а стендовые книги ссылаются ровно на этот каталог (`rerun2/book*.yaml:22-23`) ⇒ байт-нейтральной формы нет; для Detail-строк она нереализуема определительно. Готовый план на ближайший полный `--resnapshot` — в отчёте. **Приёмка:** build/vet чисты · `-race` 12/12 · `-shuffle=on` зелёный · парити EXACT `n=13618 … 0.9655 (56/58)` · ценз диффом ИМЁН 455→475, удалено 0 · **19 мутаций, 19 красных** (две сначала выжили и вскрыли дыры в тестах — обе закрыты, в т.ч. регресс-класс D20.4 «распарсено, но не проведено в раннер»).

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,448 @@
# РЕСЁРЧ ОБЩНОСТИ — инвентаризация языковой привязки движка. Фаза 1, отчёт бэкенд-сессии, 2026-07-31
**Промт:** `docs/BACKEND_GENERALITY_RESEARCH_SESSION_PROMPT.md` (оркестратор №9, курсовая директива владельца D39.59).
**Режим:** read-only, $0. Кода не тронуто ни строкой — `git status` по `backend/` пуст, ни одного `go build`/`go test`/`gofmt` с правкой не запускалось.
**Метод:** 8 срезов кода просканированы, каждый АДВЕРСАРИАЛЬНО перепроверен вторым агентом (автор≠ревьюер) с прогоном чужих grep-команд; отдельно 5 сквозных разборов (цены снапшота · синк с D-логом · пересборка пака-21 · сухой прогон второй пары · алгоритмы), каждый тоже кросс-чекнут. 26 проверяющих проходов; несущие числа я пере-мерил сам и помечаю это явно.
> **Ревью-шапка (оркестратор №9, 31.07): фаза 1 ПРИНЯТА, D39.60; фаза 2 — СТОП до пяти ответов владельца (§12).** Короткая приёмка по норме 30.07: отчёт прочитан целиком; восемь несущих утверждений пере-проверены исполнением — рецепт §6 воспроизвёл хеш пака моим прогоном (`a28ed743c99c`), счёт живых CJK-литералов совпал (27 строк / 12 файлов), ko/Hangul-асимметрия подтверждена (`cjkShare` = Han+кана, Hangul — в 5 сайзинг-сайтах и в 0 вердиктных), `ExportNormalize` действительно без цель-гейта, `embedded.go` действительно без хеширования, цитата-заморозка D39.24 в `repair.go:182-189` дословна («repayable only … as one deliberate change to the target seam»), `segmentation` не ставит ни один шиппинг-конфиг, Ш-1 (`goldenMaskedDiff`) построен. Два нита, не влияющих на выводы: (а) «6 прод-сайтов» `ExportNormalize` — якорей перечислено 7 (5×waverun + export + quality); (б) «Ш-1 построен вопреки записи в D-логе» — неточность: лендинг D39.17 Ш-1 записал, устарела только плановая записка (строка 604 D-лога). Рекомендации оркестратора по пяти вопросам §12 — в D39.60. ⚠ Контекст, узнанный ПОСЛЕ сдачи этого отчёта: DeepSeek 31.07 сменил веса flash под тем же слагом (D39.61) — исполнение «общего resnapshot» из §9 гейтится этой развилкой; сама карта от неё не зависит.
---
## 1. Эхо-блок
1. **Книго-привязки в движке практически нет: 4 сайта из 118** — и это главный положительный результат по оси, которую владелец назвал «НИКОГДА».
2. **Долг = 149 сайтов в 45 файлах** (133 в `.go`), из них **111 не забуканы**; вёдра: A=27 · B=6 · C=104 · D=12 · легитимно E=106.
3. **Ось долга — ИСТОЧНИК/ПАРА 63%, ЦЕЛЬ (ru) 30%**, книга 3%. Но у 12 дефектов пака-21 пропорция ОБРАТНАЯ (доминирует цель) — пак-21 чинит не ту ось, о которой директива.
4. **Долг меньше, чем в бэклоге:** строка 32 пишет «isRuTarget×11 · TokenizeCyrillic×6» — это счёт грепа; боевых **call-site 6 и 2**. Живых CJK-литералов в исполняемом Go — **27 строк в 12 файлах** из 201 (87% — комментарии).
5. **Вторая пара уже едет:** golden-фикстура — **ja→ru книга** (`internal/pipeline/testdata/golden/book.yaml`), скелет доказан. Но она идёт через `prompt_override`, без langpack и без пар-конфига — полный стек второй парой не проверялся никогда.
6. **ja→ru запустится безопасно, en→ru — небезопасно:** для en молча спят детектор эха (`cjkShare`=0) и майнер (`hanRuns`=0). Требуют Go, не данных.
7. **Цена: любой сдвиг снапшота = перепокупка книги целиком** (`snapshot.go:51-57`); ре-пин возможен ровно у одной оси из 20 (`memory_version`). Вынос литерала в `configs/langpacks/` двигает `LangpackVersion` **включая комментарии**; вынос в `internal/lang/data/` — $0.
8. **Найдена дыра дисциплины:** `internal/lang/data/*.txt` (6 файлов, из них `injection.txt` едет НА ПРОВОД, `target-ru.txt` определяет вердикты санитайзера) **не хешируются ничем** — «байты ЕСТЬ версия» на эту плоскость не распространяется.
9. **Найден живой баг сверх задачи:** `isCJKLang` числит `ko`, а `cjkShare`/CJK-leak/repair-гард Hangul НЕ содержат — корейское (и любое не-Han) эхо проходит молча и не эскалируется.
10. **Момент выбран верно и это дешевле не станет:** оплаченный корпус сегодня — два мини-прогона масштаба $0.130.23; один общий `--resnapshot` стоит центы, после МАСШТАБА — порядки.
---
## 2. Что проверено исполнением лично (не агентами)
| Заявление | Команда | Результат |
|---|---|---|
| размер кодовой базы | `find backend -name '*.go' \| wc -l` + `-not -name '*_test.go'` | 177 файлов / 50 456 строк; прод **83 файла / 27 102 строки** |
| CJK-литералы в проде | `find backend -name '*.go' -not -name '*_test.go' \| xargs grep -nP '[\x{4e00}-\x{9fff}\x{3040}-\x{30ff}]' \| grep -vP '^\S+:\d+:\s*(//\|\*)'` | **27 строк в 12 файлах** (всего с CJK — 201 строка, 174 = комментарии) |
| кириллица в проде | та же форма с `[\x{0400}-\x{04ff}]` | **66 строк в 16 файлах** (всего 421, из них 355 = комментарии) |
| строка 32 бэклога | `grep -rn 'isRuTarget' --include='*.go' backend/` | 10 строк = 6 call-site + 1 определение + 3 комментария |
| то же | `grep -rn 'TokenizeCyrillic'` | 6 строк = **2 вызова** + 1 определение + 3 комментария |
| эмбед не хеширован | `grep -n 'embeddedFS\|sha256\|Sum(' backend/internal/lang/embedded.go` | только `:21` объявление и `:469` `ReadFile`**хеширования нет** |
| руби-канал мёртв | `grep -rn 'rubyToCandidates' --include='*.go' backend/` | прод-вызовов **ноль** (`seeding.go:47` зовёт только `AttachRubyAliasesToManual`) |
| асимметрия Hangul | `grep -rn 'Hangul' --include='*.go' backend/ \| grep -v _test` | Hangul ЕСТЬ в 5 сайтах сайзинга/нормализации, НЕТ в 3 сайтах вердикта |
| `matchVersion` ре-пинуем | `grep -n 'matchVersion' backend/internal/membank/memory.go` | `:383` — фолдится ВНУТРЬ `memory_version` ⇒ путь `moveBankOnly` открыт |
| `ExportNormalize` без гейта | `grep -rn 'ExportNormalize(' --include='*.go' backend/ \| grep -v _test` | 6 прод-сайтов, **ни один не за `isRuTarget`** |
---
## 3. Карта по пяти вёдрам
Вёдра: **A** = вынести в пар/цель-ДАННЫЕ · **B** = пар-скоупнутый Go-модуль за гейтом · **C** = общий алгоритм + величина/таблица из данных · **D** = удалить · **E** = легитимно (не долг).
Полный машинный список якорей — ниже по вёдрам, в форме `файл:строки`. Каждый сайт открывался и читался телом; заявления, не подтверждённые верификатором, помечены.
### 3.1 Ведро A — вынести в данные (27 сайтов, 17 файлов)
```
configs/langpacks/zh-ru/dc-checkers.txt:19 configs/pairs/ja-ru.yaml:2
internal/checks/cheapgates.go:223,250,340,367 internal/checks/output.go:31
internal/checks/repair.go:103 internal/checks/sanitizer.go:465,777
internal/chunk/chunker.go:229,551 internal/chunk/ingest.go:404,410
internal/membank/memory.go:803 internal/miner/miner.go:43
internal/miner/miner_palladius.go:73 internal/miner/miner_patterns.go:24,200
internal/miner/miner_substrate.go:29 internal/text/data/trad2simp.txt:320,544
internal/text/norm.go:147,198 internal/terminology/terminology.go:647
internal/lang/data/cjk-section.txt:28 internal/checks/sanitizer.go:360
internal/checks/cheapgates.go:238
```
Несущие сайты, по убыванию последствий:
- **`internal/text/norm.go:147` + `internal/text/data/trad2simp.txt` (508 отображений).** Таблица традиционный→**упрощённый КИТАЙСКИЙ** применяется по-рунно к КАЖДОМУ исходному ключу КАЖДОЙ пары, без языкового параметра, из 20 call-site (банкнота, терминолог, банк, майнер). Для ja она **активно вредит**: содержит 準→准, 鐘→钟, 餘→余, 廣→广, 藝→艺 — обычные современные японские кандзи переписываются в китайские формы и часть различий **схлопывается в один ключ**; при этом японских синдзитай-фолдов (辺, 沢) в ней НЕТ (`grep -c 辺 backend/internal/text/data/trad2simp.txt` → 0). Верификатор поправил формулировку: промах 渡邊/渡辺 существует и БЕЗ таблицы (это пробел данных), а вред самой таблицы — в обратном: она **сливает ja-различия**.
`grep -n 'trad2simp\|NormalizeSourceKey' backend/internal/text/norm.go`
- **`internal/checks/cheapgates.go:367``translitInterjections` (забукана строка 26).** Кириллический словник в Go, потребитель — свободная функция `lintTranslitInterjections` (`:374`), вызываемая безусловно из `RunCheapGates` (`:153`): **ни пар-, ни цель-гейта нет вообще**. Содержательно список смешанный — «нани/десу/кья» японские, «ауч/упс/хмф» английские (шапка `:356` говорит «JP/EN fillers»); формулировку строки 26 «переезд в данные ЦЕЛИ» стоит уточнить, но переклассификация в `ja-ru` (предложенная одним агентом) **опровергнута**: сканируется ВЫХОД, привязки к паре в механизме нет.
- **`internal/checks/cheapgates.go:223,250` — русская типографика диалога Go-свитчем** (`'—'`, `'«'`, `'»'`, `','`). В ТОМ ЖЕ пакете уже есть данными-выраженный двойник: `voice.go:255,264-297` сегментирует реплики через `reply_dash`/`reply_open`/`reply_close` из `internal/lang/data/target-ru.txt:166-168`. Два сегментатора речи в одном пакете, один на данных, второй на литералах. Поправка верификатора: данными покрыты **3 литерала из 6** (эн-тире, дефис и запятая атрибуции двойника не имеют).
- **`internal/miner/miner_palladius.go:73``strings.ReplaceAll(t, "ъ", "")`.** Русское орфографическое правило в файле, чья шапка (`:14-17`) декларирует «ТАБЛИЦА — это ДАННЫЕ, тут только АЛГОРИТМ». Путь на прод подтверждён: `isPalladiusToken:74``PalladiusConformance:117``terminologist.go:169`.
- **`internal/membank/memory.go:803` — формат строки редакторской инъекции** («•», « → », «»») собирается в Go, тогда как ВСЕ заголовки и аннотации вокруг уже уехали в `internal/lang/data/injection.txt`. Ёлочки — целевая типография.
- **`internal/checks/repair.go:103,138``时辰`/`半个时辰` Go-литералами в operator-detail**, тогда как линт-двойник рендерит ту же строку из пар-данных (`checkers.go:272,295``dc-checkers.txt:76-77`). `checkers.go:21` заявляет «this file no longer holds any language literal» и держит это тестом; `repair.go` (пак-16) дисциплину не унаследовал.
- **`internal/lang/data/cjk-section.txt:28``chapter_unit` = `章 节 節 回`**, при том что шапка файла называет себя «Universal CJK … A linguistic CONSTANT». `話` (доминирующая единица японских вебновелл, 第1話) отсутствует; `detectChapterUnit` вернёт 0 и книга станет ОДНОЙ главой молча.
### 3.2 Ведро B — легитимный пар/семейный модуль, но без гейта (6 сайтов)
```
internal/lang/langpack.go:772 internal/membank/memseed.go:510
internal/miner/miner_alias.go:93 internal/miner/miner_patterns.go:183
internal/miner/miner_substrate.go:74 internal/miner/miner_palladius.go:115
```
- **`miner_substrate.go:74` — генератор кандидатов «любая N-грамма 1..6 внутри рана письма без сегментации».** Это факт о scriptio continua, данными не выражается. Легитимен как код — но пар-гейта нет: `mining.go:81` зовёт майнер при любом `r.pack != nil`.
- **`langpack.go:772` (+`:486-492`) — семь ОБЯЗАТЕЛЬНЫХ категорий Палладия** (`initials/finals/yw/special_i/retroflex/vfinal/vfinal_initial`). Поливанов — плоская мора→кириллица, кросс-произведения инициалей и финалей в нём нет. ja-пак либо не грузится (**возвращается ошибка, не паника** — поправка верификатора, `validate():494`), либо проходит валидацию ложью. **Самый жёсткий блокер слоя данных.**
- **`memseed.go:510` — японский классификатор фуриганы** («вся база — кандзи, всё чтение — кана ⇒ кандидат-имя», плюс руны `ー`/`・` на `:546`) живёт в общем банке **без всякого гейта**. Мёртв на практике (см. §5), но класс — пар-модуль в общем слое.
- **`miner_patterns.go:183` / `miner_alias.go:93` — порядок имени (фамилия = префикс) и контейнмент как признак алиаса.** Оба — control flow, не таблица. Для пробельного источника контейнмент даёт ложные рёбра (`Ann ⊂ Anna`).
- **`miner_palladius.go:115` — «слово = максимальный ран букв»** (найдено верификатором, сканер пропустил). Для цели без пробелов вся строка станет одним токеном.
### 3.3 Ведро C — общий алгоритм + величина из данных (104 сайта, 35 файлов)
Самое населённое ведро; ниже — по классам, полный список якорей приведён после.
**C-1. Оценка токенов и калибровка нарезки (забуканы 34/40; 11 сайтов).**
`render.go:349-366` `EstimateTokens` = `cjk + other/3`, флор 16, где `cjk` = HanHiraganaKatakanaHangul одним классом. Из неё: `max_tokens` каждого вызова (`stagerun.go:116`) → резервация в ledger → `request_hash`; бюджет банкноты (`banknote.go:287`); вторая независимая копия той же арифметики в `memory.go:494-506` тратит `glossary_token_budget`. **Таксономия классов зашита в Go-типе** (`config/pipeline.go:136` — ровно два поля, одно названо `cjk`): пара, которой нужен третий коэффициент, не выражается данными. Литерал `bankWorstLineTokens = EstimateTokens("蛊"×8 + "я"×40)` (`banknote.go:292`, забукан 40) — worst-case прямо CJK-src/кириллица-dst.
Последний фолбэк калибровки — **литералы zh-ru прямо в Go** (`config/pipeline.go:843-852`: 1797/3200/1.1978/0.3852) и `configs/pairs/{ja,en}-ru.yaml` их наследуют, потому что блок `segmentation` в них отсутствует. **Поправка верификатора:** комментарий `pipeline.go:832-841` утверждает «every SHIPPING pipeline sets the whole block explicitly» — это неправда, `grep -n 'segmentation' backend/configs/pipeline-*.yaml` пуст.
**C-2. Цель-шов ru (забукана 32; ~18 сайтов).**
`isRuTarget` (`disposition.go:310`) + 6 боевых call-site (`chunkrun.go:52`, `waverun.go:386,500`, `quality.go:215`, `repair.go:208,574`) · `TokenizeCyrillic` (`text/runes.go:32`) + 2 вызова · 12 живых сайтов `unicode.Cyrillic` · ё→е фолд в общем нормализаторе (`text/norm.go:198`) · реестр целей Go-мапой (`lang/embedded.go:25`) · `var ruSanitizer = lang.TargetChecksFor("ru")` (`sanitizer.go:21`, пакетная переменная на init).
Важная характеристика класса: гейт `isRuTarget` спроектирован **на молчание, а не на ложь** (`disposition.go:305-309`) — на не-ru цели гейты просто не срабатывают. Это долг ПОКРЫТИЯ, не КОРРЕКТНОСТИ. Исключение — `checkers.go:393` `isCyrLetter`: на не-кириллической цели ВСЕ проверки границы слова проходят, и каждая запись `registerNeg` вырождается в голый подстрочный матч (находка верификатора, класс — ложное срабатывание).
**C-3. Экспорт без гейта — проверено лично.** `checks.ExportNormalize` применяется к КАЖДОМУ финалу из 6 прод-сайтов (`waverun.go:535,539,541,617,619` · `export.go:324` · `quality.go:368`) **без предиката цели**, при том что шапка `sanitizer.go:17-20` утверждает «the sanitizer is isRuTarget-gated». Внутри — `ideographicPunctFold` (`sanitizer.go:666`): `、``,`, `。``.`, с мотивацией «a «、»/«。» **in a Russian final** is an unambiguous wrong-glyph rendering». На CJK-цели это не no-op, а порча. **Одна оговорка, которая делает этот пункт дешёвым: `ExportNormalize` по своей же шапке (`:673-677`) НЕ является входом снапшота/вердикта — «a change re-projects existing checkpoints for free, no re-bill». Гейт сюда = $0.**
(Первичное заявление агента про «французский пробел» ОПРОВЕРГНУТО кросс-чеком: `spaceBeforePunctRE` живёт в `StripCosmetic`, а тот гейтится. В отчёт вошла только выжившая улика.)
**C-4. Детекторы, привязанные к письменности источника.**
`disposition.go:271` `cjkShare` (Han+кана, БЕЗ Hangul) — единственный детектор эха в интринзик-классификаторе и единственный эскалируемый триггер эха (`disposition.go:142-149`). Для en он структурно недостижим. Сюда же `sanitizer.go:433` (CJK-leak) и `pipeline/repair.go:435` (гард ремонта) — те же три письменности.
**Живой баг:** `isCJKLang` (`disposition.go:297-303`) числит `ko` наравне с zh/ja, а Hangul в трёх детекторах отсутствует — то есть для корейского источника движок (а) считает нарезку по CJK-фертильности, (б) печатает предупреждение `sourceEchoExposure` (`runner.go:388`), и при этом (в) **не может увидеть эхо**. Это не вопрос общности, это дефект.
**C-5. Сегментация исходника.** `ingest.go:150,185-214` — детект глав только по `第<цифры><юнит>`; `ingest.go:266,319` — лестница кодировок с единственной не-UTF-8 ветвью GB-семейства и пар-литералом `"zh"`; `ingest.go:652` — экран кодировки epub видит только XML-декларацию (забукана 34а); `chunker.go:605``var sourceAbbrevs = lang.SentenceAbbrev("en")`, ключ прибит в Go при том, что данные корректно секционированы по источнику.
**Существенная поправка кросс-чека:** отказ «вся книга = одна глава» — **только для .txt**. `ingestEPUB` (`ingest.go:449-553`) кладёт главу на spine-документ и `splitTextChapters` не зовёт вовсе, поэтому en-EPUB и ja-EPUB с `第N話` нумеруются штатно, без правки Go.
**C-6. Пороги майнера и банка.** `FrozenConfig` целиком (`miner.go:43-58`), длины кандидатов 1..6 / 2..4 / 2..6 (`miner_substrate.go:29`, `miner_patterns.go:188,200`), пороги эмиссии `emitMinFreq=5`/`emitRankCap=200`/`runeLen<2` (`miner_emit.go:27,33,306` — последний и есть Go-половина забуканной строки 18: `蛊` в один рун не проходит **ни через эмиссию, ни через алиас-канал** — третий сайт того же порога найден верификатором на `miner_alias.go:44,93`), пороги ключа банка `minKeyLenHan=2`/`minKeyLenPhonetic=3` (`memory.go:72`).
**C-7. Терминолог.** `terminology.go:248` — подстрочный матч без границы слова (5 потребителей); `:815` `sharedRunes` — «общая руна = общая морфема» (для en почти всегда истинно); `:337` `window` режет KWIC по ±N РУН без учёта границ слова (найдено верификатором) — данными не чинится ни при каком значении ширины; `terminologist.go:59,61` — размеры батча/KWIC в рунах источника.
Полный список якорей ведра C:
```
configs/pairs/ja-ru.yaml:1 · configs/pipeline-c1.yaml:17,26,85,86
checks/cheapgates.go:146,313,435,594,603 · checks/checkers.go:224,304,393,433,435,470,501
checks/repair.go:124,131,165,197 · checks/sanitizer.go:21,133,350,433,457,706,795
chunk/chunker.go:192,217,421,439,605,629 · chunk/ingest.go:140,150,266,319,391,652
config/book.go:195 · config/pipeline.go:136,312,792,843 · lang/data/sentence-abbrev.txt:4
lang/embedded.go:25,180 · lang/langpack.go:178,486,664,870,897
membank/memory.go:72,494,505,1082 · membank/memseed.go:331
miner/miner.go:47 · miner/miner_emit.go:27,202,306 · miner/miner_palladius.go:39,128
miner/miner_patterns.go:25,188 · miner/miner_substrate.go:44
pipeline/banknote.go:33,44,175,292 · pipeline/bookrun.go:112 · pipeline/chunkrun.go:183
pipeline/disposition.go:258,259,269,271,299,310,324 · pipeline/quality.go:44,156,393
pipeline/render.go:361 · pipeline/repair.go:86,208,435,489 · pipeline/runner.go:349
pipeline/snapshot.go:431 · pipeline/stagerun.go:116 · pipeline/terminologist.go:59,61,169
pipeline/waverun.go:541 · terminology/terminology.go:248,337,386,567,815
text/norm.go:137,150,153,198 · text/runes.go:32
```
### 3.4 Ведро D — удалить (12 сайтов)
| Сайт | Что |
|---|---|
| `cmd/tmctl/render.go:89,485` | `⟨проверить⟩` продублирован глифами в CLI-строках; канон — `lang/data/injection.txt:9`, и он несёт **два значащих ведущих пробела**, которых копия не имеет ⇒ **уже разошлись** |
| `configs/langpacks/zh-ru/dc-checkers.txt:7-17` | 11 строк `cjk_numeral` — третья копия универсальной константы (после `lang/data/cjk-section.txt:6-19` и `configs/langpacks/zh/numeral.txt`); `parseDCCheckers` (`langpack.go:897`) требует её непустой от ЛЮБОЙ пары |
| `configs/pipeline-c2.yaml:36` | `prompt_override` на zh-ru путь в пар-генерическом конфиге; причина чисто косметическая (имя файла ≠ имя роли). Переименовать `judge-selector.md``judge.md` — и строка исчезает (забукано 42) |
| `internal/miner/miner.go:52` + `miner_patterns.go:19` | мёртвый вес `palladius` в таблице (канал не эмитится) и `PackVersion = "zh-universal-v1"` — поле **write-only**, ни одного чтения по всему репо, включая тесты |
| `internal/miner/miner_substrate.go:123` | мёртвая `freq_stratum` с zh-калибровкой — ни одного вызова (найдено верификатором) |
| `internal/chunk/chunker.go:222` | точный логический дубль `ingest.isHeaderSeparator`, синхронизируемый только комментарием |
| `internal/checks/cheapgates.go:56,125,130` + `lang/langpack.go:73,135,822` | 6 живых указателей на `checkers_zh_ru.go` — файла нет с `952469b` (**24.07, 7 дней назад**, а не «год», как заявил агент). Вредны именно для этой инвентаризации: рекламируют пар-модуль там, где код уже generic |
| `internal/checks/checkers.go:24` | шапка утверждает, что регистр-чекер читает цель-данные; фактически `registerNeg` приходит из ПАР-пака (`:106`). Ложная документация, приводящая к двойной букировке |
| `prompts/zh-ru/{translator-banknote,terminologist,repair/*}.md` | проводной формат каналов (`⟦TM-BANK-v1⟧`, набор типов, `⟦TM-NO-DST⟧`, `⟦TM-NOCHANGE⟧`) пересказан прозой в каждом пар-промпте (забукано 36г). Верификаторы **переклассифицировали C→D**: это не пара-зависимая величина, а инвариант движка, продублированный в пар-файл |
**Существенное смягчение по 36г от верификатора:** заявления «мис-типизация ломает канал молча» преувеличены трижды — неизвестный тип типа падает в безопасный `"term"` (`banknote.go:73,241`), битый сепаратор ловится `malformedSeparatorAt` и даёт громкий `parse_fail`, а `config/prompt_lint_test.go:22-89` УЖЕ линтует все `.md` под `prompts/` по всем парам, включая будущий ja-ru пак, и требует настоящий таб в банкнота-промпте. Не пинятся: сам сепаратор, словарь типов, лимит строк, layout терминолога.
### 3.5 Ведро E — не долг (106 сайтов)
Сюда ушли: пар-строки в `*_test.go` и golden (гардрейл CLAUDE.md), generic-Unicode-разметка (`unicode.IsLetter`, `IsDigit`), поля `book.yaml` как данные (`yo_policy`, `gender`, `decl`), ja-ориентированные колонки схемы БД (руби), `Р2`/`Р6`-метки решений кириллицей в комментариях, `configs/pairs/*.yaml` как правильный адрес пар-данных, и — отдельно — `internal/lang` как **эталон уже исполненной изоляции**.
Две записи ведра E, которые стоит прочитать как предупреждения, а не как «чисто»:
- `lang/data/refusal.txt` — плоский четырёхъязычный блэклист, читаемый **целиком для любой книги**: паттерн `抱歉[,]` (частая китайская фраза) на эхнутом китайском срабатывает как ОТКАЗ, маскируя эхо; пятый язык не покрыт вовсе.
- `configs/pipeline-*.yaml`**ни один шиппинг-конфиг не включает** `gates.terminology`, `gates.banknote`, `gates.repair`, `gates.voice`, `mining` (`grep -n 'terminology\|banknote\|repair:\|voice\|contrast_path' backend/configs/*.yaml` → пусто). Это меняет тяжесть половины сайтов банкноты/терминолога: сегодня они не исполняются. Санитайзер, наоборот, **включён везде** (`enabled: true` в c1 и трёх арм-ямлах).
---
## 4. Счёт масштаба
| Метрика | Число |
|---|---|
| Прод-код бэкенда | **83 файла / 27 102 строки** (весь `.go`: 177 / 50 456) |
| Уникальных сайтов инвентаря | **255** (226 от сканеров 14 дублей + 43 добора верификаторов) |
| **ДОЛГ (A+B+C+D)** | **149 сайтов в 45 файлах** — 133 в `.go` (35 файлов), 16 в данных/конфигах/промптах (10 файлов) |
| Из них НЕ забукано | **111 из 149** (74%) |
| A / B / C / D / E | 27 / 6 / 104 / 12 / 106 |
| Ось долга | источник+пара **63%** · цель (ru) **30%** · книга **3%** · нет **4%** |
| Книго-привязка поимённо | **4 сайта**: `ingest.go:140` (60 рун по заголовкам Мастера Гу) · `miner_emit.go:27` (пороги с эталонного прогона 蛊真人) · `memseed.go:510` (ja-фуригана без гейта) · `memseed.go:331` (нота «Polivanov» на любой паре) |
| Долг по пакетам | checks 34 · pipeline 28 · miner 21 · chunk 17 · lang 10 · configs 9 · text 8 · membank 7 · terminology 6 · config 5 · prompts 3 · cmd 1 |
| Живых CJK-литералов в исполняемом Go | **27 строк / 12 файлов** |
| Живых кириллических литералов в исполняемом Go | **66 строк / 16 файлов** (из них ~30 — русские комментарии в SQL-DDL `store/migrate.go`, нарушение нормы «язык кода английский», не языковая привязка) |
**Что эти числа говорят, а что нет.** 149 сайтов — не 149 задач: класс `EstimateTokens` — это 11 сайтов и одна правка; цель-шов — 18 сайтов и один пакет. Честная оценка объёма работы — **шесть пакетов** (§9), а не полторы сотни точечных фиксов.
---
## 5. Сухой прогон второй пары: трасса отказов
Стартовые факты: `configs/pairs/` = zh-ru, ja-ru, en-ru (все три есть); `configs/langpacks/` = только `zh/` и `zh-ru/`; `prompts/` = только `zh-ru/`.
### ja→ru, в порядке исполнения
1. **ГРОМКО, до БД и до провода:** `config/pipeline.go:899-903` — нет `prompts/ja-ru/translator.md`; ошибка называет ожидаемый путь; падают обе стадии одним списком. **Образцовый отказ.** Лечится двумя файлами.
2. **ТИХО — главный риск:** `runner.go:281-284` — нет каталога `configs/langpacks/ja-ru``pack = nil`, **ни строки лога**. Гасит разом: майнер, DC-чекеры, политику заголовков, speech-cue, sizing терминолога и `LangpackVersion` в снапшоте. Громко становится только под `--verify-bank` (`mining.go:44-48`).
3. **ТИХО:** нет блока `segmentation` в `pairs/ja-ru.yaml` ⇒ zh-ru литералы 1797/3200/1.1978/0.3852; кана считается по фертильности кандзи ⇒ `est_out` завышен, чанки мельче. Направление безопасное (не обрезание), платим числом вызовов и когезией edit-юнита. *Величина завышения (~1.51.7×) — гипотеза, в репо не мерена.*
4. **ГРОМКО и правильно:** Shift-JIS/EUC-JP отбивается `ingest.go:325-329` с точным текстом. UTF-8 проходит.
5. **ТИХО, зависит от книги:** `第N話` не в `chapter_unit` ⇒ .txt-книга станет одной главой. **EPUB не затронут.**
6. **ТИХО:** срез банкноты безусловен (`banknote.go:323`), а предупреждение об отсутствующем `target_script` печатается только при включённом `gates.banknote` — которого нет ни в одном конфиге.
Работает для ja «из коробки»: эхо-гейт, CJK-leak санитайзера, гейт магнитуд 万/億, нарезка предложений с `「」`, коридор coverage из пар-файла, инъекция банка через цель-данные, все `isRuTarget`-гейты.
**Снято кросс-чеком:** «руби→глоссарий работает из коробки» — НЕВЕРНО, `rubyToCandidates` не имеет ни одного прод-вызова (проверено мной лично); боевой сид зовёт только `AttachRubyAliasesToManual`, которая навешивает чтение на УЖЕ вручную засиженный терм.
### en→ru — другие классы
- **E-1** тот же громкий отказ по промптам.
- **E-2** сегментация глав: для .txt — вся книга одна глава (ломает окна `since_ch`/`until_ch` в `memory.go:625-633` и сброс sticky в `wave.go:83-87`); **для EPUB работает штатно**. «Chapter 12» невыразимо данными: `matchHeaderLine` (`chunker.go:186-197`) не терпит пробела между маркером и цифрой и требует рун-юнит после цифр, а парсер маркера срезает хвостовой пробел (`langpack.go:594`). **Go.**
- **E-3** эхо-детектор недостижим: `cjkShare = 0` на английском эхе, `FlagCJKArtifact` невозможен, эскалация по эху не сработает никогда. Единственный бэкстоп — `detectLatinInsertion`, но он SUBSTANTIVE (чанк дропается в плейсхолдер, а не чинится) и **не входит в `escalatable()`**. *Опора: D19.1 (`05-decisions-log.md:274`) мерил эхо и на en (0/6) — то есть класс в проекте измерялся, а детектора для него физически нет. Ссылку на D19.2 из первичного разбора я снял: D19.2 явно ограничена плотным CJK-входом.*
- **E-4** майнер = ноль (`hanRuns` пуст). Само-маскируется: при `pack == nil` он и так не запускается.
- **E-5** аттестация банкноты подстрокой без границы слова («art» в «start») плюс регистрозависимость (нормализация ключа регистр складывает, а сравнение по книге — нет).
### Числа
**Данными лечится 11 позиций** (промпты пары ×2 · `segmentation` ·`len_ratio` уже есть · `encoding` · `target_script` · `heading.txt` · `speech-cue.txt` · `terminology.txt` · `dc-checkers.txt` · промпты терминолога/ремонта · частотный артефакт).
**Требует Go — 5 позиций:** G1 монолитный манифест пака (`langpack.go:178-185` + `486-492`) · G2 алфавит кандидатов майнера (`miner_substrate.go:44,48`) · G3 детектор эха по письменности (`disposition.go:271-286`) · G4 детект глав только по CJK-грамматике (txt-путь) · G5 эмбед-данные вне всех хешей. **Плюс 2 латентных:** `sourceAbbrevs("en")`, `ruSanitizer` — на этих двух парах не стреляют.
**Ни одна из пяти Go-позиций не блокирует запуск** — все либо усыпляют детектор, либо обесценивают механизм.
**Приёмочный критерий сегодня:** ja→ru проходит **безопасно** без единой правки Go (деградируют майнер и калибровка); en→ru проходит **небезопасно** — две молча спящие дыры (эхо и, на txt, главы). Устойчиво разделяет пары ровно это: G2 и G3.
---
## 6. Цены: что перекупается
**Механика в трёх фактах (перепроверена построчно кросс-чеком).**
1. Снапшотов ДВА — волновые (`snapshotIDForWave`, `snapshot.go:222`), различаются подмножеством стадий и версией банка.
2. `snapshotID` входит в КАЖДЫЙ `RequestHash` (`render.go:305-308`) ⇒ сдвиг = промах всех чекпойнтов волны ⇒ громкий стоп и требование `--resnapshot`. Собственный комментарий кода (`snapshot.go:51-57`): «the whole book is RE-BILLED, even for byte-identical wire requests whose verdict merely needs re-classifying».
3. Единственный механизм не платить при сдвинутом снапшоте — **точечный ре-пин**, и он срабатывает только когда разошлось РОВНО `memory_version` (`repin.go:54,61-91`). Из 20 осей ре-пинуема **одна**.
**Что это значит для вёдер:**
| Адресат выноса | Цена | Улика |
|---|---|---|
| `configs/langpacks/<src\|pair>/` | **перепокупка обеих волн всех книг ЭТОЙ пары**, ре-пин невозможен. Хеш берётся над СЫРЫМИ байтами до парсинга ⇒ **добавление комментария стоит столько же, сколько правка правила** | `langpack.go:196,205-207,299`; асимметрия с промптами, где комментарии стрипаются ДО sha256 (`render.go:127-131`) |
| `internal/lang/data/` (эмбед) | **$0 по снапшоту** — и это не льгота, а ДЫРА (см. ниже) | `embedded.go:20-21`, хеширования нет (проверено лично) |
| `configs/pairs/<pair>.yaml` | **$0**, если резолвнутое значение то же (фолдятся ЗНАЧЕНИЯ, не хеш файла) | `snapshot.go:38-46,74-83` |
| не-фолдящийся гейт-конфиг | **$0**, ратифицированный прецедент | `config/pipeline.go:305-312` (`target_script`) |
| **НОВАЯ пара** (`configs/langpacks/ja-ru/`) | **$0 для всех существующих книг** — хеш скоупится по паре | `langpack.go:210-227` |
| `packAlgoVersion` или новый ОБЯЗАТЕЛЬНЫЙ файл манифеста | **перепокупка ВСЕХ книг ВСЕХ пар** + fail-loud у каждого существующего пака | `langpack.go:40,178-185,200-203` |
**Ратифицированная фигура дешёвого выноса уже существует и измерена:** отгрузить МЕХАНИЗМ (ридер + дефолт) — отсутствующий опциональный файл в хеш не пишется (`readOptional`, `langpack.go:567-576`), — а ФАЙЛ авторить на ближайшем оплаченном `--resnapshot`. Так сегодня и живут `terminology.txt` и `speech-cue.txt`: ридеры отгружены, файлов в репо нет. Прецедент цены измерен: одна строка в `dc-checkers.txt` двигала `a7d4be2c0465``133d71e8d132`, и оба «нита общности» были отложены до полного resnapshot (**D39.31 п.5**; первичный разбор атрибутировал это D39.53 — исправлено кросс-чеком).
**$0-инструмент оценки, который стоит забрать в норму.** Хеш пака воспроизводим без запуска Go:
```bash
cd backend/configs/langpacks && { printf 'langpack-v2';
for f in surnames-single.txt surnames-compound.txt title-suffix.txt ordinal-title.txt rank-word.txt \
topo-suffix.txt grade-prefix.txt numeral.txt alias-particle.txt title-formant.txt sentence-terminator.txt; do
printf '\x00zh/%s\x00' "$f"; cat "zh/$f"; done
for f in palladius.txt palladius-phonotactics.txt; do printf '\x00zh-ru/%s\x00' "$f"; cat "zh-ru/$f"; done
printf '\x00zh-ru/heading.txt\x00'; cat zh-ru/heading.txt
printf '\x00zh-ru/dc-checkers.txt\x00'; cat zh-ru/dc-checkers.txt; } | sha256sum | cut -c1-12
# → a28ed743c99c (совпадает с записанным langpack-v2-a28ed743c99c)
```
Оговорка: стендовые книги объявляют `langpack_extend`, поэтому в их payload едет форма `langpack-v2-x…` (`langpack.go:391`) — рецепт даёт БАЗУ.
### 6.1 Находка: эмбед-плоскость вне всякой дисциплины версий
`internal/lang/data/*.txt` — шесть файлов, **ни в одном контент-хеше** (проверено лично: `embeddedFS` используется только для `ReadFile`). При этом:
- `injection.txt` → заголовки инъекции глоссария и редактора → **байты провода**;
- `target-ru.txt` → санитайзер, а санитайзер есть диспозиция и переписывает финальный текст;
- `terminator.txt`, `cjk-section.txt` → чанкер → **границы чанков** → провод.
Единственная защита — ручной бамп соответствующей константы. Механизма «байты ЕСТЬ версия», выстроенного для `configs/langpacks/` и для `trad2simp.txt`, здесь НЕТ. Живая улика: коммит `8b1d8d1` добавил **+59 строк** в `target-ru.txt` и не тронул ни `CheapGateVersion`, ни `SanitizerVersion` (в том случае категории были новыми и вердикты не двигались — но механизм этого не знает).
Следствие для денег: правка байта в `injection.txt` без бампа `RenderFormatVersion` меняет провод, `content_hash` уезжает, а `projectRebill` спроектирует $0 (`rebill.go:137-139` пропускает юнит с неизменным снапшотом) ⇒ **тихая пере-оплата вне контура согласия Р6**.
**Это жёсткое предусловие ко всему плану:** каждый вынос литерала в данные увеличивает объём вердикт-несущего поведения, живущего в нехешируемых байтах. Без починки — «вынесли в данные» означает «сняли drift-защиту».
### 6.2 Правило условного фолда (выведено из прецедентов кода)
> Изменение можно честно НЕ фолдить тогда и только тогда, когда его выход (1) не входит ни в один байт оплаченного запроса, (2) не входит ни в один вход разрешения диспозиции чекпойнта или `final_hash`, и (3) пересчитывается каждым прогоном из уже сохранённых артефактов.
> **Ортогональное правило присутствия:** любой НОВЫЙ фолд обязан быть условным по присутствию (указатель+`omitempty` или `{enabled:false}`), чтобы отгрузка механизма стоила $0 тем, кто им не пользуется.
Прецеденты, на которых это стоит: расщепление `bankSliceVersion`/`bankParseVersion` (D39.58) · DEFER фолда `pack.Version()` до wiring майнера (D39.16) · условный фолд секции неподписанных строк (`memory.go:428-437`: «re-bills nobody who had nothing to re-render») · `BudgetUSD` не фолдится · few-shot фолдится только при наличии `---FEWSHOT---`.
**Нарушители правила присутствия сегодня — две оси:** `style_check_version` и `render_format_version` фолдятся БЕЗУСЛОВНО, из-за чего правка одного стилевого правила = перепокупка всех книг всех пар. Проект при этом для `VoiceCheckVersion` мотивировал отказ от фолда буквально этим аргументом (`config/pipeline.go:266-267`).
---
## 7. Синк с документацией: что заморожено ратификацией (п.7 задания)
Rewrite нельзя делать «починкой» — часть сайтов заморожена явными решениями. Список заморозок:
| # | Что | Решение | Статус |
|---|---|---|---|
| З1 | **ru-target-долг** (`isRuTarget`-call-site, `TokenizeCyrillic`, множитель ×2) — «задокументированное ОГРАНИЧЕНИЕ, НЕ чинить этим паком; едет с канал-B/таргет-работой» | **D39.24 §15.3**, цитируется в коде дословно (`checks/repair.go:182-189`) | канал B закрыт (D39.2628), «таргет-работа» не открывалась. **Диспозиция назначена — строка 32 бэклога (D39.34).** Пункт ×2 уже погашен данными (`dc_ratio dc1_unit_in_hours`) ⇒ долг меньше формулировки |
| З2 | **`x/text/language.Tag` ОТВЕРГНУТ** для гейт-предикатов: CLDR likely-subtags документированно «subject to change», 6/18 расхождений, а `isRuTarget` гейтит санитайзер → экспортный `FinalText` ⇒ нестабильность попадала бы в снапшот-ВЕРДИКТЫ | **D39.16 див.1** (`05-decisions-log.md:599`) | исполнено буквально: `grep -rn 'x/text/language' --include='*.go' backend/`**0**. **Причина в силе.** Но появилась митигация того же класса (`norm.go:69` `xTextVersion` + пин-тест) — если пакет захочет типизированный тег, обязан предъявить фолд версии и идти амендментом |
| З3 | **Пар-кеинг DC-чекеров — DEFER до ja→ru-реплики** | D39.16 див.2 | в силе |
| З4 | **Фолд `pack.Version()`** отложен был до wiring майнера — исполнен | D39.16 див.3 | закрыт |
| З5 | **«KEEP glosses»** — CJK-глосса `(羅漢拳)` в русском выводе НЕ вырезается | подпись владельца 16.07 (D39.2/D39.4), 6 сайтов в `sanitizer.go` | **менять границы глоссы = менять подписанное поведение** |
| З6 | **Отказ от обобщения «X-X»-редупликации** в правило — отвергнут как FP-опасный | D20.4, `cheapgates.go:361-366` | прямая ловушка для «очевидного» хода «заменим список правилом» |
| З7 | **Жанровый словарь как класс ОТМЕНЁН** — пустой слот в `Load()` есть ЗАПИСАННОЕ РЕШЕНИЕ | D39.47, `langpack.go:290-294` | не переоткрывать под видом «данных пары» |
| З8 | **Петля ремонта построена и НЕ включается** | D39.38 | влияет на цену пака-21 |
| З9 | **Не-CJK майнер** — назначен отдельный пак с прототипом `mine_nonhan.py` и требованиями G1G10 | строка 35 бэклога (D39.37/43/50) | не бесхозная заморозка, а назначенный пак |
**Расхождения док↔код («сломанный телефон»), найденные попутно:** шапка `sanitizer.go:17-20` утверждает гейт, которого у `ExportNormalize` нет (§3.3) · шапка `checkers.go:24` утверждает цель-данные там, где приходят пар-данные · комментарий `pipeline.go:832-841` утверждает, что шиппинг-конфиги ставят блок `segmentation` — ни один не ставит · комментарий `chunkrun.go:186` «nil-inert for a no-pack book» ложен: указатель `Checkers` никогда не nil при ru-цели · 6 указателей на удалённый `checkers_zh_ru.go`.
**Раскладка на 7 слоёв целевой архитектуры** (`09-target-architecture.md`): слой 1 — сегментация/фертильность/заголовки; слой 2 — сам сеам (эталон); слой 4 — пороги банка и майнер; слой 5 — `translitInterjections` как единственный Go-литерал среди данными-выраженных чекеров; слой 6 — `ExportNormalize` без гейта; **слой 7 — строка «target-aware гейты — ОТКРЫТО» держится в шапке-таблице с 26.07**, то есть целевая архитектура пакет цель-шва уже ЖДЁТ.
---
## 8. Пересборка входа пака-21 «чекеры»
**Нулевая находка: все якоря D39.39 устарели.** Пак-19 (`8b1d8d1`) сдвинул `checkers.go`, `mempostcheck.go`, `waverun.go`. Кто возьмёт пак-21 по строкам из D-лога — попадёт мимо. Актуальные якоря (перепроверены обоими проходами):
| # | Дефект | Актуальный якорь | Корзина |
|---|---|---|---|
| 1 | супрессор K5c | `checks/checkers.go:409-412` | (III)→(I) после ответа на Р2 |
| 2 | атрибуция K4b | `checks/checkers.go:522-538` | **(I)** |
| 3 | `chevronSpeechShape` | `checks/cheapgates.go:250-275` | (II) |
| 4 | `inner_marker` на тире | `checks/cheapgates.go:209-212` | **(I)** (новый детектор, не фикс) |
| 5 | предохранитель K5a | `checks/cheapgates.go:515-526` | (II) |
| 6 | заглавные | `checks/checkers.go:446-447` | (II) |
| 7 | гомоглифы / порог 3 | `checks/checkers.go:433,453` | (II), кроме гомоглифа |
| 8 | `两` в `cheng_re` | `configs/langpacks/zh-ru/dc-checkers.txt:65` | **(I)**, но дорогой |
| 9 | множество принятых форм | `membank/mempostcheck.go:144-154` | (II) |
| 10 | однознаковые/подстрочные ключи | `membank/mempostcheck.go:80-112` + `memory.go:1062-1075` | (II) |
| 11 | U+0301 | `text/runes.go:42` + `mempostcheck.go:169` | **(I)** |
| 12 | черновик вне охвата | `pipeline/waverun.go:501` | **(III)** — не дефект, забукано 46 |
**Корзины:** (I) общий класс, чинится generic-алгоритмом + данными — переживает генерализацию; (II) привязка в Go, фикс = перепроект слоя; (III) дефект постановки, а не кода.
**Главный вывод пересборки — ось не та.** Среди 12 дефектов собственно zh-привязок **три** (#5 парсер магнитуд, #8 данные пака, #10 сегментация исходника). Остальное — привязка к ЦЕЛИ (ru) и к типографике. То есть пак-21 в нынешней постановке чинит ось, **ортогональную** названной директивой. Это не отменяет пак — но меняет его порядок относительно пакета цель-шва.
**Структурная находка сверх задания (подтверждена независимо):** дефект #9 после пака-20 УХУДШИЛСЯ. `miner.Term` (`miner_emit.go:43-55`) поля `Decl` не имеет, `attachConsolidatedDst` (`terminologist.go:425-437`) ставит только `Dst` — по всему репо нет ни одного пути записи склонённых форм на майненой стороне. Значит 149 авто-строк холодного банка (D39.58) приходят с НУЛЁМ склонённых форм, и пост-чек их не примет. **Это смыкается с аркой автономности банка D39.59(2) и должно решаться там, а не в паке-21.**
**Ещё одна проверяемая находка:** на ja→ru книге БЕЗ пака `lintNumberMagnitude` **активен** с китайскими идиомными допущениями. Механика закрывается статически: `runner.go:270-277` ставит `CompileCheckersFor` в `defer`, срабатывающий на всех выходах `loadLangPack` включая ранние `return nil`; `magnitudeStem` приходит из цель-данных ВНЕ блока `if dc != nil` (`checkers.go:93`); гейт `cheapgates.go:422` проходит; `cjkMagnitudeOrders` читает вшитый `lang.DefaultCJKSection()`. Шапка `cheapgates.go:57-58` «They fire 0 on a non-zh source» к нему **не относится**.
### Р1Р4 после генерализации
| | Переживает? | Диспозиция |
|---|---|---|
| **Р1** гипербола 千万 | **расщепляется на три** | ДАННЫЕ (какие строки идиоматичны — в пар-пак рядом с `qianwan_veto_word`) — снять с владельца · ПОЛИТИКА — слить с Р2 · КНИЖНЫЙ остаток (довод построен на том, что «тот же автор в главе 2 пишет 数十万», а межглавного числового согласования в движке нет как механизма) — **снять как вопрос про конкретную книгу** |
| **Р2** что есть дефект в 成 | **переживает целиком, и должен быть РАСШИРЕН** | языково-слепой контракт детектора и самый дорогой из четырёх (precision 1.000 против 0.167). Переформулировать: «детекторы единиц/шкал судят ЗНАЧЕНИЕ рендера или его ФОРМУ?» — один ответ на семейство (DC1, магнитуды, любой пересчёт), а не на иероглиф |
| **Р3** сокращённая форма терма | **ФАКТИЧЕСКИ ЗАКРЫТ** | D39.44 Q4 уже постановил: «сокращённая форма = ПОЛЕ существующей записи, пост-чек обязан её принимать». Остаток — работа (строка 27), и это ТОТ ЖЕ шов, что #9. **Рекомендация: снять с владельца, слить с #9** |
| **Р4** неразрешимая речь/мысль | **переживает как НОРМА, а не как вопрос про класс** | «у детектора бывает потолок recall by construction, он пишется в контракт правила». Правило уже де-факто действует в коде. Задать один раз, цель-слепо, и перестать переспрашивать поклассово |
**Итог: на подпись владельца остаются ДВА вопроса вместо четырёх** — Р2 (расширенный до семейства единиц) и Р4 (в форме нормы).
### Цена пака-21 — с исправлением
`CheapGateVersion` фолдится в снапшот БЕЗУСЛОВНО (`snapshot.go:435`) ⇒ **любой из 12 фиксов сегодня = перепокупка каждой стендовой книги.** Напрашивающийся «нулевой шаг» (сделать фолд условным по образцу `VoiceCheckVersion`) **сам платный**: `repin.go:82-86` — «a component that was folded and no longer is — not a bank move» ⇒ `moveOther`. Фактическая цена, впрочем, копеечная (стендовые книги = мини-прогоны по $0.130.23).
Две поправки кросс-чека к первичной оценке, которые меняют порядок работ:
- **#9/#10 ДЕШЕВЛЕ, чем казалось:** `matchVersion` фолдится внутрь `memory_version` (`memory.go:383`, проверено мной), а это единственная ре-пинуемая ось ⇒ стоят только реально затронутых юнитов.
- **#8 ДОРОЖЕ всех:** правка `dc-checkers.txt` двигает `LangpackVersion` — отдельное поле снапшота ⇒ `moveOther` ⇒ перепокупка обеих волн всех zh-книг. Ратифицированный прецедент ровно об этом: D39.56 отказался шипать `speech-cue.txt` по той же причине.
**Дешёвых пунктов, не трогающих пар-шов:** #11 (U+0301) · #2 (сузить атрибуцию до спана) · #4 (`inner_marker` симметрично вето) · гомоглиф отдельным детектором смешанного письма · строгая форма `OffLanguage` (строка 28) · строка 26 в данные.
*Оговорка по строке 28, которую нельзя терять:* последний живой замер (D39.58) утечку алфавита **не воспроизвёл** (0/150) и вскрыл ДРУГОЙ механизм — `甲等 → класс Цзя`, целиком кириллица, строгой формой `OffLanguage` не ловится (это строка 36а, непроверенное поле `type`). Подавать строку 28 как «самый дешёвый выигрыш» нельзя.
---
## 9. План переписывания пакетами
**Несущее ценовое решение, от которого зависит весь порядок:** любой сдвиг снапшота = перепокупка книги, а ре-пинуема одна ось из двадцати. Значит правильная фигура — **не «дешёвые пакеты вперёд», а один общий `--resnapshot`, в который собраны ВСЕ снапшот-двигающие правки**. И делать это надо СЕЙЧАС: оплаченный корпус — два мини-прогона масштаба $0.130.23; после МАСШТАБА (7,78 млн симв.) тот же дифф будет стоить порядки.
Приёмочный критерий каждого пакета — один: **«пара, которой нет в репо (ja→ru / en→ru), проходит этот слой без правки Go»**.
### П0 — «Байты есть версия» (предусловие, обязателен первым)
**Что:** `lang.EmbeddedVersion()` = sha256 по всей эмбед-FS в фиксированном порядке, свёрнутый в снапшот рядом с `LangpackVersion`. ~15 строк.
**Зачем:** без него каждый следующий пакет увеличивает объём вердикт-несущего поведения в нехешируемых байтах (§6.1). Заодно закрывает канал тихой пере-оплаты вне Р6.
**Цена:** новая ось фолда ⇒ один resnapshot. **Приёмка:** правка байта в `data/target-ru.txt` даёт громкий resnapshot, а не тихую смену вердиктов.
### П1 — Цель-шов (слой 7; целевая архитектура его уже ждёт)
**Что:** `isRuTarget` (6 call-site) → инертность-по-данным вместо Go-предиката · `TokenizeCyrillic` → токенизатор с алфавитом цели из данных (закрывает и #11, и самозадокументированный долг `checks/repair.go:182-189`) · реестр целей `//go:embed data` + резолв по имени вместо мапы из двух Go-строк · `ruSanitizer` → поле `Checkers` · **гейт на `ExportNormalize`** · ё→е фолд из `NormalizeTargetForm` в цель-данные.
**Цена:** гейт `ExportNormalize`**$0** (по собственной шапке не вход снапшота/вердикта). Реестр целей — $0 (поведение на ru не меняется). Токенизатор и ё-фолд двигают `CheapGateVersion`/`memoryNormAlgoVersion` ⇒ в общий resnapshot.
**Ратификация:** ОБЯЗАТЕЛЬНА — амендмент З1 (D39.24 §15.3 «НЕ чинить»); формально проще амендировать строку 32 бэклога (D39.34). З2 соблюдать: строковые предикаты, никакого `language.Tag`.
**Приёмка:** книга с `target_lang: en` проходит все гейты слоя 7 инертно **по отсутствию данных**, а не по Go-ветке; golden байт-идентичен.
### П2 — Скрипт-шов источника (закрывает живой баг)
**Что:** `cjkShare` → доля рун ИСХОДНОГО письма в выходе (письмо объявляется, не нюхается) · консолидация ≥11 выражений «класс CJK» в ≥4 редакциях, с явным решением по Hangul · `isCJKLang` → атрибут данных.
**Цена:** `classifierVersion` + `SanitizerVersion` ⇒ resnapshot. **Не косметика:** схлопывание меняет вердикт в `repair.go:435` и `sanitizer.go:490`.
**Приёмка:** en→ru книга, чей черновик вернул исходник дословно, даёт `FlagCJKArtifact`-класс и эскалируется; ko-источник перестаёт быть слепым пятном.
### П3 — Нарезка и оценка (слой 1, самый wire-тяжёлый)
**Что:** таксономия классов `EstimateTokens` из данных (не два поля в Go-типе) · фолбэк `segmentation` = **громкая ошибка** вместо zh-литералов (правило D39.59 «терпимость движка к своим данным = воркэраунд») · детект глав generic (маркер-строка + цифры + опциональный юнит, с пробелом), закрывает «Chapter 12» · аллоулист кодировок из данных · `sourceAbbrevs` по языку книги.
**Цена:** `chunkerVersion` + `estimatorVersion` + `segmentation` ⇒ resnapshot; сдвигает границы чанков ⇒ реальный провод. **Самый дорогой пакет — тем важнее, чтобы он ехал в том же resnapshot, что П0П2.**
**Приёмка:** en-txt с «Chapter 12» нарезается по главам; ja-книга получает свои коэффициенты или падает громко.
### П4 — Пак как механизм (слой 2)
**Что:** манифест по КАНАЛАМ вместо плоских 11 обязательных файлов (`manifest.txt` в каталоге источника; `validate()` требует файлы только объявленных каналов; майнер получает nil-канал и молчит) · табличный список опциональных файлов вместо четырёх копий блока read→hash→parse→assign (нетто 35 строк) · явное решение, что новые файлы не оверлеятся книгой.
**Цена:** бамп `packAlgoVersion` = **перепокупка всех книг всех пар** ⇒ обязан ехать в общем resnapshot и только в нём.
**Приёмка:** каталог `configs/langpacks/en/` с одним объявленным каналом грузится; отсутствие каналов майнера = тишина с WARN, а не отказ и не ложь.
### П5 — Майнер как семейный модуль (слой 4) — ГЕЙТ на реальную вторую пару
**Что:** алфавит кандидатов и длины из данных · сырой (не нормализованный) источник для ja, чтобы катакана дожила до детектора · второй ДЕТЕКТОР для пробельных языков (строка 35, прототип `mine_nonhan.py`, требования G1G10).
**Почему последним:** это единственный пакет, чью правильность нельзя доказать на текущей паре. Пока нет ja/en-книги на стенде, любые решения тут — гадание.
**Приёмка:** ja-книга даёт непустой банк с катаканными именами; парити zh EXACT сохранён.
### П6 — Расщепление цены (НЕ рекомендация, а вопрос владельцу — §12)
**Сводная цена и порядок.**
| Пакет | Двигает снапшот | Может ехать отдельно |
|---|---|---|
| П0 | да (новая ось) | нет — идёт первым в общем resnapshot |
| П1 | частично ($0-части: `ExportNormalize`-гейт, реестр целей) | $0-части — да |
| П2 | да | нет |
| П3 | да (самый тяжёлый) | нет |
| П4 | да (все пары) | нет |
| П5 | да | да — гейтится второй парой |
Рекомендуемый порядок: **$0-части П1 → один общий resnapshot (П0+остаток П1+П2+П3+П4) → П5 по появлении второй книги.**
**Приборы доказательства — существующие, новых не нужно:** golden байт-в-байт (`internal/pipeline/golden_test.go` + маскированный структурный дифф Ш-1, `golden_test.go:330-336,406-425`**построен**, вопреки записи в D-логе) · майнер-парити (`TM_MINER_PARITY=1`; оговорка: `n=13618` и три категории пинятся точно, а recall — полосой 0.9600.970 и `古月` — только как top-50, так что «recall 0.9649 EXACT» подавать нельзя) · `go test -race`.
**Дыра приборов, которую пакет обязан закрыть своим средством:** golden — книга **без langpack**, поэтому путь с загруженным паком не пинится байт-в-байт вовсе; `banknote` и `repair` в capture тоже отсутствуют. Для ведра A golden не защита — нужен прямой замер `pack.Version()` рецептом из §6.
---
## 10. Алгоритмы: что строить и чего НЕ строить (п.6 задания)
**Строить (кроме уже расписанного в §9):**
- **Токенизация цели** — шов один: алфавит слова приходит цель-данными, `unicode.Cyrillic` остаётся ЗНАЧЕНИЕМ по умолчанию для ru. Все 5 мест висят на `*Checkers`, плумбинг не нужен.
- **`EstimateTokens` честно для нескольких письменностей без вендорского токенизатора** — коэффициент на класс письма из данных пары; калибровка офлайн по реальным токенизаторам. **Оговорка кросс-чека:** в репо лежат 4 настоящих `tokenizer.json` (`glm-4.6`, `qwen2.5`, `qwen3`, `deepseek-v3.2`), и токенизатора БОЕВОЙ модели (deepseek-v4) среди них нет — «калибровка офлайн за $0» для неё сегодня не обеспечена.
- **`internal/lang` как приёмник** — четыре конкретные дыры: жёсткий манифест (§9 П4), копипаста опциональных блоков, per-target реестр в двух Go-строках, нехешированная эмбед-плоскость (§9 П0). Сильные стороны не трогать: две плоскости с разными жизненными циклами, `Version()` = контент-хеш, fail-loud на пустую таблицу, громкая ошибка на неизвестную категорию (`langpack.go:796` — поведение ЛУЧШЕ, чем описал первичный разбор).
**НЕ делать:**
1. **Не возвращать `x/text/language.Tag`** — ратифицированно отвергнуто (З2), причина в силе.
2. **Не тащить UAX#29-сегментатор** — он явно НЕ сегментирует идеографику (на стороне источника не решает ничего), для кириллицы почти эквивалентен «максимальному рану букв», и вносит ВТОРУЮ независимую Unicode-редакцию в вердикт-путь.
3. **Не снимать `unicode.Version`/`xTextVersion` из версионных тегов** «раз скрипты теперь из данных» — таблицы всё равно тулчейновые.
4. **Не пар-кеить DC-чекеры «для симметрии»**З3, DEFER до ja-пака.
5. **Не определять письмо источника/цели авто-детектом по тексту** — вердикт станет функцией случайного состава входа и невоспроизводим на резюме. Объявлять, не нюхать.
6. **Не трогать кана-фолд `NormalizeSourceKey`** ради ja — он внутри `NormVersion()``memory_version`; катаканный сигнал возвращается подачей майнеру сырого текста, а не ослаблением общего нормализатора.
7. **Не возвращать книжные/жанровые словари в пар-слой**З7.
8. **Не дробить `internal/lang`** на `lang/src|pair|target` — число файлов не критерий сплита.
9. **Не «терпеть» собственные данные** — правило владельца 31.07: тихий фолбэк вместо отсутствующих пар-данных и есть воркэраунд (сегодня их 10, поимённо в §5).
**Отброшено как противоречащее нормативу:** `LangPack`-интерфейс с реестром плагинов (реализация одна; «интерфейс объявляет потребитель») · пакет `internal/script`/`unicodeutil` (запрещённые util-имена) · дженерик-обёртки над картами пака · интерфейс `TermDetector` с реализациями zh/ja (возвращает пару в Go, только за интерфейсом) · лемматизатор в движок ради честного `sameLexeme` (новая зависимость; default-B уже ратифицированно выбросил pymorphy3-каналы — **D39.12**, не D39.14).
---
## 11. Критик полноты
**Чего этот отчёт НЕ содержит и содержать не может:**
1. **Ни одного исполнения.** Сессия read-only; ни `go test`, ни прогон, ни замер. Всё выведено из чтения тел. Первый кандидат на проверку исполнением — активность `lintNumberMagnitude` на ja→ru без пака (закрывается статически, но исполнением не подтверждена).
2. **Все числовые оценки поведения второй пары — гипотезы.** «est_out завышен ~1.51.7×», «чанки на 40% меньше», «завышение ~30% для en» из кода не выводятся: фертильность выведена только на zh-ru (R²=0.9633). Направление («безопасное, платим числом вызовов») — из кода; величины — нет.
3. **Оценки объёма работы в строках Go** («~15 / ~35 / ~40 строк») не верифицируемы и как минимум одна посчитана по половине call-site.
4. **Ведро C — 104 сайта, и оно самое субъективное.** Граница «C против E» проходит по вопросу «нужна ли этой величине пар-зависимость вообще», а он местами решается суждением. Верификаторы переклассифицировали 20 сайтов из 226; вероятно, ещё 1015 спорны.
5. **eval/ не сканировался вовсе** — вне зоны бэкенда, но там живут прототипы (`mine_nonhan.py`) и токенизаторы, влияющие на П5 и на калибровку.
6. **Ни одна цифра recall/precision D39.39 не пере-мерена** — все остаются «на одной книге, одной паре, одном жанре»; генерализация этот дисклеймер усиливает, а не снимает.
7. **Размеченный набор пакета-6 (`books/gu-zhenren/labels/`) лежит вне git** — на приёмку пака-21 я опираюсь по описанию отчёта, не по файлу.
8. **Не оценена привязка тех чекеров, которых полигон не размечал** (`lintYofikation`, санитайзер, DC6, транслит-междометия).
9. **Не проверялось, что происходит с ПАРАЛЛЕЛЬНЫМИ парами** (две книги разных пар в одной БД) — весь анализ вёлся в предположении одной пары на прогон.
10. **Слабое место метода:** сканеры дважды поверили комментариям вместо кода (шапка о «shipping configs set the whole block», шапка о гейте санитайзера) и один раз не дочитали вызовы функции (руби-канал). Все три пойманы кросс-чеком — но это ровно тот класс, который проходит незамеченным, если верификатор один. Дисциплина «автор≠ревьюер» здесь окупилась трижды.
**Что в отчёт НЕ вошло, хотя агенты это заявляли** (опровергнуто кросс-чеком, фиксирую, чтобы не всплыло повторно): «французский пробел молча съест экспорт» (регекс в гейтованной функции и не матчит U+202F) · «руби работает из коробки» (прод-вызовов нет) · «ja/en-книга загрузится и молча поедет на zh-числах» (падает раньше, на промптах) · «нулевой шаг стоит $0» (сам платный) · «фиксы #9/#10 дорогие» (ровно наоборот) · «Ш-1 не построен» (построен, `golden_test.go:406-425`).
---
## 12. СТОП. Что на владельце
**Вопрос 1 (главный, бьёт по ПОСЫЛКЕ задачи).** Директива названа по оси ПАРЫ, и по ней результат хороший: книго-привязки 4 сайта, вторая пара уже едет в golden, ja→ru проходит без правки Go. Но измерение говорит, что **больший и более замороженный кусок долга лежит на оси ЦЕЛИ** (30% всего инвентаря; среди 12 дефектов пака-21 — доминирует), и именно он заморожен D39.24 «НЕ чинить». Вопрос: **пакет П1 (цель-шов) входит в эту арку или ждёт отдельной санкции?** Я не могу ратифицировать амендмент чужого решения.
**Вопрос 2 (деньги, решает порядок).** Подтверждаете ли фигуру **«один общий `--resnapshot` сейчас»** вместо россыпи дешёвых пакетов? Аргумент: цена перепокупки сегодня — центы (корпус = два мини-прогона), после МАСШТАБА — порядки; а ре-пинуема одна ось из двадцати, так что «делать по кусочку» означает платить за каждый кусочек отдельно.
**Вопрос 3 (П6, где я обязан оспорить сам себя).** Напрашивается расщепление хеша пака по влиянию: `heading.txt` двигает провод — фолдить; `dc-checkers.txt` только наблюдаемость — не фолдить. Прецедент формы есть (D39.58). **Но посылка «наблюдаемость — не вердикт» противоречит собственной позиции проекта**, записанной дважды (`snapshot.go:397-402`: «editing a rule shifts the recorded style-flag counts, so a bump is a loud --resnapshot»). Прежде чем это класть на подпись, надо развести «наблюдаемость, попадающая в `chunk_status`/`retrieval_state`» и «наблюдаемость, пересчитываемую из сохранённых ответов». **Подавать как готовое решение отказываюсь; подаю как вопрос.**
**Вопрос 4 (Р1Р4).** Предлагаю снять с владельца два из четырёх: **Р3 закрыт** D39.44 Q4 (остаток — работа, сливается с #9), **Р1 расщепляется** на данные + политику (в Р2) + книжный остаток (снять). Остаются Р2 в расширенной форме («детекторы единиц судят ЗНАЧЕНИЕ или ФОРМУ?») и Р4 в форме нормы. Подтверждаете?
**Вопрос 5 (пак-21).** По карте пак-21 распадается: ~6 дешёвых пунктов, не трогающих пар-шов; 6 дефектов уезжают в rewrite-пакеты; #12 и K4a снимаются как не-дефекты кода; #9 уезжает в арку автономности банка. **Оставляем пак-21 как единицу или растворяем в П1/П2 и арке банка?**
**Отдельно, вне вопросов — живой баг, который стоит починить независимо от всех решений:** `isCJKLang` числит `ko`, а три детектора (`cjkShare`, CJK-leak, гард ремонта) Hangul не содержат. Для корейского источника движок считает нарезку как CJK, печатает предупреждение об экспозиции эха и при этом эхо увидеть не может.
**Фаза 2 (переписывание) НЕ начата и не начнётся без ратификации.** Ни строки кода не тронуто.