textmachine/docs/archive/prompts/BACKEND_EFFORT_HANDLE_SESSION_PROMPT_2026-08-02.md

47 KiB
Raw Blame History

ИСПОЛНЕН И ПРИНЯТ (D39.91, 02.08.2026, код 553f1a3). Отчёт: ../reports/EFFORT_HANDLE_2026-08-02.md (ревью-шапка приёмки). Работа B выделена в пак экрана 46 (D39.92 п.1 + D39.93), работа C не стартовала (строка 16 жива).

Промт бэкенд-сессии: РУЧКА ЭФФОРТА + ЭКРАН ЦЕЛЕВОГО ЯЗЫКА + ДОБИВКА ХОЛОДНОГО ПРОГОНА (строки 104 · 46 · 16)

Выдан 02.08.2026, оркестратор №10; решение владельца по развилке строки 74 (D39.87): вариант (б) — явный reasoning_effort: "low" для черновика ПЛЮС правка Go, дающая ручку тем ролям, у которых её нет. Зона: backend/ + стенд ~/books/gu-zhenren/coldrun-b/ + свой отчёт в docs/archive/reports/. НЕ коммитить — лендит оркестратор. Первый деливерабл — эхо-блок ≤10 строк (первым сообщением ДО работы: как понял скоуп / три работы и их СТОП-точки / потолки денег / что вне скоупа; подтверждения не жди — работай до СТОП-условий).

Деньги (жёстко): работа A = $0. Работа B = $0. Проба банка на low (§3.4) ≤ $0.10. Работа C (прогон) ≤ $5.00 суммарно. ⚠ $5 — ВНЕШНИЙ предохранитель, и он НЕ первый. Внутри прогона стоят два суб-бюджета, которые связывают раньше и гаснут МОЛЧА, без ошибки: gates.terminology.budget_usd: 0.05 (≈4 прохода терминолога — WARN budget would be exceeded by the next batch; the remaining terms are left unconsolidated + break) и escalation.budget_usd: 0.10 (≈11 хопов — WARN escalation hop denied by a USD ceiling; keeping the primary flag, деградация без падения; ровно это усекло наблюдение эскалаций на прошлой пробе). Оба — в ~/books/gu-zhenren/coldrun-b/pipeline.yaml. Не спутай молчащий суб-бюджет с отказом модели — иначе поставишь ложный СТОП; и не подними их молча — правку суб-бюджета объяви в отчёте с причиной. Потолки продублированы в book.yaml ceilings: book_usd: 5.00 И day_usd: 5.00 (ключа budget_usd не существует — строгий декодер упадёт; ⚠ day_usd считается по КАЛЕНДАРНОМУ дню UTC и по ЭТОЙ БД, store/ledger.go:39,47 — через полночь ось обнуляется, несущий предохранитель = book_usd). Превышение любого потолка = СТОП+релей. Проба §3.4 живёт в СВОЁМ проекте (свой book_id, свой project_db) ⇒ её леджер отдельный и в потолок $5 работы C не входит — $0.10 сверх; в отчёте выведи ТРИ числа: проба · прогон C · сумма пака. В отчёте деньги — двумя независимыми путями (леджер И собственный пересчёт провайдерского usage по вендор-ценам); помни: леджер = НИЖНЯЯ граница (строка 78: 2xx с битым декодом списывается и в request_log не попадает — на прошлой пробе это было $0.0151 неизвестности на 17 оплаченных вызовов).


§0. Рамка и ГЛАВНЫЙ мандат этого пака

Слово владельца дословно: «элегантно встроить в текущее решение по коду. Чтоб было чисто». Это не украшение — это приёмочный критерий. Перевожу его в проверяемые вопросы, на каждый из которых отчёт обязан ответить:

  1. «Это новый механизм или использование существующего?» Правильный ответ — второй. Поле Stage.Reasoning существует с самого начала (config/pipeline.go:208), проброс на провод существует (stagerun.gollm/capability.go), капабилити-слой различает провайдеров данными. Ничего из этого изобретать заново НЕ надо.
  2. «Появится завтра ЧЕТВЁРТАЯ синтетическая стадия — она унаследует ручку сама или её опять забудут?» Это главный вопрос пака. Корень дефекта — не «забыли ключ», а рукописные литералы config.Stage, каждый из которых молча теряет поля родителя: в шиппинг-коде их ровно три (terminologist.go:515обе бэнк-роли; terminologist.go:568 — не-проводная, из неё читается только Name; internal/pipeline/repair.go:384 — ⚠ в дереве ДВА repair.go, нужен пакет pipeline; здесь родительская стадия РЕАЛЬНАЯ и несёт выбор владельца, который просто теряется), плюс ЧЕТВЁРТЫЙ в live-риге (internal/pipeline/live_reprobe_test.go), и он не декоративный — см. §3.4. Правка, чинящая места копипастой, дефект НЕ закрывает — она его тиражирует. Перед стройкой пере-проверь список сам: grep -rn 'config\.Stage{' --include='*.go' backend/.
  3. «Заработает ли пара, которой в репо ещё НЕТ, без правки Go?» и «вторая книга той же пары — без ложных флагов?» — обязательны на каждый фикс, как всегда.
  4. «Не появилось ли второго способа сказать то же самое?» Один шов, одно место решения, никаких параллельных путей.

Дисциплина: никаких хаков и ворэраундов; каждый фикс — поддерживаемое мультиязычное решение с тестом. Архитектурная дыра → СТОП+пинг с диагнозом и вариантами, не чинить на месте. Комментарии — 12 строки «почему», улики — в отчёт (норма владельца 26.07). Самопроверка исполнением обязательна (свой код + сформированные запросы + полученные результаты); вывод на агрегате до вскрытия единиц запрещён — перед любым «узел работает» открой хотя бы одну живую единицу с каждой стороны. Дифф ^func Testисполнением, не памятью. В конце — адверсариальный проход author≠reviewer по своим правкам. Канал вопросов: непонятно / конфликт промта с кодом / замер бьёт по посылке → СТОП+пинг оркестратору через владельца, НЕ интерпретация. Право сказать «этого делать не надо» — есть, с аргументом в отчёте.


§1. Онбординг (карта чтения, целиком доки НЕ читать)

  1. CLAUDE.md (гардрейлы: .env НЕ читать · DeepSeek thinking НЕ отключать · аномалия провайдера → вендор-дока, не гадать) → CURRENT-STATE в docs/PROGRESS.md (строки 104, 46, 74, 16, 13б — твои).
  2. docs/architecture/05-decisions-log.md — блоки D39.86 и D39.87 целиком (приёмка ре-пробы со всеми числами и поправками; решение владельца по развилке + мандат «элегантно и чисто» как приёмочный критерий).
  3. docs/experiments/00-provider-quirks.md, секция DeepSeek-V4-Flash-0731 целиком, особенно п.3а и п.10 — вендор-таблица маппинга эффорта и что именно замерено на боевой форме. Читать ПЕРЕД любым платным вызовом.
  4. docs/archive/reports/COLDRUN_B_DEBUG_2026-08-02.mdревю-шапка обязательна (в ней поправки приёмки; тело отчёта местами точнее шапки не является).
  5. backend/README.md (инварианты «ЛОМАТЬ НЕЛЬЗЯ») + docs/architecture/12-go-style-notes.md §0 (норматив общности).

§2. Что УЖЕ установлено замером — не пере-открывать (приоры, опровергаются аргументом/замером)

  • Блокер — не эхо, а ПУСТЫЕ ответы. На боевом max_tokens=8496 0 из 9 вызовов пригодны: размышление (1521 тыс. симв.) съедает общий бюджет, до ответа модель не доходит. Удвоение потолка НЕ помогает (4/5 пустых при 16992) — вариант «поднять флор» фальсифицирован и закрыт.
  • Причина — вендор-дефолт эффорта. Дословно из guides/thinking_mode: «Thinking mode is enabled by default, with the default effort being high». Маппинг: у deepseek-v4-flash low→low, high→high, xhigh→high, max→max; у deepseek-v4-pro low→high — то есть на pro ручка эффорта не работает вовсе. Сноска вендора: «We will update the actual mapped effort of deepseek-v4-pro in early August 2026» — то есть прямо сейчас; при аномалиях у РЕДАКТОРА идти в вендор-доку, а не гадать.
  • reasoning: "low" на deepseek-стадии легален и гейт echoMineViolation НЕ трогает (гейт инспектирует МЕХАНИЗМ capabilities.reasoning.control, не значение; у deepseek ReasoningNone, где off/"" — осознанный no-op, а low уходит на провод). Проверено проводом: 22 тела с reasoning_effort:"low", ноль ключей thinking, ни одного пустого reasoning_content (отчёт: 24/24 разобранных; пере-счёт приёмки по сырому логу — 27/27, разница только в знаменателе) ⇒ гардрейл «thinking не выключать» не нарушается.
  • Замеры варианта (б) на 20 чанках: 20/22 вызовов finish=stop, 18/20 чанков отгружено, волна $0.028195 all-in ($0.019489 только flash), латентность 944 с. Цена: эхо 3/20 · 1 черновик из 18 пришёл ЦЕЛИКОМ НА АНГЛИЙСКОМ и прошёл как ok (это и есть работа B).
  • Ре-ген лечит СТОХАСТИКОЙ, а не бюджетом: единственный выживший вызов пробы A уложился в 8285 токенов при базовом потолке 8496 и выданных 16992 ⇒ доливать бюджет бессмысленно.
  • Терминолог на 0731 сломан: 4 батча из 5 length с completion=8000 ровно и пустым телом, банк консолидировал 1 терм из 81 (было 21/21 stop до смены весов). При thinking-off он был здоров 5/5 — но thinking-off это разворот гардрейла, мы его НЕ делаем.
  • Терминолог на low НЕ ЗАМЕРЕН НИКЕМ. Это открытый вопрос твоей §3.4, а не известный факт. Формулировку квирков п.10 «терминолог … ручкой НЕ лечится» читай вместе со следующей фразой того же буллета — «бэнк-роли не имеют ручки эффорта вовсе ⇒ всегда едут вендор-дефолтом high»: там сказано «ручки НЕТ», а не «low пробовали». Противоречия с этим промтом нет.

§3. Работа A — ручка эффорта для ролей, у которых её нет (строка 104). $0 кода + ≤$0.10 пробы

Цель: выбор владельца «сколько думать» должен доезжать до КАЖДОГО платного вызова движка, а не только до стадий книги. Сегодня он доезжает до draft/edit и теряется у бэнк-ролей (терминолог, классификатор) и у repair.

Делай РОВНО так (ратифицировано):

  • Значение приходит из ДАННЫХ (конфиг), Go не ветвится ни по провайдеру, ни по паре, ни по книге.
  • Ручка ран-скоупная, не пар-данные и не книжный канон — в пар-пак и в book.yaml она не заходит.
  • Правка обязана накрыть все три места разом и так, чтобы четвёртое такое же место не могло появиться молча (см. §0 п.2).
  • repair.go:384: родительская стадия st РЕАЛЬНАЯ и уже несёт выбор владельца — здесь речь не о новом ключе, а о прекращении его потери. Доккоммент repair.go:378-379 («no reasoning setting, so the provider default holds — on DeepSeek that means thinking stays ON and the echo mine is not armed») декларирует посылку, которую замер фальсифицировал — он обязан уехать вместе с правкой.
  • Ловушка хеш-оси, закрыть ТЕМ ЖЕ диффом — ОБЕ расщеплённые пары, не одна: bankCheckpointExists строит Request БЕЗ Temperature/Reasoning (terminologist.go:498-501), а runAttemptС ними (stagerun.go:403-406); Reasoning входит в RequestHash (internal/pipeline/render.go:279,308 — в дереве ДВА render.go, нужен пакет pipeline). ТА ЖЕ пара есть на пути repair: repairCheckpointExists (repair.go:350) собирает Request тем же обрезанным способом, и её доккоммент (repair.go:346-349) прямо декларирует «mirrors runRepairAttempt's request identity exactly … the two must address the same checkpoint» — правка :384 без :350 этот инвариант ФАЛЬСИФИЦИРУЕТ. Сегодня оси совпадают только потому, что значения нулевые. ⚠ Расходятся они в ОБЕ стороны, и вторая — денежная, она и опаснее: (i) paid ложно-false — на резюме уже оплаченного прохода бюджетный пред-чек засчитает оценку заново и может оборвать проход до первого вызова; (ii) paid ложно-true — на стенде, где уже лежат бэнк-чекпойнты, записанные при ПУСТОМ Reasoning (а такой стенд у тебя есть — reprobe/optB), проба адресует старый хеш и вернёт «оплачено», из-за чего гейт суб-бюджета (terminologist.go:583, условие !paid && …) не выполнится ВООБЩЕ, а runAttempt посчитает новый хеш, чекпойнта не найдёт и уйдёт в свежий ПЛАТНЫЙ вызов мимо gates.terminology.budget_usd — прикрывать останется только книжный потолок. Оба направления закрываются ОДНИМ диффом и оба обязаны иметь тест: (1) резюм оплаченного пасса бюджетом не режется; (2) свежий пасс на стенде со старыми чекпойнтами гейт бюджета ПРОХОДИТ, а не обходит. Пере-проверь сам, нет ли третьей такой пары: grep -rn 'RequestHash(Request{' --include='*.go' backend/.
  • Доккомменты эхо-гейта, тем же диффом (обязанность D39.86 п.2 / D39.87): config/models.go:440-448 и llm/capability.go:52-58 утверждают инвариант «echo-prone провайдер ОБЯЗАН держать thinking на дефолте провайдера». После санкции (б) это неверно: тот же провод легален через stages[].reasoning и запрещён через model.extra_body (thinkingControlExtraKeys содержит сам ключ reasoning_effort при любом значении). Гардрейл «thinking не выключать» цел — неполна ДОКУМЕНТАЦИЯ защиты, и следующая сессия прочитает её как полную. Сам гейт не ослаблять.

Реши сам и аргументируй в отчёте:

  • Форма шва. Мой приор (опровергается аргументом): корень — рукописные литералы config.Stage, теряющие поля; значит лечение — ОДИН шов деривации синтетической стадии, где по каждому полю принято ЯВНОЕ решение, и все три места идут через него. Если найдёшь форму чище — бери свою, но ответь §0 п.2 явно.
  • Гранулярность ручки внутри блока банка. gates.terminology обслуживает ДВЕ роли и допускает ДВЕ РАЗНЫЕ модели (Model для терминолога и ClassifyModel/ClassifierModel() для классификатора). Одна ручка на обе или две — решить и обосновать: у ролей разная форма задачи (длинный рендер против короткой классификации с закрытым словарём), и замер показал, что в стену упирается именно длинная (классификатор при high уложился в 1323 токена вывода). Не размножай ключи без нужды, но и не склеивай молча.
  • Temperature тем же диффом. Та же конструкция роняет и её (на провод уходит temperature: 0). Сегодня ущерба нет — DeepSeek в thinking-режиме температуру молча игнорирует (quirks) — но при смене модели бэнк-роли поедут на нуле без единой строки конфига, это описывающей. Решить осознанно: пробрасывать, или явно зафиксировать нуль комментарием «почему так правильно».
  • Мульти-провайдерность ручки. У control = extra_body_disable (glm-5/5.1) ПУСТОЙ эффорт означает не «вендор-дефолт», а thinking:{type:disabled} — то есть thinking ВЫКЛЮЧЕН, зона эха. Конфиг это допускает: gates.terminology.model не ограничен семейством. Дизайн обязан закрывать оба режима осознанно, иначе ручка починит только ReasoningNone-семейство и оставит на glm тихий thinking-off.
  • Наш enum против вендорского. Валидация (config/pipeline.go:954-957) принимает "" | off | low | medium | high — это НАШ набор, он per-стадийный и слеп к провайдеру. У DeepSeek документированы low/high/max (+xhigh в таблице маппинга): medium на deepseek — неопределённое поведение, а max/xhigh нашим конфигом недостижимы вовсе. Нужно ли валидировать значение против капабилити РЕЗОЛВНУТОЙ модели — твой дизайн-вызов; если да, это касается и новой ручки. Аргументируй решение либо явный отказ.

§3.4. Проба банка на low (≤$0.10, ОБЯЗАТЕЛЬНА перед работой C). Терминолог на low не мерил никто — это открытый вопрос, а не известный факт.

  • ⚠ Хост пробы: НЕ coldrun-a. Тот проект — ЗАМОРОЖЕННЫЙ ЭТАЛОН (банк-стоп, подписные сайдкары), на нём держится сравнимость цены строки 16; писать в него ЗАПРЕЩЕНО, только читать. Отдельной команды «прогнать только бэнк-стадию» не существует (--verify-bank лишь ОСТАНАВЛИВАЕТ после банка), а майнинг-стоп идёт после ВСЕЙ черновой волны ⇒ проба «с нуля» купила бы ещё одну черновую волну и вышла за потолок.
  • Маршрут (приор, опровергается аргументом): СВОЙ проб-проект, а не резюм чужого. Заведи ~/books/gu-zhenren/coldrun-b/reprobe/bank-low/ по образцу reprobe/classify6/: свой book_id, свой project_db, свои ceilings: book_usd 0.10 / day_usd 0.10, source_file = срез coldrun-a на чтение, черновая стадия на выбранном уровне. Смета: черновая волна ≈$0.02 + батчи банка ≈$0.01 ⇒ порядок $0.035, влезает с запасом. Так проба изолирована, её леджер отдельный, и провалиться она может не тронув ничего. ⚠ Альтернатива «резюмнуть optB, у которого волна уже куплена» дешевле, НО: у него остаток потолка $0.000534 при book_usd: 0.04 (потрачено $0.039466) — потолок пришлось бы поднимать, а в его БД лежат СТАРЫЕ бэнк-чекпойнты, написанные при пустом Reasoning, то есть ровно материал для ложно-true из ловушки §3. Выберешь этот путь — аргументируй и закрой оба риска явно.
  • ⚠ ДВА молчащих пути обрыва — критерий обязан их различать. Пасс бэнк-роли деградирует БЕЗ ошибки и БЕЗ падения: (i) ролевой суб-бюджет gates.terminology.budget_usd (terminologist.go:583-594) — WARN budget would be exceeded by the next batch; the remaining terms are left unconsolidated + break; (ii) книжный потолок леджера — отказ резервации. В ОБОИХ случаях consolidated проседает ровно так же, как при сломанной модели. Поэтому вердикт «low не работает» имеешь право вынести ТОЛЬКО предъявив, что ни один из двух путей не сработал: прочитай RoleSpentUSD роли, остаток суб-бюджета и spend ДО и ПОСЛЕ, и приведи их в отчёте рядом с числом батчей. Иначе получится ложный СТОП, отменяющий работу C на пустом месте.
  • Ответь числами: сколько батчей finish=stop из скольких, сколько термов консолидировано из скольких, off_language, цена, и вскрой СЫРОЕ ТЕЛО хотя бы одного батча (прошлая сессия этого не сделала и сама назвала это слабостью). Критерий: батчи должны пролезать. Не пролезают на low — это НОВАЯ развилка (другой уровень / другая модель бэнк-роли) ⇒ СТОП+релей владельцу с числами, работу C не начинать.
  • Классификатор проверяется тем же заходом ригом 6/6 (internal/pipeline/live_reprobe_test.go, build-tag live, ~$0.0004). ⚠ Риг несёт тот самый ЧЕТВЁРТЫЙ рукописный config.Stage, а runBankAttempt оставляет от переданной стадии только Name. После твоего шва риг ОБЯЗАН ехать через тот же шов — иначе его зелёное 6/6 не доказывает про low ничего (ложно-зелёный результат за $0.0004). Это и есть живая проверка вопроса §0 п.2: если риг пришлось править руками отдельно — шов недостаточно элегантен.

§4. Работа B — экран целевого языка (строка 46). $0

Предмет: на low наблюдался полный связный черновик на английском, прошедший гейт черновой стадии как disposition=ok. Корень: classify экранирует ИСХОДНУЮ письменность, пустоту, обрыв и отказ; «не исходный и не целевой» не ловит ни один предикат. Санитайзер поймал бы, но он стоит только на последней стадии (chunkrun.go:52, isFinal).

Делай РОВНО так:

  • Область — выход не-последней стадии КНИГИ, и только её.isFinal=false — это НЕ синоним «черновик»: тем же runAttempt(..., isFinal=false) идут бэнк-роли (terminologist.go) и repair, а их ответы законно не в целевой письменности (таблица терминов несёт исходные ханьские ключи; repair возвращает спан). Экран, повешенный на «любую не-последнюю стадию» буквально, даст 100% ложных флагов на терминологе. Скоуп задай так, чтобы это было невозможно, и покажи в отчёте, ЧЕМ именно он ограничен (роль? позиция в Stages? явный признак «это шиппинговая проза»?).
  • Экран данными, не Go-ветвлением. ⚠ Носитель gates.terminology.target_script НЕ годится — я его предлагал в черновике промта и снимаю: ключа нет ни в одном шиппинговом конфиге репо, и живёт он под ЧУЖИМ гейтом (при выключенном терминологе не валидируется) ⇒ новый экран оказался бы инертен в проде. Носитель выбери сам и обоснуй: у движка уже есть дата-план целевой стороны (internal/lang/data/, checks.Checkers с TargetActive()/TargetScriptNonLatin(), Book.TargetLang) — приор в том, что ответ там, а не в новом ключе конфига. Ревью-вопрос: «пара, которой в репо нет, получает экран автоматически или требует правки Go?»
  • Это ВЕРДИКТ-ДВИГАЮЩЕЕ изменение. Порядок: сначала дизайн и пинг с ним, потом код. В дизайне обязан назвать развилку, а не предрешать её: (а) предикат внутри classify() ⇒ бамп classifierVersion (disposition.go:107-118), который фолдится в снапшот (snapshot.go:430) ⇒ снапшот двигается у ВСЕХ книг и голден пере-захватывается; (б) отдельный гейт/флаг вне classify() ⇒ область фолда другая. Цена (а) на существующей книге — промах ВСЕХ чекпойнтов, --resnapshot + пере-покупка; на свежем стенде coldrun-b — ноль. Голден пере-захватывается ОДИН раз под ратифицированную смену поведения, и маскированный структурный дифф обязан быть пуст, если менялись только версии/хеши (голден-гард = инвариант №8, D23 п.1).
  • labels-фриз работа B двигать НЕ ДОЛЖНА вовсе — она не трогает предикаты k2/k4a/k4b/k4_inverse/K6. Любое отклонение от чисел §7 = регресс, а не новый базлайн ⇒ СТОП+пинг, не пере-базлайнить.

Реши сам и аргументируй:

  • Вторая половина дыры, и она важнее для общности. detectLatinInsertion (checks/sanitizer.go:228) внутри санитайзера НЕ обусловлен TargetScriptNonLatin(), хотя доккоммент disposition.go:302-305 объявляет именно эту защиту (реальный гард стоит только на репэйр-пути — quality.go:215, repair.go:208). Следствие: как только будущая латинописьменная цель поедет задокументированным путём расширения (data/target-<tgt>.txt в go:embed), детектор сработает на ЧИСТОЙ целевой прозе и дропнет 100% чанков; а частичный файл цели невозможен — CompileCheckers паникует, то есть новая цель ОБЯЗАНА включить санитайзер. Ревью-вопрос владельца для →en/→de сегодня отвечается НЕТ. Кандидат лечения — тот же шов, что уже применён к репэйру. Твой вызов: чинить это здесь (по-моему — да, это одна работа с первой половиной) или выносить с носителем; ответь явно.
  • Что делать с пойманным юнитом: флаг+скип, ре-ген, или эскалация. Помни: empty/length сегодня retryable, но НЕ escalatable (disposition.go:142-149), и ре-ген лечит стохастикой (§2).

§5. Работа C — добивка холодного прогона (строка 16). ≤$5

Идёт только после того, как работы A и B ЗАКРЫТЫ И ЗАМОРОЖЕНЫ (код + пере-захваченный голден + зелёная батарея ВМЕСТЕ с ними) и §3.4 зелёная. Причина жёсткая: работа B двигает версию, фолдящуюся в снапшот ⇒ любая правка B после первого платного вызова C промахивает ВСЕ чекпойнты книги — смок C1 осиротеет и C2 перекупит его целиком, а «итоговая цена холодного старта» (единственный деливерабл строки 16) станет невыводимой. Работа B застряла на дизайн-пинге → работа C НЕ стартует, это легитимный исход захода.

Стенд ~/books/gu-zhenren/coldrun-b/ собран, $0-проверен и стоит нетронутым: свежая БД, сид НЕ подключён (прогон холодный), pipeline.yaml побайтно равен эталону coldrun-a кроме шапки, ключи проверены.

Правка стенда, которую делаешь ТЫ (не подразумевается — делай явно): в ~/books/gu-zhenren/coldrun-b/pipeline.yaml черновая стадия сейчас несёт reasoning: "off"это и есть тот no-op, который отправил прошлый прогон в стену 0/9. Поставь туда выбранный владельцем уровень; комментарий строки («NO-OP у deepseek … эхо-мину НЕ вооружает») после правки неверен и должен уехать вместе с ней. Редакторскую стадию (deepseek-v4-pro) НЕ трогай: у pro эффорт не настраивается (§2), "off" там останется no-op'ом. Бэнк-роли — по итогам §3.4. Каждую правку стенда перечисли в отчёте построчно.

Механика ступеней (не гадать): майнинг-стоп идёт после ВСЕЙ черновой волны. C1 смок = source_file из 2 глав. C2 добор = ДОПИСАТЬ остальные главы в тот же source_file, ту же БД, тот же проект — вторую БД НЕ создавать, непрерывность автобанка и есть предмет отладки. ⚠ ЛЕГИТИМНО при доборе: рост автобанка двигает draft-снапшот; байт-неизменные юниты спасает re-pin (repin.go), а изменённые инъекции глав смока перекупятся ПОД порогом консента (min($0.50, 5%), rebill.go) — это НЕ тихая перепокупка и НЕ дефект: посчитай, объясни, ложного СТОПа не делай.

Предохранитель редакторской волны (узел без рычага). Редактор стенда — deepseek-v4-pro, у которого по §2 ручка эффорта НЕ работает (low→high), а сама редакторская волна не гонялась НИ РАЗУ — ни до смены весов, ни после (coldrun-a закрылся на банк-стопе). То есть в C1 ты впервые запускаешь узел того же класса отказа, что убил черновик и терминолога, и рычага у тебя там нет. Останови после ПЕРВЫХ 2 edit-юнитов и посмотри finish_reason, completion_tokens и непустоту content на каждом прежде чем пускать волну целиком. Упор в потолок / пустое тело / completion ровно в лимит = тот же блокер ⇒ СТОП+пинг с числами, не подбор числа и не «поднимем флор».

  • C1. Черновая волна → майнинг-стоп → терминолог → банк-пауза --verify-bank как ТВОЯ инспекционная точка (не подпись владельца — банк автономен, D39.77): вскрой банк (язык dst · экран целевой письменности · размеры · KWIC-санити · доля ⟨проверить⟩), вскрой ГЛАЗАМИ 23 черновика, сверь деньги двумя путями. Всё объяснимо → продолжай с НЕподписанным банком (пере-запуск translate без --verify-bank). Редакторская волна → гейты/чекеры → экспорт → вскрой 23 финала глазами.

  • C2. Остальные ~8 глав тем же порядком (банк-пауза на твоё усмотрение, аргументируй).

  • Обязательные наблюдения per-узел: счётчики волн/ретраев/эскалаций · эхо-события · упоры max_tokens · банкнота: кандидаты→банк и потери на пути · инъекция банка — подтверждать байт-диффом СЫРОГО ТЕЛА: LOG_LEVEL=debug LOG_LLM_BODIES=1 ./bin/tmctl translate … (ТОЛЬКО вместе — при дефолтном LOG_LEVEL тела не пишутся вовсе, main.go:66), НЕ по injected_ids (там только exact-хиты); ⚠ тела в логе УСЕЧЕНЫ (obs/logging.go) — на длинных ответах JSON не парсится, поэтому деньги считай из request_log, а не из лога · распределение flag_reason · wall-clock по стадиям и итогом · деньги нарастающим итогом двумя путями · минимум ОДИН намеренный стоп+резюм посреди волны · бэкапы F4 на каждом платном старте.

  • ⚠ ОСИ ГОЛОСА — впервые получат данные (строка 13б). Флаггер голоса живёт на ФИНАЛЬНОЙ волне (waverun.go:392,512), а редакторская волна не гонялась НИ РАЗУ — поэтому на coldrun-a оси показывают flags=0 over attributed=0 of replies=0, и это «не считалось», а не «чисто». Твой прогон — первый, где они реально отработают: вынеси их числа со знаменателями отдельным пунктом отчёта, это гейт решения владельца по speech-cue.txt. ⚠ Помни: поле rules= в строке VOICE говорит «гейт СКОНФИГУРИРОВАН» (читается из конфига времени отчёта, quality.go:436), а не «отработал» — честный дискриминатор это знаменатели. Прогноз цены — приор, чтобы ты узнал аномалию, а не просто упёрся в потолок (опровергается замером; считай свой по ходу): черновая волна 20 чанков на low ≈ $0.02 · терминолог ≈ $0.010.02 · редакторская волна — никогда не гонялась, оценка из единственного наблюдённого вызова deepseek-v4-pro (9059 выходных токенов, $0.008706) на ~14 edit-юнитов ⇒ ≈$0.14. Итого порядок $0.2 на 10 глав, потолок $5 = запас ×20. Если фактическая цена уходит за ~$1 — это не «дорого», это СИГНАЛ: останавливайся и смотри, что покупаешь, а не жди потолка. ⚠ Редактор едет на вендор-дефолте high и придушить его нельзя (маппинг pro low→high), а вендор объявил смену маппинга pro на начало августа — если редакторские вызовы начнут упираться в потолок или возвращать пустое, это тот же класс, что блокер 74, и он требует СТОП+пинга, а не подбора числа.

  • Дебаг-дисциплина: дефект узла → СТОП волны (чекпойнты держат) → диагноз до корня (аномалия провайдера → официальная вендор-дока, НЕ гадать) → фикс по норме §0 (мультиязычный, с тестом; батарея + голден зелёные ДО resume) → точечный redrive (пере-покупка видима и посчитана). Заморозка прогона чекпойнтом ради доработки — ЛЕГИТИМНЫЙ исход, не провал.


§6. Чего НЕ делать

Сид НЕ заводить (прогон холодный) · судья Ф2 не гоняется · DC7-остаток НЕ мерить (строка 98 требует СИДОВОГО прогона — этот бессидовый) · backend/configs/models.yaml: блоки capabilities (включая reasoning, min_max_tokens) и price — ВЕРДИКТ-НЕСУЩИЕ (резолвнутая капабилити фолдится в снапшот): любая их правка обнуляет чекпойнты и перекупает прогон ⇒ трогать ТОЛЬКО до первого платного вызова работы C, с явной записью в отчёт; ослаблять echoMineViolation или флаг echoes_when_thinking_offнельзя вообще · docs/ — чужая зона: твоё в ней РОВНО два места — свой отчёт в docs/archive/reports/ и секция ## Бэкенд в docs/PROGRESS.md; docs/experiments/* (зона полигона, включая 00-provider-quirks.md), docs/architecture/*, docs/product-requirements.md — только ЧИТАТЬ, находки для них — пунктом отчёта, правит оркестратор · thinking у DeepSeek НЕ выключать ни в одной конфигурации (проба C прошлой сессии была карантинным ЗАМЕРОМ по вопросу владельца, а не разрешением; боевой гейт echoMineViolation цел и трогать его не надо) · проект ~/books/gu-zhenren/coldrun-b/reprobe/optNoThink/ — СПЕНТ-проба, НЕ резюмить (его book.yaml указывает на карантинную копию models.yaml с выключенным thinking) · CheapGateVersion/labels-фриз/голден-фикстуры двигать ТОЛЬКО под работу B по процедуре §4 · слаги моделей не менять без live-фактчека /models · ручка #77 (ре-ген эха перед эскалацией) сама не включается — она за владельцем · чужое в дереве не трогать: START_PROMT.MD, frontend/, platform/, .gitignore (⚠ фронт-сессия сейчас ЖИВАЯ и коммитит — перед любой git-операцией git status и опознание чужого; reset --hard/history-rewrite запрещены) · НЕ коммитить · тексты книги в отчёт НЕ цитировать (сырьё живёт durable в ~/books).


§7. Отчёт и СТОП

docs/archive/reports/EFFORT_HANDLE_<дата>.md: эхо-шапка · работа A (форма шва + ответы на четыре вопроса §0 + числа пробы §3.4) · работа B (дизайн, что решено по второй половине дыры, маскированный дифф голдена) · работа C — per-узел наблюдения, оси голоса со знаменателями, итоговая цена холодного старта ЦЕЛИКОМ, включая редактуру (это и есть закрытие строки 16) двумя путями · дефекты: найдено / починено (с тестами) / отложено (с носителем) · критик полноты против себя (обязательная секция) · адверсариальный проход по своим фиксам · заявление = команда: каждое число сопровождено командой, которой получено — приёмка их пере-ранит · git-список тронутого (только своё).

Батарея в отчёт числами: go build ./... · go vet ./... · go vet -tags live ./internal/pipeline/ · go test -race -count=1 ./... · майнер-парити TM_MINER_PARITY=1 … -run Parity EXACT · labels-фриз TM_CHECKER_LABELS=1 (k4b 10/1/36/99 · k4_inverse 3/0/1/71 · k2 34/1/6/51 · K6 1/6/0/251 · k4a 0/0/0/348) · голден TestGoldenDeterminism · gofmt -l.

Краткий итог — docs/PROGRESS.md, секция ## Бэкенд, допиши СВЕРХУ; бэклог-таблицу и CURRENT-STATE НЕ трогать. D-номер лендинга проставит оркестратор. СТОП — приёмка оркестратора.