# Промт: ХОЛОДНЫЙ ПРОГОН ДВИЖКА на схеме v16 (бэкенд-сессия, ПЛАТНАЯ) > Выдан оркестратором №21, 31.08. Очередь — п.2 CURRENT-STATE в `docs/PROGRESS.md`. > **ДЕНЬГИ САНКЦИОНИРОВАНЫ ВЛАДЕЛЬЦЕМ 31.08: ≈$0.60, потолок $0.80, ДЕСЯТЬ глав ПОЛНОЙ ЦЕПЬЮ > включая редакторскую волну.** Прежняя цифра очереди «≈$0.05» снята как протухшая (§1в). > ⚠ Промт прошёл два рубежа: механическую сверку 12 блоков и опровергатель в четыре линзы — > 53 находки применены, 8 из них блокеры. Фактура ниже пере-проверена ИСПОЛНЕНИЕМ; где не смогли — > сказано прямо. ## 0. Какая проблема и что решит твой результат Движок переводит книги за деньги. С **27.08** в него легло семь коммитов и ~15 ратифицированных решений: входная дверь шва, стоп банка ФЛАЖКОМ внутри движка, схема хранилища **v16**, полоса отказов в два яруса с классом 15, объёмный потолок `--max-units`, гейт схемы, писатель книги (`tmctl build`). **Ни одно из них не проверено деньгами.** Проверено исполнением: последний платный вызов движка в корпусе — **17.08** (5 вызовов классификатора в `coldrun-b/reprobe/classify6`, $0.005582), всё остальное — до 02.08. Ни один существующий леджер не стоит на сегодняшней схеме, и ни один не гонял ПОЛНУЮ цепь на HEAD. Значит все эти решения сегодня — обещания кода и тестов, а не факты о работающей системе. **Твой результат** — первый платный сквозной прогон на текущем HEAD, который отвечает на один вопрос: **переводит ли движок книгу насквозь и отдаёт ли файл — на настоящих деньгах, настоящих ключах, настоящем провайдере.** Не «зелёная батарея», а книга, которую можно открыть. Он же снимает гейт с чужих работ, ждущих его с 20.08: строки бэклога **202** (живой прогон через API платформы) и **216** (подпись банка · halt на потолке · резюм после пополнения против ЖИВОГО движка). Слово владельца 20.08: «гонять одну неготовую систему против другой смысла нет» — поэтому первым идёт движок, один. Попутно и почти даром закрываются строки **154**, **157**, **160**, **198** (§5.7). ⚠ **Качество перевода — НЕ твой предмет.** Художественную оценку делает полигон. Ты меряешь МЕХАНИКУ и ДЕНЬГИ. Границы предмета: ты не судишь, хорош ли перевод, не калибруешь ставку платформы и не трогаешь дверь выдачи (её в платформе просто нет — `createExport`/`getExport` не смонтированы). ## 1. Что именно ты делаешь ### 1а. Форма прогона — делай РОВНО так **Новый проект, новый каталог, новый `book_id`.** Ни один существующий стенд не переиспользуется. Причины механические, все проверены исполнением: 1. **Схема.** Проектные БД корпуса стоят на **v7–v15** (на v14 — 13 из 36, одна на v15), бинарь HEAD — на **v16**; число применяемых версий у каждого стенда своё. Мигрировать чужой стенд ради холодного прогона — значит необратимо тронуть чужую улику. 2. **Конфиг.** Старый `book.yaml` с ключами `mined_delta:`/`mined_rejects:` **ОТКАЗЫВАЕТСЯ, exit 10** (D39.158 п.5): пути решений теперь выводятся конвенцией `<каталог>/.mined-delta.yaml`. Такие ключи несут 17 файлов корпуса, включая оба прежних холодных прогона. 3. **Потолки.** Потолки существующих стендов пробиты новой ценой и защищать перестали (`coldrun-a` `book_usd: 0.25` против пересчитанных ≈$0.56). **Каталог:** `books/gu-zhenren/coldrun-v16/` — создаёшь ты. **Исходник:** `books/gu-zhenren/coldrun-a/guzhenren-ch1-10.gb18030.txt` (sha256 `0b5f9b0266d8…`, 28 174 знака без переводов строк, 10 глав). Копируешь к себе, оригинал не трогаешь. Тождество байтов выбрано НАРОЧНО: **ровно этот файл лежит и под `bank-low`, и под `minirun`**, то есть под обоими историческими базлайнами, с которыми ты сравниваешь деньги (§5.3). **`pipeline.yaml` — копия `coldrun-b/reprobe/bank-low/pipeline.yaml`** с починенными по §1б путями. Любое отличие выпиши в записку-план ПОСТРОЧНО: сравнимость денег держится на конфиге, а не только на байтах исходника. **`escalation.budget_usd` обязан быть > 0** — в репозиторном шаблоне он 0, и тогда «эскалационные хопы» §5.3 и запас $0.60→$0.80 меряют пустоту. **Сид: идём БЕЗ `glossary_seed`**, как bank-low; решишь иначе — это пинг, а не выбор. ### 1б. ⚠ ЛОВУШКА ПУТЕЙ — главная в этом паке, проверь ПЕРВЫМ делом На машине **ДВА чекаута** одного репозитория: | Путь | Ветка | Что там | |---|---|---| | `/home/ubuntu/projects/textmachine-main` | `main` | ТВОЙ. HEAD с паком писателя книги | | `/home/ubuntu/projects/textmachine` | **`polygon`** | ЧУЖОЙ, ветка полигона | `books/` в твоём дереве — **СИМЛИНК** на `/home/ubuntu/projects/textmachine/books`; `/home/ubuntu/books` — **тот же симлинк**. То есть корпус физически лежит в чужом чекауте и версионируется ОТДЕЛЬНЫМ git-репо. ⚠ **`book.yaml` несёт СЕМЬ абсолютных путей под ДВУМЯ разными корнями.** - Под `/home/ubuntu/projects/textmachine/` — только **`models:`** и **`langpack_root:`**. ⇒ **ОБА переведи в `/home/ubuntu/projects/textmachine-main/backend/configs/…`.** - Под `/home/ubuntu/books/` — `pipeline:`, `source_file:`, `project_db:`, `langpack_extend:`. Это твой каталог прогона; они и должны смотреть туда. - `prompt_override:` — если используешь, это `…-main/backend/prompts/`, НЕ `configs/`. ⚠ **ЕДИНСТВЕННОЕ ИСКЛЮЧЕНИЕ — `mining.contrast_path`.** Jieba-контраст лежит ТОЛЬКО в `/home/ubuntu/projects/textmachine/eval/exp16/data/jieba_dict_general_zh.txt` (5 МБ, gitignored); в `textmachine-main` его нет, а репозиторный `pipeline-c1.yaml` секции `mining:` не несёт вовсе. Оставь путь в polygon-дереве как есть (чтение чужого чекаута законно) либо скопируй файл к себе. **Без него `--verify-bank` отказывает, и ось §5.4 закрывается целиком.** **Зачем всё это.** В polygon-дереве **нет каталога `langpacks/ru`** — он есть только в `main`. Два чекаута `backend` различаются ТОЛЬКО этим: `models.yaml` и промпты совпадают побайтово, так что снапшот прогона от выбора чекаута не зависит. Но `ru/reader.txt` — это слова, которые читатель видит на дыре. `LoadReaderWords` на отсутствующий каталог возвращает дефолты **без ошибки**. **Проверки исполнением, обе обязательны:** 1. `ls -d <твой langpack_root>/ru/reader.txt` — ДО покупки. 2. Ось закрывается только вторым шагом из §5.1 (`--partial` на книге с дырой). ⚠ **На complete-книге ловушка НЕВИДИМА:** сборка с `langpacks/ru` и без него даёт побайтно один файл и ни одного WARN. ⚠ Дисциплина симлинка: `find books -name X` **без `-L` даёт ЛОЖНЫЙ НОЛЬ** (оркестратор на этом уже попался). Всегда `find -L`. И никогда не создавай симлинков внутрь `books/`. ### 1в. Деньги — санкция владельца, делай РОВНО так Очередь несла «≈$0.05». **Цифра устарела в ~4.5 раза:** DeepSeek пере-пинен коммитом **15.08** (`76049bb`, D39.137) под вендорские цены, вступившие в силу **16.08 16:00 UTC** — flash `input 0.14→0.44`, `output 0.28→1.32`; pro `0.435→1.32` / `0.87→3.96`. Заход `bank-low`, стоивший $0.045095 в июльских деньгах, по этим ценам стоит **$0.2017** (множитель 4.47, пере-считано из его же токенов). **Слово владельца 31.08: ≈$0.60, потолок $0.80, ДЕСЯТЬ глав, ПОЛНАЯ ЦЕПЬ включая редакторскую волну.** ⚠ **«Потолок» здесь не абсолютный.** Он сверяется ДО каждого вызова против `committed + reserved`, но против ОЦЕНКИ, а списывается факт — поэтому итог может выйти за $0.80 на величину порядка одной максимальной резервации (`backend/internal/store/ledger.go` — «do not overshoot the ceiling by more than one maximum reservation»). На этом объёме это центы; знать об этом обязана ты, а не отчёт. Обязательны все три ручки: - **`--ceiling-usd 0.80`** на `translate` — КНИЖНЫЙ КУМУЛЯТИВНЫЙ потолок, перекрывает `book.yaml`, назад не пишется, обязан быть > 0; - **`ceilings: { book_usd: 0.80, day_usd: 1.00 }`** в `book.yaml` — продублировать ОБА (Р7: конфиг падает, если оба ≤ 0; день не должен срабатывать раньше книги); - **`--max-units` — ДВУМЯ ПОРЦИЯМИ, и это несущее требование, а не оптимизация.** - **Первая покупка:** `--max-units` заведомо малый (2–3 юнита). Обязана дать **exit 0** и строку «Next: N output unit(s) … have never been delivered». Это **единственное живое предъявление объёмного потолка** — механизма, который §0 называет среди проверяемых. При `--max-units` = `units_total` он не сработает НИ РАЗУ и останется там же, где был: в тестах. - **Вторая покупка:** остаток, `--max-units` = `units_total` из `tmctl manifest --json`. Уже оплаченные юниты не считаются и не пере-оплачиваются. Сохрани WARN про майнящую банк книгу и ЗАФИКСИРУЙ, потребовался ли `--resnapshot` — это живое основание `PD-422` и п.5 очереди. ⚠ **$0.60 — ОЖИДАНИЕ, $0.80 — потолок. Между ними запас на ретраи и эскалационные хопы**, которые объёмный потолок не тратит, а деньги тратят. **Упёрся в $0.80 — это exit 4, СТОП и ПИНГ, а не тихая пере-нарезка скоупа.** Подъём потолка просят при СРАБАТЫВАНИИ стопа, не по проекции: прогнозный запрос оставляет ложный след «владелец согласился на пере-оплату», которой не было. ⚠ **Сметы ПЕРВОЙ покупки у движка НЕТ** — `--dry-run` у `translate` отвергается явно. Потолки и есть твоя единственная защита. Смета ПЕРЕ-прохода существует, она $0 и без ключей. ⚠ **Гони в ДОЛИНУ.** У DeepSeek цена ходит окнами: пики **UTC 01–04 и 06–10 вдвое дороже**. Цены в `models.yaml` пинованы ПИКОВЫЕ, поэтому в долине леджер завысит — это в безопасную сторону. **Время старта запиши ПОЛЕМ в артефакт:** перенос машины обнулил mtime всего сырья, на mtime не опирается никто. ### 1г. Состав прогона Гони **полную цепь, включая редакторскую волну, на ДЕСЯТИ главах** — объём и состав заданы словом владельца (§1в), тобой не выбираются. Довод, почему не draft-only, и он честный: проверено исполнением по всем **36** базам корпуса — роль `judge` не вызывалась **НИ РАЗУ нигде**, а редакторская волна **гонялась и оплачена** на малых прогонах (19 баз), но **НЕ на холодном старте**: у `coldrun-a` и во всей семье `coldrun-b` ноль редакторских вызовов. Именно это держит строку бэклога **16**. Не измерена не «редактура вообще», а ПОЛНАЯ ЦЕПЬ ОДНИМ ЗАХОДОМ на холодном старте: draft+терминолог и edit меряли разные стенды под разными конфигами. Десять глав выбраны ради сравнимости: тот же байтовый исходник и тот же объём, что у обоих исторических базлайнов, поэтому множитель «июль → сегодня» получается без экстраполяции (§5.3). ⚠ Приор оркестратора, **опровергается твоим замером**: draft+терминолог ≈$0.20, редакторская волна на тех же десяти главах ≈$0.38–0.40, итого ≈$0.58 при потолке $0.80. Не влезает — **стоп и пинг, не режь скоуп молча**. ## 2. Зона записи и git **Пишешь:** `books/gu-zhenren/coldrun-v16/` (каталог создаёшь) + отчёт сессии. **Не пишешь:** `backend/`, `platform/`, `frontend/`, `eval/`. **`docs/` — тоже не пишешь**, и это ОСОЗНАННОЕ сужение канона на этот пак: `CLAUDE.md` разрешает бэкенд-сессии писать итог в свою секцию `docs/PROGRESS.md`, но здесь итог и пинги едут ОТЧЁТОМ, а в `PROGRESS.md` и `archive/reports/` их кладёт оркестратор — иначе твоя строка уедет чужим коммитом из живого дерева. Пинг = секция отчёта либо прямой канал §12. - **Ты НЕ коммитишь.** Ни в этот репозиторий, ни в репозиторий книг. Лендит оркестратор. - ⛔ **Книга и производные в репозиторий `textmachine` не коммитятся НИКОГДА** (CLAUDE.md). - ⛔ **НИКОГДА:** `git add -A` · `git add .` · `git commit -a` · `reset --hard` · `checkout` поверх грязного дерева · перезапись истории · `git stash` (стек общий с другими сессиями). - В дереве лежит незакоммиченная работа ДРУГИХ живых сессий (`platform/**`) — **не трогать вообще**. ⚠ **Прогон НЕИЗБЕЖНО пачкает репозиторий КНИГ, и роли для него в проекте не определено.** Тот репозиторий ОТСЛЕЖИВАЕТ `.db` (и `-wal`/`-shm`), а `.book.epub`/`.book.txt` его `.gitignore` не покрывает; `tmctl migrate` переписывает отслеживаемый файл БД. В ролевой таблице `CLAUDE.md` зоны `books` **нет вообще**. ⇒ **Ничего там не коммить и не прибирать.** Оставь `git -C books status` грязным, назови его состояние в отчёте дословно, вопрос «кто коммитит книги» подними пингом. ⛔ **И ЧИТАТЬ чужие БД не безобидно.** `sqlite3 …` **без `?mode=ro`** открывает базу НА ЗАПИСЬ, чекпойнтит WAL и УДАЛЯЕТ отслеживаемые `-wal`/`-shm`. Проверено исполнением при подготовке пака: одна SELECT-выборка по `coldrun-a` оставила две строки ` D` в чистом до того репозитории. ⇒ **Любое чтение чужой базы — только `sqlite3 'file:<путь>?mode=ro'`.** **Нашёл баг движка — ПИШИ, не чини.** Правка `backend/` — отдельный пак. Исключение ровно одно: если без однострочной правки прогон физически не стартует, ты **пингуешь** и ждёшь, а не патчишь молча. ## 3. Карта чтения — ЗАКОН, пять позиций 1. **`docs/experiments/00-provider-quirks.md`** — ЦЕЛИКОМ и ДО первого платного вызова. Обязательное пре-чтение перед любым обращением к провайдеру: живые слаги, thinking, `finish_reason`, игнорируемые параметры. ⚠ Проба падает или ведёт себя странно ⇒ **идём в вендор-доку, НЕ гадаем**. 2. **`docs/architecture/18-bank-ontology.md`** — ратифицирована D39.158, обязательное пре-чтение перед всем, что трогает банк. Три роли носителей · единственные писатели · дисциплина проекции. 3. **`backend/README.md`** — механика движка: волны, стадии, чанкование, артефакты. 4. **`docs/architecture/15-money-path.md` §2 «Деньги ДВИЖКА»** — леджер, оба потолка, leftover-reserved. ⚠ Якоря дока пере-проверены и починены 31.08, им можно верить. 5. **`docs/architecture/17-seam-inbound-law.md`** — закон входной двери шва. Всё остальное — код первичен, достаёшь сама грепом. Ратифицированное вложено в тело этого промта. ## 4. Разметка свободы **Делай РОВНО так (отступление = пинг оркестратору, не интерпретация):** - новый каталог, новый `book_id`, `pipeline.yaml` — копия bank-low с `escalation.budget_usd > 0`, без сида; чужие стенды не мигрировать и не переиспользовать (§1а); - пути: `models:` и `langpack_root:` — в `textmachine-main`; `mining.contrast_path` — исключение (§1б); - **число глав ДЕСЯТЬ и `--max-units` двумя порциями — санкция владельца (§1в), не твой выбор.** ⚠ Меньшее N на ВТОРОЙ покупке даёт остановку по объёму, а она печатает **exit 0** — ШТАТНОЕ ЗАВЕРШЕНИЕ, неотличимое в коде от «книга переведена». Скоуп молча усохнет; - бинарь `tmctl` **собрать из HEAD** своего дерева и записать `sha256`. Причина не в том, что стендовый `~/.local/bin/tmctl` чего-то не умеет — он от 30.08 23:17 и пак писателя книги в нём есть, а на 31.08 он побайтно совпадает с HEAD-сборкой. Причина в том, что **личность бинаря, которым куплен прогон, обязана быть зафиксирована числом**, а стенд пере-собирают чужие сессии без предупреждения; - ключи — `--keys-file` **абсолютным** путём. Цепь резолва: окружение → `--keys-file` → `.env` рядом с `book.yaml` → `./.env` в CWD. `--keys-file` **падает громко** на нечитаемом или пустом файле и принимается **только `translate`**. Единственные заполненные файлы ключей на машине — `/home/ubuntu/projects/textmachine/backend/.env` и `.../eval/.env` (576 Б, оба тронуты 30.08 01:01, что совпадает со словом владельца «починил ключи 30.08»). ⛔ **Файлы ключей НЕ ОТКРЫВАТЬ** — ни тебе, ни субагентам. Наполненность проверяется ПРОГОНОМ; - оба денежных потолка выставлены до первого платного вызова (§1в); - деньги считаются **из сырого леджера ДВУМЯ независимыми путями** (§6.3); - **`make battery` в `backend/` ДО первой покупки.** Не `go test ./...` — батарея держит ещё `vet -tags live`, `gofmt`, `golangci-lint` и `-race`, и только она гейт зоны. Скипы вслух; - **`tmctl migrate` отдельным шагом** — что он применит и что печатает, см. §1а п.1 и §6.2; - ⛔ **ПЕРВАЯ ЖЕ правка исходника закрывает платную часть НАВСЕГДА** — правило §5.6, и оно бьёт твою свободу выбирать порядок фаз. **Решаешь сама и аргументируешь:** - порядок фаз внутри платной части и где ставить свои стоп-точки; - нужен ли `--verify-bank` и в какой фазе (см. §5.4); - какие дополнительные $0-пробы дёшевы и стоят того. ## 5. Что прогон обязан предъявить — по осям ### 5.1 Сквозной путь, структура глав и файл книги `translate` → `status` → `report` → `manifest --json` → `export --json --pairs` (и отдельно голый `export` — это РАЗНЫЕ каналы) → **`build`**. **Шесть состояний честности D39.175 — это pending · withheld · incomplete · ghost · stale · drift, и живут они в ТРЁХ разных местах**, отчего и разъезд счёта «шесть состояний, но пять дыр». Четыре — перечисление `HoleKind` (`HolePending` · `HoleWithheld` · `HoleIncomplete` · `HoleStale`; пятая константа `HoleNone` = дыры нет). Пятое, **ghost**, — не `HoleKind`, а счётчик `BookExport.GhostRows`: переведённый текст, которому текущая нарезка не находит места; целостность он рубит наравне с дырами (`complete := len(holes) == 0 && exp.GhostRows == 0`). Шестое, **drift**, — булево поле отчёта и WARN, в файл не пишется. **Твой прогон штатно даст ОДНО:** `complete=true` либо `pending`. Остальные — $0-провокации ПОСЛЕ платной части, и порядок у них жёсткий: **§5.6**. ⚠ **`config_drift=false` и `stale_unknown=false` — самая дешёвая НОВАЯ фактура прогона.** Оба поля ни разу не имели честного «нет»: все стендовые книги под дрейфом. **`stale_unknown=true` на свежей книге означает СБОЙ, а не дрейф** — ищи его в WARN. ⇒ **Сохраняй stderr прогона целиком.** **Структура глав — узел строки бэклога 160, и он $0.** По `manifest --json` назови: сколько глав получили `heading` из текста, а сколько — цифровой рендер движка; совпадает ли число глав с 10; что напечатано меткой главы в собранных EPUB и txt. На листе владельца висит ровно этот вопрос (В-4/Ф-30, лейбл главы без заголовка) — приложи **дословные метки**, а не пересказ. ⚠ **Две ловушки `build`:** 1. `build --format epub` **МОЛЧА УДАЛЯЕТ** лежащий рядом `.book.txt` (и наоборот): набор рядом с БД всегда от ОДНОЙ сборки. А `StatusArtifacts.book_files` публикует ПОЛНУЮ карту форматов независимо от того, что записано. ⇒ **Собирай ОБА формата одной командой** (без `--format`) и не считай наличие пути в `book_files` доказательством наличия файла. 2. После коммита файлов `build` удаляет копии незапрошенных форматов, и сбой этого `os.Remove` возвращается ГОЛОЙ ошибкой ⇒ **exit 1 при том, что новые файлы УЖЕ на диске, а `BuildReport` не печатается вовсе**. ⇒ **При ЛЮБОМ ненулевом коде посмотри, что реально лежит на диске.** ⛔ **ПОРЯДОК СБОРКИ.** Чистая книга собирается и СОХРАНЯЕТСЯ **до** любой правки исходника: собери оба формата одной командой, скопируй пару файлов в `artifacts/clean/` внутри каталога прогона — и только потом провоцируй. Демонстрацию `--partial` гони с `--out` в отдельный путь, иначе она перезапишет НА МЕСТЕ ровно тот файл, который ты отдаёшь владельцу. ⚠ **Ось «издательский результат».** Клейм очереди «0 fatals / 0 errors на трёх стендовых EPUB» был «со слов сессии»; **две трети пере-проверены независимо** при подготовке промта: `epubcheck` на машине НЕТ, но java 21 есть и валидатор приносится одной командой; пере-собранный бинарём HEAD EPUB настоящего перевода (стенд `minirun`) дал 0 fatals / 0 errors. Третья точка — **твой** EPUB. ⚠ Третий стенд (`acceptance`, единственный с `ghost`/`withheld`/`incomplete`) дёшево не пере-собирается — его pipeline-конфиг протух по трём классам. Эти три состояния либо возникнут у тебя сами, либо **останутся непроверенными, и так и запиши**. ⚠ **Живой читалки на машине нет ни одной.** Не изобретай: **передай файл владельцу** и назови ось открытой до его ответа. ### 5.2 Коды выхода — таблица, сверяй фактические | Код | Что случилось | |---|---| | 0 | чисто (в т.ч. остановка по `--max-units` — это ЗАВЕРШЕНИЕ) | | 1 | инфраструктура, ошибка разбора флага, пойманная ПАНИКА | | 2 | завершено С ФЛАГАМИ | | 3 | стоп подписи банка (намеренная человеко-в-цикле пауза, НЕ падение) | | 4 | halt по денежному потолку (книга или день) | | 5 | graceful stop (пойман SIGINT/SIGTERM) | | 10 | конфиг не поедет: нечитаем, неразбираем, невалиден, нет ключа | | 11 | исходник КНИГИ не читается/не декодируется | | 12 | проект залочен другим `tmctl` | | 13 | схема проекта не этого бинаря — нужен `tmctl migrate` | | 14 | документ решений прочитан и отклонён — решает ПОЛЬЗОВАТЕЛЬ | | 15 | документ принят, запись не завершилась — отчёт называет, какой файл лёг; шли тот же документ снова | | 16 | `build` отказался писать книгу с дырами — либо доделать, либо `--partial` | | 19 | класс отказа, номера которому этот бинарь не знает | Каждый код, который ты увидишь, — с командой и фактическим `$?`. Кода, которого не видела, не называй. ⚠ **Exit 15 у `build` на этом прогоне НЕДОСТИЖИМ** без инъекции сбоя ФС между двумя `rename` — не заказываю. Но знай: 15 означает, что ЧАСТЬ файлов уже на диске. ### 5.3 Деньги Разложи стоимость по стадиям и ролям и положи на **ОБА** исторических базлайна — они меряли разное, и только вместе покрывают твою цепь: - **`bank-low`** (`coldrun-b/reprobe/bank-low/guzhenren-bank-low.db`) — терминологический контур: draft flash $0.021289 + draft pro $0.010350 = $0.031639 · терминолог $0.005750 · классификатор $0.007706 · **весь заход $0.045095**; - **`minirun`** (`books/gu-zhenren/minirun/guzhenren-minirun.db`) — РЕДАКТОРСКИЙ контур на том же исходнике побайтно: draft flash $0.018834 (58) · draft pro $0.003371 (3) · **edit editor pro $0.092086 (16)** · весь заход $0.114291. Оба — в ИЮЛЬСКИХ деньгах. Твоя задача — дать то же разложение в СЕГОДНЯШНИХ и назвать множитель. ⚠ **Леджер = НИЖНЯЯ граница** (строка 78). «Оплаченный хвост» собирается из **ДВУХ таблиц**: - по `checkpoints` — ретраи (`attempt>0`) и эскалационные хопы (`escalation=1`). ⚠ У `checkpoints` **НЕТ `book_id`** — связь только через `JOIN jobs j ON c.job_id = j.id WHERE j.book_id=…`; - по `request_log` — `ok=0 AND cost_usd>0` и `estimated=1`. ⚠ Колонок `attempt`/`escalation` в `request_log` НЕТ, запрос по букве старой редакции упал бы. ⛔ **НЕ путь к сумме:** `chapters[].cost_usd` из `status --json` — это стоимость только ПОСЛЕДНЕЙ резолюции строки. ⚠ **В денежных таблицах НЕТ идентификатора прогона:** `checkpoints` и `spend` пожизненные по книге, единственная ось разделения прогонов в них — `checkpoints.created_at` (UTC). Ось прогона есть только в телеметрии (`request_log.trace_id`). **Ты покупаешь ДВУМЯ порциями (§1в) — спланируй разбор заранее.** ### 5.4 Банк и стоп подписи Стоп банка стал **флажком на НОВИЗНЕ** (D39.158 п.1): `--verify-bank` останавливает прогон перед edit-волной **только** если в карте есть кластер, вся поверхность которого ещё не предъявлялась; память предъявления — `bank_stop_presented`, схема v16. Прогон, который НЕ стопится, обязан свернуть неподписанные строки в банк ПЕРЕД стадией. ⚠ **Нота проверяется ДВУМЯ прогонами — реши сама, влезает ли.** Первая половина: первый `--verify-bank` даёт РОВНО ОДИН стоп. Вторая: повторный `--verify-bank` **БЕЗ единого решения по термам НЕ стопится второй раз** — это и есть новизна-как-флажок. Проверив только первую, ты проверишь ноту наполовину, и так и напиши. Наблюдаемое: `exit 3` · строка «the delta holds terms no stop has shown before» · строки в `bank_stop_presented` · файл `.mined-signature.yaml`. Провал записи памяти НЕ валит прогон — он даёт один лишний доброкачественный стоп, и это штатно. Форматы, изменившиеся и ни разу не виденные на живых данных: `.mined-signature.yaml` получила конверт `map_version: tm-signature-map-v1` + `map_id`; `.bank.json` — якорь свежести `as_of`. ⚠ **Атомарность сайдкаров пере-проверена по коду 31.08:** через `writeFileAtomic` идут **ЧЕТЫРЕ** — `.manifest.json`, `.bank.json`, `.mined-signature.yaml`, `.auto-bank.yaml`; неатомерен **ОДИН** — `.bank-stop.txt` (`os.WriteFile` с усечением; это отрендеренная ТАБЛИЦА, не JSON). **Файла `bank-stop.json` не существует.** Форматы книги идут через staged-commit. ⚠ Прежняя запись №18 («атомарны три из шести, среди них `bank-stop.json`») в этой части УСТАРЕЛА — если встретишь её в доках, это она, а не твой результат. **Строка бэклога 240** («оплаченный стоп подписи может исчезнуть МОЛЧА») заведена оркестратором №20 ЧТЕНИЕМ КОДА и честно помечена **PLAUSIBLE — сценарий не воспроизведён**. Её платформенную половину берёт пак P12. Дёшево предъявишь что-то ЗА или ПРОТИВ — это ценнее чтения кода; дорого — не гонись, скажи в obstacles. ### 5.5 Что ты оставляешь платформе (это и есть снятие гейта 202/216) Платформа **сочинила сама** форму артефактов шва и никогда не видела настоящих. Каналов **ПЯТЬ**, а не три: **манифест** (`manifest --json`) · **сайдкар банка** (`.bank.json`) · **причины флагов** · **`events.jsonl`** (аутбокс схемы v15 — главный канал шва, который твой прогон и создаёт) · **`export --json --pairs`** (единственный канал, несущий ТЕКСТ). **Чего ждёт другая сторона — читай в ЕЁ коде, не по памяти и не из этого промта** (D39.132): манифест — `platform/internal/ingest/manifest.go`, сайдкар банка — `platform/internal/ingest/bank.go`, причины флагов — `platform/internal/ingest/notes.go` (рукописный словарь причин → коды замечаний контракта). Читать чужую зону можно, писать в неё нельзя. ⚠ **Карта причин флагов — НЕ файл движка:** движок отдаёт причины значениями `flag_reason` в `export`/`status`; это и есть строка бэклога 204. Сравнивай наблюдённые значения со словарём `notes.go`. ⚠ **Расхождений может не быть вовсе** — «сверено, расхождений ноль, вот обе стороны списком» полноценный результат, а не пустая работа. Каталог прогона остаётся на диске целиком; в отчёт положи ФОРМУ артефактов (структура, ключи, примеры значений) — отчёт уедет в репозиторий, каталог нет. **Дёшево и сверх заказа, если останется время** (обе пробы $0, обе после платной части): назови в отчёте путь к своей БД и её размерности (глав/юнитов/строк) — `PD-297` платформы ждёт корпусную книгу для замера round-trip, и без этого следующая сессия пере-покупает прогон. ### 5.6 $0-провокации ПОСЛЕ платной части — ЖЁСТКИЙ ПОРЯДОК ⛔ **ГЛАВНОЕ ПРАВИЛО, и оно бьёт твою свободу выбирать порядок фаз (§4): ПЕРВАЯ ЖЕ правка исходника закрывает платную часть НАВСЕГДА.** После неё ни `translate`, ни `redrive` по этой книге не запускаются. Причина — строка бэклога **238**, подтверждённая обеими половинами: резюм-фаст-пас требует совпадения И `content_hash`, И снапшота; правка исходника НА МЕСТЕ (исходник в снапшот не входит) роняет фаст-пас, и `translate` **перекупает юниты БЕЗ предупреждения в смете**. Гейт `--accept-rebill` этот путь не ловит по конструкции. Единственный видимый след — INFO-строка `manifest: the stored manifest is stale (source or cut changed)`. Порядок проб — ровно такой: 1. **`stale`** — правка исходника, **РАВНАЯ ПО БАЙТАМ** и внутри чанка (сдвинешь границы нарезки — получишь `ghost` вместо `stale`, а в отчёте напишешь, что stale проверен) → `status --json` → `build`. ⛔ Идёт ПЕРВОЙ: `staleUnits` под config drift возвращает «неизвестно» сразу, ничего не считая, а любая правка конфига двигает снапшот ⇒ `drift=true` ⇒ ось `stale` для этой книги закрыта НАВСЕГДА. 2. **Строка 238** — на тех же данных: `status --json` скажет, что пере-оплаты нет, а `build` скажет `stale N`. **Расхождение двух $0-поверхностей и есть предъявление строки.** 3. **`--partial` / дыры** — с `--out` в отдельный путь (§5.1), и здесь же глазами найти русскую строку маркера дыры — это второй шаг оси §1б. 4. **Второй `--verify-bank`** (§5.4). 5. **Второй `translate`** — строка бэклога **198**: юниты резолвятся бесплатно; посмотри, появились ли ПОВТОРНЫЕ анонсы юнитов в `events.jsonl`. Ключ анонса — `unit::::`, без метки нарезки; это первый настоящий аутбокс на схеме v15 и первая возможность увидеть механизм на данных, а не в коде. 6. **ПОСЛЕДНЕЙ — строка 239:** снять edit-стадию в **КОПИИ** `pipeline.yaml` → `status --json` покажет `config_drift=false` и черновики как полную книгу, а `export`/`build` на том же конфиге покажут дрейф. ⛔ Эта проба двигает снапшот, поэтому она последняя. ### 5.7 Что закрывается ДАРОМ — из того, что ты и так сохраняешь **Строки бэклога 154 и 157** гейчены именно этим прогоном и закрываются числами, которые уже печатаются: из stderr терминолога выпиши `families` / `families_refused` / `families_held`; из `manifest --json` — распределение размеров юнитов (минимум/медиана/максимум знаков) и `units_total` по главам. Это единственный носитель замера, на который обе строки гейчены; без него они переезжают на следующий платный прогон. ## 6. Мандат самопроверки ИСПОЛНЕНИЕМ Самоотчёт «проверено» без исполнения регулярно оказывается ложным и здесь стоит ДЕНЕГ. **Тебе ЯВНО разрешены субагенты.** Модель задавай ИМЕНЕМ и знай, сколько их у тебя работает. По умолчанию для трудного суждения — **Fable 5**; обычно хватает одного-двух, веер под предмет выбираешь ты. 1. **Записка-план ДО первой покупки** — что покупаешь, каким потолком защищено, чем докажешь; `N` для обеих порций `--max-units` названы числом. Пишется в каталог прогона **и ДОСЛОВНО повторяется первой секцией отчёта**: отчёт уезжает в репозиторий, каталог прогона нет. Записка, дожившая только до конца сессии, приёмке не предъявляется. 2. **Сухой проход $0 ПЕРЕД покупкой:** `status` · `manifest` · `report` ключей не требуют. ⚠ Но `status`/`manifest` на никогда-не-запускавшейся книге **СОЗДАЮТ и мигрируют БД**. ⚠ На ТВОЕЙ свежей книге `tmctl migrate` напечатает `migrate: created at schema v16` (или `already at schema v16`); **`backups/` НЕ появится** — restore point на новой БД не берётся. Строка `pre-migrate: backed up … at schema v14` — контракт СУЩЕСТВУЮЩЕЙ книги, и её ты не увидишь. Хочешь увидеть глазами — сделай на СВОЕЙ КОПИИ чужого стенда вне `books/`, и так и запиши. 3. **Деньги — двумя независимыми путями.** Оба печатает ОДНА $0-команда `tmctl report --config book.yaml`: строка `Book ledger: committed=… reserved=…` считает `SUM(spend.committed_usd)`, а `ROUTING/MONEY: … spend by model:` собирается из `checkpoints`. Сойдутся — приводишь обе; разойдутся — это НАХОДКА, а не помеха. 4. **Активная проверка живости.** Раз в пару часов сверяй рост числа вызовов и трат по леджеру ДВУМЯ чтениями. Зависшая задача от идущей неотличима по молчанию. 5. **Адверсариальный проход по СВОЕЙ ГОТОВОЙ работе — ПЕРЕД сдачей.** Не перечтение: субагент получает твой отчёт, твои команды и мандат «найди, где она выдаёт непроверенное за проверенное». **Артефакт — секция отчёта «Адверсариальный проход»:** какой моделью, сколько агентов, что каждому дано на вход, и КАЖДАЯ находка дословно + твоя диспозиция (принято и исправлено / отклонено с доводом). Ноль находок — тоже запись, но тогда назови, что именно субагент проверял и какими командами. Оси, на которых пак уязвим **по моему суждению** — приор, не потолок: клеймы о деньгах · клеймы о кодах выхода, которых ты не видела · клейм «EPUB валиден» · утверждение, что артефакт совпал с ожиданием платформы. Считаешь, что уязвимо другое (тождество нарезки, честность `complete`) — замени ось с доводом и скажи об этом. 6. **Перед отчётом сверь КАЖДЫЙ клейм с результатом инструмента ЭТОЙ сессии.** 7. **Последний абзац отчёта — план или обещание? Сделай сейчас.** 8. **Интервальная сверка с заказом.** На каждой естественной границе (после сухого $0-прохода · после первой порции · после edit-волны) прогоняй по осям §5 короткую сверку «что уже предъявлено / что ещё нет», и хотя бы одну отдай субагенту с явными критериями §7. Длинная сессия дрейфует от заказа незаметно для себя. ⛔ **Тесты и гейты не подгонять под зелень.** Править или удалять тест/голден/гейт, чтобы он прошёл, — НЕДОПУСТИМО. Несогласие с тестом — пинг, не правка. ## 7. Записка-план и комплектность До первой покупки — записка-план (§6.1). Перед сдачей — механическая сверка отчёта против §5 по осям: каждая ось получает вердикт **предъявлено / не предъявлено / опровергнуто**. Три исхода, не два: «не проверено» ≠ «опровергнуто». ## 8. «Заявление = команда» Каждое число и каждая категорика отчёта идут С КОМАНДОЙ, которой получены. Приёмка пере-ранит выборочно. Клейм о рантайме без живого прогона = **PLAUSIBLE**, и так и помечается. Клейм без ре-рана — «со слов сессии». ## 9. Эхо-протокол старта **ДО первой правки и ДО первой покупки** — ≤10 строк: скоуп / инварианты / чего не делаешь. Отправь первым действием по каналу (§12). Эхо служит и проверкой канала. ## 10. Obstacle reporting Обязательная секция отчёта: **что НЕ удалось и что НЕ проверено**. Отсутствие инструмента, недостижимая ось, непонятое поведение — сюда. Пустая секция при непустой работе читается как дефект отчёта. Ты вправе сказать «этого делать не надо» с аргументом — это поощряется, а не штрафуется. ## 11. Канал вопросов Конфликт промта с кодом или доками ⇒ **пинг, НЕ интерпретация**. Промт мог устареть между написанием и исполнением; код первичен. Настоящую развилку неси быстро. **Правь курс через оркестратора:** mid-flight правки доезжают ТОЛЬКО релеем — владелец пере-передаёт правку отдельным сообщением, ты эхо-подтверждаешь, и она отдельным пунктом отчёта. ## 12. Прямой канал Механизм — `CLAUDE.md` §«Связь между сессиями»; файл **`/tmp/textmachine-channel`**. Впиши туда СВОЙ блок первым делом, дописывая в КОНЕЦ и не трогая чужие. Перед тем как писать кому-то — сверься с `ListAgents`: файл переживает смерть сессии, `ListAgents` нет. ⚠ Дословно: **нужной роли нет, файла нет или имя не отвечает ⇒ КАНАЛА НЕТ, и это НОРМАЛЬНЫЙ случай: НЕ опрашивай сессии подряд.** Вопрос — секцией в отчёт. --- ## Приложение А. Известные грабли прежних холодных прогонов Промт на холодный прогон писался ДВАЖДЫ, оба отработаны (`docs/archive/prompts/`). Третий заход (работа C промта `BACKEND_EFFORT_HANDLE`, 02.08) закрыт владельцем как неуспешный — и **прогон там не начался вовсе**. Техническая причина: `DeepSeek-V4-Flash-0731` сменил веса под тем же слагом, а thinking у вендора включён по умолчанию с эффортом high. ⇒ **Слаг живой ≠ модель та же.** Перед покупкой сверь ПОВЕДЕНИЕ модели, а не только доступность слага. `coldrun-b` заморожен ЛЕГИТИМНО: фаза C остановлена чекпойнтом по букве промта (критерий «0 пустых» нарушен 8 из 9). Его собственная база ПУСТА — деньги «coldrun-b» потрачены в подпроектах `reprobe/*`. Оба каталога — улика, read-only. ## Приложение Б. Готовые команды (проверены на HEAD, но пере-проверь) ``` # бинарь из HEAD + его личность cd /home/ubuntu/projects/textmachine-main/backend && go build -o <твой путь>/tmctl ./cmd/tmctl sha256sum <твой путь>/tmctl # $0-глаголы, ключей не требуют, безопасны в любом порядке: tmctl --config book.yaml tmctl bank-apply --config book.yaml --decisions decisions.json [--dry-run] tmctl seed-lint --seed glossary.yaml # ⛔ ПЛАТНЫЕ: # translate — твой глагол, см. §1в # redrive — этот пак его НЕ заказывает НИГДЕ. Не запускай: он и платит, и разрушительно # сбрасывает флаговую телеметрию, и принимает голую форму без селектора. # полная стоимость из сырья — ⛔ ВСЕГДА mode=ro (§2) sqlite3 'file:?mode=ro' "SELECT printf('%.6f',COALESCE(SUM(committed_usd),0)), printf('%.6f',COALESCE(SUM(reserved_usd),0)) FROM spend WHERE book_id='';" ```