textmachine/docs/archive/prompts/BACKEND_ARCH_CLEANUP_SESSION_PROMPT_2026-07-19.md
2026-07-19 17:47:52 +03:00

16 KiB
Raw Blame History

⟶ ОТРАБОТАН → 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 (инварианты 18) → 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 (плагины P1P6) — 6 интерфейсов языковых данных уже спроектированы; эта сессия делает их data-backed и вне pipeline/.
  4. D-лог D39.12D39.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/P1P6 + загрузчик + реестр, без самих данных.
  • 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-я пара). Комментарии — как в окружающем коде (констрейнты, не пересказ).
  • Инварианты 18 не трогать (деньги/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-продолжение.