138 lines
16 KiB
Markdown
138 lines
16 KiB
Markdown
# Промт: сессия БЭКЕНД (промежуточная) — изоляция языковых данных из пайплайна + алгоритмы/чистота кода, 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/<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 += 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-продолжение.
|