# Эксперимент 24. Холодный прогон «от двери до ФАЙЛА» — настоящая книга, настоящие деньги > **Пре-регистрация.** Всё, что ниже строки «ГРАНИЦА ФРИЗА», написано ДО первого платного вызова и > закоммичено фриз-коммитом. Результаты дописываются ПОСЛЕ прогона, отдельной секцией, и ничего в > пре-реге не правят: расхождение называется, а не подгоняется. **Зона:** полигон · **Пак:** `docs/POLYGON_COLD_RUN_A_SESSION_PROMPT.md` (редакция 2) · **Дата:** 11.09.2026 **Предмет:** строка бэклога **16** — цена и проходимость книги, ДОВЕДЁННОЙ ДО КОНЦА, не измерены ни разу. ## 0. Что именно проверяется Одна настоящая книга (蛊真人, главы 1–3, zh→ru) проходит весь путь: интейк → цена → холд → прогон → остановка на подпись банка → решение человека через дверь правок → резюм → редакторская волна → сборка выгрузки → скачанный файл → **человек читает первый абзац**. У каждого узла напечатано, ЧЕМ он предъявлен. ⚠ **Судьи на этом пути НЕТ.** Боевой `pipeline-c1.yaml` несёт две стадии — `draft` и `edit`; `role: judge` живёт только в `c2`. `escalation.budget_usd: 0` ⇒ эскалация не исполняется; `gates.coverage.enabled: false` ⇒ из пяти гейтов работают четыре. Проверяемый путь: **черновик → редактор → четыре $0-гейта → выгрузка.** ⚠ **О качестве перевода пак не судит вовсе:** 蛊真人 узнаётся моделями (претрейн), и любое суждение о качестве было бы суждением о памяти модели. Чтение человеком отвечает на один вопрос — «это связный русский текст, а не мусор и не обрывок». ## 1. ГРАНИЦА ФРИЗА — что зафиксировано до первого цента | Предмет | Значение | |---|---| | Фриз-sha | `b0f5d8915c8553993f42e6e3a9d6fbd18adfa68e` | | Фриз-дерево | локальный **клон** `~/tm-coldrun-a/freeze` (0 грязных строк при 13 в главном дереве) | | Бинари | `tmctl` · `tmplatformd` · `tmplatformctl`, собраны из клона, у каждого `vcs.revision=b0f5d89…`, `vcs.modified=false`, строк `vcs.*` — 3 | | Исходник (оригинал) | `books/gu-zhenren/coldrun-v16/guzhenren-ch1-10.gb18030.txt`, 57838 байт, sha256 `0b5f9b0266d8c32ac717a41211d2ed15d4f2a07f37a701fb686e255ab6c89f37` | | Исходник (СРЕЗ, что покупается) | главы 1–3, 17564 байта, sha256 `ed870ba6065ce3eb4eec12e80238efbc2be8511f38334ab1d92d5693f4ef4df9` | | Фактический pipeline-YAML | `~/tm-coldrun-a/mirror/cfg/pipeline-c1.yaml`, sha256 `a46b33ee65b7713b4fbf86f64c788ba6b11eb0a219170c145a6205088156ad49` — **побайтно равен** `backend/configs/pipeline-c1.yaml` фриза (`cmp`) | | Артефакт контраста | `mining-contrast.zh.txt` = jieba 0.42.1 `dict.txt`, sha256 `7197c3211ddd98962b036cdf40324d1ea2bfaa12bd028e68faa70111a88e12a8`, 349 046 строк | | Шаблон книги | `~/tm-coldrun-a/book-template-c1.yaml`, sha256 `f66e681ff55b2653fc87944f45d7214bac0cd209f42102f642267d1ef61d8057` | | Потолки книги (шаблон) | `book_usd: 1.25` · `day_usd: 2.50` — машинный бэкстоп; сессия останавливается и пингует РАНЬШЕ, на факте $1.00 | | Грант платной учётки | $2.50 (отдельная учётка, не дымовая — иначе леджер смешивает дымовые холды с боевыми) | **Объём заказа — вариант (а) пака:** режется ИСХОДНИК, грузится срез трёх глав. Довод сильнее, чем «сверка честнее»: при варианте (б) семь незаказанных глав — это ДЫРЫ, дверь обязана отдать файл `--partial` с пометкой (`D39.178`), и центральный критерий `exports.complete = true` недостижим ПО ПОСТРОЕНИЮ. **Срез по $0-манифесту (`tmctl manifest --json`, читающий верб, ключей не требует):** | Глава | `units_total` | `chunks_total` | `expected_usd` | символов | |---|---|---|---|---| | 1 `第一节:纵身亡魔心仍不悔` | 2 | 2 | 0.032424 | 3287 | | 2 `第二节:逆光阴五百年觉悟` | 1 | 2 | 0.028459 | 3051 | | 3 `第三节:请一边玩蛋去` | 1 | 2 | 0.023237 | 2421 | | **книга** | **4** | **6** | `expected_usd 2.08412008` · `book_once_usd 2.00` · `step_max_usd 0.13647876` | 8759 | ⚠ `expected_usd` книги включает `book_once_usd` $2.00 — это ПОТОЛКИ контура банка (`gates.terminology.budget_usd: 1` + `classify_budget_usd: 1`), а не смета. Смета текста — сумма глав, **$0.084120**. Пинится **сумма `units_total` по заказанным главам = 4** (пин «≥1 глава с `units_total ≥ 2`» из первой редакции пака охранял то, чего не бывает). ## 2. Пре-рег-таблица: узел → что ДОЛЖНО произойти → чем предъявлено → что считается провалом | # | Узел | Ожидание (числом или строкой) | Чем предъявлено | Провал узла | |---|---|---|---|---| | 1 | Стенд — мой | слушатель на `127.0.0.1:8097` принадлежит МОЕМУ pid; на `11434` — заглушки нет вовсе (платная фаза) | `ss -ltnp` с pid | на порту чужой процесс | | 2 | Код — из фриза | у трёх бинарей `vcs.revision=b0f5d89…`, `modified=false`, строк `vcs.*` > 0 | `go version -m` | любое из трёх не так ⇒ СТОП | | 3 | Гость и деньги | учётка заведена `POST /auth/dev-login`; грант $2.50 одной строкой `credit_ledger.kind='grant'` | `tmplatformctl balance` + строка леджера | самореги нет, пополнения по HTTP нет — это ожидаемо | | 4 | Интейк | `201`, `chapter_count = 3`, `character_count` ≈ 8759 | тело ответа + строка `books` | не 3 главы ⇒ СТОП до оплаты | | 5 | Срез совпал | `units_total = 4`, по главам 2/1/1 | `chapters`+`units` в Postgres против таблицы §1 | расхождение ⇒ СТОП до оплаты | | 6 | Цена и бонд | `term_consistency_funded: true`, `verdict: covers_all`, `affordable_chapters: 3`, `hold ≈ 2 241 629 µUSD` (= ⌈expected×1.25⌉ + step_max + бонд 2 000 000) | `GET /v0/books/{id}/run-options` | `false` ⇒ СТОП до оплаты (тихая потеря консолидации терминов) | | 7 | Старт | `202`, `status: translating`, `ordered_chapters: 3`; строка `runs` с `bond_funded = t` | ответ + строка `runs` | отказ старта ⇒ СТОП и пинг | | 8 | Ключи живы | первый платный вызов не отказан по авторизации | `request_log.err` пусто на первой строке | отказ провайдера ⇒ СТОП и пинг (не моя поломка) | | 9 | Кадры | `events.jsonl` несёт `hello · progress · unit_done · spend · bank_stop · finished`; `run_attempts.last_seq` растёт | счёт кадров по типам + `last_seq` | кадров нет при живом юните ⇒ дефект | | 10 | Банк-стоп | `runs.status = awaiting_bank`, exit **3**, `.bank.json` несёт непустой `proposed[]` | статус + exit + копия сайдкара | стоп не наступил ⇒ **исход «узел не наступил»**, а не провал (三 условия разом: `--verify-bank` И edit-волна И некогда не показанный кластер) | | 11 | Проекция банка на платформе | `bank_terms` = **0** ПОКА прогон не закрыт и **> 0** ПОСЛЕ | `GET /v0/books/{id}/bank` + `select count(*)` | ноль ПОСЛЕ закрытия ⇒ дефект | | 12 | Дверь правок | `POST …/bank/corrections` `preview:true` → `changed:true`; затем `preview:false` → `accepted[0].state = applied`; на диске появляется `.mined-delta.yaml` | тело ответа + файл | отказ двери ⇒ дефект | | 13 | Резюм | `202`, вторая строка в `run_attempts` (attempt_no = 2), `exit_code = 0` | `run_attempts` | прогон не возобновился ⇒ дефект | | 14 | Книга переведена | `units.state = translated` для всех **4** юнитов | `select state, count(*)` с контрольным счётом юнитов книги | любой юнит не `translated` ⇒ книга не доведена | | 15 | Сборка | `tmctl build`: `complete: true`, `pending/withheld/incomplete/stale/ghost = 0`, `stale_unknown: false`, `config_drift: false` | stdout сборки (на API этих полей НЕТ) | любое не так ⇒ книга не целая | | 16 | Выгрузка | `exports.state = ready`, `exports.complete = t` в Postgres, `size_bytes` = числу скачанных байт | строка `exports` + `%{size_download}` | `complete` не `t` ⇒ дверь отдала книгу с дырой | | 17 | ФАЙЛ | скачаны байты, sha256 напечатан; EPUB читается структурно (zip + `container.xml` + `nav` + spine = 3) | sha256 + разбор zip | файл не открывается ⇒ провал | | 18 | Человек прочитал | первый абзац перевода — связный русский текст | цитата в отчёте | не текст ⇒ провал | | 19 | Деньги сошлись | Σ `request_log.cost_usd` ≈ `spend.committed` ≈ Σ `credit_ledger` settlement ≈ (грант − баланс); открытых резерваций **0** | четыре счёта в µUSD рядом | расхождение — **назвать**, не подгонять | | 20 | Ничего не реплеено | на платной базе `count(*) where tm_hit=1` печатается С РАЗБИВКОЙ ПО ПОПЫТКАМ, `distinct model_actual` не содержит `local-*` | запросы к `project.db` | есть `local-*` ⇒ прогон измерил заглушку | | 21 | Расхождение форм | механический счёт по ОТГРУЖЕННОМУ тексту: сколько канонических терминов отданы более чем одной передачей и в каких главах | `eval/door_to_file/spread.py` + `tmctl export --json --pairs` | — (это ЗАМЕР, у него нет «провала») | ⚠ **Про «три следа»: их не три.** Postgres платформы МАТЕРИАЛИЗУЕТСЯ из `events.jsonl` движка (`Sink materializes a stream into the reporting database`), а текст, манифест и файл платформа берёт теми же вербами `tmctl`. ⇒ согласие Postgres, диска движка и отчёта сборки — это **одна база, согласная сама с собой**, а не три свидетеля. По-настоящему независимы только **скачанные байты и их sha256**; биллинга провайдера у нас нет. Это не отменяет сверку — это меняет то, что она доказывает. ## 3. Стоп-правила (остановка и пинг оркестратору, не решение сессии) 1. фактическая трата дошла до **$1.00** (1 000 000 µUSD); 2. `runs.paused_reason` НЕПУСТО — любое из четырёх (`run_limit_reached · credit_exhausted · daily_ceiling · ceiling_unknown`); 3. срез не совпал с §1 — стоп ДО оплаты; 4. `term_consistency_funded: false` — стоп ДО оплаты; 5. бинарь не из фриза — стоп до устранения. ## 4. Инструменты (зафиксированы фризом вместе с пре-регом) * `eval/door_to_file/drive.sh` — драйвер фаз с гейтами; отказывает, а не предупреждает. * `eval/door_to_file/collect.py` — сборщик следов: фриз-гейт, Postgres, диск движка, отчёт сборки, деньги. * `eval/door_to_file/spread.py` — счёт расхождения форм по отгруженному тексту (строка бэклога 406). * `eval/door_to_file/stub/` — $0-заглушка провайдера `local` (перенос штатной `fakeProvider` стенда). * `eval/door_to_file/zeropipe/` — рендер $0-пайплайна (перенос штатного `zeroCostPipeline`). **Позитивный контроль каждого прибора исполнен ДО платной фазы** (§«Фаза 0» в результатах): подсаженный ненулевой банк, удержанный юнит и открытая резервация красят сборщик; книга с дырой красит отчёт сборки; чужой и беcштамповый бинарь красят гейт; самотест `spread.py` ловит подсаженную вторую форму.