# Промт: сквозной пак «ХОЛОДНЫЙ ПРОГОН B — платформа → бэкенд → ФАЙЛ, ВТОРОЙ раз» > ✅ **АРХИВ — ПАК ОТРАБОТАН И ПРИНЯТ 11.09: акт `D39.252`.** Книга второй раз дошла от двери до ФАЙЛА, > факт **$0.396657** при ожидании ≈$0.42; пре-рег заландился ДО первого цента (`4ee7f03`) и не тронут > (+638/−0). ⭐ Две меры денежной дыры разошлись в РАЗНЫЕ стороны на одних данных (единицы 23.5→41.2 %, > деньги 25.4→21.1 %). ⭐ **85.7 % оплаченного выхода книги — размышление, а не текст.** ⛔ Прибор > приоритета №1 солгал вердиктом `split` по подписанному имени героя при 58 вхождениях и нуле > конкурентов. Качество впервые судилось по ОРИГИНАЛУ рядом с переводом: 26 находок, 1 крит. > Ряды 434 · 436 · 437 · 438. ⛔ **Инструкции отсюда НЕ ИСПОЛНЯЮТСЯ** — читать только как историю. > Выдан оркестратором №23 (сессия `textmachine-11`) 11.09. Пак **ПЛАТНЫЙ**, санкция владельца получена > дословно («разрешаю») на прямой вопрос с числами: **ждём ≈$0.42, машинный кап ≈$2.5 холда**. Носитель > санкции — `docs/NEAR_TERM_PLAN.md` §«Решения владельца, уже полученные». ## 1. Какая проблема и что решит твой результат Месяц назад движок умел переводить, но никто не видел, как платформа ведёт настоящую книгу от двери до файла. 11.09 это увидели один раз — **прогон A**: три главы `蛊真人`, 27 платных вызовов, **$0.419423**, книга дошла до EPUB. Один прогон дал знак, но не величину. **Твой прогон B покупает четыре вещи, которых нет ни у кого, и каждая — не «ещё раз то же самое»:** 1. **ДВЕ миграции схемы ни разу не шли на живом прогоне** — только в тестах, и база прогона A стоит на `schema_version` **16**. `v17` — `wave_selection` (`backend/internal/store/migrate.go:484`=`CREATE TABLE IF NOT EXISTS wave_selection`): что каждая волна ВИДЕЛА в банке, ось, которой у `retrieval_state` нет. `v18` — **`reasoning_in_completion`** (`migrate.go:519`), и ⛔ **это НЕ `reasoning_tokens`**: тот лежит в базовой схеме как `INTEGER NOT NULL DEFAULT 0` (`migrate.go:94`) и на DeepSeek равен нулю ПО ПОСТРОЕНИЮ — адаптер намеренно оставляет его нулём и уводит присланное провайдером число в новую колонку (`provider_openai.go`, ветка `ReasoningSubset`). Новая колонка **НУЛЛАБЕЛЬНА и трёхзначна: `NULL` — вопрос не задан · `0` — измеренный ноль · `>0` — думанье**, и `DEFAULT 0` не поставлен намеренно, иначе дефект вернулся бы первой же строкой. **Приёмка спрашивает ТРЁХЗНАЧНОСТЬ, а не «не ноль».** 2. **Прибор консистентности впервые даст числа С ЖИВОГО ПРОГОНА.** Сегодня все `I1`/`I2` получены ПОВТОРНЫМ чтением одной и той же сохранённой базы прогона A. Пере-скан не то же, что прогон: он не проходит через запись. 3. **Платформенный пак (идемпотентный резюм, терминальное состояние) проверяется СКВОЗЬ,** а не юнитами. 4. **Вторая точка по денежной дыре — но ЧЕСТНО о том, что она даёт.** Весь довод «четверть денег купила пустоту» стоит на ОДНОМ прогоне. ⚠ И не обманывайся ссылкой на квирки §3д: там сказано, что парный дизайн ловит эффект ×2.5 за **13 пар**, ×2.0 за 22, ×1.4 за 93 — **n = 2 этой нормы не выполняет и выполнить не может**. ⇒ B покупает не величину, а **пре-регистрированный знаменатель и проверку ЗНАКА**. Написать в отчёте «25.4 % подтверждено» по двум розыгрышам — ошибка, и я её не приму. ⛔ **И вот чего твой прогон НЕ покупает, чтобы ты не потратил на это ни цента:** он **НЕ** отвечает на вопрос «безопасно ли редактору думать меньше» (ряд 433). Это парный дизайн на повторах с армом без фактора, он стоит отдельных денег и отдельного заказа. Твой прогон идёт на БОЕВЫХ настройках как есть. ## 2. Зона записи и git ⛔ **ЭТОТ ПАК НЕ ПРАВИТ КОД НИ ОДНОЙ ЗОНЫ.** Ни `backend/`, ни `platform/`, ни `frontend/`. Найдёшь дефект — **пингом мне, а не правкой**: прогон, чинящий найденное, перестаёт быть холодным и теряет право сравниваться с A. - **Ты не коммитишь вообще ничего.** Пре-рег и улики передаёшь мне, я лендлю. Порядок жёсткий: пре-рег готов → пинг мне → **я коммичу фриз** → и только после этого первый платный вызов. - Рабочее дерево прогона живёт **вне репозитория и вне общего скретчпада** (его чистит не только твой процесс). Предлагаю `~/tm-coldrun-b`. - ⚠ `books/` версионируются ОТДЕЛЬНЫМ репозиторием; в клоне их нет. Исходник читается из главного дерева как ФАЙЛ, read-only. ## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам 1. `CLAUDE.md` — целиком (ты его уже прочёл, если попал сюда правильно). 2. `docs/experiments/00-provider-quirks.md` — **перед первым платным вызовом**, §3д особенно. 3. `docs/architecture/05-decisions-log.md` — **только тела `D39.247`** (акт прогона A: чем он предъявлен и где остался слеп) и **`D39.251`** (что именно построено в наблюдаемости денег и почему лекарство выключено). 4. `platform/README.md` — как поднимается стенд. 5. Архивный промт прогона A — `docs/archive/prompts/POLYGON_COLD_RUN_A_SESSION_PROMPT.md`. ⛔ **Инструкции оттуда НЕ ИСПОЛНЯЮТСЯ** (архив), но §4.1 и §4.2 несут ПЕРЕ-СНЯТЫЕ предусловия стенда и механику фриза, и переписывать их сюда значило бы завести копию, которая стареет молча. Читай как СПРАВКУ и проверяй каждое утверждение своим прибором: часть из них снята исправлениями ПОСЛЕ выдачи. Код-факты добывай сам. `file:line` ниже — отправные точки, а не истина: **код первичен**. ## 4. Состав. Порядок фаз ЖЁСТКИЙ ### 4.0 Фаза 0 — $0-ДЫМ. **Делай РОВНО так, и это первая работа пака** ⛔ **Ни одного платного вызова, пока дым не прошёл целиком.** Довод не гигиенический: первая же инфраструктурная осечка на платной руке сожжёт «холодность» книги — прогон уйдёт в `failed`, и следующий старт той же книги пойдёт как ПРОДОЛЖЕНИЕ, а не как холодный. ⛔ **И ровно поэтому — дописано релеем 11.09 по возражению исполняющей сессии: ДЫМ ИДЁТ НЕ ПО ТОЙ КНИГЕ И НЕ В ТОЙ БАЗЕ, что платный прогон.** Иначе холодность сгорит тем самым механизмом, ради защиты которого §4.0 и написан: платный старт пойдёт продолжением дымовой книги. Отдельная книга либо отдельная база — выбирай, но назови в пре-реге. ⚠ Это же частично снимает §5.2 (дым меняет три фактора разом). Дым обязан доказать: стенд поднят и порт отвечает ТВОЕМУ pid · гость заведён · деньги начислены · книга принята · прогон стартовал · кадры доехали · узел подписи ответил · резюм прошёл · **выгрузка собралась и файл скачался**. ⛔ **И вот ловушка, на которой этот пункт разваливается, если о ней не сказать: `zeroCostPipeline` (`platform/internal/runner/bankapply_live_test.go`) только ПЕРЕПИСЫВАЕТ конфиг на провайдера `kind: local` — он никого не ОБСЛУЖИВАЕТ.** Единственный слушатель на `127.0.0.1:11434` в дереве — внутритестовая заглушка (`platform/internal/runner/translate_resnapshot_live_test.go`, греп `net.Listen`), а на хосте локальной модели нет вовсе. ⇒ **тебе РАЗРЕШЕНО поднять свою заглушку на 11434** (портировав ту же, или исполнив несущий её живой тест) — и это не обход, а штатный путь. ⚠ Не сделав этого, ты упрёшься в отказ соединения посреди дыма, и дешёвым выходом станет «дым неприменим, иду за деньгами» — ровно то, ради предотвращения чего §4.0 существует. ⛔ **Пин фазы 0 — ЗАГРУЗЧИК, а не текстовый скан.** Счёт платных слагов в получившемся конфиге оставь КОНТРОЛЬНОЙ величиной (ноль против ненулевого счёта тех же слагов в `backend/configs/pipeline-c1.yaml`), но **сам пин — движок, который этот файл ЗАГРУЗИЛ бесплатным глаголом**. Довод замерен и стоил платформенной зоне круга приёмки: её рецепт был «проверен гардом» — сканом имён — и производил файл, который движок отказывается грузить (`escalate_to must differ from the primary model`, `EXIT=10`). Имя в конфиге и загружаемый конфиг — разные предметы. ### 4.1 Предусловия — **проверь КАЖДОЕ своим прибором, список от прогона A мог устареть** Известное на 11.09 (справка, не истина): локальной модели на машине НЕТ (ни `ollama`, ни слушателя на 11434) ⇒ настоящие узлы проходятся только платно · кластер Postgres поднят на `-h /tmp -p 55433 -U postgres`, ОС-роль `ubuntu-26` в нём НЕ заведена · четыре переменные окружения решают, существует ли путь вообще (`TM_PLATFORM_EXPORT_FORMATS` пуст по умолчанию ⇒ ручки выгрузки не монтируются, и последней трети пути для тебя нет) · `epubcheck`/`java` на хосте нет и поставить их нельзя. ⛔ **АРТЕФАКТ КОНТРАСТА МАЙНИНГА — и здесь я в первой редакции ПЕРЕВЕРНУЛ факт, поймал опровергатель.** `CheckMiningContrast` делает **ТОЛЬКО `os.Stat`** (`backend/internal/config/pipeline.go:558`=`func (p *Pipeline) CheckMiningContrast`) — никакой sha он не сверяет и **удовлетворится фальшивым кандидатом**, который лежит рядом на диске (`~/tm-p9-work/cfg/contrast-zh.txt`, 992 байта). ⇒ **sha256 сверяешь ТЫ, руками**: рецепт и эталон — `docs/experiments/16-bank-mining.md:183`=`Словарь-артефакт (контраст)` (jieba 0.42.1 `dict.txt`, `7197c3211ddd98962b036cdf40324d1ea2bfaa12bd028e68faa70111a88e12a8`). ⚠ И ловушка имени: в конфигах файл зовётся `mining-contrast.zh.txt` и резолвится ОТ КАТАЛОГА `pipeline.yaml`, а источник — `jieba_dict_general_zh.txt`. **Неверный артефакт молча меняет контур банка, то есть портит ровно те числа консистентности, ради которых B и покупается.** ⛔ **ПИН ДО ФРИЗА, дешёвый и обязательный: `GET /v0/capabilities` показывает НЕПУСТОЙ `export_formats`.** Выгрузка гейтится ТРЕМЯ условиями сразу (`platform/internal/config/config.go`, греп `ExportsEnabled`), а не одной переменной, и проба возможностей — единственный дешёвый способ узнать, что выполнены все три, ДО того как двинутся деньги. ⛔ **Ключи провайдера.** Значение `TM_PLATFORM_ENGINE_KEYS_PATH` даю я по твоему пингу. **Нет значения ⇒ СТОП ДО фриза.** `.env` читать запрещено гардрейлом. ### 4.2 Фриз — **делай РОВНО так** **Фриз = sha коммита ПЛЮС бинари, собранные из ЛОКАЛЬНОГО КЛОНА** (`git clone <репо> <путь>`). Довод — главное дерево движут параллельные сессии. ⛔ **Не `git worktree`.** Бинарь из ЛИНКОВАННОГО воркри не несёт VCS-штампа **ВООБЩЕ** (замер: 24 строки `go version -m`, из них `vcs.*` — 0), потому что `.git` воркри — ФАЙЛ и поиск корня VCS в Go его пропускает. ⇒ правило «отказывать при `vcs.modified=true`» на таком бинаре выполняется ВСЕГДА и не проверяет ничего. У клона `.git` — настоящий каталог, и штамп живой. **Третье условие отказа обязательно: отсутствие строк `vcs.*`.** Перед сборкой — `test ! -e /tmp/.git`; `GOFLAGS=-buildvcs=false` в фриз-сборке **ЗАПРЕЩЁН**. ⚠ Штамп снимается **на КАЖДУЮ попытку**, а не один раз: резюм может сменить бинарь под тем же прогоном — сверяй по `run_attempts`, а не по тому, что лежит на PATH в конце. ⛔ **ПОРЯДОК ЖЁСТКИЙ, и он важен потому, что пре-рег обязан НАЗЫВАТЬ тот самый sha, который поедет:** клон → записал sha и собрал бинари → написал пре-рег, НАЗЫВАЮЩИЙ этот sha → отдал мне → **я коммичу** → ты сверил, что заландженный пре-рег называет твой sha → и только теперь первый платный вызов. ⚠ **Что делать, если я молчу.** Канал может отсутствовать — это нормальный случай, а не авария. **Ждёшь меня до конца своего хода, потом ОСТАНАВЛИВАЕШЬСЯ и пишешь отчёт** с готовым пре-регом и пометкой «жду лендинга фриза и значения `TM_PLATFORM_ENGINE_KEYS_PATH`». ⛔ **Без обоих платная фаза не начинается ни при каких обстоятельствах** — и это не формальность: пре-рег, не заландженный ДО денег, перестаёт быть пре-регом. ⚠ **Что фриз НЕ запрещает:** потолки правятся **БЕЗ пере-фриза** — фриз-гейт смотрит на ПОКУПАЮЩИЙ файл, а не на кассу. Меняется ЧТО покупается или чем судится — новый фриз; меняется СКОЛЬКО тратить — объявление в отчёте. Правка собственного драйвера после фриза — тоже новый фриз. ### 4.3 Пре-регистрация — **главный рубеж пака, и он дороже самого прогона** ⛔ **ЗНАМЕНАТЕЛЬ ПРЕ-РЕГИСТРИРУЕТСЯ ДО ДЕНЕГ, иначе B ответит числом на другой вопрос.** B — ЕЩЁ ОДИН одиночный прогон, и две точки распределением не станут. Настоящая ценность B не «вторая точка к 25.4 %», а `request_log` ВСЕХ единиц прогона ⇒ **доля выброшенных первых попыток ПО ЕДИНИЦАМ, а не по вызовам.** **Мера задана мной, делай РОВНО так** (я снял её на прогоне A своим прибором, числа ниже — твой базис сравнения): - **единица** = `(chapter, chunk_idx, stage, role)`. ⚠ **Единица ОХВАТЫВАЕТ попытки и охватывает их намеренно** — номера попытки в ключе нет. И знай асимметрию: у стадии `terminology` все строки прогона A несут `chapter = 0`, то есть `chunk_idx` там — индекс майнинг-батча, а не чанк главы. Одно слово «единица» покрывает два разных предмета; называй, какой именно, в каждом числе. - **знаменатель** = единицы, за которые заплачено хоть раз (`sum(cost_usd) > 0`). ⚠ На прогоне A этот фильтр **не отсеял НИЧЕГО** (17 единиц всего и 17 платных) — значит его поведение ни разу не проверялось, и на B единица из одних чекпойнтов может появиться впервые. Печатай ОБА счёта. - **ЧИСЛИТЕЛЬ ПЕРВЫЙ — выброшенная покупка:** единицы, где есть хоть одна оплаченная и НЕ принятая попытка (`ok = 0 AND cost_usd > 0`). **Прогон A: 4 из 17 = 23.5 %**, тогда как по ВЫЗОВАМ то же событие даёт 4 из 27 = **14.8 %**. Две меры расходятся в полтора раза — вот почему мера объявляется заранее. - ⛔ **ЧИСЛИТЕЛЬ ВТОРОЙ, и первая редакция этого промта его СЛЕПО ПРОПУСКАЛА** (нашёл опровергатель, я пере-снял сам): **единицы, за ПРИНЯТЫЙ результат которых заплачено больше одного раза** (`ok = 1`, ячейка куплена дважды). На прогоне A это вся стадия терминологии, пере-купленная на резюме: **$0.028742 = 6.9 % цены книги**, и мера «выброшенная первая попытка» этого НЕ ВИДИТ вовсе — строки `ok = 1`. ⚠ Черновик на том же резюме приехал бесплатно (6 строк `tm_hit = 1`), терминология — нет. **Обе доли печатаются отдельно; складывать их в одно «потеряли N %» НЕЛЬЗЯ — это разные беды.** ⚠ **ДВА ПУТИ К ДЕНЕЖНОМУ ЧИСЛУ — и честно о том, чего их совпадение стоит.** Путь 1 — по колонке `degraded`; путь 2 — по `ok = 0 AND cost_usd > 0`, колонки `degraded` не касаясь. У меня на A оба дали ровно **$0.106472 = 25.4 %** цены книги. ⛔ **Но на A они совпадают ПО ПОСТРОЕНИЮ**, а не независимо: `degraded` там принимает ненулевое значение ровно на тех же четырёх строках. ⇒ совпадение на B — слабая улика, а вот РАСХОЖДЕНИЕ — сильная находка: оно означает, что классификатор и признак приёмки разъехались. ⚠ И не путай числа: **25.4 % — доля ДЕНЕГ, 23.5 % — доля ЕДИНИЦ.** Это разные величины, и подменять одну другой в отчёте нельзя. В пре-рег идут также: **ожидаемый исход КАЖДОГО шага, написанный ДО прогона** · sha256 исходника · sha256 ФАКТИЧЕСКОГО pipeline-YAML (платформа берёт файл ЦЕЛИКОМ, пер-полевого оверрайда нет ⇒ «прогон на c1» без sha — утверждение без носителя) · список глав с `units_total` · грант, TTL выгрузки. ⛔ **ПРЕТРЕЙН — И ЭТО ТЕПЕРЬ НЕ ЗАПРЕТ, А ПРОЦЕДУРА (слово владельца 11.09 отменило прежнюю редакцию).** `蛊真人` узнаётся моделями 4 из 5. Прежняя редакция этого промта на этом основании запрещала клеймы о качестве вовсе — **владелец отменил запрет: он хочет увидеть качество на боевой книге.** Но опасность никуда не делась и становится СИЛЬНЕЕ, когда читатель — большая модель: она способна «увидеть» в переводе то, что помнит из претрейна, и не заметить того, чего в переводе нет. ⇒ процедура вместо запрета: **каждая находка о качестве обязана нести ДВЕ цитаты рядом — фрагмент ОРИГИНАЛА и фрагмент ПЕРЕВОДА.** Находка, которая не может показать место в исходнике, — не находка, а воспоминание. ### 4.4 Платная фаза **Реши сам и аргументируй:** какую книгу и сколько глав брать. ⛔ **Глав немного — слово владельца.** ⛔ **ОГРАНИЧЕНИЕ, ОБЪЯВЛЕННОЕ ЗАРАНЕЕ (решение оркестратора 11.09, ряд 435): ЭСКАЛАЦИЯ В B НЕ ИСПОЛНЯЕТСЯ.** `backend/configs/pipeline-c1.yaml:223`=`budget_usd: 0` держит её выключенной, а комментарий над ней требует ручного оверрайда приёмочной сессией. **Оверрайд НЕ делаем:** байт-в-байт тождественный покупающий файл — лучшее, что есть у сравнения A↔B, и оно дороже одного непроверенного пути. ⇒ **назови это в пре-реге ограничением**, а не умолчи, и не считай отсутствие хопов свойством движка. Мой приор, опровергается замером: те же главы 1–3 той же книги, что и в A. ⛔ **И вот ловушка, которая стоила бы тебе ТРОЙНОГО бюджета, — первая редакция промта в неё попадала.** Файл `books/gu-zhenren/coldrun-v16/guzhenren-ch1-10.gb18030.txt` — это **10 глав, 57838 байт**. Прогон A ел не его, а **СРЕЗ в 17564 байта**, sha256 `ed870ba6065ce3eb…`, сохранённый как `/home/ubuntu-26/tm-coldrun-a/material/guzhenren-ch1-3.gb18030.txt` (срез байт-в-байт равен первым 17564 байтам целого файла — проверено мною обеими sha). **Интейк главами резать НЕ умеет**: загрузишь целый файл — купишь ×3.3 текста против объявленных ≈$0.42. ⇒ **режешь файл сам и кладёшь его sha в пре-рег.** ⭐ **Границу среза я пере-снял по возражению исполняющей сессии (байтовая граница в GB18030 могла разрубить многобайтный символ) — она ЧИСТАЯ:** срез декодируется целиком, **9021 знак**, кончается на границе абзаца, и несёт **ровно 3 заголовка** — `第一节` · `第二节` · `第三节` (в целом файле их 10; контроль печатается рядом). ⚠ **И ловушка имени, на которой я сам получил ложный ноль:** глава здесь размечена иероглифом **节**, а не 章 — мой первый греп искал `第…章` и нашёл 0. Инвентарь разметки — `backend/internal/lang/data/cjk-section.txt`. ⛔ **ДВА ПОТОЛКА, а не один, и первая редакция называла только платформенный.** Холд платформы ≈$2.5 — и **движковые потолки в `book.yaml`**: у прогона A стояло `book_usd: 1.25`, `day_usd: 2.50`. Прогон остановится на ДВИЖКОВОМ потолке раньше, чем на платформенном, и «упёрся в потолок» будет про число, которого ты не ждал. Назови в пре-реге ОБА и скажи, какой ставишь ты. ⛔ **A↔B СРАВНИМЫ НЕ ПО КНИГЕ — И ЭТО НАДО ЗАПИСАТЬ ОГРАНИЧЕНИЕМ, А НЕ ЗАМОЛЧАТЬ.** Между фризом прогона A (`b0f5d89`) и сегодняшней головой — **107 коммитов и 52 файла движка** (+7678/−85), включая `stagerun.go`, `disposition.go`, `quality.go`, `httpllm.go`, `provider_openai.go`, `requestlog.go` и `models.yaml`, то есть ровно денежный путь. **B меряет ДРУГОЙ движок.** Одинаковая книга делает сравнимыми ТЕКСТЫ, но не числа денег. ⇒ в пре-рег: sha движка B, число коммитов между ним и A, и прямая строка «двойная оплата могла измениться из-за наших правок, а не из-за провайдера». ⛔ **Приёмка каждого узла — по ТРЁМ независимым следам** (Postgres · диск и systemd · HTTP), не по самоотчёту движка. ⛔ **Живость длинного прогона проверяется АКТИВНО:** не жди финального уведомления — раз в пару часов сверяй рост числа вызовов и трат по леджеру ДВУМЯ чтениями. **Зависшая задача от идущей по сигналу завершения неотличима, и у зависания нет цвета.** ⛔ **СЛЕДИ ЗА ЛОГАМИ И ЛОГИКОЙ ЖИВЬЁМ, а не только по итогу (слово владельца 11.09).** Прогон — это не «запустил и жди файл»: смотри, что движок пишет, пока он это пишет. Каждое предупреждение, каждый флаг, каждая регенерация, каждый незнакомый `finish_reason` — читаются ТОГДА, а не в разборе. Вопрос к каждому: **согласуется ли поведение с тем, что, по твоему чтению кода, должно было произойти?** Расхождение логики и лога — находка, даже если прогон кончился успешно. Веди это списком по ходу: «время · что увидел · чего ожидал · что это значит». ⛔ **Деньги: ждём ≈$0.42, кап ≈$2.5 холда.** Упёрся в потолок — **СТОП и пинг мне**, не режь молча и не проси подъёма «по проекции»: прогнозный запрос оставляет ложный след «владелец согласился на пере-оплату», которой не было. ### 4.5 ⭐ ВЫЧИТКА ВСЕГО ПЕРЕВОДА — отдельным опус-агентом с МИЛЛИОННЫМ контекстом ⛔ **Это заказ владельца дословно, и это главная качественная работа пака.** **Делай РОВНО так в части формы:** 1. Подними **отдельного агента на opus** (модель задавай ЯВНО) и **загрузи ему в контекст ЦЕЛИКОМ**: **(а)** весь получившийся перевод и **(б)** весь исходный китайский текст тех же глав. ⛔ **Контекст НЕ ЭКОНОМИТЬ** — слово владельца: «пусть не экономит контекст, ему должно на всё хватить». Никаких выжимок, никаких «первых N абзацев», никакого пересказа вместо текста. Режешь текст — режешь находки, и молча. 2. Его мандат — **искать МАЖОРЫ, которые жёстко критуют по тексту и его качеству**, в ПОРЯДКЕ ПРИОРИТЕТА владельца (он назвал его сам, и порядок несущий): 1. **КОНСИСТЕНТНОСТЬ банка памяти и терминов** — один и тот же термин/имя/титул, приехавший в разных местах по-разному; термин, разошедшийся с банком; забытая форма. 2. **ОТСУТСТВИЕ ВЫДУМОК** — текст, которого в оригинале НЕТ: дописанные предложения, пояснения от себя, «додуманные» связки, исчезнувшие куски (пропуск — та же выдумка, только с другим знаком). 3. **ХУДОЖЕСТВЕННОСТЬ И ЧИТАЕМОСТЬ** получившегося русского текста. 4. **ОТСУТСТВИЕ TRANSLATIONESE** — кальки, порядок слов оригинала, «китайский синтаксис русскими словами». 3. ⛔ **Форма КАЖДОЙ находки — две цитаты рядом:** фрагмент ОРИГИНАЛА и фрагмент ПЕРЕВОДА, плюс глава/юнит, плюс какой из четырёх приоритетов нарушен, плюс severity. **Находка без цитаты из исходника не принимается** — см. абзац о претрейне выше: модель знает эту книгу и способна «вспомнить» то, чего в нашем переводе нет. 4. **Решаешь сам и аргументируешь:** сколько таких читателей поднять и как разделить между ними работу (один на всё · по приоритетам · по главам с перекрытием). Мой приор, опровергается доводом: **один агент на ВЕСЬ текст сразу** — консистентность банка по построению не видна тому, кто читает главу отдельно. Если делишь — объясни, чем компенсируешь потерю сквозного взгляда. ⚠ **И назови ОТРИЦАТЕЛЬНЫЙ результат тоже:** «выдумок не нашёл» — это результат, но только рядом с контрольной величиной («прочитано столько-то знаков перевода против стольких-то знаков оригинала»). ⛔ **ДОКАЗАТЕЛЬСТВО ДОЧИТЫВАНИЯ — обязательно, дописано релеем 11.09 по возражению исполняющей сессии.** Инструменты чтения РЕЖУТ длинные файлы молча, и тогда «выдумок не нашёл» становится утверждением о НЕПРОЧИТАННОМ, неотличимым от находки. ⇒ читатель обязан напечатать: **знаков оригинала · знаков перевода · ПОСЛЕДНЕЕ предложение оригинала и ПОСЛЕДНЕЕ предложение перевода**. Не напечатал — его отчёт не принимается. **Контроль для среза глав 1–3: 9021 знак оригинала** (снято мною). ### 4.6 ⭐ СВЕРКА ПРИБОРОВ С ВЫЧИТКОЙ — ради этого прогон и стоит своих денег ⛔ **ОДНА КЛЕТКА ЭТОЙ ТАБЛИЦЫ ИЗВЕСТНА ЗАРАНЕЕ — замер оркестратора 11.09 на артефактах прогона A, ряд 434.** Прибор консистентности нашёл передачу у **40 термов из 69**, у **29** вернул `renderings={}` — и молча записал их в `spread = 0`, то есть в КОНСИСТЕНТНЫЕ. Проверка текстом: финальная форма банка реально стоит в отгруженном файле у **26 из 29**. ⇒ его итоговая строка «TERMS SHIPPED IN MORE THAN ONE SHAPE: 0» посчитана по 40 термам, а не по 69, и **«расхождения нет» у него неотличимо от «передачи не нашёл»**. ⚠ Матчер ловит СЛОВО, а не форму: у `高脚吊楼` он вернул «Свайные», тогда как текст несёт «свайного дома / свайные дома / свайных домов». ⇒ **для тебя это значит три вещи, и все три в пре-рег:** знаменатель прибора печатается ВСЕГДА («нашёл у M из N») · ненайденные **проверяются текстом**, а не засчитываются в консистентные · и **эти 26 термов — твой готовый список кандидатов** на клетку «прибор смолчал, читатель нашёл». ⚠ Опус-читателю список НЕ давай: он находка о ПРИБОРЕ, а не о тексте, и подсказка сузила бы его взгляд. У движка есть СВОИ приборы качества: детерминированные $0-гейты, отчёт качества, счёт расхождения форм (`I1`/`I2`), флаги и колонка `degraded`, банк памяти и пост-проверка. **Все они утверждают что-то о тексте. Твоя работа — спросить, совпадает ли их мнение с тем, что увидел читатель.** Построй таблицу 2×2 и заполни её именами находок: | | **читатель нашёл** | **читатель не нашёл** | |---|---|---| | **прибор сказал** | подтверждение | ложная тревога прибора | | **прибор смолчал** | ⛔ **СЛЕПАЯ ПОВЕРХНОСТЬ** | согласие | ⛔ **Интересны ДВЕ клетки, и левая нижняя — самая дорогая: это дефект, который сегодня уезжает читателю молча.** Каждую такую назови отдельно: что именно прошло мимо, какой прибор обязан был это поймать, и почему не поймал — нет механизма, есть но выключен, есть но смотрит не туда. ### 4.7 КОД, КОТОРЫЙ ОТРАБОТАЛ — читать с оглядкой на получившийся текст **Не ревью движка вообще, а ревью ТОГО ПУТИ, который реально исполнился на этой книге.** Порядок обратный обычному: сначала находка в тексте, потом код, который её пропустил. Назови: какие стадии и гейты реально бежали · какие не бежали и почему · где в коде живёт механизм, отвечающий за каждый найденный мажор. ⚠ Пример связи, которую ждут: читатель нашёл разъехавшийся термин ⇒ читается путь инъекции банка и пост-проверка ⇒ ответ «механизма нет» / «механизм есть, но решает по единице, которой в продукте нет» / «механизм есть и промолчал вот здесь». ⛔ **Кода НЕ ПРАВИТЬ** (§2). Находка = пинг мне со строками. ### 4.8 ДЁРГАТЬ API ПЛАТФОРМЫ ПО-РАЗНОМУ — не один счастливый путь Слово владельца: «пусть подёргает по-разному апишку через платформу». Один проход по счастливому пути доказывает, что дверь открывается, и ничего не говорит о том, что за ней. ⛔ **ГДЕ ЭТО ДЕЛАТЬ — исправлено релеем 11.09 по возражению исполняющей сессии, и возражение верное.** Дёрганье API на ИЗМЕРЯЕМОМ прогоне САМО ПРОИЗВОДИТ число, которое потом предъявляется как свойство движка: резюм и второй старт — ровно то, что числитель-2 §4.3 (пере-покупка ПРИНЯТЫХ единиц) и меряет. ⇒ **делай РОВНО так:** - **ВСЕ формы дёрганья — на $0-РУКЕ** (стенд с заглушкой): API там тот же самый, провайдер подменён, и стоит это НОЛЬ. Никаких оснований экономить на числе форм. - **В ИЗМЕРЯЕМОМ платном прогоне — РОВНО ОДИН резюм, объявленный в пре-реге.** У прогона A резюм БЫЛ (две попытки прогона в леджере, терминология пере-куплена на второй), поэтому один резюм не портит сравнение, а СОХРАНЯЕТ его: без него A и B меряли бы разное. **Решаешь сам, что дёргать; мой приор — не менее шести РАЗНЫХ форм:** заказ в главах против заказа в ЗНАКАХ (это разные ветки контракта и разные счётчики) · повтор того же запроса (идемпотентность) · резюм · старт второго прогона при идущем первом · выгрузка во ВСЕХ смонтированных форматах · узел подписи банка · отказные пути (несуществующая книга · нехватка баланса · курсор с мусором). ⛔ **Ожидаемый исход КАЖДОГО дёрганья пишется ДО него.** Иначе это не проверка, а экскурсия: любой ответ двери задним числом выглядит правильным. ### 4.9 Фаза 3 — $0 после прогона. **Состав задан РОВНО так; чем именно предъявлять — решаешь сам** Прибор консистентности по ОТГРУЖЕННОМУ тексту существует и строить его НЕ НАДО — он живёт в `backend/internal/pipeline/bookconsistency.go` и достаётся как `QualityReport().Consistency`; печатает его `backend/cmd/tmctl/render.go`. Снимай `I1`/`I2` **с печатаемыми знаменателями** (число без знаменателя в этом паке не принимается). Дальше: выгрузка · структурное чтение EPUB (zip + `container.xml` + `nav`; `epubcheck` на хосте нет, и это законно) · **обе новые миграции предъявлены ДАННЫМИ**: `wave_selection` несёт строки ОБЕИХ волн (они выбирают над РАЗНЫМИ банками — черновик над базовым с исключёнными намайненными, редактор над обогащённым), а `reasoning_in_completion` предъявляется **ТРЁХЗНАЧНО**: сколько строк `NULL`, сколько `0`, сколько `>0`. ⛔ Не гонись за «не нулём»: `0` здесь — законный измеренный ответ, и отличать его от `NULL` — весь смысл миграции. ### 4.10 ⭐ НАХОДКИ ВНЕ ЗАКАЗА — и это отдельный заказ владельца, а не приятный побочный эффект Слово владельца 11.09: **«важно, чтоб она находила проблемы даже там, где мы не ждём»**. Поэтому здесь стоит вопрос, у которого НЕТ заранее известного ответа, и он задаётся в КАЖДОЙ фазе, а не один раз в конце: > ⛔ **Что в этом прогоне стоит дороже, работает хуже или ведёт себя страннее, чем должно бы, — и о чём > НИКТО не спрашивал?** ⭐ **Ради чего вопрос заведён — реальный случай, и он стоил четверти цены книги.** Удорожание из-за падающих запросов НА НАШИХ СОБСТВЕННЫХ настройках никто не заказывал искать: просто кто-то посмотрел в леджер без гипотезы и увидел, что 25.4 % денег ушло в выброшенные первые попытки. Ни один тест не был красным, ни один гейт не сработал, в отчёте стояла зелень. **Находка такого рода ценнее исполнения заказа**, потому что заказанное найдут и без тебя. **Что докладывать (слово владельца, дословно по составу):** **криты · мажоры · регрессии · баги · жёсткие точки улучшения.** Каждое — **АРГУМЕНТИРОВАННО**: что видел · чем предъявлено (`file:line`, строка лога, запрос и ответ, число из леджера) · почему это именно крит/мажор, а не вкусовщина · чего это стоит в деньгах, тексте или доверии читателя. ⚠ **И следи за КОДОМ, а не только за выдачей.** Ты читаешь логи и результаты движка — значит у тебя в руках единственная в проекте позиция, с которой видно и поведение, и его причину сразу. Увидел странность в выдаче — иди в код, который её произвёл, и назови место. Увидел в коде путь, который на этой книге НЕ исполнился, хотя должен был, — это тоже находка. ⛔ **Кода не править** (§2): находка = пинг мне со строками. ## 5. Где этот пак мягкий — четыре места, назвал я, веер выбираешь ты Мандат самопроверки — **исполнением**, субагенты разрешены явно. Направление: 1. **Сборщик, который молчит, и сборщик, который прочитал ноль, — неотличимы.** Засей в стендовую БД заведомо ненулевой банк и заведомо удержанный юнит и потребуй, чтобы сборщики стали КРАСНЫМИ. Не покрасневший на подсадке сборщик в платную фазу НЕ ДОПУСКАЕТСЯ. 2. **Дым меняет ТРИ фактора разом** (провайдер + книга + база) ⇒ при провале платной руки он не разделяет причину. Где дёшево — меняй по одному. 3. **Отрицательный замер обязан доказать, что спросил существующее.** Рядом с каждым нулём ПЕЧАТАЙ контрольную величину. И помни две ловушки среды: `grep` здесь — обёртка над ugrep, чтит `.gitignore` и **не видит `books/`**; `sqlite3` как CLI на машине НЕТ — только `python3` + `mode=ro`. 4. **Число, выведенное из соседнего поля, не краснеет нигде.** Если в строке есть поле, прямо отвечающее на вопрос (номер попытки живёт в `trace_id`), любой ВЫВОД ответа — по времени, по порядку, по соседству — уже дефект метода, даже когда сходится. ### ⭐ Адверсариальная стойка — то, чем оркестратор судит чужую работу; суди ею свою Владелец просил передать это прямо. Ниже не правила пака, а СПОСОБ СМОТРЕТЬ, и он ловит то, чего не ловят ни тесты, ни второй круг: - ⛔ **Автор и ревьюер — разные роли, даже когда это один ты.** Перечтение собственной работы рубежом НЕ считается. Поднимай отдельного читателя, которому НАЗВАНО, где мягко, и не показывай ему свои выводы раньше, чем он прочтёт предмет. - ⛔ **Спрашивай у аномалии, о ЧЁМ она — о предмете или о твоём приборе.** Вмешательство в замер производит ложные улики, похожие на находки: у прошлой смены запись «непонятный исход» оказалась здоровой, а сломан был цикл того, кто мерил. - ⛔ **Верный результат при неверном методе не краснеет нигде.** «Сошлось» — не доказательство: сходятся и по счастливому порядку строк. Спрашивай «чем это НАЗВАНО в самой строке?» прежде, чем вычислять. - ⛔ **«Не воспроизвелось» — не «недостижимо».** Верный прогон при неверной гипотезе неотличим от «дефекта нет». Назови ЦЕПЬ звеньев от входа к следствию и проверь каждое, прежде чем писать «не воспроизводится». - ⛔ **Утверждение о молчании вакуумно.** «Ошибки не было», «лишнего не купили», «предупреждений нет» — проверяемо только рядом с фикстурой или контролем, где это ОБЯЗАНО было прозвучать. - ⛔ **Заимствованное число проверяется не на существование, а на ТУ ЛИ КЛЕТКУ.** Та же роль, та же модель, та же стадия, тот же режим? Прошлый пак чуть не включил денежный механизм по замеру из чужой роли. - ⛔ **Зелёная батарея плюс полный каталог мутаций сходимостью НЕ являются.** Три смены подряд направленный второй читатель находил 6, 7 и 9 настоящих дефектов при полной зелени. - ⭐ **И главный вопрос отчёта — не «что не получилось», а «что ты знаешь и не сказала».** На прямой вопрос сессия однажды назвала ДВЕНАДЦАТЬ слепых поверхностей своего прибора вместо одной, и две из двенадцати не прозвучали бы без вопроса: одну она видела в собственном выводе и прошла мимо, вторую знала из своего же комментария в коде. ## 6. Предметные оси ревью Выбери 1–3 и назови какие: **деньги под гонкой** · **граница «холодности»** (что в прогоне перестало быть первым разом) · **провенанс каждого числа** (чем снято, каким прибором, на какой клетке). ## 7. Записка-план ДО работы Перед первой командой — записка: фазы, что чем предъявляется, где ждёшь осечки. Комплектность против заказа сверяй механически, а не памятью. ## 8. Заявление = команда Каждое число и каждая категорика отчёта идут **с командой, которой получены**. Приёмка пере-снимает. ## 9. Эхо-протокол старта **Первым действием** — ≤10 строк СВОИМИ словами: что понял · что считаешь опасным · что считаешь неверным. Дословный пересказ подтверждает канал, но не понимание, и ошибку промта повторяет вместе с ним. **Адрес бери из `/tmp/textmachine-channel`** — блок с `role=оркестратор`, — а не из этого промта: имя сессии не переживает рестарт окружения, и вписанное сюда имя однажды окажется мёртвым. Перед отправкой сверься с `ListAgents`: файл переживает смерть сессии, а `ListAgents` — нет. ## 10. Что НЕ удалось — обязательная секция отчёта И вторая её половина, без которой она вырождена: **«где прибор слеп и я это знаю»** — что невидимо · почему не чинил · чем закрывается. ⭐ Формулировка прошлой смены, идущая нормой: **«в коде названо, в отчёте нет — значит для следующей смены НЕ названо».** **И ОТДЕЛЬНОЙ секцией — находки вне заказа (§4.10):** криты · мажоры · регрессии · баги · жёсткие точки улучшения, каждая аргументированно и с носителем. ⚠ Эта секция обязана быть непустой ИЛИ нести строку «искал вот так, не нашёл» с перечислением того, где искал: «находок нет» и «не смотрел» в отчёте выглядят одинаково. ## 11. Канал вопросов и право отказаться Конфликт промта с кодом или доками — **пинг мне, не интерпретация**. И у тебя есть право сказать «этого делать не надо» с аргументом: прошлые три сессии возражали, и в двух случаях правы были они. ### ⭐ Старший коллега — Fable 5. **Разрешён ОДИН на сессию (слово владельца 11.09)** У тебя есть право поднять **одного** агента на модели **`fable`** и держать его как СОВЕТЧИКА при сомнениях — тем же способом, каким это делает оркестратор. Владелец разрешил ровно одного на сессию. **Как с ним работать, и форма здесь важнее числа:** - **Поднимаешь ОДНОГО и держишь его весь пак.** Ценность этого агента — в НАКОПЛЕННОМ контексте смены: он помнит, что ты уже решил и почему. ⛔ **Второго не поднимай** — вопросы ДОСЫЛАЮТСЯ первому (`SendMessage` по его id), а не адресуются свежему. Свежий агент вместо накопленного — потеря именно того, ради чего он заведён. - **Модель задавай ЯВНО** (`model: "fable"`), иначе она унаследуется и ты не будешь знать, что у тебя работает. - **О чём его спрашивать:** сомнение в решении · развилка, где оба пути выглядят законными · «не заказываю ли я уже построенное» · «не противоречит ли это ратифицированному» · спорная формулировка в отчёте. ⚠ **Спрашивай С КОНТЕКСТОМ и со СВОЕЙ рекомендацией** — вопрос без твоего варианта ответа даёт совет ни о чём. - ⛔ **Он советчик, а не источник истины: его ответ проверяется деревом.** У оркестратора он за смену ошибся дважды на фактах (называл платный прогон бесплатным, объявлял ряд новым предметом) — и оба раза его ВЫВОД оставался верным. Проверяй посылки, принимай выводы по существу. - **Что он дал оркестратору за эту смену** — для калибровки, чего от него ждать: поймал, что я собирался завести новый ряд бэклога под предмет, у которого ряд уже был; развернул порядок паков доводом, который я не назвал; и назвал условие, без которого два прогона стали бы несравнимы. ## 12. Прямой канал Механизм — `CLAUDE.md` §«Связь между сессиями». Впиши свой блок в `/tmp/textmachine-channel` ПЕРВЫМ действием. Нужной роли нет ⇒ канала нет, и это нормально: НЕ опрашивай сессии подряд. ## 13. Критерий завершённости У каждого пункта заказа — исход (сделано · не делаю с доводом · пинг) · круги СОШЛИСЬ (последний не дал НОВЫХ находок) · числа сняты ПОСЛЕ последней правки · всё живое в ДЕРЕВЕ или у меня, а не в письме · явное **«работа завершена, править не планирую»**. Без последнего пак считается идущим.