textmachine/docs/archive/prompts/BACKEND_COLDRUN_V16_SESSION_PROMPT_2026-08-31.md

55 KiB
Raw Blame History

Промт: ХОЛОДНЫЙ ПРОГОН ДВИЖКА на схеме v16 (бэкенд-сессия, ПЛАТНАЯ)

ОТРАБОТАН И ЗАКРЫТ. Промт исполнен платной бэкенд-сессией 31.08.2026; развилка «довести ≈$1.00 / остановиться» закрыта словом владельца «не доводить» на $0.436110 из санкции $0.80. Отчёт — ../reports/COLDRUN_V16_REPORT_2026-08-31.md, ратификация — D39.179. Инструкции отсюда НЕ исполнять (правило архива). Перенесён из docs/ оркестратором №22 02.09.2026: два носителя — таблица docs/README.md и CURRENT-STATE — уже объявляли его лежащим здесь, а физически он оставался в живом каталоге.

Выдан оркестратором №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. Схема. Проектные БД корпуса стоят на v7v15 (на v14 — 13 из 36, одна на v15), бинарь HEAD — на v16; число применяемых версий у каждого стенда своё. Мигрировать чужой стенд ради холодного прогона — значит необратимо тронуть чужую улику.
  2. Конфиг. Старый book.yaml с ключами mined_delta:/mined_rejects: ОТКАЗЫВАЕТСЯ, exit 10 (D39.158 п.5): пути решений теперь выводятся конвенцией <каталог>/<book_id>.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 заведомо малый (23 юнита). Обязана дать 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 0104 и 0610 вдвое дороже. Цены в models.yaml пинованы ПИКОВЫЕ, поэтому в долине леджер завысит — это в безопасную сторону. Время старта запиши ПОЛЕМ в артефакт: перенос машины обнулил mtime всего сырья, на mtime не опирается никто.

1г. Состав прогона

Гони полную цепь, включая редакторскую волну, на ДЕСЯТИ главах — объём и состав заданы словом владельца (§1в), тобой не выбираются.

Довод, почему не draft-only, и он честный: проверено исполнением по всем 36 базам корпуса — роль judge не вызывалась НИ РАЗУ нигде, а редакторская волна гонялась и оплачена на малых прогонах (19 баз), но НЕ на холодном старте: у coldrun-a и во всей семье coldrun-b ноль редакторских вызовов. Именно это держит строку бэклога 16. Не измерена не «редактура вообще», а ПОЛНАЯ ЦЕПЬ ОДНИМ ЗАХОДОМ на холодном старте: draft+терминолог и edit меряли разные стенды под разными конфигами.

Десять глав выбраны ради сравнимости: тот же байтовый исходник и тот же объём, что у обоих исторических базлайнов, поэтому множитель «июль → сегодня» получается без экстраполяции (§5.3).

⚠ Приор оркестратора, опровергается твоим замером: draft+терминолог ≈$0.20, редакторская волна на тех же десяти главах ≈$0.380.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 <db> … без ?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 Сквозной путь, структура глав и файл книги

translatestatusreportmanifest --jsonexport --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_logok=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 · файл <db>.mined-signature.yaml. Провал записи памяти НЕ валит прогон — он даёт один лишний доброкачественный стоп, и это штатно.

Форматы, изменившиеся и ни разу не виденные на живых данных: <db>.mined-signature.yaml получила конверт map_version: tm-signature-map-v1 + map_id; <db>.bank.json — якорь свежести as_of.

Атомарность сайдкаров пере-проверена по коду 31.08: через writeFileAtomic идут ЧЕТЫРЕ<db>.manifest.json, <db>.bank.json, <db>.mined-signature.yaml, <db>.auto-bank.yaml; неатомерен ОДИН<db>.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) · сайдкар банка (<db>.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 --jsonbuild. Идёт ПЕРВОЙ: 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:<bookID>:<wave>:<chapter>:<unit>, без метки нарезки; это первый настоящий аутбокс на схеме v15 и первая возможность увидеть механизм на данных, а не в коде.
  6. ПОСЛЕДНЕЙ — строка 239: снять edit-стадию в КОПИИ pipeline.yamlstatus --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 <db> 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 <report|status|export|build|manifest|backup|migrate> --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:<db>?mode=ro' "SELECT printf('%.6f',COALESCE(SUM(committed_usd),0)),
  printf('%.6f',COALESCE(SUM(reserved_usd),0)) FROM spend WHERE book_id='<id>';"