16 KiB
⟶ ОТРАБОТАН →
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. НЕ коммитить (лендит оркестратор). Сдаёшь:
- Код рефактора + фиксов + тесты; поведенчески НЕЙТРАЛЬНО для zh→ru (это РЕФАКТОР-перемещение данных, не смена поведения — доказывается байт-стабильностью golden с точностью до одного version-поля).
backend/ARCH_CLEANUP_REPORT.md— результаты каждой фазы-воркфлоу (ресёрч-буллеты, синтез, фикс-лист с диспозициями do/defer/don't, лог исполнения, ревью-вердикт), golden-дифф, «багфиксы вне плана», residual.
Онбординг
CLAUDE.md(гардрейлы) →backend/README.md(инварианты 1–8) →docs/architecture/09-target-architecture.md§0.1 инвариант общности (любая книга/пара/структура; пара = ось данных — это север) + §2 слой-2.docs/architecture/10-prompt-architecture.md— прецедент, который расширяем: промпты УЖЕ живут pair-keyed (Stage.Prompts[pair]+PromptPathFor+ fail-loud + снапшот-фолд). Языковые данные получают ту же форму.docs/architecture/11-implementation-plan.md§3 §B5 (плагины P1–P6) — 6 интерфейсов языковых данных уже спроектированы; эта сессия делает их data-backed и внеpipeline/.- D-лог D39.12–D39.15;
docs/experiments/00-provider-quirks.md. - Грунтовка по коду (где сейчас зашит язык):
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-findclusterAlias— оставить)? Где 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/<lang>/*.yaml+<pair>/*.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 += bankTokenBudgetwire-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-продолжение.