Ratify D39.86: coldrun-b accepted, floor-16000 falsified, echo mine reconfirmed on live weights, bank-role reasoning gap and target-language screen opened as rows

This commit is contained in:
Claude (backend session) 2026-08-02 14:05:42 +03:00
parent 1ecf5c2f1a
commit 84e2fe0fd7
6 changed files with 475 additions and 12 deletions

File diff suppressed because one or more lines are too long

View file

@ -15,7 +15,7 @@
- `experiments/` — эмпирика полигона: [00-provider-quirks.md](experiments/00-provider-quirks.md) — **читать перед любым вызовом провайдера**; [08-cost-model-v2.md](experiments/08-cost-model-v2.md) — денежная модель; [09-pilot-protocol.md](experiments/09-pilot-protocol.md) — пилот Ф2.5; остальные 0116 — отчёты закрытых экспериментов (судьба — в баннерах/D-логе).
- `research/` — фактура ресёрчей 0122; у принятых — ревью-шапки, часть тел под ⚠ superseded: **читай баннер прежде содержимого**. Ключевые для навигации: 15 голос · 16 ридер-IDE · 17 внешняя критика · 18 рычаги качества · 19 нарезка · 20 банк-майнинг · 21 обзор транспорта · 22 доменные харнессы · 23 шов движок↔платформа (читать перед любым кодом стыка).
- [PROGRESS.md](PROGRESS.md) — журнал: CURRENT-STATE + **ЕДИНЫЙ БЭКЛОГ** (единственный трекер) + живой хвост хроники. НЕ источник решений.
- Активные хендофф-промты сессий (состав обновляется при каждом лендинге — норма D39.80): [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояния не дублирует) · [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md) (полигон, отложен). · [BACKEND_COLDRUN_DEBUG_SESSION_PROMPT.md](BACKEND_COLDRUN_DEBUG_SESSION_PROMPT.md) (**текущий бэкендный**: ре-проба flash + отладочный холодный прогон coldrun-b). Фронт-промт — в чужой зоне `frontend/docs/`.
- Активные хендофф-промты сессий (состав обновляется при каждом лендинге — норма D39.80): [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояния не дублирует) · [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md) (полигон, отложен). **Активного бэкендного промта нет:** coldrun-b отработан фазами A/B и заархивирован (D39.86) — фаза C переиздаётся ПОСЛЕ решения владельца по развилке строки 74. Фронт-промт — в чужой зоне `frontend/docs/`.
- Зоны фронта (чужие, читать при касании стыка; каждая ведёт СВОЙ зонный бэклог — единый бэклог их строк не принимает, D39.84): [../frontend/](../frontend/) — веб-интерфейс: промт фронт-сессий S0S7 + [STACK_DECISIONS.md](../frontend/docs/STACK_DECISIONS.md) (пины версий точными числами и ловушки, сверены с вебом 02.08) + [BACKLOG.md](../frontend/docs/BACKLOG.md) · [../platform/](../platform/) — SaaS control plane: README-заглушка + [BACKLOG.md](../platform/BACKLOG.md).
- `archive/` — история ([правила архива](archive/README.md)): закрытые промты (`prompts/`) · отчёты с ревью-шапками (`reports/` — на них ссылаются приёмки) · исполненные арх-доки (`architecture/`) · слайсы хроники `PROGRESS-*.md`. Инструкции оттуда не исполнять.
- Диаграммы: [../backend/docs/components.puml](../backend/docs/components.puml) · [../backend/docs/pipeline.puml](../backend/docs/pipeline.puml) — дом рядом с кодом (D39.80), правятся бэкендом одним коммитом с кодом; вручную НЕ рендерить (владелец смотрит PlantUML-расширением VS Code).

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,8 @@
> **⟶ ⚠ АРХИВ — ОТРАБОТАН ЧАСТИЧНО, ИНСТРУКЦИИ НЕ ИСПОЛНЯТЬ (оркестратор №10, 02.08.2026).**
> **Исход: фазы A и B ИСПОЛНЕНЫ и ПРИНЯТЫ (D39.86) за $0.114378 из потолка $0.15; фаза C НЕ ЗАПУСКАЛАСЬ** — её условие («здоров по ВСЕМ критериям») нарушено замером: 8 пустых ответов из 9 на боевом потолке. Заморозка чекпойнтом объявлена этим же промтом легитимным исходом (§0) и таковой признана.
> Отчёт с ревю-шапкой и всеми поправками приёмки: [../reports/COLDRUN_B_DEBUG_2026-08-02.md](../reports/COLDRUN_B_DEBUG_2026-08-02.md). Решение — [../../architecture/05-decisions-log.md](../../architecture/05-decisions-log.md) D39.86.
> **Что осталось живым:** фаза C переиздаётся ОТДЕЛЬНЫМ промтом ПОСЛЕ решения владельца по развилке строки 74 — стенд `~/books/gu-zhenren/coldrun-b/` собран, $0-проверен и стоит нетронутым. Переиздание обязано учесть, что появилось после выдачи этого промта: правка по строке 104 (у бэнк-ролей нет ручки reasoning — без неё банк не собирается), строка 46 (экран целевого языка), новые вендор-факты quirks п.3а/п.10. Приор §3 «нужен амендмент `echoMineViolation`» — ОТОЗВАН для стадийной ручки и ОСТАЁТСЯ в силе для бэнк-ролей.
# Промт бэкенд-сессии: РЕ-ПРОБА FLASH + ОТЛАДОЧНЫЙ ХОЛОДНЫЙ ПРОГОН С АВТОБАНКОМ (строка 74 → контроль всех узлов; деньги потолками)
**Выдан 02.08.2026, оркестратор №9; санкция владельца 02.08 («надо идти и делать холодный прогон с контролем бэкенда; цель — отладка бэкенда»).** Ты — бэкенд-сессия TextMachine с двойной ролью: подготовка/верификация готовности → контролируемый платный прогон с отладкой каждого узла. Зона: `backend/` + стенд `~/books/gu-zhenren/` + свой отчёт в `docs/archive/reports/`. НЕ коммитить — лендит оркестратор. **Первый деливерабл — эхо-блок ≤10 строк** (первым сообщением ДО работы: как понял скоуп / фазы и их СТОП-точки / потолки денег / что вне скоупа; подтверждения не жди — работай до СТОП-условий).

View file

@ -0,0 +1,421 @@
> **⟶ РЕВЮ-ШАПКА ОРКЕСТРАТОРА №10 (02.08.2026, приёмка → D39.86). ВЕРДИКТ: ПРИНЯТО. Заморозка фазы C — легитимный исход по D39.83, не провал.**
>
> **Пере-проверено исполнением (не чтением):** батарея вся зелёная независимо — `build`/`vet`/`vet -tags live` exit 0 · `go test -race -count=1 ./...` все пакеты `ok` · майнер-парити EXACT (`n=13618 catastrophe{方源:0 蛊:1 蛊师:2 古月:22} recall@proposed=0.9655`) · labels-фриз 5/5 ячеек (k2 34/1/6/51 · k4_inverse 3/0/1/71 · k4a 0/0/0/348 · k4b 10/1/36/99 · K6 AFTER 1/6/0/251) · голден PASS · 5 новых тестов наблюдаемости PASS. **Деньги пере-выведены мной из СЫРЬЯ** (`sqlite3` read-only по четырём БД пробы, пересчёт провайдерских `usage`-колонок по вендор-ценам мимо `ledger.CostUSD`): леджер **$0.114378**, независимый путь **$0.099267**, разница **$0.015111** = три `estimated`-строки декод-фейлов (строка 78 живьём); инвариант `committed ≡ Σ checkpoints` держится **во всех четырёх** проектах до 6-го знака (не только на optB). Живая проверка новой строки `BANKNOTE` на БД coldrun-a воспроизвела `lines=182 over 18/20 chunk(s) · parse-fail chunks=3`, sha256 БД до/после идентичен. Все несущие счётчики §3.2/§3.4а пере-выведены из `chunk_status`/`request_log` и сошлись (18/20 · 20/22 stop · эхо 3/20 и 4/20 · терминолог 1/5 и 5/5 · 0 из 9 при 8496 · 4 из 5 пустых при 16992). Порог 6/6 подтверждён артефактом, и оговорка честна: `元石` (4 вхождения) и `灵泉` (1) стоят в `prompts/zh-ru/classifier.md` дословно, остальных четырёх там **0** ⇒ дискриминирующая часть 4/4 — настоящая.
>
> **Вердикты 9-осевого refute-воркфлоу (скептик + независимый арбитр на каждую ось):** CONFIRMED — Д1 (механизм и якорь `chunkrun.go:52` точны, воспроизведено на самом артефакте) · Д2 · Д4 · Д3 (слом live-рига бисектнут до коммита D39.64) · карантин пробы C (боевой `models.yaml` побайтно = `git show HEAD:`, гейт цел и функционален) · стенд ≡ эталону. PARTIALLY_CONFIRMED — §3.1 и §3.3 (поправки ниже).
>
> **Поправки приёмки — читать вместе с телом (тело НЕ переписано, дисциплина «отчёт — артефакт сессии»):**
> 1. **§3.3 «посылка строки 74 неверна» — верно ТОЛЬКО про стадийную ручку.** Для бэнк-ролей посылка ЖИВА: поля `reasoning` у синтетической `config.Stage` нет, а единственный дата-путь `model.extra_body` гейт запрещает — `thinkingControlExtraKeys` включает сам ключ `reasoning_effort` при ЛЮБОМ значении (`models.go:446-448`). ⇒ на поверхности, ради которой строка 74 и писалась (терминолог, cap 8000), выбор прежний: правка Go либо амендмент гейта. Вариант (б) — НЕ «правка одной строки конфига».
> 2. **§3.3, второе:** после санкции (б) один и тот же провод легален через `stages[].reasoning` и запрещён через `model.extra_body`; доккомменты гейта (`models.go:440-448`, `capability.go:52-58`) при этом продолжают утверждать инвариант «echo-prone провайдер ОБЯЗАН держать thinking на дефолте провайдера». Санкция (б) **обязана** тем же решением привести доккомменты в соответствие — иначе следующая сессия прочитает защиту как полную.
> 3. **§3.1 «нет автоматического пути восстановления ВООБЩЕ» — слишком сильно; но «больший бюджет не лечит» — ВЕРНО, и арбитраж это усилил.** Путь есть и был включён: `regenerate_before_escalate: 1` (`stagerun.go:177`) вылечил гл.3/чанк 1 (attempt=1, `stop`, отгружен). **Но вылечил не бюджет:** победивший вызов уложился в **8285** токенов — НИЖЕ базового потолка 8496, при выданных 16992 ⇒ добавка не была потрачена и причиной быть не могла. **Лечит стохастика вызова, а не потолок** — то же свойство, что квирки п.6 («эхо/думание стохастичны ПО ВЫЗОВУ при побайтно одном запросе»). Следствия для развилки: (i) вариант (а) фальсифицирован ещё и механизмом, не только ценой; (ii) `regenerate_before_escalate: 2` (×4) бессмыслен — доливать нечего; (iii) реальный дешёвый рычаг того же класса — **N ре-ролов на БАЗОВОМ потолке** (ручка #77, строка 77), но при наблюдённой отдаче ~1/5 ожидание ≈5 роллов/чанк ≈ $0.0125 — дороже и (б), и (г), так что рычаг понят, а не рекомендован. Путь к ДРУГОЙ модели закрыт КЛАССОМ ФЛАГА, и это доказано сильнее, чем в отчёте: хоп был настроен и профинансирован (`escalate_to: deepseek-v4-pro`, `escalation.budget_usd: 0.10` при расходе $0.0596), а `escalated=0` на всех восьми юнитах. Ещё: из 7 терминальных флагов 3 — `decode_error`, третий класс, не retryable и не escalatable; и «14 оплаченных вызовов» в §3.1 занижает счёт на три — оплачено 17 (сам отчёт это признаёт строкой о списанных декод-фейлах, но в сводное число их не берёт).
> 4. **Д2: шов назван на 2/3.** Третья идентичная синтетическая стадия — `repair.go:384`, и её доккомментарий (`repair.go:377-378`) декларирует ровно ту посылку, которую этот отчёт фальсифицировал («no reasoning setting, so the provider default holds — thinking stays ON»). Латентно (ключа `gates.repair` нет ни в одном шиппинг-конфиге), но штатная правка Д2 её пропустит. Адресация: проводной шов ровно ОДИН — `:515`; `:568` до провайдера не доезжает (оттуда читается только `st.Name`), а `:515` общий для ОБЕИХ ролей.
> 5. **Д1: «это не тихая порча» — верно только там, где санитайзер ВКЛЮЧЁН и цель = ru.** Условие тройное (`isFinal && Gates.Sanitizer.Enabled && checkers.TargetActive()`), отчёт назвал одно. ⚠ Контрпример «есть легальная сборка без секции sanitizer» я в черновике приёмки взял неверно и снимаю: `configs/pipeline-c2.yaml` НЕИСПОЛНЯЕМ (`CheckRunnable` рубит `core: C2` и стадию `role: judge`, `config/pipeline.go:469-486`), а его отсутствующий санитайзер уже забукован условием оживления (строка 33 / `13-tech-debt-anchors.md:45-47`). **Настоящая дыра — на оси ЦЕЛИ и она ДВУСТОРОННЯЯ:** (i) без данных цели весь слой 7 инертен ПО ОТСУТСТВИЮ (осознанный дизайн, `disposition.go:302-305`) ⇒ для не-русской цели рубежа нет вовсе; (ii) но как только будущая ЛАТИНОПИСЬМЕННАЯ цель поедет задокументированным путём расширения (`data/target-<tgt>.txt` в go:embed), `detectLatinInsertion` (`checks/sanitizer.go:228`) сработает на ЧИСТОЙ целевой прозе и дропнет 100% чанков — внутри санитайзера он НЕ обусловлен `TargetScriptNonLatin()`, хотя доккоммент `disposition.go:302-305` объявляет именно эту защиту (реальный гард стоит только на репэйре — `quality.go:215`, `repair.go:208`), а частичный файл цели невозможен (`CompileCheckers` паникует) ⇒ новая цель ОБЯЗАНА включить санитайзер. ⇒ ревью-вопрос «заработает ли пара, которой в репо нет, без правки Go?» для →en/→de отвечается **НЕТ**. Плюс: даже на сегодняшнем ru-пути худший исход — не потеря юнита, а ТИХО ОТГРУЖЕННЫЙ релейный перевод (zh→en→ru), если билингв-редактор отрендерит русский с английского черновика; ни один гейт этого не различает.
> 6. **Деньги черновой волны варианта (б): $0.028195, а не $0.0257.** Число отчёта не воспроизводится ни из одного естественного среза; из сырья: `chunk_status` draft ≡ Σ чекпойнтов ≡ мой независимый пересчёт = **$0.028195** (все попытки, включая хоп на pro $0.008706 и два выброшенных `length` $0.005085); только flash — **$0.019489**. Для сравнения проба C: **$0.012287** волна / $0.009265 flash-only. Вывод отчёта «цена на уровне до-0731-базлайна» уцелевает только в flash-only-чтении.
> 7. **Вариант (г) стоит ≈×9, а не ×3.1.** «×3.1» — отношение вендор-ЦЕН за токен; отчёт не учёл, что pro на том же чанке выдал **9059** выходных токенов против медианы **2330** у flash-low. Из единственного наблюдённого хопа: $0.008706/чанк ⇒ **≈$0.174 на волну 20 чанков, ×8.9 к (б) и ×7.0 к базлайну coldrun-a**. n=1 — прогноз, не замер; но подавать владельцу «×3.1» нельзя.
> 8. **Вендор-факт, которого в отчёте НЕТ, и он бьёт по (г):** та же страница `guides/thinking_mode` (пере-снята мной, HTTP 200) даёт маппинг per-модельно — у `deepseek-v4-flash` `low→low`, а у **`deepseek-v4-pro` `low→high`** ⇒ **на pro ручка эффорта не работает**, придушить его думание нечем. И сноска (3) дословно: *«We will update the actual mapped effort of `deepseek-v4-pro` in early August 2026»* — то есть прямо сейчас; тезис «pro вендором не тронут» имеет срок годности. Обе записи внесены в `experiments/00-provider-quirks.md` (п.3а).
> 9. **Строка `VOICE`: поле версии говорит «гейт СКОНФИГУРИРОВАН», а не «гейт отработал»**`quality.go:436` читает `Gates.Voice.Enabled` из конфига ВРЕМЕНИ ОТЧЁТА, а счётчики приходят из строк, записанных ВО ВРЕМЯ прогона; воспроизведено: включить `gates.voice` в `pipeline.yaml` ПОСЛЕ прогона — и `tmctl report` напечатает `rules=voice-v1-…` при нулях, то есть «измерено, чисто» для книги, которую никто не мерил. Это ровно тот провал coldrun-a §7, ради которого строка вводилась. Честный дискриминатор — ЗНАМЕНАТЕЛИ: живое чтение coldrun-a даёт `flags=0 over attributed=0 of replies=0`, а оси там **никогда не считались** (флаггер живёт на ФИНАЛЬНОЙ волне, `waverun.go:392,512`; редакторская волна не гонялась) ⇒ **бэклог 13б по-прежнему без данных** (не «оси пустые»). Тем же классом: §10 утверждает «гейт выключен — строки нет» — ложно, условие печати дизъюнктивно, и `SpoilerLeaks>0` при выключенном гейте голоса строку напечатает (поведение кода верное, формулировка отчёта и комментария — нет). И знаменатель `BANKNOTE` = `len(states)`, включая ПРИЗРАЧНЫЕ строки `retrieval_state`, тогда как соседний агрегатор их фильтрует (`quality.go:259-260`) — на coldrun-a совпало (20 строк = 20 чанков), поэтому живая верификация это не поймала; после пере-чанковки покрытие занижается. Всё три — строка 105.
> 10. **Остаточный артефакт карантина:** проект `optNoThink` стоит на банк-паузе (рассчитан на резюм), и его `book.yaml:28` навсегда указывает на ungated `models-PROBE-ONLY.yaml` — любой резюм ИМЕННО этого проекта снова поедет с выключенным thinking. Боевые проекты его не подхватывают; помечено как СПЕНТ-проба, не резюмить.
> Мелкие овер-атрибуции (не меняют выводов, исправлены в D-ноте): `ledger.go:47` — это `internal/store/ledger.go`, а не пакет `internal/ledger/` · «ja-фрагмент мерился zh-таблицей» исторически неверно (до D39.64 `cjkShare` был Han+кана, то есть к кане слеп НЕ был; слеп был к ko/en) · `classifierVersion` — строковый литерал, сам не бампается, дисциплина ручная, а его бамп = смена snapshot id ⇒ промах ВСЕХ чекпойнтов книги (`--resnapshot` + пере-покупка) — цена, которую Д4 не назвал · новый тихий отказ в live-риге: `lang.LangScripts` на незарегистрированном `srcLang` возвращает nil без ошибки, и 100%-эхо ПРОХОДИТ пробу (сегодня безвредно — zh/ja зарегистрированы).
>
> **Ратифицировано в D39.86;** новые строки бэклога **104** (ручка reasoning у бэнк-ролей + repair) и **105** (мис-вердикт классификатора); строка **46** получила живой носитель и повышенный класс; **44** закрыта фальсификацией; **13б** уточнена; **16 НЕ закрыта** (фаза C не гонялась). Развилка строки 74 — у владельца.
# coldrun-b: отладочный холодный прогон — ФАЗА A ✅ · ФАЗА B ✅ (блокер строки 74 ВОСПРОИЗВЕДЁН) · ФАЗА C ЗАМОРОЖЕНА развилкой владельца
**Сессия:** бэкенд, 02.08.2026. **Промт:** `docs/BACKEND_COLDRUN_DEBUG_SESSION_PROMPT.md` (оркестратор №9, D39.83). **Сессия НЕ коммитит.**
**Деньги фазы B: $0.114378 из потолка $0.15** (76.3%), двумя независимыми путями (§4). Фаза C денег не тратила.
**Эхо-блок скоупа** (как понят): зона `backend/` + стенд `~/books/gu-zhenren/coldrun-b/` + этот отчёт · фаза A = верификация готовности $0 · фаза B = ре-проба flash ≤$0.15 · фаза C = прогон ≤$5 · вне скоупа: сид, судья Ф2, DC7, полигон-слоты, движение `CheapGateVersion`/labels/голдена, ручка #77, чужие файлы, коммиты, цитирование текста книги.
---
## §0. Итог одной страницей
1. **Фаза A зелёная.** Батарея воспроизведена числами; сквозной $0-путь и CLI-читаемость проверены исполнением; в чек-листе наблюдаемости найдены и **починены $0 две дыры** (счётчики голос-флаггера и канала банкноты считались движком, но не имели НИ ОДНОЙ поверхности вывода).
2. **Фаза B: боевая форма НЕ здорова — блокер строки 74 воспроизведён на проводе.** При боевом потолке `max_tokens=8496` **0 из 9** черновых вызовов дали пригодный ответ (8 `empty`, 1 `length` с обрывком). **Вариант (а) «флор 16000» ФАЛЬСИФИЦИРОВАН:** на удвоенном потолке 16992 — 4/5 тоже пустые, размышление растёт и съедает добавку.
3. **Найден работающий путь, и он дешевле, чем ожидалось:** явный `reasoning_effort: "low"`**правкой ОДНОЙ строки ран-конфига, БЕЗ правки Go и БЕЗ амендмента `echoMineViolation`** (посылка бэклога 74 о необходимости амендмента **неверна** — обоснование в §3.3, проверено исполнением). На нём **18 из 20 чанков отгружены** (20 из 22 свежих вызовов `finish=stop`), цена волны на уровне до-0731-базлайна.
4. **Цена этого пути названа честно:** эхо 3/20 (15%) против 2/20 у coldrun-a, **и один черновик из 18 пришёл целиком НА АНГЛИЙСКОМ** — класс, которого до-0731 в прогонах не было.
5. **Терминолог вариантом (б) НЕ лечится:** у бэнк-ролей вообще нет ручки reasoning, они всегда едут вендор-дефолтом `high`. 4 из 5 батчей вернулись пустыми, банк консолидировал 1 терм из 81. **Любая резолюция строки 74 обязана накрыть терминолога отдельно** — это требует правки Go, которую сессия НЕ делает до решения владельца.
6. **Классификатор 6/6 — порог взят** ($0.000390, `finish=stop`), с честной оговоркой о 2 «подсказанных» термах (§3.5).
7. **Фаза C не запускалась**: промт делает её условной на «здоров по ВСЕМ критериям», а критерий «0 пустых ответов» нарушен. Стенд coldrun-b построен, проверен $0 и стоит нетронутым — прогон стартует одной командой сразу после решения владельца.
**Что прогон уже ДОКАЗАЛ о бэкенде** (живыми деньгами, а не тестами): нарезка · черновая волна на 4 воркерах · classify/disposition (поймал 3/3 эха, все `length`/`empty`) · эскалация одним хопом с ре-гейтом · канал банкноты (129 строк на 14/20 чанков) · майнер+слияние банка (76 кандидатов, 100% dst в кириллице, 0 утечек письма) · банк-пауза `--verify-bank` (exit 3 + сайдкары) · деньги (`committed ≡ Σ checkpoints`, потолок физически выстрелил на 98.7%) · F4-бэкап перед каждым платным стартом · graceful SIGINT посреди волны · **$0-резюм** (20 юнитов из `chunk_status` + 5 чекпойнтов, 0 вызовов, леджер байт-в-байт тот же).
---
## §1. Фаза A — верификация готовности ($0)
### A1. Батарея — числа и команды
| Проверка | Команда | Результат |
|---|---|---|
| Сборка | `go build ./...` | exit 0 |
| Вет | `go vet ./...` · `go vet -tags live ./internal/pipeline/` | exit 0 (второй — после фикса, см. §5-Д3) |
| Сьют | `go test -race -count=1 ./...` | все пакеты `ok` (pipeline 82.4 с, store 16.1 с) |
| Майнер-парити | `TM_MINER_PARITY=1 go test ./internal/miner/ -run Parity -count=1 -v` | PASS · `n=13618 catastrophe{方源:0 蛊:1 蛊师:2 古月:22} recall@proposed=0.9655 (56/58 GT)` |
| Labels-фриз | `TM_CHECKER_LABELS=1 go test ./internal/checks/ -run TestCheckerLabelsBaseline -count=1 -v` | k4b **10/1/36/99** ✓ · k4_inverse **3/0/1/71** ✓ · k2 **34/1/6/51** ✓ · k4a **0/0/0/348** ✓ |
| Labels-фриз K6 | `TM_CHECKER_LABELS=1 go test ./internal/membank/ -run TestK6LabelsBaseline -count=1 -v` | AFTER **tp=1 fp=6 fn=0 tn=251** ✓ |
| Голден | `go test ./internal/pipeline/ -run TestGoldenDeterminism -count=1 -v` | PASS |
Все 5 фрозен-ячеек промта воспроизведены точно. **Батарея пере-прогнана ПОСЛЕ моих правок — зелёная (§5).**
### A2. Сквозной $0-путь и CLI-читаемость
- **Сквозняк** = `TestGoldenDeterminism` (полный пайплайн draft→edit на фейк-провайдере, 8 юнитов, 4 flagged; `book run finished … run_usd=0.000000`). Отдельного CLI-достижимого фейк-провайдера нет — согласен с приором промта.
- **CLI-читаемость проверена НЕ локальной моделью, а read-only чтением БОЕВОЙ БД coldrun-a** — это строго сильнее: реальные данные, реальный drift, $0, и заодно проверка инварианта «`OpenReadOnly` ничего не мутирует».
`sha256 guzhenren-coldrun-a.db` **до и после** трёх команд — `770488e241d4…` идентичен.
`tmctl status` → CONFIG-DRIFT + проекция пере-оплаты `20 юнитов ≈ $0.024056`; `tmctl report` → 68 строк request_log; `tmctl export``--plaintext`) → JSON с `config_drift:true`.
- **Само-поправка при разборе:** первое прочтение «0/14 юнитов против 20 оплаченных = чанкер поехал» **оказалось неверным**. `status`/`export` считают EDIT-юниты (`edit_ceiling_out: 3200`), а 20 — DRAFT-чанки (`draft_budget_out: 1797`). Отношение 20/14 = 1.43 сходится с пар-калибровкой 56/37 = 1.51. Нарезка не менялась.
### A3. Чек-лист наблюдаемости — «чем смотрю» / что починил
| Узел | Есть? | Чем смотрю |
|---|---|---|
| Логи, тела запросов | есть | `LOG_LEVEL=debug` + `LOG_LLM_BODIES=1` (`main.go:65-70`, приватность по умолчанию). ⚠ Тела **усечены** (`obs/logging.go:103` `truncateForLog`) — на ответах с 20k reasoning JSON не парсится; для денег это лечится путём №2 через `request_log` (§4) |
| Деньги | есть | `tmctl status` (committed/reserved/потолок/%/прогноз) · `tmctl report` (per-call usage+cost+finish) · `estimated-cost rows` — отдельная строка для оценочных списаний · инвариант `committed ≡ Σ checkpoints` проверен SQL |
| Эскалации, ре-биллы | есть | `report``ROUTING/MONEY: escalation hops=… · spend by model: …` · WARN-строки `stage escalated…` / `escalation hop denied by a USD ceiling` |
| Статус на ЖИВОЙ БД | есть | `NewReadOnlyRunner``store.OpenReadOnly` без flock (`runner.go:159-167,218-223`) — проверено на боевой БД (см. A2) |
| Чекпойнты / resume / redrive | есть | `redrive --dry-run` ($0, валидирует ключи+конфиг) · **$0-резюм проверен живьём** (§3.4) |
| F4 pre-flight | есть | `preflightBackup` в диспетчере `run()` (`main.go:74-79,88-93`) — **этот прогон его первый боевой клиент**: 3 бэкапа созданы, `integrity_check` зелёный |
| Волны / ретраи | есть | `draft wave started … chunks=N workers=N` · `stage flagged, regenerating with a larger budget … next_max_tokens=…` |
| Майнер, банк-пауза | есть | `bank-mining: …` + сайдкары `*.db.mined-signature.yaml` / `*.db.bank-stop.txt` |
| Терминолог-батчи | есть | `terminology … estimate before any call` · `terminology finished … consolidated/unanswered/off_language/cost_usd` |
| flag_reason | есть | `report` → секция FLAGS; `status``worst_flag` по главам |
| **Канал банкноты** | **ДЫРА → починил $0** | счётчики `n_banknote_lines`/`banknote_parse_fail`/`banknote_truncated` писались в `retrieval_state` с пака-20, но **ни одна поверхность их не печатала** — прошлый холодный прогон читал их SQL-ом руками |
| **Счётчики голос-флаггера** | **ДЫРА → починил $0** | `VoiceFlags`/`VoiceReplies`/`VoiceAttributed`/`VoicePairRegister`/`SpoilerLeaks` агрегируются в `quality.go:269-276`, но `renderQuality` их не печатал, `report --json` не существует ⇒ единственный прогон с включённым гейтом не мог прочитать свои же оси |
| Диск | есть | `df -h ~/books` → 854 G свободно; весь стенд 101 M |
**Фиксы наблюдаемости (оба — только слой рендера, вердиктов и снапшота не касаются):**
- `cmd/tmctl/render.go` — секция `=== BANKNOTE …===`: `lines=N over K/M chunk(s) · parse-fail chunks=… · truncated chunks=…`. Покрытие по чанкам печатается рядом с суммой намеренно: 12 строк на 12 чанках и 12 строк на одном — разные факты, и общая сумма второй случай прячет.
- `cmd/tmctl/render.go` — строка `VOICE (axes AC…)`: счёт **вместе со знаменателями** (2 из 31 атрибутированных реплик ≠ 2 из 3), ось D отдельно, версия правил рядом с числами (гейт голоса намеренно не фолдится в снапшот).
- Обе печатаются только когда каналу есть что сказать ⇒ книга без них байт-идентична прежнему выводу. Голден их не пинит (`renderQuality`/`renderReport` не входят в `testdata/golden/`), `CheapGateVersion` не тронут.
- Тесты: `cmd/tmctl/render_observability_test.go`, 5 штук — включая **тест молчания** на каждую строку и тест «гейт отработал и нашёл ноль» (различение «не измерено» и «измерено, чисто» — ровно тот провал, который coldrun-a §7 честно назвал).
- **Верификация на живых данных:** новая строка BANKNOTE на БД coldrun-a печатает `lines=182 over 18/20 chunk(s) · parse-fail chunks=3` — независимо воспроизводит числа, которые прошлая сессия добывала руками («18/20», «parse_fail на 3 чанках из 20»).
### A4. Стенд
`~/books/gu-zhenren/coldrun-b/` — свежая БД, **сид не подключён** (ключа `glossary_seed` нет), `book.yaml` от эталона coldrun-a (лейблы/жанр/`register_blocklist` как в эталоне), `ceilings: book_usd 5.00 / day_usd 5.00`. `pipeline.yaml` **побайтно равен** эталонному, кроме шапки-комментария ⇒ цена фазы C будет сравнима со строкой 16 напрямую.
Срез: главы 12 (строки 1171 среза coldrun-a, 12 706 байт); добор допишет главы 310 в ТОТ ЖЕ файл, после чего он станет побайтно равен срезу coldrun-a (`sha256 0b5f9b02…c89f37`).
Ключи проверены $0: `tmctl redrive --config … --dry-run` → «No flagged chunks match the selector».
**Две находки стенда, обе исправлены на месте:**
1. `coldrun-a/pairs/zh-ru.yaml`**не мусор, а несущий файл**: `LoadPair` ищет пар-слой рядом с ран-конфигом, и он несёт АБСОЛЮТНЫЙ `prompts_root`. Без копии в coldrun-b конфиг падает fail-loud'ом («no prompt for pair zh-ru role editor»). Тело файла сверено с репозиторным — идентично, кроме `prompts_root`. *(Мой первый разбор назвал каталог «мёртвым остатком» — неверно, поправлено исполнением.)*
2. ⚠ **`ceilings.day_usd` считается по КАЛЕНДАРНОМУ дню UTC и по ЭТОЙ БД** (`ledger.go:47,62-72`). Через полночь UTC ось обнуляется ⇒ несущий предохранитель прогона — `book_usd`, а не `day_usd`. Записано в комментарий `book.yaml`; на длинном прогоне это надо помнить.
### A5. Веха
Дыр класса «нужно чужое решение» на фазе A не найдено ⇒ перешёл в B без ожидания.
---
## §2. Носитель ре-пробы — почему НЕ расширение live-рига (девиация от промта, с аргументом)
Промт предлагал расширить `live_conformance_test.go` боевым рендером. Я сделал **сильнее и проще**: поднял отдельный проект `reprobe/` (своя БД, свой потолок `$0.15`, принуждаемый ДВИЖКОМ) и погнал по нему **сам боевой путь**`tmctl translate --verify-bank`.
Почему так:
- Вопрос строки 74 звучит «расходится ли БОЕВАЯ форма». Ручной риг мог бы разойтись с ней по любой из осей (сборка сообщений, флор `applyModelFloor`, добавка `bankTokenBudget`, температура, порядок ретраев) — и тогда я бы мерил свой риг. Это ровно тот класс ошибки, который проект уже ловил у полигона (D37).
- Боевой путь даёт бесплатно: реальные `reserve→settle→checkpoint`, реальный `classify`, реальную эскалацию, реальные сайдкары банк-паузы и **деньги В ЛЕДЖЕРЕ** (иначе цену пробы пришлось бы считать одним путём).
- N=20 вместо N≈812: на эхе порядка 615% дюжина вызовов не отличает норму от регрессии.
- Отдельная БД сохраняет право пробы провалиться, не тронув леджер и чекпойнты боевого coldrun-b.
Промт сам объявляет свои чек-листы приорами, опровергаемыми аргументом — считаю условие выполненным. Единственное, что осталось ручным ригом, — порог классификатора 6/6 (боевого верба у него нет); он тоже переведён на боевой денежный путь, см. §5-Д4.
---
## §3. Фаза B — числа
### 3.1 Проба A: текущая шиппинговая форма (`reasoning: "off"` = вендор-дефолт `high`)
`LOG_LEVEL=debug LOG_LLM_BODIES=1 ./bin/tmctl translate --config ~/books/gu-zhenren/coldrun-b/reprobe/book.yaml --verify-bank`
Разбивка — по `checkpoints.attempt` (attempt 0 = боевой потолок, attempt 1 = движковое удвоение), не по глазомеру:
| Потолок | Свежих вызовов | пригодных | вердикт движка |
|---|---|---|---|
| **8496** (боевой: флор 8000 + `bankTokenBudget` 496) | 9 | **0** | `finish=length` на 9 из 9; 8 × `empty` (контент пуст) + 1 × `length` (обрывок 993 симв.) |
| **16992** (движковый ре-ген, ×2) | 5 | **1** | 4 × `length`+пусто, 1 × `stop` (уложился в 8285 ток.) |
| 2xx с нечитаемым телом (`decode_error`) | 3 | — | тело не декодируется, вызов списан (строка 78) |
**Механизм вскрыт на сыром проводе, а не выведен из счётчиков** (тела из лога, `LOG_LLM_BODIES=1`):
| # | finish | completion_tokens | `content` | `reasoning_content` |
|---|---|---|---|---|
| 0 | length | 8496 (= весь потолок) | 993 симв. | 15 424 симв. |
| 1 | length | 8496 | **0** | 18 770 |
| 2 | length | 8496 | **0** | 19 165 |
| 3 | length | 8496 | **0** | 20 884 |
| 4 | length | **16991** | **0** | 21 528 |
| 5 | length | **16991** | **0** | 21 322 |
Модель **пере-переводит главу фразу за фразой ВНУТРИ размышления**`reasoning_content` — готовые русские предложения) и не доходит до ответа. Удвоение потолка добавляет ~2 000 символов размышления и **не сходится**: это не дегенеративный луп, а многословная обдумка (механизм D39.61 п.2, теперь при ~100% частоте на боевой форме).
**Вариант (а) «поднять флор до 16000» фальсифицирован замером.** Вендорская норма для эффорта `high` — max output **384K** (`quick_start/pricing`), это ×45 к нашему флору; при $0.28/1M выхода один чанк стоил бы до **$0.107** против сегодняшних $0.0012 (≈×90 COGS). Это не флор, это другая экономика.
**Архитектурная деталь, которая делает ситуацию тупиковой без решения:** `empty` и `length`**retryable, но НЕ escalatable** (`disposition.go:142-149`). Это правильная посылка D2 («лечение обрыва — больший бюджет на той же модели»), но 0731 её опровергает: больший бюджет НЕ лечит, а путь к другой модели для этого класса флага закрыт. ⇒ на текущем конфиге у черновой волны **нет автоматического пути восстановления вообще**: каждый чанк терминально флагается и книга не выезжает.
Волна остановлена мной **graceful SIGINT** на 14 оплаченных вызовах — дальше она пере-покупала бы уже доказанный факт. (Побочно: механика стоп/продолжить H10 проверена — чекпойнты удержали, см. §3.4.)
### 3.2 Проба B: явный `reasoning_effort: "low"` — вариант (б)
Тот же боевой путь, отдельный проект `reprobe/optB/`, потолок $0.04. Изменена **одна строка** ран-конфига: `stages[draft].reasoning: "low"`.
Все числа — по СВЕЖИМ вызовам (`request_log.tm_hit=0`), чтобы $0-реплеи резюма не раздували знаменатель:
| Ось | Проба A (дефолт `high`) | Проба B (`low`) | coldrun-a 31.07 (до смены весов) |
|---|---|---|---|
| Черновые вызовы `finish=stop` | **1 / 14** | **20 / 22** | 72 / 74 *(за ЧЕТЫРЕ волны — не одна волна, в лоб не сравнивать)* |
| **Чанков отгружено** (draft-юнитов `ok`) | **1 / 8 затронутых** | **18 / 20** | **20 / 20** |
| Эхо (`cjk_artifact`) | 0 (до эха не доходило) | **3/20 = 15%** | 2/20 = 10% |
| **Терминолог: батчей `stop`** | не дошёл | **1 / 5** | **21 / 21** |
| Цена чистого вызова | — | **$0.000270.00135** | ~$0.00124 |
| Цена черновой волны, 20 чанков | не выехала | **≈$0.0257** (чистые вызовы) | **$0.02474** |
| Латентность | 68190 с | **944 с** | 877 с |
| Wall-clock волны (4 воркера) | — | **3 мин 06 с** | ~4 мин |
**Читать так: вариант (б) возвращает черновую волну к до-0731-поведению и к до-0731-цене** (разница волн $0.0257 против $0.0247 — в пределах разброса, улучшением НЕ называю).
**Цена варианта (б), названная честно:**
- Эхо вернулось на **15% (3/20)** против 10% у coldrun-a. Гейт поймал все три; одну эскалация на `deepseek-v4-pro` вылечила ($0.008706), две остались флагнутыми — **потому что потолок $0.04 (98.7% выбран) отказал в следующих хопах**. То есть наблюдение эскалации усечено моим потолком, а не дефектом.
- ⚠ **Один черновик из 18 пришёл ЦЕЛИКОМ НА АНГЛИЙСКОМ** (ch1/chunk1: 6 078 симв., кириллица 0.000, латиница 0.792) и **прошёл гейт как `ok`**. На coldrun-a таких 0/20. Разбор класса — §5-Д1.
- Ⓘ Число 15% — на N=20. Против «~6%» D39.61 оно не сопоставимо в лоб: та цифра снята другим харнессом на другой сборке запроса. Что 15% и 10% статистически неотличимы на таких N — тоже верно; поэтому вывод формулирую как «эхо есть и его надо считать», а не «эхо выросло».
### 3.3 ⚠ Посылка бэклога 74 об амендменте `echoMineViolation`НЕВЕРНА
Строка 74 пишет: «(б) слать `reasoning_effort` явно … но **нужен амендмент `echoMineViolation`**». Проверено чтением кода и **исполнением** — амендмент не нужен:
- Гейт (`config/models.go:485-501`) инспектирует **МЕХАНИЗМ**, а не значение: он запрещает `capabilities.reasoning.control` ∈ {`extra_body_disable`, `effort`} и ключ thinking-выключателя в `extra_body`.
- У DeepSeek `control = ReasoningNone`, и это **не в запрещённом множестве**.
- При `ReasoningNone` (`llm/capability.go:167-171`): `off` и `""` не шлют ничего (осознанный no-op — thinking остаётся ON), **а `low|medium|high` уходят на провод как `reasoning_effort` как есть**.
- Исполнение: конфиг с `reasoning: "low"` на deepseek-стадии **загрузился без ошибки** и провод получил уровень (вызовы отработали за 944 с при 170300 ток. размышления вместо 1521 тыс.).
- Вендор-дока подтверждает, что это НЕ выключение thinking: тумблер — `{"thinking":{"type":"enabled/disabled"}}`, эффорт — отдельный параметр `{"reasoning_effort":"low/high/max"}`, а `none` в OpenAI-формате у DeepSeek не существует вовсе.
**Инвариант «DeepSeek thinking никогда не выключать» доказан НА ПРОВОДЕ, а не аргументом** (разбор тел пробы B):
- тело запроса несёт ровно `['max_tokens','messages','model','reasoning_effort','stream','temperature']`, `reasoning_effort = "low"`, **ключа-выключателя `thinking` в теле НЕТ**;
- **24 из 24 разобранных ответов несут НЕПУСТОЙ `reasoning_content`** (261 … 20 570 симв., медиана 925) ⇒ модель думала на каждом вызове.
⇒ Инвариант **не нарушается**, гейт трогать не нужно, вариант (б) — правка ран-конфига. **Но это не значит, что он бесплатен: эмпирическая часть посылки (эхо деградирует непрерывно с эффортом, D39.61 п.4) подтверждена этим прогоном — 3/20 эха и 1/18 английского выхода.** Решение остаётся владельца; сессия ручку в боевом `coldrun-b/pipeline.yaml` НЕ ставила.
### 3.4 Вендор-сверка (правило двух направлений — сделана ДО диагноза)
`curl -sSL https://api-docs.deepseek.com/updates` (HTTP 200, 02.08):
- **Новых записей после `Date: 2026-07-31` НЕТ** ⇒ второй смены весов вендор не объявлял; наблюдаемое — то же событие 0731, но замеренное на боевой форме.
- Дословно из той же записи: тестировали официальный V4-Flash *«using the DeepSeek Harness minimal mode … with the **max effort level**, topp=0.95, and temperature=1.0»* — вендорская поза для 0731 — агентный высокий эффорт.
`curl -sSL https://api-docs.deepseek.com/guides/thinking_mode` (HTTP 200, 02.08) — **ключевая и НОВАЯ для наших доков строка**:
> «Thinking mode is enabled by default, **with the default effort being `high`**»
и таблица маппинга для `deepseek-v4-flash`: `low→low`, `high→high`, `xhigh→high`, `max→max`.
⇒ Мы не шлём `reasoning_effort` ⇒ едем на вендор-дефолте **`high`** ⇒ на плотной ханьской прозе он не укладывается ни в 8496, ни в 16992. Запись квирков от 04.07 («только high/max, low/medium→high») **устарела**: `low` — документированный отдельный уровень. Это факт для `00-provider-quirks.md`; правку файла оставляю оркестратору (чужая зона).
### 3.4а Проба C: thinking ВЫКЛЮЧЕН (`extra_body {"thinking":{"type":"disabled"}}`) — пере-замер эхо-мины на весах 0731
**Повод:** вопрос владельца «а выключить ризонинг нельзя?». Ответ доктриной был бы нечестным: вся наша эмпирика «thinking off → эхо» снята на `V4-Flash-Preview`, весов которых больше нет, а канон проекта требует пере-проверять клейм о поведении модели живой пробой. Замерил.
Проект `reprobe/optNoThink/`, потолок $0.03, тот же срез 10 глав. Пробная копия `models-PROBE-ONLY.yaml` (вне git, с громкой шапкой) снимает флаг `echoes_when_thinking_off` и включает вендорский выключатель; **боевой `configs/models.yaml` не тронут, гейт `echoMineViolation` в репо цел**. Движок на старте сам напечатал WARN про эхо-зону (`sourceEchoExposure`) — второй рубеж громкий.
| Ось (тот же текст, 20 чанков, N=20) | **A: дефолт `high`** | **B: `reasoning_effort: low`** | **C: thinking OFF** |
|---|---|---|---|
| Чанков отгружено | **1 / 8 затронутых** | 18 / 20 | 18 / 20 |
| Пустых/обрывов среди вызовов | **13 из 14** | 2 из 22 | **0 из 22** |
| Эхо (`cjk_artifact`) | — (до эха не доходило) | 3 / 20 = 15% | **4 / 20 = 20%** |
| Выход не на целевом языке | — | **1 / 18 (английский)** | **0 / 18** |
| Терминолог, батчей `stop` | не дошёл | **1 / 5** | **5 / 5** |
| Деньги за весь заход | $0.059590 | $0.039466 | **$0.014932** |
**Что это значит:**
1. **Эхо-мина на 0731 ЖИВА** — 4/20 при выключенном thinking. Клейм, который кодирует флаг `echoes_when_thinking_off`, пере-подтверждён на новых весах, а не унаследован от старых.
2. Но **механизм её отрабатывает**: гейт поймал 4 из 4, эскалация на `deepseek-v4-pro` вылечила 2 по $0.0024; **оставшиеся 2 не были вылечены только потому, что МОЙ пробный потолок $0.03 отказал в хопах** (`escalation hop denied by a USD ceiling; keeping the primary flag` — деградация, а не падение). На боевом потолке $5 вылечились бы все четыре, добавив ~$0.010.
3. **Терминолог при выключенном ризонинге здоров: 5/5** против 1/5 у варианта (б). Это единственная из трёх конфигураций, где стадия банка работает БЕЗ правки Go.
4. **Разница 15% vs 20% эха между (б) и (C) на N=20 статистически неразличима** — «непрерывная деградация защиты с эффортом» (D39.61 п.4) этими данными направленно согласуется, но НЕ разделяется.
**Чего проба C НЕ измеряла и что решает всё:** качество прозы. Все три пробы мерили детерминированные оси (finish/пусто/эхо/письмо/деньги). Канон «reasoning-off непригоден для роли переводчика на плотном CJK» (D19.1/D21.9) стоит НЕ только на эхе, и черновик без размышления может быть заметно хуже как текст, проходя при этом все $0-гейты. Это предмет судьи Ф2, который не гонялся. **Поэтому C — измеренная опция, а не рекомендация: её принятие означает разворот ратифицированного гардрейла и обязано опираться на читку качества, а не на мои счётчики.**
### 3.5 Порог классификатора 6/6 — ВЗЯТ
`TM_LIVE=1 TM_CLASSIFY6_CONFIG=…/classify6/book.yaml go test -tags live -run TestLiveClassifierHarmSet -v ./internal/pipeline/`
`hits=6/6` (元石·元海·蛊室·池塘·灵泉·酒肆 → `term`), `finish=stop`, `max_tokens=8000`, usage `1143/1024 cached/1323 compl`, **$0.000390**, `bad_lines=0`, латентность 16.4 с.
Кандидаты намеренно поданы с **НЕВЕРНЫМ** черновым типом (`name`/`place`) — иначе тест прошла бы и модель, просто повторяющая вход.
**Честная оговорка, снижающая вес числа:** `元石` и `灵泉` стоят **дословно** в `prompts/zh-ru/classifier.md` как примеры класса `term`. Дискриминирующее подмножество — 元海/蛊室/池塘/酒肆, и оно тоже **4/4**. Читать как «4 решено + 2 вспомнено», а не как 6 независимых решений.
Ⓘ Классификатор в стену размышления НЕ упирается (402→1323 ток. вывода): его задача короткая и с закрытым словарём. Стена специфична для ДЛИННОЙ генерации на плотном хане.
### 3.6 Терминолог — вариантом (б) НЕ вылечен (несущее ограничение развилки)
В той же пробе B, после черновой волны:
| Батч | finish | completion | content | цена |
|---|---|---|---|---|
| 0 | length | **8000** (весь потолок) | пусто | $0.002716 |
| 1 | length | **8000** | пусто | $0.002731 |
| 2 | length | **8000** | пусто | $0.002268 |
| 3 | **stop** | 2131 | есть | $0.001095 |
| 4 | length | **8000** | пусто | $0.002459 |
`terminology finished … consolidated=1 unanswered=80 bad_lines=0 off_language=0 cost_usd=0.011270` — **банк консолидировал 1 терм из 81.**
Контраст, который делает это регрессией, а не свойством стадии: на coldrun-a (до смены весов) терминолог отработал **21 батч из 21 с `finish=stop`, ноль обрывов**. Стадия была здорова и перестала быть.
**Корень (грунтован кодом):** бэнк-роли собирают синтетическую стадию `config.Stage{Name, Role, Model}` (`terminologist.go:515`, `:568`) — поле `Reasoning` **пустое**, и у `gates.terminology` ключа `reasoning` нет вовсе. При `ReasoningNone` пустой эффорт не шлёт ничего ⇒ **терминолог и классификатор всегда едут вендор-дефолтом `high`**, что бы владелец ни выбрал для черновой стадии.
**Резолюция строки 74 обязана накрыть терминолога отдельным изменением**, и это правка Go (см. §5-Д2). Промт это предвидел («cap 8000 бьёт и СТАДИЮ ТЕРМИНОЛОГА … резолюция обязана накрыть терминолога») — подтверждаю замером и называю точный шов.
### 3.7 $0-резюм и стоп/продолжить — проверены живьём
`./bin/tmctl translate --config …/optB/book.yaml --verify-bank` (повтор):
`EXIT=3` · `stage resolved from chunk_status` × **20** · `attempt served from checkpoint` × **5** · `calling model` × **0** · committed **$0.039466 → $0.039466** (SQL: 41 чекпойнта, `SUM(cost_usd)` идентична до и после).
Плюс graceful SIGINT посреди волны пробы A: процесс вышел через `context canceled`, БД цела, оплаченные попытки сохранены.
---
## §4. Деньги — двумя независимыми путями
| Проект | Путь №1: леджер движка | Путь №2: НЕЗАВИСИМЫЙ пересчёт | Инвариант |
|---|---|---|---|
| `reprobe` (проба A) | **$0.059590** | **$0.044480** | `committed ≡ Σ checkpoints` ✓ |
| `optB` (проба B) | **$0.039466** | **$0.039466** | `committed ≡ Σ checkpoints` ✓ |
| `classify6` | **$0.000390** | $0.000390 | ✓ |
| `optNoThink` (проба C) | **$0.014932** | $0.014932 | ✓ |
| **Итого фазы B** | **$0.114378** из $0.15 (76.3%) | | |
Путь №2 = мой собственный пересчёт **провайдерских** `usage`-колонок из `request_log` по опубликованным вендор-ценам (flash $0.14/$0.0028/$0.28), read-only через `sqlite3`, **не через `ledger.CostUSD`**.
**Расхождение $0.015110 у пробы A — не ошибка, а строка 78 бэклога в живом виде:** три вызова вернули 2xx с нечитаемым телом («2xx body decode failed (call IS billed)»). Провайдер их списал, токенов не сообщил, движок консервативно засеттлил **оценку** $0.015111 (и честно печатает `estimated-cost rows: 3` отдельной строкой). $0.044480 + $0.015111 = $0.059591 ≈ леджер. ⇒ **леджер = нижняя граница реального счёта провайдера**, ровно как промт предупреждал; величина неизвестности на этой сессии — $0.0151.
Потолки отработали физически: `optB` встал на 98.7% ($0.039466 / $0.04) и **отказал в дальнейших эскалационных хопах**, не уронив прогон.
---
## §5. Дефекты: найдено / починено / отложено
### Починено (с тестами, батарея зелёная)
**Д3. Live-риг не собирался** (пре-существующий, попал бы в любую live-пробу). `go vet -tags live ./internal/pipeline/``undefined: cjkShare`: D39.64 заменил `cjkShare` на `sourceScriptShare(s, scripts)`, а build-tagged файл не обновили ⇒ **per-adapter live conformance физически не запускался с D39.64**. Починено: у каждой пробы появился `srcLang`, доля меряется против объявленных письменностей ЕЁ языка (ja-фрагмент против zh-письменностей недосчитывал бы собственное эхо).
**Наблюдаемость (§A3):** строки BANKNOTE и VOICE + 5 тестов, включая тесты молчания.
### Найдено, НЕ починено — требует решения владельца/оркестратора
**Д1. Черновик на ТРЕТЬЕМ языке проходит гейт черновой стадии.** ch1/chunk1 пробы B: полный, связный перевод **на английский**, `disposition=ok`, флага нет.
- Корень: `classify` экранирует **исходную** письменность (`sourceScriptShare``cjk_artifact`), пустоту, обрыв и отказ. Выход на языке, который не исходный и не целевой, ни под один предикат не попадает. Это ровно бэклог-46 («38/40 дефектов латиницы живут в черновиках вне охвата гейтов»).
- **Проверил последний рубеж, прежде чем называть это дырой:** прогнал ЭТОТ текст через боевые чекеры ($0, временный харнесс, удалён) — `checks.SanitizeOutput` возвращает `total=1, cosmetic_only=false, "Latin insertion (a phrase of consecutive Latin words)"``sanitizer_defect` ⇒ flag+skip. **Но санитайзер стоит ТОЛЬКО на финальной стадии** (`chunkrun.go:52`, `isFinal`).
- ⇒ **Честная формулировка: это не тихая порча, а потеря юнита + оплаченный впустую редактор.** Английский черновик доезжает до редактора (деньги уплачены); если редактор вернёт русский — самолечение; если сохранит английский — санитайзер флагнет и юнит уедет пустым.
- Частота: 1/18 на `effort: low`, 0/20 на до-0731-дефолте. Класс подтверждён квирками (D39.61 п.5: «единственный за 48 вызовов выход НА АНГЛИЙСКОМ»).
- Дизайн-вопрос, а не хак: нужен ли **target-script экран на выходе ЧЕРНОВОЙ стадии** (у терминолога такой уже есть — `gates.terminology.target_script`). Это вердикт-двигающее изменение ⇒ по промту СТОП+пинг, не чиню.
**Д2. У бэнк-ролей нет ручки reasoning** (§3.6). Шов назван точно: `terminologist.go:515` и `:568` строят `config.Stage` без `Reasoning`; у `config.TerminologyGate` поля нет. Минимальная мультиязычная форма — `reasoning` (и, возможно, `classify_reasoning`) в `gates.terminology`, прокинутая в обе синтетические стадии; общность не страдает (это ран-скоупная ручка, не пар-данные). **Не строю до решения владельца по развилке** — знать, ЧТО прокидывать, можно только после выбора.
**Д4. Роль `classifier` мис-вердиктится как эхо.** Проба 6/6 вернула правильный ответ, но с `disposition=flagged reason=cjk_artifact`: `classifyOutput` даёт поблажку `SourceEchoExpected` только `roleTerminologist` (`chunkrun.go:37`), а ответ классификатора по формату ТОЖЕ состоит из исходных ханьских термов (`元石⇥term`) ⇒ доля исходного письма выше порога 0.15 на каждом батче.
- Ущерб **ограничен телеметрией**: `runBankRoleBatches` кладёт `run.texts[i] = att.text` **без проверки диспозиции** (`terminologist.go:603`), парсинг проходит, эскалации на этом пути нет. Но каждый батч классификатора будет светиться `ok=0 cjk_artifact` в `request_log`, завышая эхо-сигнал.
- Латентно: `classify_types` выключен во всех шиппинг-конфигах. Фикс — одно слово, но он **двигает вердикт** (`classifierVersion` фолдится в снапшот) ⇒ по промту СТОП+пинг.
**Д5. `LOG_LLM_BODIES` усекает тела** (`obs/logging.go:103`) — на ответах с 20k размышления JSON не парсится, и лог перестаёт быть вторым путём для денег. Не дефект логгера (усечение осознанное), а граница метода: второй путь строить от `request_log`, а не от лога. Записал как факт метода, фикса не предлагаю.
### Отложено с носителем
- Правка `00-provider-quirks.md` (дефолт эффорта = `high`; запись 04.07 устарела; строка 0731 п.1 о «флоре 16000» опровергнута на боевой форме) — **чужая зона, оркестратору**, фактура в §3.1/§3.4.
- Строка 78 (леджер = нижняя граница) получила живое число: $0.0151 неизвестности на 14 вызовов.
- Строка 46 (гейт черновика) получила живой носитель — Д1.
---
## §6. Фаза C — почему не запущена и что готово
Промт: «здоров по ВСЕМ критериям → фаза C без ожидания. НЕ здоров → СТОП+релей». Критерий «0 пустых ответов» нарушен на текущей шиппинговой форме (8 из 9). Запускать прогон на $5 конфигом, который покупает пустоту, — это сжечь деньги на уже доказанный факт.
**Готово к старту одной командой** после решения владельца: стенд `coldrun-b` собран, конфиг-санити пройден исполнением, ключи проверены, БД свежая и пустая ($0.000000), потолки на месте, F4-бэкап отработает на старте.
**Развилка — владельцу (числа в §3):**
| Вариант | Статус по замеру | Цена |
|---|---|---|
| **(а) флор 16000** | ❌ **ФАЛЬСИФИЦИРОВАН**: 4/5 пустых при 16992; вендорская норма для `high` — 384K вывода (×45 к флору, ≈×90 COGS) | — |
| **(б) `reasoning_effort: "low"`** | ✅ **работает на черновой волне**: 18/20 `stop`, цена на уровне до-0731; амендмент гейта **НЕ нужен** (§3.3) | эхо 3/20 · 1/18 выход на англ. · **терминолога надо чинить отдельно (Д2, правка Go)** |
| **(в) ждать вендора** | нейтрален: новых записей changelog после 31.07 нет | простой |
| **(в′) thinking OFF** *(замерено, §3.4а)* | ✅ **0 пустых из 22 · терминолог 5/5 · $0.014932 за заход — в 2.6× дешевле (б)**; выключатель документирован вендором и в НАШЕМ OpenAI-транспорте | **эхо-мина жива: 4/20**, лечится гейтом+эскалацией по $0.0024/шт; **разворот ратифицированного гардрейла** `echoMineViolation`; **качество прозы не судилось никем** |
| **(г) сменить модель черновика** *(вне списка промта — предлагаю как реальную альтернативу)* | не замерен; косвенно: `deepseek-v4-pro` вендором **не тронут** обновлением 0731 и в пробе B успешно отработал эскалационный хоп на боевом рендере ($0.008706, `finish=stop`) | ~×3.1 COGS черновика; **0 правок Go, 0 правок гейта** — только строка модели в ран-конфиге |
**Моя рекомендация (решение — не моё):** (б) для черновой стадии **вместе с** Д2 для терминолога; при этом Д1 (экран целевого письма на черновой стадии) становится не «когда-нибудь», а условием безопасности этого выбора, потому что `low` — тот режим, в котором выход на третьем языке наблюдался. Если владелец не хочет трогать Go в этом заходе — (г) даёт рабочий прогон сегодня же ценой COGS и без единой правки кода; замерить его стоит ~$0.03 (одна волна на 10 главах).
**Ручку #77 (`regenerate_echo_before_escalate`) сам не включал** — по слову владельца, тем же решением.
---
## §7. Заявление = команда (приёмка пере-ранит)
```bash
cd backend
go build ./... && go vet ./... && go vet -tags live ./internal/pipeline/
go test -race -count=1 ./...
TM_MINER_PARITY=1 go test ./internal/miner/ -run Parity -count=1 -v
TM_CHECKER_LABELS=1 go test ./internal/checks/ -run TestCheckerLabelsBaseline -count=1 -v
TM_CHECKER_LABELS=1 go test ./internal/membank/ -run TestK6LabelsBaseline -count=1 -v
go test ./internal/pipeline/ -run TestGoldenDeterminism -count=1 -v
go test ./cmd/tmctl/ -run 'TestRenderQuality|TestRenderReport' -count=1 -v # новые строки наблюдаемости
# $0-чтения (ничего не мутируют; sha256 БД до/после совпадает)
./bin/tmctl report --config ~/books/gu-zhenren/coldrun-a/book.yaml | grep -E 'BANKNOTE|VOICE|ROUTING'
./bin/tmctl status --config ~/books/gu-zhenren/coldrun-b/reprobe/optB/book.yaml
./bin/tmctl report --config ~/books/gu-zhenren/coldrun-b/reprobe/optB/book.yaml
# платные (уже оплачены — повтор реплеит чекпойнты за $0)
LOG_LEVEL=debug LOG_LLM_BODIES=1 ./bin/tmctl translate --config ~/books/gu-zhenren/coldrun-b/reprobe/book.yaml --verify-bank
LOG_LEVEL=debug LOG_LLM_BODIES=1 ./bin/tmctl translate --config ~/books/gu-zhenren/coldrun-b/reprobe/optB/book.yaml --verify-bank
set -a; . ./.env; set +a; TM_LIVE=1 \
TM_CLASSIFY6_CONFIG=/home/ubuntu/books/gu-zhenren/coldrun-b/reprobe/classify6/book.yaml \
go test -tags live -run TestLiveClassifierHarmSet -v ./internal/pipeline/
# вендор-сверка
curl -sSL --compressed https://api-docs.deepseek.com/updates
curl -sSL --compressed https://api-docs.deepseek.com/guides/thinking_mode
```
**Сырьё (durable, вне git):** `~/books/gu-zhenren/coldrun-b/` — стенд · `…/reprobe/` (БД, `run-01-draft.{stdout,stderr}.log`, `backups/`) · `…/reprobe/optB/` (БД, логи двух прогонов, `*.db.mined-signature.yaml` 76 термов, `*.db.bank-stop.txt`, `backups/`) · `…/reprobe/classify6/` (БД, `classifier-6of6.json`).
---
## §8. Состояние дерева (только моё; НЕ коммичено)
```
M backend/cmd/tmctl/render.go (+2 блока рендера: BANKNOTE, VOICE)
M backend/internal/pipeline/live_conformance_test.go (починка сборки live-тега: cjkShare→sourceScriptShare)
? backend/cmd/tmctl/render_observability_test.go (новый: 5 тестов на обе строки, включая молчание)
? backend/internal/pipeline/live_reprobe_test.go (новый: боевой риг порога классификатора 6/6)
```
Чужое не тронуто: `START_PROMT.MD`, `frontend/`, `platform/`, `.gitignore`, `docs/` кроме этого отчёта и записи в `PROGRESS.md`. Во время сессии параллельная сессия залендила D39.84 — моя зона с ней не пересекается. Временный измерительный харнесс (`internal/checks/tmp_offlang_probe_test.go`) удалён. `CheapGateVersion`, labels-фикстуры и голден-фикстуры не двигались.
---
## §9. Критик полноты (обязательная секция — против себя)
- **N мал.** 14 вызовов пробы A и 24 пробы B — одна книга, одна пара, один срез, одно окно (UTC 23:5200:22, долина). «0 из 9» — сильное число, «эхо 15% против 10%» — слабое: на таких N эти доли статистически неразличимы, и я не утверждаю, что эхо выросло.
- **Проба A и проба B не строгий A/B.** Между ними изменена одна строка конфига, но окна разные (23:52 против 00:02) и провайдер мог вести себя по-разному; общий вывод держит только потому, что дельта огромна (0 пригодных из 9 против 20 `stop` из 22), а не потому, что эксперимент чистый.
- **Цена варианта (б) на КАЧЕСТВЕ не измерена вовсе.** Я мерил детерминированные оси (finish/пусто/эхо/письмо/деньги). Читабелен ли черновик при `low` так же, как при `high`, не судил никто — D39.61 это тоже фиксировал как незакрытое. Рекомендация (б) опирается на «работает и стоит столько же», а не на «переводит так же хорошо».
- **Вариант (г) я предлагаю, не замерив.** Основание косвенное: вендор объявил v4-pro нетронутым, и один хоп на нём отработал. Один вызов — не замер; перед выбором (г) нужна волна.
- **Английский выход я видел один раз.** Утверждать частоту класса по 1/18 нельзя; я утверждаю только существование класса и отсутствие гейта на черновой стадии.
- **Порог 6/6 наполовину «подсказан» промптом** — сказано в §3.5; независимая часть 4/4.
- **Терминолог-стену я объясняю тем же механизмом, что и черновую**, но вскрыл её счётчиками (`completion=8000` ровно, content пуст) и НЕ открывал сырое тело хотя бы одного батча терминолога — это слабее, чем разбор §3.1, где тела вскрыты.
- **Автор = ревьюер.** Адверсариальный проход по моим фиксам (§10) сделан мной же; внешнее ревью — за оркестратором. Два клейма я в ходе сессии опроверг сам («чанкер поехал» и «`pairs/` — мусор»), и это единственное свидетельство, что проход не был формальным.
---
## §10. Адверсариальный проход по СВОИМ фиксам
| Фикс | Атака | Итог |
|---|---|---|
| Строка BANKNOTE | Двигает ли голден/вердикты? | Нет: `renderReport` не входит в `testdata/golden/`, вердикты не читает. Голден пере-прогнан — PASS |
| Строка BANKNOTE | Сломает ли книгу без канала? | Нет: печатается при `lines>0 parse_fail>0 truncated>0`; тест молчания `TestRenderReportStaysSilentWithoutTheBanknoteChannel` |
| Строка BANKNOTE | Верны ли числа? | Независимо воспроизвела руками добытые числа coldrun-a (182 / 18 из 20 / parse-fail 3) |
| Строка VOICE | Не выдаёт ли «чисто» за «не измерено»? | Условие включает `VoiceCheckVersion != ""`, а он ставится ТОЛЬКО при включённом гейте (`quality.go:436-438`) ⇒ гейт выключен — строки нет; гейт включён и ноль — печатается ноль со знаменателями. Тест `…PrintsZeroWhenTheGateRan` |
| Строка VOICE | Ложится ли на неполные данные? | Все поля — счётчики int, `dashIfEmpty` на версии; nil-путей нет |
| Общность обоих | «Заработает ли пара, которой в репо НЕТ, без правки Go?» | Да: счётчики над store, ни одного пар/книжного литерала |
| Общность обоих | «Вторая книга той же пары — без ложных флагов?» | Да: ни одна строка не флагает, обе — чистая наблюдаемость |
| Фикс live-рига | Не изменил ли смысл пробы? | Изменил в правильную сторону: доля меряется против письменностей ЯЗЫКА пробы; ja-фрагмент прежде мерился бы zh-таблицей |
| Риг 6/6 | Не обходит ли шов егресса? | Обходил — и **это поймал `TestProviderEgressSeamIsSingle`**. Переписан на `runBankAttempt` (боевой денежный путь) ⇒ гейт зелёный, а цена пробы попала в леджер (было — считалась мимо него) |
| Риг 6/6 | Не подыгрывает ли тесту? | Кандидаты поданы с НЕВЕРНЫМ типом; «подсказанные» промптом 元石/灵泉 вынесены отдельным счётчиком `discriminating 4/4` |
| Стенд coldrun-b | Не отличается ли от эталона? | `pipeline.yaml` побайтно равен coldrun-a кроме шапки; `book.yaml` отличается ровно потолками, путями и book_id — перечислено в §A4 |
| Все правки | Батарея после них | `build`/`vet`/`vet -tags live`/`-race -count=1` — зелёные; парити EXACT; labels 5/5 фрозен; голден PASS |

View file

@ -38,19 +38,36 @@
### ⚠ `deepseek-v4-flash``DeepSeek-V4-Flash-0731`: слаг стабилен, ВЕСА СМЕНИЛИСЬ (полигон, 2026-07-31)
**Вендор-факт** (`api-docs.deepseek.com/updates`, запись `Date: 2026-07-31`; снято `curl`, счёт вхождений = 1 по копии без пробелов): *«The official release of the DeepSeek-V4-Flash API is now in public beta. The API calling method remains unchanged — simply set the model name to `deepseek-v4-flash` to use the latest version.»* · *«DeepSeek-V4-Flash-0731 keeps the same model architecture and size as DeepSeek-V4-Flash-Preview, and was only re-post-trained.»* · *«Significantly enhanced **agent** capabilities…»* · *«Note: This update only upgrades the DeepSeek-V4-Flash API. The DeepSeek-V4-Pro API and the APP/WEB models are unchanged.»***v4-pro (редактор, эскалационный хоп) НЕ тронут.** В `/v1/models` ничего не изменилось — там прежние два слага. **Урок календаря: «слаг живой» ≠ «модель та же»; версию проверять поведением, а не листингом.**
**Вендор-факт** (`api-docs.deepseek.com/updates`, запись `Date: 2026-07-31`; снято `curl`, счёт вхождений = 1 по копии без пробелов): *«The official release of the DeepSeek-V4-Flash API is now in public beta. The API calling method remains unchanged — simply set the model name to `deepseek-v4-flash` to use the latest version.»* · *«DeepSeek-V4-Flash-0731 keeps the same model architecture and size as DeepSeek-V4-Flash-Preview, and was only re-post-trained.»* · *«Significantly enhanced **agent** capabilities…»* · *«Note: This update only upgrades the DeepSeek-V4-Flash API. The DeepSeek-V4-Pro API and the APP/WEB models are unchanged.»***v4-pro (редактор, эскалационный хоп) ВЕСАМИ не тронут.** В `/v1/models` ничего не изменилось — там прежние два слага. **Урок календаря: «слаг живой» ≠ «модель та же»; версию проверять поведением, а не листингом.**
**У «v4-pro не тронут» есть срок годности (вписано оркестратором 02.08, D39.86):** та же страница `guides/thinking_mode` несёт сноску *«We will update the actual mapped effort of `deepseek-v4-pro` in early August 2026»* — то есть ПРЯМО СЕЙЧАС. Веса пока прежние, но вендор объявил смену МАППИНГА ЭФФОРТА у pro; любой довод формы «берём pro, он не тронут» обязан нести эту оговорку и пере-проверяться пробой, а не changelog'ом (changelog на 02.08 новее 31.07 записей не имеет — сверено оркестратором `curl`, HTTP 200).
1. **ФЛОР 8000 ПРОБИТ — боевая форма отдаёт ПУСТОЙ `content`.** Живьём 31.07 18:54 UTC: черновая волна боевым `translator.md` при `max_tokens=8000` дала `finish=length`, `completion_tokens=8000`, `content` = 0 символов на **4 чанках из 4**. ⚠ **Сравнение с холодным прогоном (2 из 68) НЕ является чистым контролём и понижено до индикативного:** тот ехал ДРУГИМ промптом (`translator-banknote.md`) и с ДРУГИМ потолком (`max_tokens=8496`). Несущая улика — не оно, а СОБСТВЕННЫЕ пробы провода: **один и тот же чанк, один и тот же рендер, cap 8000 → `length`+пусто, cap 16000 → `stop`+перевод** (таблица п.2). *(Испр. 31.07 по ревью.)*
2. **Механизм — не дегенеративный луп, а многословная обдумка.** 20 025 симв. `reasoning_content` = 122 строки, все уникальны: модель пере-переводит фразу за фразой внутри размышления и не доходит до ответа. Наблюдённый `reasoning_tokens` **на одном и том же чанке** (`chunk-1-0`, дефолтный эффорт): **98 · 8000⌐ · 14014 · 16000⌐** (⌐ = упор в потолок) — разброс ×163 при побайтно одном входе. На двух других чанках: 3117 и 16001⌐. **Хвост тяжёлый: при потолке 16000 упор случился в 2 пробах из 5.** *(Испр. 31.07 по ревью: прежняя формулировка смешивала три чанка в один ряд и пробу с потолком 8000 в знаменатель 16000.)*
3. **`reasoning_effort` — запись 04.07 устарела.** Вендор-дока `guides/thinking_mode` (снята 31.07, счёт = 3) разделяет **тумблер** `{"thinking":{"type":"enabled/disabled"}}` и **эффорт** `{"reasoning_effort":"low/high/max"}`: `low` — отдельный документированный уровень. Замер: `low` при потолке 8000 и temperature 0.3 → `finish=stop`, reasoning **170313** ток., **$0.000360.00091** за вызов (без ручки — $0.00220.0045 за пустой ответ).
4. **`effort:"low"` ПЕРЕ-ВООРУЖАЕТ эхо-мину:** 1 чистый китайский выход из 16 базовых вызовов (`cjk_share 0.83`, `finish=stop`). **Уточнение рамки D19.2: защита от эха деградирует НЕПРЕРЫВНО с эффортом, а не скачком на «выключено».** Движок эту ручку для deepseek слать не может и не должен — `config.echoMineViolation` (`models.go:276-281`); замер — его первое эмпирическое подтверждение.
**3а. ДЕФОЛТ ЭФФОРТА = `high`, и маппинг per-модельный** (дословно с той же страницы, снято `curl` HTTP 200 бэкендом 02.08 и пере-снято оркестратором при приёмке): *«Thinking mode is enabled by default, **with the default effort being high**»*. Таблица маппинга «запрошенный эффорт → фактический»:
| Запрошено | `deepseek-v4-flash` | `deepseek-v4-pro` |
|---|---|---|
| `low` | **`low`** | **`high`** |
| `high` | `high` | `high` |
| `xhigh` | `high` | `max` |
| `max` | `max` | `max` |
⇒ (i) **не слать `reasoning_effort` = ехать на `high`** — вот почему боевая форма упирается в стену (п.10); (ii) **на `deepseek-v4-pro` ручка `low` — НЕ РАБОТАЕТ** (маппится в `high`): рычаг бюджета размышления существует ТОЛЬКО у flash, и любой план «перевести роль на pro и придушить эффорт» несостоятелен; (iii) `none` в OpenAI-формате у DeepSeek не существует вовсе (колонка `reasoning.effort:"none"` — Anthropic-формат), запись 04.07 «`none` → 400» в силе.
4. **`effort:"low"` ПЕРЕ-ВООРУЖАЕТ эхо-мину:** 1 чистый китайский выход из 16 базовых вызовов (`cjk_share 0.83`, `finish=stop`). **Уточнение рамки D19.2: защита от эха деградирует НЕПРЕРЫВНО с эффортом, а не скачком на «выключено».****Хвост «движок эту ручку слать не может — `echoMineViolation`» ОТОЗВАН (оркестратор 02.08 по коду, D39.86): движок её слать МОЖЕТ.** Гейт (`config/models.go:485-501`) инспектирует МЕХАНИЗМ (`capabilities.reasoning.control` ∈ {`extra_body_disable`, `effort`} + thinking-ключ в `extra_body`), а не значение `stage.reasoning`; у deepseek `control = ReasoningNone`, где `off`/`""` — осознанный no-op, а `low|medium|high` уходят на провод как есть (`llm/capability.go:167-171`). Конфиг `stages[draft].reasoning: "low"` грузится без ошибки и доезжает до провода — проверено исполнением (coldrun-b §3.3). ⇒ **вопрос «включать ли `low`» — экономико-качественный (эхо растёт), а не «нельзя технически»; амендмент гейта для этого НЕ нужен.**
5. **Микро-few-shot: ⚠ ПРЕЖНЯЯ ФОРМУЛИРОВКА ОТОЗВАНА (31.07, адверсариальное ревью).** Числа «reasoning ×1.9» и «постинструкция дешевле на 23.3%» получены НЕПАРНЫМ сравнением средних на распределении, чей разброс ×163 (п.2). **Парный пересчёт по тем же 12 фрагментам:** few-shot думает МЕНЬШЕ базы на **7 из 12** (медиана Δ **65** ток., знаковый тест p=0.77); постинструкция думает БОЛЬШЕ базы на **9 из 12** (медиана Δ **+208**, p=0.15). «+91%» — артефакт четырёх попаданий в хвост. Скидка постинструкции на 58% состоит из ПРЕФИКСНОГО КЭША (её `system` побайтно равен базовому — sha `e9ea1ae7dae0`, постинструкция уходит в USER-хвост; кэш 95.0% против 27.5% у базы); при пересчёте по некэшированной цене остаётся 9.0%. **Что устояло:** суммарная цена арма few-shot на этой выборке +28.4% и без кэш-эффекта, и **единственный за 48 вызовов выход НА АНГЛИЙСКОМ** (5 770 симв, `finish=stop`) — его. Эхо в том же арме НЕ атрибутируется few-shot (см. п.6).
6. **⚠ ЭХО НА 0731 СТОХАСТИЧНО ПО ВЫЗОВУ, а не детерминировано по фрагменту** — прямая улика: два вызова с **побайтно идентичным запросом** (sha `5c304c9b3cf4`, `effort:low`, cap 8000, temp 0.3) дали `cjk_share 0.000` и `cjk_share 0.831`. **Это отменяет посылку строки ниже («ретраи не помогают — детерминировано для фрагмента»), снятую на `deepseek-chat`, и посылку комментария `disposition.go:138-148` («retry just re-produces them»), из-за которой `cjk_artifact` идёт СРАЗУ в эскалацию.** Арифметика ремонта перевернулась: эскалация на v4-pro = **$0.007335 за ОДНО эхо** ($0.014670 холодного прогона — это ДВА эха на разных чанках, id 58 и 62), простой ре-ген на flash при `effort:low` = **$0.00096** (**≈7.6×** дешевле). Предложение бэкенду: N=1 ре-ген ПЕРЕД эскалацией. Гейт не ослабляется — D19.2 цел.
7. **Разгон думания привязан к ПЛОТНОМУ ХАНЬСКОМУ ВХОДУ, не к модели вообще.** Тот же промпт и параметры (cap 8000, дефолтный эффорт): **en** (877 ток. входа) → `stop`, reasoning **435**; **zh короткий** (776 ток.) → `stop`, reasoning **3393**; **zh длинный** (1679 ток.) → `length`, reasoning **8000⌐**, `content` пуст. При сопоставимом входе zh требует **×7.8** размышления против en ⇒ конфаунд длины закрыт. Границы: en n=1, zh-короткий n=1, zh-длинный n=8; **ja не проверялся**.
8. **Вендорская рамка бюджета вывода** (`quick_start/pricing`): контекст 1M, **max output 384K**, и *«For the high and max reasoning effort levels, a maximum output length of 384K tokens is recommended»*. Наш флор 8000 — **на два порядка ниже** вендорской нормы для высокого эффорта ⇒ дело не в «поломке», а в смещении ДЕФОЛТНОГО эффорта при нашей калибровке под прежний чекпойнт. Багрепортов о регрессии в открытом поиске нет (31.07).
9. **Движковый леджер `reasoning_tokens` для deepseek держит 0 СОЗНАТЕЛЬНО** (`provider_openai.go:22-24`, `ReasoningSubset` — thinking внутри `completion_tokens`, иначе двойной счёт). Длину думания видно только на сыром проводе — при диагностике идти туда, а не в `request_log`.
10. **БОЕВАЯ ФОРМА, замер бэкенда 02.08 (coldrun-b, ре-проба строки 74; принято D39.86).** Всё ниже снято САМИМ боевым путём `tmctl translate`, не ригом:
- **«Поднять флор до 16000» ФАЛЬСИФИЦИРОВАНО.** При боевом `max_tokens=8496` (флор 8000 + `bankTokenBudget` 496) — **0 из 9** свежих вызовов пригодны (8 пусто + 1 обрывок 993 симв., все `finish=length`, `completion` ровно в потолок). На движковом удвоении до 16992 — **4 из 5 тоже пустые**; сырые тела: `reasoning_content` 15 424 → 21 528 симв., то есть добавка потолка уходит в думание. Механизм п.2 подтверждён на боевой форме при ~100% частоте. Сходиться некуда: вендорская норма вывода для `high` — 384K (п.8), ×45 к флору.
- **`reasoning_effort:"low"` возвращает волну к жизни:** 20 из 22 свежих черновых вызовов `finish=stop`, 18 из 20 чанков отгружено, латентность 944 с против 67190 с. Цена — ниже; эхо — выше (см. следующий пункт).
- **⚠ ЭХО-МИНА ПРИ ВЫКЛЮЧЕННОМ THINKING ЖИВА НА ВЕСАХ 0731 — клейм пере-подтверждён, а не унаследован** (проба C, вендорский тумблер `extra_body {"thinking":{"type":"disabled"}}` в КАРАНТИННОЙ копии models.yaml вне git; боевой конфиг и гейт не тронуты): **эхо 4/20** против 3/20 у `effort:low` и 0 пустых из 22 вызовов. Это важно: вся прежняя эмпирика флага `echoes_when_thinking_off` была снята на весах `V4-Flash-Preview`, которых больше нет (п. «Вся эмпирика P4» ниже) — теперь клейм имеет носителя на ЖИВЫХ весах. Флаг остаётся оправданным. На N=20 разница 15% vs 20% статистически неразличима: направление согласуется с «непрерывной деградацией защиты» (п.4), но не разделяет её.
- **Новый класс дефекта: выход на ТРЕТЬЕМ языке.** При `effort:low` 1 черновик из 18 пришёл полным связным переводом **на английский** (`finish=stop`, кириллица 0.000) и прошёл гейт черновой стадии как `ok``classify` экранирует ИСХОДНУЮ письменность, пустоту, обрыв и отказ, а «не исходный и не целевой» не ловит ни один предикат (движковая сторона — бэклог 46). При `high` и при thinking-off таких 0/18. Класс совпадает с единственным английским выходом 31.07 (п.5).
- **Терминолог 0731 упирается в ту же стену и ручкой НЕ лечится:** 4 батча из 5 вернулись `length` с `completion=8000` ровно и пустым телом (на coldrun-a до смены весов было 21/21 `stop`), банк консолидировал 1 терм из 81. Причина движковая, не вендорская: бэнк-роли не имеют ручки эффорта вовсе (бэклог 104) ⇒ **всегда едут вендор-дефолтом `high`**. При выключенном thinking стадия здорова (5/5) — это единственная из трёх замеренных конфигураций, где банк работает без правки Go.
*(Полигон, отчёт `archive/reports/POLYGON_PROMPTLANG_ANTIECHO_2026-07-31.md`; харнесс `eval/promptlang/`. Развилка «поднять флор / разрешить `low` / ждать» — за подписью владельца, §2 отчёта.)*
*(Полигон, отчёт `archive/reports/POLYGON_PROMPTLANG_ANTIECHO_2026-07-31.md`; харнесс `eval/promptlang/`. Пункты 3а и 10 — бэкенд-сессия coldrun-b, `archive/reports/COLDRUN_B_DEBUG_2026-08-02.md`, внесено оркестратором при приёмке D39.86. Развилка «поднять флор / разрешить `low` / ждать / сменить модель» — за подписью владельца.)*
**Находка (эксп. 03):** reasoning реально улучшает реалии/имена в переводе (羅生門: «Радзёмон»→«Рашо-мон»), но локально нежизнеспособен (8.6 мин/фрагмент). **Открытый вопрос для бэкенда: проверить think-ON на быстром облачном черновике/редакторе как рычаг качества.**