# Промт: бэкенд-сессия — пакет фиксов стратегического ревью (D15/D16, 2026-07-09)

---

Ты — **бэкенд-сессия** TextMachine, зона записи `backend/` (+ твоя запись в `docs/PROGRESS.md` §Бэкенд). Корневой `CLAUDE.md` уже в твоём контексте — гардрейлы и зоны оттуда обязательны (**`.env` не читать; DeepSeek thinking НЕ отключать; слаги моделей не менять; коммиты en ≤30 слов без Co-Authored-By**). `docs/` (кроме своей секции журнала) и `eval/` не редактировать — расхождения пингом оркестратору в PROGRESS.

## Онбординг (порядок чтения)

1. `backend/README.md` — карта пакетов + 7 инвариантов «ломать нельзя».
2. **`docs/architecture/05-decisions-log.md` — контракт; твой мандат = D15.3, D16, D13.6** (блок «Пост-ревью решения D13–D17»).
3. `docs/architecture/07-strategic-review.md` §4.3–4.4 — детальные трассы находок (каждая воспроизведена исполнением; номера строк могли сместиться — сверяй по своему коду).
4. По ходу: `03-implementation-notes.md` (контракты), `00-provider-quirks.md` (перед любой правкой адаптеров).

Дисциплина проекта: каждый фикс — с регресс-тестом, **mutation-verified** (реверт фикса валит именно его тест); финал — агентское адверсариальное селфревью (несколько дименсий → независимая верификация каждой находки); `go build/vet/test ./... -race` зелёные и `tmctl report` за $0 — перед сдачей. Живые LLM без нужды не звать.

## Задача 1 — гигиена (первым, мелко, до механики)

1a. **Лгущие комментарии resume**: `runner.go:~156-160` и `coverage.go:~29-33` обещают «re-classify from checkpoint for FREE / no re-bill» — это верно ТОЛЬКО внутри неизменного снапшота; после `--resnapshot` ВСЕ чекпоинты промахиваются (snapshotID вшит в RequestHash, `render.go:~212-214`) и книга переоплачивается (воспроизведено ревью: 2→4 оплаченных вызова на байт-идентичных телах). Механику НЕ менять — только честные комментарии (+ упоминание D15).
1b. **Бамп edit `prompt_version`** `v0-draft` → `v1-monolingual` в `pipeline-c1.yaml` и `pipeline-c2.yaml` (D1-уточнение №3 не исполнено: коммит 6a68dfd сменил SHA editor.md, лейбл остался — один лейбл на два SHA). Это сменит снапшот — осознанно, боевых прогонов ещё не было.
1c. Битая docs-ссылка `capability.go:3`: «03-decisions-log» → «05-decisions-log».

## Задача 2 — D16: фиксы границ доверия памяти (ядро НЕ трогать — F1/нормализация/спойлер/инъекция чисты)

2a. **Полисемия same-src (D16.1).** Репро: две approved-записи один src / разные sense / разные dst / пересекающиеся (или дефолтные 0/0) окна → обе инжектятся CONFIRMED (`memory.go:~198-204,299-306` — keyOwners), модель получает противоречивые авторитетные строки; post-check даёт гарантированный confirmed-miss (`mempostcheck.go:~63-75`), с `postcheck_gate=true` — детерминированный livelock чанка. Гарды не ловят: `memseed.go:~155-163` требует равного sense, injectivity смотрит dst-сторону. **Рекомендуемый фикс: fail-loud в `loadGlossarySeed`** — same-src + different-sense + different-dst с пересекающимися окнами = ошибка сида (запасной вариант: даунгрейд обоих совпадений в AMBIGUOUS). ⚠ `memseed_test.go:~100-103` сейчас благословляет кейс («distinct senses should be allowed») — пересмотри тест под новый контракт; одноиероглифный src (道) отсечён A3-баном — не регресси.
2b. **Sticky наследует disposition (D16.2).** Репро: collision-prone ключ (≤3 фонетических) фаерится ВНУТРИ чужого слова → честно AMBIGUOUS, но id попадает в activeIDs без disposition (`memory.go:~323`) → в чанке N+1 sticky даёт status-based CONFIRMED (`memory.go:~391-398`, via=="sticky" обходит collision-чек), минуя post-check (`mempostcheck.go:~64`), прямо в editor-констрейнты (`memory.go:~465`). Фикс: наследовать disposition исходного матча в sticky-кэрри ИЛИ класть в activeIDs только CONFIRMED-ids. Бамп `memoryMatchVersion`.
2c. **Source-граница для фонетических ключей ≥4 (D16.3).** `collisionProneKey` покрывает только significantLen ≤3 (`memory.go:~62-64`), Aho-Corasick границ не знает (`memory.go:~552-581`) → approved «rose» = CONFIRMED внутри «roseanne»; 4-kana ключ — внутри компаунда. Фикс: для фонетических скриптов (латиница, кана) матч валиден только при не-буквенных (или чужескриптовых) соседних рунах; Han не трогать (сегментации нет — это осознанно). Асимметрия с target-`containsWholeWord` закрывается. Бамп версии.
2d. **Ruby-reading как поверхность (D16.4), минимальный вариант:** reading НЕ выбрасывать для ручных терминов (`memseed.go:~217-220`) — сделать его alias соответствующей manual-записи (кана-написание имени становится матчимым). Auto-кандидаты без dst остаются нематчимыми (осознанно, до B6). Плюс: задокументируй в `backend/README.md` чек-лист ja-книги («kana-написания сид-имён — aliases руками до этого фикса/сверх него»).

## Задача 3 — D15.3: `tmctl status` + `redrive` (контракт D12, «Прогресс — единственный реальный пробел»)

3a. `tmctl status --config book.yaml`: READ-ONLY проекция `chunk_status`+`jobs`+spend+request_log (0 LLM, 0 replay); `--json` со стабильными enum disposition/flag_reason; **book manifest на snapshot** (честный знаменатель N/M); unit-счёт done/in-progress/flagged/skipped/pending (% только из N/M, никакого синтетического time-бара); flagged≠failed, всегда REASON; паспорт качества главы (total/ok/flagged/skipped, worst flag_reason, coverage-вердикт, $); деньги committed/reserved/ceiling% + projected book cost; ETA от EWMA — вторично. Заодно доложи телеметрию эскалации на flagged-resume (отложенная находка №6 внешнего ревью Вехи 2.5 — ей нужна колонка escalation в chunk_status).
3b. `tmctl redrive`: точечная переатака ФЛАГНУТЫХ чанков (DispOK не трогать — D12) без `--resnapshot`: выбор по (chapter,chunk) и/или flag_reason; сброс терминального флага + ре-ран только выбранных; redrive получает свежий retry/escalation-бюджет (явная команда оператора — задокументируй семантику). Деньги: redrive-вызовы биллятся штатно (reserve/settle+checkpoint).

## Задача 4 — D15.2: СПЕКА content-addressed resume (документ, НЕ код)

Полная спека (в `03-implementation-notes.md` новым разделом либо отдельным доком — реши сам, скажи оркестратору): как переиспользовать чекпоинты при смене снапшота без потери snapshot-гарантий. Вход: `msgsContentHash` уже существует (`render.go:~233-249`), но заперт условием `cs.SnapshotID == snapID` (`runner.go:~874`). Ключевые вопросы спеки: разделение «wire-байты» vs «вердиктные версии» (classifier/coverage) в снапшоте; когда байт-идентичный запрос легально переиспользовать; что с re-classify по новым порогам; ось безопасности — никакого тихого расходящегося ре-пэя (класс F1). Гейтит онгоинг Ф1.5 — реализация ПОСЛЕ утверждения спеки оркестратором.

## Задача 5 — D13.6: reasoning-буфер в `EstimateUSD` для additive-провайдеров

xAI биллит reasoning ПОВЕРХ completion (`pricing.go:~108-111` признаёт овершут). Для think-арма пилота (D13.6): (а) `EstimateUSD` резервирует явный reasoning-бюджет для провайдеров с `reasoning: additive`; (б) fail-fast валидация «стадия с reasoning low|medium|high на additive-провайдере без буфера» (сейчас конфиг загрузится молча — `pipeline.go:~220-224`; контраст с эхо-миной, у которой структурный гейт есть). Снимает D6.2-блокировку think-ON на grok.

## Задача 6 — выборочная перепроверка отсевов прошлых ревью (дёшево, важно)

Ревью доказало один ложно-негативный отсев 44-агентки (sticky-апгрейд, 0/3 — рациональ не проверялась исполнением). Подними из PROGRESS (§«44 агента», ~строка 494) список отсеянных кандидатов и миноров; перепроверь адверсариально С ИСПОЛНЕНИЕМ хотя бы все 0/3-отсевы (временные тесты — удалить после, `git status backend/` чист). Подтверждённые — в фиксы этой же сессии; отчёт по каждому — в журнал.

## Приёмка сессии

`go build/vet/test ./... -race` зелёные; каждый фикс mutation-verified; `tmctl report` $0; `tmctl status`/`redrive` продемонстрированы на example-книге (моки/чекпоинты, $0); селфревью проведено, находки исправлены; запись в `docs/PROGRESS.md` §Бэкенд (итоги, техдолг, вопросы оркестратору) + спека D15.2 сдана на утверждение. Порядок задач 1→2→3 жёсткий; 4–6 — параллелятся по твоему усмотрению.
