textmachine/docs/BACKEND_PLAN11_SESSION_PROMPT.md

181 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

> **⚠ СТАТУС: ЧАСТИЧНО ОТРАБОТАН — Block A + ядра ПРИНЯТЫ И ЗАЛЕНДЕНЫ (19.07, D39.13).** Сдано: WS2 ✅ (чанкер output-бюджет + edit-единицы + src→dst + golden) · WS1a/b/c-инфра ✅ (eager-clients, rate-guard, base/enriched split) · WS4-core ✅ (банкнота-парсер) · WS6-частично (конфиг-тай). **Резидуал R1R5** (волновой ИСПОЛНИТЕЛЬ · WS3-майнер · WS4-12-точек · WS5-чекеры · арм-конфиги) — точные дизайны в `backend/PACK11_REPORT.md` §Резидуал. **Промт ОСТАЁТСЯ АКТИВНЫМ:** сессия-продолжение стартует по нему + отчёту (читать ОБА; сданное не пере-строить — оно под тестами).
# Промт: сессия БЭКЕНД — единый пак по плану 11 (волновой раннер · чанкер/единицы · банк W1.5 · банкнота · чекеры · армы), 2026-07-19
> **Место в очереди (пост-D39.12):** исследовательская программа арх-ресета (D39D39.10) и дизайн-синтез
> (D39.11) ЗАВЕРШЕНЫ. План **`docs/architecture/11-implementation-plan.md` РАТИФИЦИРОВАН (D39.12)** после трёх
> рубежей верификации ($0-симуляции с числами — исполнены и воспроизводимы). Эта сессия — СТРОЙКА строго по
> нему. **Решение владельца: весь объём — ОДНОЙ сессией**, четырьмя блоками с чекпойнт-ревью между.
## Кто ты и что сдаёшь
Бэкенд-сессия TextMachine. **Зона записи: `backend/`** (вкл. `configs/`, `prompts/`); всё остальное читать
можно, править нельзя (расхождения — пингом через отчёт/владельца). **НЕ коммитить** — лендит оркестратор
после приёмки (git-гардрейл CLAUDE.md: никаких reset --hard/rebase/checkout поверх грязного дерева). Сдаёшь:
1. Код WS1WS6 по плану + тесты из (д)-секций (пины/golden/race/kill-9).
2. **`backend/PACK11_REPORT.md`** — per-буллет чек-лист (✓/девиация+причина), тест-логи, golden-диффы,
раздел «багфиксы вне плана», раздел «структурные переносы» (если рефакторил), residual.
## Онбординг (порядок чтения, ~45 мин)
1. `CLAUDE.md` (гардрейлы: `.env` НЕ читать · 18+ уровень 3 · PUML не рендерить · книга и производные ВНЕ git)
`backend/README.md` (**инварианты 18 — ломать нельзя, каждый закреплён тестами**) →
`docs/architecture/03-implementation-notes.md`.
2. **`docs/architecture/11-implementation-plan.md` ЦЕЛИКОМ — это твоя спека.** Структура: WS1WS6, каждый
(а) что менять / (б) алгоритм / (в) конфиг+снапшот / (г) исполненная $0-верификация с числами /
(д) тест-спека ПОСЛЕ стройки / (е) открытое; §7 порядок · §8 манифест resnapshot · §9 диспозиции ·
§10 развилки владельца · §11 гейтнутые армы. План верифицирован трижды — **не пере-решай его решения**;
несогласие или найденная дыра = эскалация запиской, не тихая девиация.
3. `docs/architecture/05-decisions-log.md`: карта актуальности в шапке + D39D39.12 подробно;
`09-target-architecture.md` §0.1 (**инвариант общности — НЕСУЩИЙ:** никакой захардкоженной структуры
книги/пары; пара = ось данных).
4. **`docs/experiments/00-provider-quirks.md`** — ПЕРЕД любым кодом около адаптеров/конфигов моделей
(вкл. свежую запись «mistral rate-limiter» в §Транспорт).
5. Референсы по мере работы: `eval/exp16/*.py` (**frozen miner-v1 — эталон порта WS3**, SHA в exp16 §1.10),
`eval/design11/` (симуляции/фикстуры плана — твои golden-входы; python — `eval/.venv`), `research/20` §B3
(банкнота), `research/19` §B (контекст чанкера). Авто-память сессий — point-in-time, верь коду/докам.
## Порядок работы (по §7 плана; единый пак, 4 блока, гейты между)
- **Блок A** = WS1 (волновой раннер) + WS2 (чанкер-бюджет + edit-единицы) — несущий каркас, разблокирует всё.
- **Блок B** = WS3 (Go-майнер W1.5) + WS4 (банкнота, 12 точек).
- **Блок C** = WS5 (DC-чекеры + omission-бэкстоп + данные пакета zh-ru + `tmctl export --pairs`).
- **Блок D** = WS6 (армы конфигом + связка с rate-guard + атрибуция) — конфиг-пак.
После КАЖДОГО из блоков A/B/C — чекпойнт-ревью (см. §Верификация). Единый `--resnapshot` по §8 в сессии
**НЕ исполнять** (плановое событие после приёмки, одна переоплата); но **golden re-capture** под
ратифицированную смену поведения — исполнять по мере: маскированный структурный дифф обязан быть объясним
(только хеши/версии/новые поля) и прикладывается в отчёт каждый раз.
## Чек-лист исполнения (буллеты; ТОЧНАЯ спека — в плане; при расхождении буллета с планом побеждает ПЛАН)
**WS1 (план §1):**
- Eager-build ВСЕХ клиентов в W0 (`Stages[].Model EscalateTo`); `client()` в волнах read-only + громкий
отказ на miss (закрывает гонку `runner.go:171-181`; трипваер на будущую 3-ю модель-ось).
- W0-precompute sticky-цепочки (`Select` — чистая src-производная функция). Golden: инъекц-байты precompute ≡
байтам последовательного раннера над НОВЫМ чанк-сетом WS2, fresh↔resume.
- **Пер-волновой снапшот:** `snapshot_W1` (draft-стадии + base-bank = хеш approved `Source∈{seed,ruby}`),
`snapshot_W2` (edit-стадии + enriched-bank = все approved вкл. mined). Механика для ОБОИХ состояний
`PostcheckGate` — по §1(в).
- **Инвариант секвенирования (НЕСУЩИЙ):** W2 НИКОГДА не пере-рендерит/пере-хеширует draft-стадию — редактор
читает черновик по `final_hash`-чекпоинту. Пин: draft `request_hash` байт-стабилен под обогащённым банком.
- W1.5-стоп-механика: стоп после W1 → карта подписи → подпись владельца → **персист дельты ОТДЕЛЬНЫМ
mined-write-путём (штамп `Source:mined`; НЕ через `loadGlossarySeed` — тот хардкодит `Source:seed`,
`memseed.go:131`)** → resume в W2. Подпись mid-run трогает ТОЛЬКО mined-строки; правка seed/ruby-строки
после W1 = громкий resnapshot-стоп, не тихий re-bill (пин-тест).
- Деньги под ∥: Reserve/settle из N горутин через single-writer; kill-9-тест с N живыми резервами
(`committed==SUM`, каждый потерянный вызов пере-оплачен один раз); overshoot-тест `cost>estimate`.
- Scheduler-aware ценовые окна (конфиг провайдера, не хардкод; DeepSeek ×2 = риск-пин до ре-чека 24.07) +
**пер-модельный rate-guard**: семафор конкуренции `models.yaml max_concurrency` (+опц. пейсинг);
транспорт-ось, НЕ снапшот. `waves.workers` конфиг (НЕ `Fanout` — тот занят C2).
- Grep legacy DeepSeek-слагов в `backend/configs/` (прод не задет по плану — подтверди; eval-долг только
отметь в отчёте, eval/ не правь — чужая зона).
**WS2 (план §2):**
- Бюджет draft-чанков в ВЫХОДНЫХ токенах: `est_out = 1.1978·cjk + 0.3852·other` (конфиг per-pair,
снапшот-folded `segmentationSnap`); классы символов — РЕАЛЬНЫЕ `unicode.RangeTable` из `EstimateTokens`
(НЕ ord-диапазоны скрипта — общность §0.1). Пин: `target_out=1797`**56 чанков** на 25 главах.
- Edit-единица = глава; **`EditCeilingOut=3200` (ратифицированный дефолт)**; глава >3200 → абзацный сплит
(never-split-paragraph, lossless tiling). Пин: 25 глав → **37 единиц** (фикстура `ws2_chunk_sim.py`).
8000-арм НЕ открывать (гейтнут Q2a).
- `Chunk` аддитивно: `EstOut`, `OversizedSentence` (мега-предложение = passthrough + флаг, БЕЗ клауза-сплита),
`EditUnitID`. Контракт Chapter/ChunkIdx/Text цел.
- Снос мёртвых `STMDepth`/`OverlapTokens` (`config/pipeline.go:47-48`) — carryover не строим.
- **src→dst-формат** `renderEditorConstraintBlock` (CONFIRMED-only дисциплина ЦЕЛА) + выделенный
**`render-format-version`** снапшот-компонент (НЕ `memoryMatchVersion`).
- Сайзинг max_tokens редактора: существующий механизм от `prev`-черновика (`stagerun.go:87-90`) — НОВОЙ
формулы НЕ вводить (пост-верифай F8); проверить достаточность под единицу-главу тестом.
- **Инъекция W2-единицы = СВЕЖИЙ `Select` по тексту ВСЕЙ единицы над enriched-банком** (sticky на уровне
глав вырожден); НЕ реюзить per-чанк memSel из W0 (тот над base-банком). Глоссарий-бюджет Select для
главы-единицы — открытый пункт §2(е): реши инженерно, при сомнении эскалируй.
**WS3 (план §3):**
- `miner*.go`: порт V-A→V-C **строго по frozen exp16 `arms.py`** (точные пороги §3(б); детерминизм-контракт:
сорт-ключи, целые, версии, tie-break). **Лемматизатор: дефолт B** — Палладий-подканал в Go-дефолте
дропается, зависимые фикстуры пере-пинятся (古月 21→22); **Палладий-ИНВАРИАНТНЫЕ гарантии — EXACT:
13618-кандидат-СЕТ (членство), recall 0.9649/0.9318, катастроф-скрин 方源/蛊/蛊师 ранги 0/1/2 ∈top-50.**
- Алиас-ярус-1 (R4-блоки ПЕРВЫМИ; юнит-фикстуры: 族长≠四代族长, компози-гард 古月+族长, кап-лемма-гейт
«найти»), консолидация §C2 (канон по ВСЕМ вхождениям; **майнер по построению НЕ пишет approved**), эмиссия
сид-дельты (схема `seedTerm` БЕЗ новых полей; эмиттер реюзит subsumption+fragment-фильтры, не сырой дамп).
- `Source:"mined"` (аддитивная миграция store) + mined-write-путь + `tmctl seed-lint` (сухой прогон
фейл-лаудов реального `loadGlossarySeed` по дельте).
- Паритет Go↔Python: **Python = референс**; при расхождении чинить Go; доказанный баг референса → эскалация.
**WS4 (план §4):**
- Все 12 интеграционных точек с пин-тестами (список §4(д)). Несущие: срез `⟦TM-BANK-v1⟧` ДО `classifyOutput`;
derived-checkpoint ТОЧНАЯ формула с NULL-байтами (`"tm-banknote-v1\x00"+reqHash+"\x00"+stripped`);
**re-point `final_hash` OK-пути draft на derived — ПОСЛЕ резолва эскалации** (`stagerun.go:163`, потреблять
`last.stripped` — эскалированный черновик тоже очищен); `banknoteSnap{enabled, parser_version}` в
`snapshotID()`; инструкция сноски — В ФАЙЛ промпта переводчика (PromptSHA256 двигается); генерации
**finish=stop-only**; телеметрия `n_banknote_lines`/`banknote_parse_fail`/`banknote_truncated` лауд.
- Пин: пере-парс 95 строк exp16 = 0 fail (фикстура `ws4_banknote_verify.py`); толерантный обрез — синтетика.
**WS5 (план §5):**
- Чекеры DC1 (时辰/единицы) / DC2 (масштабы чисел) / DC6 (регистр-негатив-лист) / DC7 (editor-инверсии
grade/role) — cheapgates-класс, target-gated, **наблюдаемость НЕ гейт** (landing гейтнут FP-замером §5(д)
на свежем прогоне).
- **DC3: инъекция пола — ВСЕ ТРИ состояния, вкл. hidden-мандат** (безродовые конструкции / surface-«он» до
`until_ch` — фикс класса Бай Нинбин D19.3); детерм. чекер — ТОЛЬКО male/female, паратекст-чанки исключены;
hidden-чекер НЕ строить (Ф2-кореференция).
- DC5-детекцию НЕ строить (74%/42% FP) — пак-локусы (данные) + слот сноски; рендер-политика за владельцем.
- Omission-бэкстоп: substring-матч `{dst, decl.forms, aliases}` + лёгкий детерминированный ru-стеммер
(Go-либа; БЕЗ pymorphy3); verdict-каскад и `inflection_gap`-флаг по плану.
- Данные пакета пары zh-ru (таблицы единиц, негатив-лист, verse-локусы) — версионируемый снапшот-folded пакет.
- `tmctl export --pairs` (source-join в Export уже есть) — пред-условие FP-замера DC1/DC2.
**WS6 (план §6):**
- Армы редактора = КОНФИГ (yaml/models: glm-5 / mistral-large-latest / deepseek-v4-pro), снапшот per-арм,
атрибуция арма в export/report; `echo_mine_test` обновить под варианты; editor pinned (эскалации нет — D12).
- mistral-арм разблокируется rate-guard'ом из WS1 — проверь связку тестом (семафор реально ограничивает).
## Свободы и рамки (решения владельца, 19.07)
- **Рефакторинг/перенос кода по папкам — РАЗРЕШЁН и приветствуется:** архитектурная чистота важнее
минимальности диффа. Границы: инварианты 18, контракты плана и поведение вне скоупа не менять молча;
крупные структурные переносы — отдельным разделом отчёта (ревью-абельность лендинга).
- **Без велосипедов:** реюз stdlib и существующих механизмов репо (эталоны: `coverageSnap`-фолд,
derived-checkpoint, role-registry, `baseRequestLog`, `config→stage-list`). Новая внешняя зависимость —
только с обоснованием в отчёте (канон Go: минимум зависимостей).
- **Временные тесты/харнесы** — можно и нужно: `_test.go` рядом с кодом; одноразовые скрипты — в scratchpad,
НЕ в репо; временное помечай.
- **Баги по пути** — чинить разрешено, каждый в раздел «багфиксы вне плана» (лендинг скоуп-раздельный).
- **Не костылить:** честная реализация (б)-алгоритмов; хак «чтобы тест прошёл» запрещён; недоделка =
явная строка residual, не тихий пропуск.
- **Go-каноны:** `gofmt`/`go vet`/`-race` чисто; идиоматика (обёртка ошибок `%w`, контексты, без глобального
мутабельного стейта, table-driven тесты); комментарии — в стиле окружающего кода (констрейнты, не пересказ).
- **Неконсистентность** (план↔код↔доки↔вендор): НЕ гадать — даблчек всеми тулзами (grep по репо, git log,
доки, официальная вендор-дока/вебсёрч — правило двух направлений CLAUDE.md); реальное расхождение → СТОП
по этому куску + эскалация. Провайдер-аномалия → сначала вендор-дока, интерпретацию без сверки не вшивать.
- **$0 к провайдерам:** LLM-вызовы НЕ делать (ни облако, ни локаль) — вся верификация build/test/golden/
фикстуры. Wire-корректность доказывается голденом и байт-диффами, не живыми вызовами.
## Верификация (мандат самопроверки владельца 12.07 — ОБЯЗАТЕЛЕН; + чекпойнт-ревью)
1. **Ревью исполнением непрерывно:** `go build ./... && go vet ./... && go test -race ./...` после каждого
куска; «зелёное» подтверждай ЛОГОМ, не словом (урок D37: «0 ошибок» ≠ 0 ошибок).
2. **Фикстуры плана — прогонять:** sticky-байты ≡ sequential · 56 чанков @1797 · 37 единиц @3200 ·
miner-паритет (инвариантные EXACT; зависимые — пере-пин B) · банкнота 95/0 · kill-9 с N резервами ·
seed-lint 0 фейл-лаудов · draft request_hash стабилен под обогащённым банком.
3. **Чекпойнт-ревью после блоков A/B/C** (адверсариальный воркфлоу, author≠reviewer, refute-by-default), три
линзы: (i) **алгоритм-vs-план** — реализация против (б)-секций построчно, детерминизм (сорты/целые/версии);
(ii) **сеньорское код-ревью** — Go-идиоматика, конкуренция, границы ошибок, чистота сеамов;
(iii) **функциональное** — деньги/resume/снапшот/гейты end-to-end на фикстурах. Находки чинить ДО
следующего блока; сводку каждого чекпойнта — в отчёт.
4. **Финал:** полный многоосевой адверсариал по паку (деньги/resume · снапшот/волны · детерминизм ·
банк/банкнота · чекеры · экспорт · код-качество) + `PACK11_REPORT.md`.
5. Golden re-capture — только под ратифицированную смену поведения; маскированный дифф прикладывать всегда.
## Что НЕ строить (гейтнуто/анти-скоуп — план §0/§11; в код не тащить)
Крупно-главный арм >3200 out (Q2a-гейт; потолок остаётся конфигом) · наполнение `logical`-стратегии чанкера
(сеам без контента) · carryover/lookahead · diff-редактор · reflow-отдельным-пассом · W2.5-швейный пасс ·
LLM-сегментация/ML-сцены/эмбеддинг-границы/RAG-оверлап · DC5-детерм-гейт · DC3-hidden-чекер · локальный
9B-споттер · жанр-паки · платные вызовы. Единый resnapshot — НЕ в этой сессии.
## Эскалации и отчёт
Настоящие развилки (конфликт плана с кодом, нереализуемость (б)-алгоритма, скоуп/деньги, дыры плана) —
эскалируй БЫСТРО короткой запиской через владельца (развилка + варианты + твоя рекомендация); это норма и
поощряется (образцы эры №6 — в D-логе), тихие девиации запрещены. Приёмка оркестратора после сдачи:
верификация исполнением (build/race/пины/golden-репликация) + адверсариальный рубеж-2 по сырью → лендинг →
единый resnapshot → пере-прогон 310 глав → чтение владельца (планка 2 претензии).