> **⟶ ОТРАБОТАН → `internal/lang`+`configs/langpacks/` (майнер-данные вынесены байт-точно), ЗАЛЕНДЕН, ратифицирован D39.16 (19.07). 3 дивергенции (language.Tag отвергнут, DC-чекеры/снапшот-фолд DEFER) ратифицированы. Архивная копия.** # Промт: сессия БЭКЕНД (промежуточная) — изоляция языковых данных из пайплайна + алгоритмы/чистота кода, 2026-07-19 > **Место в очереди:** ПЕРЕД R1-драйвер-свитчем (директива владельца 19.07 — вставить архитектурный проход до > завершения волнового исполнителя, пока не накопился ещё язык-специфичный код и до того, как майнер станет > живым в W1.5). После этой сессии → R1-продолжение (`BACKEND_PLAN11_SESSION_PROMPT.md`) → resnapshot → > пере-прогон → чтение. **Это не R1 и не пере-прогон.** ## Директива владельца (дословно, ратифицирована — это НЕ гипотеза сессии) Язык-специфичные русско-китайские вставки НЕ должны жить внутри `internal/pipeline/`. Горизонт — сотни языков. Пересмотреть архитектурный подход: язык-данные — вне движка, через **библиотеки где уместно** и **данные-файлами, а не константами**. **Писать ЧИСТЫЙ КОД с НОРМАЛЬНЫМИ АЛГОРИТМАМИ — как сеньоры из Google.** **НО:** не упарываться на миноры, переписывание ради переписывания НЕ делать. Один оправданный крупный рефактор (изоляция языка) + известные реальные фиксы — и всё; не плодить косметику. ## Кто ты и что сдаёшь Бэкенд-сессия. **Зона: `backend/` (вкл. `configs/`, `prompts/`) + новый каталог языковых данных.** Прочее — read-only. **НЕ коммитить** (лендит оркестратор). Сдаёшь: 1. Код рефактора + фиксов + тесты; **поведенчески НЕЙТРАЛЬНО для zh→ru** (это РЕФАКТОР-перемещение данных, не смена поведения — доказывается байт-стабильностью golden с точностью до одного version-поля). 2. **`backend/ARCH_CLEANUP_REPORT.md`** — результаты каждой фазы-воркфлоу (ресёрч-буллеты, синтез, фикс-лист с диспозициями do/defer/don't, лог исполнения, ревью-вердикт), golden-дифф, «багфиксы вне плана», residual. ## Онбординг 1. `CLAUDE.md` (гардрейлы) → `backend/README.md` (**инварианты 1–8**) → `docs/architecture/09-target-architecture.md` **§0.1 инвариант общности** (любая книга/пара/структура; пара = ось данных — это север) + §2 слой-2. 2. `docs/architecture/10-prompt-architecture.md` — **прецедент, который расширяем:** промпты УЖЕ живут pair-keyed (`Stage.Prompts[pair]` + `PromptPathFor` + fail-loud + снапшот-фолд). Языковые данные получают ту же форму. 3. `docs/architecture/11-implementation-plan.md` §3 **§B5 (плагины P1–P6)** — 6 интерфейсов языковых данных уже спроектированы; эта сессия делает их **data-backed и вне `pipeline/`**. 4. D-лог D39.12–D39.15; `docs/experiments/00-provider-quirks.md`. 5. Грунтовка по коду (где сейчас зашит язык): `miner_patterns.go` (百家姓 `surnamesSingleRaw`, суффиксы), `miner_palladius.go` (таблица Палладия), `miner_alias.go` (`aliasParticle` 的了在是…), `checkers_zh_ru.go` (时辰-таблица, числительные, «терем»-регистр), `cheapgates.go` (allowlist междометий), `disposition.go` (`isRuTarget`/`isCJKTarget`), `chunker.go` (фертильность CJK/other). Референсы данных — `eval/exp16/*.py`. ## Фазовая структура (ВОРКФЛОУ — ultracode включён; каждая фаза = отдельный воркфлоу) ### Фаза 1 — РЕСЁРЧ (независимый, 2 направления × 3 источника, свои буллеты) Параллельные агенты, каждый ищет СВОИ находки (refute-by-default, независимая перспектива). Источники каждого: **(1) Go-идиоматика/stdlib/`golang.org/x/text`, (2) наш репозиторий, (3) интернет (websearch)**. Направления: - **A. АЛГОРИТМЫ:** правильные ли алгоритмы в текст-работе (майнер n-граммы/c-value, matcher Aho-Corasick, нормализация, union-find алиасов, фертильность)? Что из этого — переизобретённый велосипед, заменяемый stdlib/`x/text` (сегментация/коллация/нормализация/`language.Tag`)? Что — уже правильный нормальный алгоритм, который ТРОГАТЬ НЕ НАДО (напр. union-find `clusterAlias` — оставить)? Где Go-библиотека реально поможет, а где честно нет (морфология/NER — вынесено в облако, не Go)? - **B. АРХИТЕКТУРА КОДА / ОБЩНОСТЬ:** как изолировать языковые данные из `pipeline/` под сотни языков. Паттерны: data-as-files + реестр-per-пара, plugin-интерфейсы, `x/text/language.Tag`. Прайор-арт: наш pair-keyed промпт-сеам; Go project-layout идиомы; i18n/l10n data-separation из индустрии (websearch). Выход фазы: два набора буллетов (алгоритмы / архитектура) с обоснованием и file:line/ссылками. ### Фаза 2 — СИНТЕЗ (короткий воркфлоу): свести все входы Реконсилировать: **ресёрч-буллеты + буллеты оркестратора (ниже) + буллеты владельца (ниже) + известный фикс-лист (ниже)**. Дедуп, разрешить конфликты, ранжировать по ценности×риску. Явно пометить, что — консенсус, что — спорно. ### Фаза 3 — ВЫВОД фикс-листа + предложений (резюмирующий воркфлоу) Из синтеза вывести **финальный actionable-список** с диспозицией КАЖДОГО пункта: **DO** (делаем сейчас) / **DEFER** (в резидуал, с причиной) / **DON'T** (переписывание-ради-переписывания — отвергнуть явно). Это рубеж против «упарывания на миноры»: пункт без ясной ценности → DON'T. Отдельно — предложения по алгоритмам/архитектуре, которые сверх скоупа этой сессии (в план/владельцу). ### Фаза 4 — ИСПОЛНЕНИЕ (редактура кода) Только DO-пункты. Временные тесты — можно. **Поведенческая нейтральность zh→ru обязательна** (см. приёмку). ### Фаза 5 — РЕВЬЮ (воркфлоу): изменения с разных точек зрения + функциональное Мульти-линзовый адверсариал (author≠reviewer): (i) корректность/поведенческая нейтральность (golden, детерминизм, снапшот); (ii) сеньор-код-ревью (Go-идиоматика, чистота сеамов, отсутствие велосипедов и над-инженерии); (iii) функциональное (пара резолвится, fail-loud на неизвестную пару, добавление 2-й пары = только данные). Находки чинить до сдачи. **Ревью НЕ должно генерить длинный минор-лист** — оно проверяет, что рефактор корректен и нейтрален, а не хантит косметику. ## Входные буллеты для синтеза (Фаза 2) **Буллеты ОРКЕСТРАТОРА (стартовое предложение — ПРЕСС-ТЕСТ ресёрчем, не имплементить слепо):** - Движок (`pipeline/`) — общий, язык-данных НЕ содержит. - Новый пакет `internal/lang/` (или лучшее по ресёрчу): интерфейсы `LangPack`/P1–P6 + загрузчик + реестр, **без самих данных**. - `configs/langpacks//*.yaml` + `/*.yaml`: 百家姓/суффиксы/частицы (zh), Палладий (zh-ru), регистр/числительные/гендер-местоимения (ru), единицы 时辰 (zh-ru). - Резолв по `Book.LangPair()`, снапшот-folded (как промпты). Добавить язык = положить каталог, **без перекомпиляции, без правок `pipeline/`**. - `golang.org/x/text/language.Tag` вместо `isRuTarget`/ручных рун-сетов (реестр языков с фолбэком; `x/text` уже в зависимостях). - НЕ трогать правильные алгоритмы: union-find, детерминированные сортировки, целочисленные пути — они верны; из движка уходят ДАННЫЕ, алгоритм остаётся. **Буллеты ВЛАДЕЛЬЦА:** язык вне `pipeline/`; сотни языков; библиотеки где уместно; чистый код + нормальные алгоритмы, стандарт «сеньор Google»; не упарываться на миноры; никакого rewrite-ради-rewrite. **Известный фикс-лист (реальные, рождены рубежом-2 D39.14 + §0.1-разбор — риды-along, не хантить сверх):** - **FL-1 (MINOR):** свернуть `bankMaxLines`/`bankTokenBudget` в `banknoteSnap` (`snapshot.go`) — сейчас `max_tokens += bankTokenBudget` wire-affecting, но не свёрнут → правка конста без бампа `bankParserVersion` = тихий re-bill на резюме. - **FL-2 (MINOR, observability):** `resumeFromChunkStatus` (`resume.go:22`) не ставит `BankFlags` → банкнота-телеметрия обнуляется на резюме готовых чанков; коммент «self-heals» ложен. Re-derive из сырого чекпоинта / не обнулять эти колонки на резюме / поправить коммент. - **FL-3 (PARTIAL, порт-fidelity):** `miner_emit.go:68` идёт по полному `mr.ranked`; референс капит `a3[:200]`/`[:30]` ДО фильтров (`eval/exp16/{alias.py:165, emit_owner_sheets.py:143,162,169}`) → карта подписи шумнее референса. Добавить top-N кап перед emission-фильтрами. - **Тест-путь:** абсолютные `/home/ubuntu/...` в `miner_parity_test.go` → env-var/`testdata`-относительные (тест-гигиена; не прод). ## Скоуп **IN:** ресёрч; изоляция языковых данных (движок→`lang`/`langpacks`); `x/text/language`-реестр; FL-1/2/3; тест-путь; доказательство общности «2-я пара = только данные» (минимальный второй langpack-скелет ИЛИ тест загрузки синтетической пары через сеам — НЕ полный ja→ru-контент). **OUT:** R1 драйвер-свитч (след. промт); пере-прогон; любая смена ПОВЕДЕНИЯ перевода zh→ru; полная ja→ru-реплика (отдельная задача); минор-хант. ## Гардрейлы (жёсткие) - **Поведенческая нейтральность zh→ru:** рефактор = перемещение ДАННЫХ; langpack-значения обязаны быть байт-равны прежним константам. Golden после = байт-стабилен С ТОЧНОСТЬЮ до одного нового version-поля (langpack-версия в снапшоте); НОЛЬ изменений вердиктов/wire/final. Один чистый resnapshot (масштаб — как chunkerVersion). Если langpack-путь меняет хоть один вердикт — это БАГ рефактора, не «улучшение». - **Снапшот-дисциплина:** langpack-данные wire-определяющи (майнер/чекеры/фертильность) → версия пакета фолдится в `snapshotID` (правка данных = громкий resnapshot, как `chunkerVersion`/промпты). Детерминизм: загрузка сортирована/версионирована, без map-order в выводе. - **Чистый код, сеньор-Google:** идиоматичный Go (`gofmt`/`vet`/`-race` чисто; обёртка ошибок `%w`; без глобального мутабельного стейта; table-driven тесты); **stdlib/`x/text` вместо велосипедов**; НО НЕ над-инженерия (union-find не превращать в «библиотеку»; не плодить абстракции без второго потребителя — а он есть: 2-я пара). Комментарии — как в окружающем коде (констрейнты, не пересказ). - **Инварианты 1–8 не трогать** (деньги/durability, снапшот, эхо-мина, детерминизм, экспорт-контракт, golden). - **$0 к провайдерам:** ресёрч — websearch + чтение кода; верификация — build/test/golden/фикстуры. LLM-вызовов перевода НЕТ. - **Неконсистентность/аномалия** — даблчек всеми тулзами (grep, git log, вендор-дока, websearch — правило двух направлений); реальное расхождение → эскалация запиской, не тихо. - Git: `.env` не читать; книга/производные вне git; PUML не рендерить; не коммитить. ## Приёмка (оркестратор — знай заранее) Пере-исполнение фикстур; спот-чек file:line; **golden байт-стабильность** (масштаб — только langpack-версия, ноль вердикт-правок); адверсариальный рубеж-2 (перемещение данных нейтрально? общность реальна — 2-я пара грузится без правок `pipeline/`? алгоритмы не сломаны, велосипеды сняты, над-инженерии нет?); проверка «не упоролись на миноры» (фикс-лист = DO-пункты с ценностью, не косметика). Затем лендинг → D-блок → R1-продолжение.