114 KiB
Эксперимент 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; на диске появляется <book>.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.00 (1 000 000 µUSD);
runs.paused_reasonНЕПУСТО — любое из четырёх (run_limit_reached · credit_exhausted · daily_ceiling · ceiling_unknown);- срез не совпал с §1 — стоп ДО оплаты;
term_consistency_funded: false— стоп ДО оплаты;- бинарь не из фриза — стоп до устранения.
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).
Позитивный контроль каждого прибора исполнен ДО платной фазы (исход по пунктам — §18): подсаженный
ненулевой банк, удержанный юнит и открытая резервация красят сборщик; книга с дырой красит отчёт сборки;
чужой и беcштамповый бинарь красят гейт; самотест spread.py ловит подсаженную вторую форму.
РЕЗУЛЬТАТЫ (дописано ПОСЛЕ прогона; ничего выше не правлено)
⭐ ГЛАВНОЕ ПОМИМО ЦЕНЫ: впервые в проекте консистентность терминов замерена ПО ТЕКСТУ, КОТОРЫЙ
ПОЛУЧИЛ ЧИТАТЕЛЬ, а не по черновику и не по фикстуре — и ответ вышел не «всё хорошо», а СЧЁТ.
Движок сам называет термины, у которых форма банка и форма черновика могли разойтись, и называет их
ДВУМЯ пометками в bank-stop.txt: spread=N (черновик дал N разных форм) — таких 9, и
INVENTED(no draft proposed it) (форму банка не предложил НИ ОДИН черновик) — таких 11, из них
7 вне первой девятки. Итого популяция вопроса — 16 терминов из 69. Что с каждым стало в
отгруженном файле, проверено поимённо (§7.1 и §7.2):
- 9 из 16 отданы формой БАНКА (
古月山寨— 5 из 5 при трёх черновых формах,甲等资质— 6 при трёх,三转蛊师,魔道巨擘,丙等,乙等资质,江城子,邪魔,话事人); - 6 из 16 отданы одной формой, но НЕ банковской (
高脚吊楼: банк «дом на сваях» — в файле «свайный дом» ×4, главы 1 и 3;凤雏: банк «Молодой Феникс» — в файле «Юный Феникс», глава 2;老嬷嬷: банк «старая мамка» — в файле «нянька» ×2, глава 3; плюс три коротких формы); - 1 из 16 отдан ДВУМЯ формами («церемония открытия апертуры» ×9 в главах 1–3 и «великая церемония открытия апертуры» ×1 в главе 1 — обе формы сосуществуют в одной главе).
⇒ Механизм РАБОТАЕТ и работает не везде, и теперь у этого есть числа. Счёт форм, не суждение о качестве. Разбор — §7.1 и §16.8; цена контура — §5.3.
Книга дошла до конца. 蛊真人, главы 1–3, zh→ru, прогон run_FTHA7S6SUCJIXS2A над книгой
bk_ROEHZBD46ALFI43E: старт 04:29:19, финиш 04:54:50 (25 мин 31 с), две попытки (банк-стоп и
резюм), status = ready, paused_reason пусто, failure_reason пусто. Все 4 юнита translated,
exports.complete = true, файл скачан и прочитан.
5. Что стоила доведённая до конца книга
$0.419424 — и по платформе, и по движку. ⛔ ПЕРВАЯ РЕДАКЦИЯ ЭТОГО АБЗАЦА БЫЛА НЕВЕРНА, снимаю
её: я написала «419 424 по платформе против 419 423 по движку, разница — округление при конверсии».
Расхождения нет вовсе. 419 423 — это МОЙ floor от float-суммы request_log, и такого числа нет ни в
одном артефакте движка. Движок объявляет свою цифру сам, кадром spend: последний кадр
events.jsonl несёт {"committed_micro_usd": 419424}, и он ceil-ит КАЖДОЕ накопительное значение
(первый кадр: 12045 при 12044.12). Поймал критик чисел; я приписала платформе округление, которое
делает движок, и выдумала несуществующее расхождение между ними.
Семь путей счёта, и все семь сошлись:
| Путь | µUSD |
|---|---|
Σ request_log.cost_usd (движок, телеметрия; дробное) |
419 423.288 |
spend.committed_usd (движок; дробное) |
419 423.288 |
Σ checkpoints.cost_usd (движок, 33 чекпойнта; дробное) |
419 423.288 |
кадр spend движка, последний (events.jsonl) — целое, движок ceil-ит |
419 424 |
Σ credit_ledger.settlement платного аккаунта |
419 424 |
| грант − баланс того же аккаунта | 419 424 |
run_attempts.spend_micro_usd ПОСЛЕДНЕЙ попытки |
419 424 |
⚠ Три дробных пути — это ОДНО число 419 423.288, не три разных; четыре целых — то же число после ceil, который делает движок на каждом кадре. Спора между ними нет и не было.
⚠ И сразу честно про эти «семь путей»: независимый среди них ОДИН. request_log, checkpoints и
spend — три записи одного и того же вычисления движка; settlement и баланс — два чтения одного
леджера; а сам леджер взял число У ДВИЖКА (через run_attempts.spend_micro_usd ← кадр spend).
Сходимость доказывает, что никто по дороге ничего не потерял и не удвоил, — и ровно это, не больше.
⛔ Ловушка, на которую я наступила и называю: spend_micro_usd попытки — величина НАКОПЛЕННАЯ, а не
приращение. Сумма по попыткам даёт 579 635 µUSD — на 38 % больше правды, потому что вторая попытка
несёт в себе первую (spend_baseline_micro_usd второй попытки = 160 211 = вся трата первой). Кто
просуммирует эту колонку по попыткам, получит завышенную цену книги и не заметит.
Открытых резерваций на конце — 0 (контроль: резерваций этого аккаунта любого состояния — 2).
5.0. Что сообщил САМ провайдер — токены, а не доллары
Доллары в этом отчёте посчитаны нами (§16.1). Провайдер сообщил вот это, и только это:
| модель | вызовов | вход | из них из кэша | выход |
|---|---|---|---|---|
deepseek-flash |
22 | 71 244 | 22 784 | 126 751 |
deepseek-v4-pro |
5 | 29 175 | 9 088 | 51 403 |
| итого | 27 | 100 419 | 31 872 | 178 154 |
41 488 выходных токенов (23.3 % всего выхода) куплены четырьмя ответами, которые были выброшены.
⚠ Колонка reasoning_tokens равна нулю на всех 33 строках. Что это значит — вендор её не
отдаёт, или наш адаптер её не разбирает — по этим данным НЕ РАЗЛИЧИТЬ, и я не гадаю. Практическое
следствие одно и оно твёрдое: «сколько из выхода было размышлением» по нашей телеметрии не видно ни
на одном вызове; видно только, что выход упирался в потолок. Для мины §5.2 это существенно —
причину «размышление съело потолок» мы читаем из журнала движка (reason=empty), а не из счётчиков.
5.1. Куда ушли деньги
| Стадия и роль | вызовов | $ |
|---|---|---|
draft / translator (deepseek-v4-flash) |
15 | 0.123656 |
edit / editor (deepseek-v4-pro) |
5 | 0.230471 |
terminology / classifier |
6 | 0.035803 |
terminology / terminologist |
7 | 0.029494 |
| итого | 33 строки = 27 ВЫЗОВОВ + 6 подстановок из чекпойнтов | 0.419423 |
⚠ Сумма четырёх округлённых подытогов даёт 0.419424 — на 1 µUSD больше настоящего итога 0.419423. Это округление ЧЕТЫРЁХ строк до шестого знака, а не потерянный вызов: при полной точности подытоги 0.123656064 + 0.230470592 + 0.035802968 + 0.029493664 = 0.419423288. Названо, чтобы читатель не искал пропавший цент.
5.2. ⛔ ЧЕТВЕРТЬ ДЕНЕГ КУПИЛА ПУСТОТУ
4 вызова из 27 вернулись с finish_reason = length и ok = 0, и стоили $0.106472 — 25.4 % всей
траты книги. (Строк в request_log 33, но шесть из них — бесплатные подстановки из чекпойнтов, а не
вызовы: «вызовов 27» и «строк 33» — разные величины, и первая редакция отчёта их смешивала.) Это ровно задокументированная мина 00-provider-quirks.md §катовер п.1–2: размышление
съедает max_tokens, content приходит пустым. Поимённо:
| id | стадия / место | модель | max_tokens на входе |
флаг движка | $ пустого вызова | перевыпуск | $ перевыпуска |
|---|---|---|---|---|---|---|---|
| 1 | draft ch1/chunk0 | deepseek-v4-flash |
8496 | empty |
0.012044 | 16992 | 0.021068 |
| 5 | draft ch2/chunk1 | deepseek-v4-flash |
8496 | length |
0.011637 | 16992 | 0.017260 |
| 7 | draft ch3/chunk0 | deepseek-v4-flash |
8496 | empty |
0.011782 | 16992 | 0.018656 |
| 31 | edit ch2/chunk0 | deepseek-v4-pro |
16000 | empty |
0.071009 | 32000 | 0.046861 |
⚠ Флага ДВА, и они разные: empty — ответ пуст (размышление съело весь потолок), length — текст
оборван на потолке. В request_log оба приходят как finish_reason = length, то есть по одной
телеметрии их не различить — различает их журнал движка (disposition=flagged reason=…).
⚠ На edit пустой вызов дороже своего же удачного повтора ($0.071009 против $0.046861 при вдвое
большем потолке): неудачный сжёг весь бюджет 16000 токенов на размышление и молчал 249 секунд.
⚠ Самый дорогой одиночный вызов прогона не дал ничего. $0.071009 — это 17 % бюджета книги, и
это ровно тот класс, про который pipeline-c1.yaml:81 пишет в комментарии: «thinking ate max_tokens:
content="", finish=length». Конфиг ставит на draft reasoning: "low" именно против этой мины —
мина сработала ВСЁ РАВНО, и на draft (3 раза), и на edit, где ручка не выставлена вовсе.
⭐ Но лечение в движке ЕСТЬ и оно работает: stage flagged, regenerating with a larger budget … reason=empty next_max_tokens=16992 — движок опознаёт пустой ответ как флаг empty и перевыпускает
вызов с удвоенным потолком. Все четыре раза второй вызов вернул текст. То есть путь не рвётся — он
дорожает: платим дважды и выкидываем первый платёж.
5.3. Терминологический контур оплачен ДВАЖДЫ
Роли банка исполнились до банк-стопа (строки 10–16, $0.036554) и снова после резюма (строки 23–28, $0.028742). Итого $0.065297 — 15.6 % книги ушло на контур банка, и $0.028742 (6.9 %) — это второй заход того же контура на той же книге. Заново ли он нужен после движения банка — вопрос к движку; здесь он просто НАЗВАН и посчитан, потому что раньше эту цену никто не отделял.
5.4. Смета против факта — второй замер множителя
| Оценка | $ | множитель к факту |
|---|---|---|
expected_usd движка (нижняя граница по построению: без ретраев и ремонта) |
0.084122 | ×4.99 |
| Ожидание пака, ИСПР. 16 дословно | 0.35–0.50, хвост до 0.65 | факт внутри вилки |
| Вилка оркестратора по историческому множителю ×3.6 от прогона 08.09 (релей 11.09) | 0.30–0.49 | факт внутри вилки |
| ФАКТ | 0.419424 | — |
⚠ У «ожидания» три написания, и они различаются на 2 µUSD — назову, чтобы это не читалось как спор:
сумма глав манифеста 84 120 · строка books (expected_micro_usd − book_once_micro_usd) 84 121 ·
ответ run-options 84 122. Множитель посчитан от 84 122 (то, что видит покупатель); от 84 120 он
был бы ×4.9860 вместо ×4.9859 — на вывод это не влияет, а на доверие к числам влияет.
⇒ Множитель «смета движка → факт» на этой книге ×4.99 при ×3.6 на опорном прогоне 08.09. Это ВТОРАЯ точка, а не подтверждение: две точки дают разброс, а не закон. Причина расхождения названа выше — четверть траты ушла на пустые ответы, которых смета не знает по построению.
6. Исход каждой строки пре-рег-таблицы
| # | Узел | Ожидание | ФАКТ | Сошлось | Чем предъявлено |
|---|---|---|---|---|---|
| 1 | стенд мой | pid на порту | tmplatformd pid 1049523 на 8097; на 11434 не слушает НИКТО (контроль: 7 слушателей на хосте) |
✅ | ss -ltnp |
| 2 | код из фриза | три условия | vcs.revision=b0f5d89…, modified=false, строк vcs.* = 3 у всех трёх бинарей |
✅ | go version -m |
| 3 | гость и деньги | грант одной строкой | u_ZWUVTETPZL2D6LML, грант 2 500 000 µUSD, строка kind='grant' |
✅ | credit_ledger |
| 4 | интейк | 201, 3 главы, character_count ≈ 8759 |
chapter_count: 3 ✅; character_count: 9677, а 8759 — это source_chars ⚠ |
✅ по главам, пин по знакам удовлетворён ДРУГИМ полем | тело 201 + books |
⚠ Пин строки 4 как он был написан — НЕ сошёлся, и это надо сказать прямо. Я ждала ≈8759 от
character_count, а он равен 9677: это счёт ИНТЕЙКА по байтам потока, и платформа сама называет
его приблизительным (internal/pgstore/books.go, и на проводе рядом едет character_count_exact).
Точный счёт знаков живёт в source_chars = 8759 и сошёлся с манифестом до единицы. Дефекта нет,
но пин был написан на поле, которое на него не отвечает.
| 5 | срез совпал | units_total 4, по главам 2/1/1 | 4, по главам 2/1/1 | ✅ | chapters+units |
| 6 | цена и бонд | funded: true, холд ≈2 241 629 | funded: true, covers_all, холд 2 241 631, expected 84 122 | ✅ (мимо на 2 µUSD) | run-options |
| 7 | старт | 202 + bond_funded=t | 202; runs.bond_funded = t | ✅ | ответ + runs |
| 8 | ключи живы | первый вызов не отказан | первый вызов оплачен ($0.012044), отказов по авторизации 0 из 33 | ✅ | request_log.err пусто во всех 33 строках |
| 9 | кадры | шесть типов | 50 кадров: hello 2 · progress 10 · spend 27 · unit_done 8 · bank_stop 1 · finished 2 | ✅ | events.jsonl |
| 10 | банк-стоп | awaiting_bank, exit 3, непустой proposed[] | наступил в 04:39; exit 3; proposed[] = 69 термов, terms[] = 0 | ✅ | runs + run_attempts + копия сайдкара |
| 11 | проекция банка | 0 до закрытия, >0 после | 0 в момент awaiting_bank; 69 строк (2 approved) после | ✅ | GET /v0/books/{id}/bank дважды |
| 12 | дверь правок | preview → apply → файл решений | changed: true, оба решения state: applied, mined-delta.yaml 886 байт | ✅ | тело ответа + файл |
| 13 | резюм | вторая попытка, exit 0 | попытка 2, exit 0, last_seq 22 | ✅ | run_attempts |
| 14 | книга переведена | 4 юнита translated | 4 из 4 (контроль: юнитов книги — 4) | ✅ | units |
| 15 | сборка | семь полей чисты | complete: true, pending/withheld/incomplete/stale/ghost = 0, stale_unknown: false, config_drift: false, total_units: 4 | ✅ | stdout tmctl build |
| 16 | выгрузка | complete = t, байты сходятся | txt: 54 151 байт, complete = t; epub: 20 187 байт, complete = t | ✅ | exports + %{size_download} |
| 17 | ФАЙЛ | байты + структура | txt sha256 c3dcf291…; epub sha256 720fd782…, 7 записей zip, nav объявлен, 3 itemref, оглавление «Глава 1/2/3» | ✅ | разбор zip |
| 18 | человек прочитал | связный русский | прочитан первый разворот главы 1 — связный русский текст, имена согласованы с подписанным банком | ✅ | цитата ниже |
| 19 | деньги сошлись | четыре счёта + 0 резерваций | семь счётов сошлись на 419 424 µUSD (§5), открытых резерваций 0 при 2 резервациях этой учётки; ⚠ независимый среди семи — один | ✅ | таблица §5 |
| 20 | ничего не реплеено | нет local-* | distinct model_actual = deepseek-flash, deepseek-v4-pro; tm_hit = 1 у 6 строк, ВСЕ шесть — banknote_export второй попытки, все по $0 | ✅ | request_log |
| 21 | расхождение форм | замер | 0 терминов из 40 отданы более чем одной формой (контроль: канонических термов 69, найдено в тексте 40); прямой счёт по двум подписанным термам — 5 из 5 и 58 из 58 в одной форме, конкурирующих 0 (§16.8) | замер | spread.py + счёт по book.txt |
Первый абзац отгруженного файла (узел 18), дословно:
Пусть тело погибнет — сердце демона не раскается. — Фан Юань, покорно отдай Цикаду Весны и Осени, и я дарую тебе лёгкую смерть!
Это связный русский текст. О качестве перевода пак суждений не делает (претрейн).
7. Счёт расхождения форм по ОТГРУЖЕННОМУ тексту (строка бэклога 406)
spread.py над tmctl export --json --pairs: 69 канонических термов, у всех 69 исходник
встречается в тексте, 40 найдены отрендеренными, и из этих сорока НИ ОДИН не отдан более чем
одной формой.
7.1. ⛔ ЗНАМЕНАТЕЛЬ ЛЕЖАЛ В МОЕЙ ЖЕ УЛИКЕ, И БЕЗ НЕГО «0» НИЧЕГО НЕ ЗНАЧИЛ
«0 из 40» отвечает на вопрос «нашёл ли прибор разнобой среди того, что видит». Настоящий вопрос
другой: что стало с теми терминами, про которые ИЗВЕСТНО, что они разошлись. Ответ лежал в
evidence/bankstop-paid/project.db.bank-stop.txt, который я сняла в момент стопа и не дочитала:
движок печатает там spread=N и перечисляет черновые формы по КАЖДОМУ терму.
Распределение: spread 1 → 60 · 2 → 6 · 3 → 2 · 4 → 1 (контроль: записей spread= ровно 69, по
числу термов). ⇒ разошлись в черновике 9 терминов из 69. Проверила все девять по отгруженному
файлу (поиск по стемам слов, каждое попадание открыто глазами):
| термин | черновик дал | подписано/сведено | в отгруженном файле | исход |
|---|---|---|---|---|
三转蛊师 |
2 формы | «гу-мастер третьего оборота» | 3 · конкурент 0 | ✅ одна форма |
古月山寨 |
3 формы (поселение · городище · горная крепость) | «горная крепость Гуюэ» подписана мной | 5 (главы 1 и 2) · конкуренты 0, 0 | ✅ одна форма |
甲等资质 |
3 формы (дар цзя · дарование первого ранга · талант класса А) | «талант первого разряда» | 6 · конкуренты 0, 0, 0 | ✅ одна форма |
魔道巨擘 |
2 формы | «корифей пути демонов» | 2 · конкурент 0 | ✅ одна форма |
高脚吊楼 |
2 формы | «дом на сваях» | 0, зато «свайный дом» ×4 (главы 1 и 3) | ⛔ в файле НЕ банковская форма |
家老 |
2 формы | «старейшина рода» | 0; в тексте «старейшины» ×13 без «рода» | ⚠ короткая форма, последовательно |
舅母 |
2 формы | «жена дяди по матери» | 0; в тексте «тётя» ×16 | ⚠ короткая форма, последовательно |
舅父舅母 |
2 формы | «дядя по матери и его жена» | 0; «дядя с тётей» | ⚠ короткая форма, последовательно |
开窍大典 |
spread=4, перечислено 3 формы |
«церемония открытия апертуры» | 9 (главы 1·2·3) + «великая церемония открытия апертуры» ×1 (глава 1) | ⛔ ДВЕ формы, и обе в одной главе |
⇒ 4 из 9 сведены и доехали · 4 из 9 отданы одной, но НЕ банковской формой · 1 из 9 отдан двумя.
⚠ Главы названы, как требует §4.5 п.2 пака, и они меняют смысл двух строк: обе формы 开窍大典
живут в ОДНОЙ главе (читатель встречает разнобой на одной странице), а не-банковский «свайный дом»
идёт через главы 1 и 3 — то есть последовательно по всей книге.
⚠ И самое важное из этой таблицы: 高脚吊楼 — случай, где закон банка на проводе (D39.104: банк
есть закон для ВСЕХ строк независимо от статуса) в тексте не виден. Банк нёс «дом на сваях», файл
несёт «свайный дом» четырежды. Доехал ли банк до промпта редактора на этих юнитах, по БД не
ответить: у редакторской стадии нет своего счётчика подтверждённых инъекций (n_exact_hits и
injected_ids заполняются на черновике, где глоссарий ещё пуст). Замерено — расхождение формы;
не установлено — где именно оно возникло.
⛔ Слепое пятно прибора я вскрыла, а не спрятала: 29 термов из 69 прибор не нашёл вовсе, и это его
слабость, а не свойство книги. Открыла глазами восемь таких единиц: 三转蛊师 отгружен как
«гу-мастера третьего оборота», 丫头片子 — «девчонку», 仙师 — «бессмертными наставниками»,
侧室 — «наложницей». Каноническая форма В ТЕКСТЕ ЕСТЬ, но склонена — а прибор её не видит.
⇒ «0 форм-расхождений» — утверждение о сорока термах, которые прибор видит, а не обо всех шестидесяти
девяти.
⛔⛔ И ПРИЧИНУ СЛЕПОТЫ Я НАЗВАЛА НЕВЕРНО — это доказано исполнением, не спором. Первая редакция
писала, что виновато правило сравнения общих префиксов (same_rendering), и заказывала следующей
сессии переписать именно его. Критик полноты применил мой же рецепт к прибору на этих самых данных:
не вернулся НИ ОДИН из 29 потерянных термов (осталось те же 40). Потому что same_rendering
участвует только в СКЛАДЫВАНИИ уже найденных форм, а теряются они раньше — на ПОИСКЕ кандидатов:
spread.py берёт кандидатов регуляркой [А-ЯЁ][а-яёА-ЯЁ\-]+, то есть только слова С ЗАГЛАВНОЙ.
«гу-мастера», «девчонку», «наложницей» — строчные и отпадают ДО того, как правило сравнения вообще
спросят. Починка генерации кандидатов (окна нужной длины, любой регистр) на тех же данных даёт
48 найденных вместо 40 — то есть слепое пятно действительно ЗДЕСЬ. ⇒ мой «0» держался в том
числе на том, что прибор не смотрел, и правильный заказ следующему — §13, переписан.
⛔ Но число расхождений у починенной копии я публиковать не стала, и вот почему — пере-снято
своими руками, а не принято от критика. Критик сообщил «шесть строк со spread ≥ 2»; моя
реализация той же починки даёт девять, и все девять — мусор: оконный поиск глотает соседние
слова и считает каждое окно отдельной формой («старейшины и», «старейшин Он», «Фан не», «глава рода
он»). ⇒ покрытие 40 → 48 — замер; счёт расхождений у починенного прибора — шум. Улика:
checks/spread-candidate-fix-probe.txt, где рядом стоят вывод фриза (0) и вывод копии (9) и назван
недостающий кусок: окну нужен ФИЛЬТР, отвергающий лишние слова.
7.2. ⛔ ЗНАМЕНАТЕЛЬ ОКАЗАЛСЯ НЕ ОДИН: движок называет ВТОРУЮ популяцию, и я её пропустила
spread=N отвечает на вопрос «разошлись ли ЧЕРНОВИКИ между собой». Он по построению НЕ ловит терм, у
которого все черновики согласны — и все согласно расходятся с банком. Такие термы движок помечает
отдельно, тем же файлом: INVENTED(no draft proposed it) — форму банка не предложил ни один
черновик. Их 11 из 69; четыре уже внутри девятки, семь — вне её, и вопрос у них ровно тот
же. Проверила все семь (контроль: INVENTED встречается в стоп-таблице 11 раз при 69 записях
spread=):
| терм | банк | что в файле | исход |
|---|---|---|---|
丙等 |
«третий разряд» | 3 (черновиковый «третий ранг» — 0) | ✅ банк |
乙等资质 |
«талант второго разряда» | 2 | ✅ банк |
江城子 |
«Цзянчэнцзы» | 1 («Река Цзянчэн» — 0) | ✅ банк |
邪魔 |
«злой демон» | 2 («злого демона», «злым демоном») | ✅ банк |
话事人 |
«распорядитель» | 1 («распорядители» — и черновик, и склонение банка) | ✅ банк |
凤雏 |
«Молодой Феникс» | 0; в файле «Юный Феникс» ×1 (глава 2) — ЧЕРНОВИКОВАЯ форма | ⛔ не банк |
老嬷嬷 |
«старая мамка» | 0 («мамк*» в файле 0); «нянька/няньку» ×2 (глава 3) | ⛔ не банк |
⛔ Моя ошибка по дороге, названная: 邪魔 я сперва посчитала «не банковским». Мой стеммер режет
хвост по длине слова и на прилагательном «злой» промахивается мимо «злого/злым» — счёт дал 0.
Открыла текст глазами: обе формы на месте. Инструмент промахнулся в сторону ложной тревоги, а не
ложного спокойствия, но промахнулся.
⇒ Объединённая популяция — 16 терминов из 69: 9 доехали формой банка · 6 отданы не-банковской
формой · 1 отдан двумя. И главное следствие для §13: знаменатель у прибора по отгруженному
тексту обязан быть ДВОЙНОЙ — spread ≥ 2 И INVENTED. На spread одном половина случаев не
видна, включая два из шести.
8. Находки прогона — с разметкой уверенности
| # | Находка | Где | Разметка |
|---|---|---|---|
| 1 | Бинарь, собранный в ЛИНКОВАННОМ git-воркри, не несёт vcs.* ВООБЩЕ (0 строк из 24), и правило «отказывать при vcs.modified=true» на нём выполняется всегда. Контроль: та же сборка из главного дерева даёт vcs.revision + modified=true |
фриз-процедура пака | замерено |
| 2 | Книга, которую пайплайн переводит бесплатно, не может быть продана. На $0-паре step_max_usd = 0, ingest.Manifest.priced() отказывает при <= 0 ⇒ 409 not_priced, старт недостижим; в логе ERROR «this book has no price projection, so it cannot be sold» |
internal/ingest/manifest.go:349 |
замерено |
| 3 | Шаблон книги по рецепту стенда роняет КАЖДЫЙ старт c1: без langpack_root движок отказывает с exit 10 «gates.terminology is enabled but this book cannot mine a bank». Ключа нет ни в backend/example/book.yaml, ни в рецепте STACK_DECISIONS |
internal/pipeline/runner.go:358 |
замерено |
| 4 | Четверть денег купила пустоту — 4 вызова из 33, $0.106472, все finish_reason=length; самый дорогой вызов книги ($0.071009) не дал ничего. Лечение в движке есть и сработало 4/4: перевыпуск с удвоенным потолком |
§5.2 | замерено |
| 5 | Терминологический контур оплачен дважды (до стопа и после резюма): $0.036554 + $0.028742 | §5.3 | замерено |
| 6 | run_attempts.spend_micro_usd — величина накопленная; сумма по попыткам завышает цену книги на 38 % |
§5 | замерено |
| 7 | Ответ старта прогона говорит term_consistency_funded: false, когда строка прогона уже несёт bond_funded = t — и через минуту тот же прогон на resume отвечает true. Наблюдено на обоих прогонах (дымовом и платном) |
POST /v0/books/{id}/runs |
замерено (причина — подозрение: ответ, вероятно, рендерится из состояния ДО допуска) |
| 8 | 409 not_priced сразу после интейка — гонка, а не дефект: проекция цены материализуется асинхронно, через несколько секунд ручка отвечает нормально. Клиент, спросивший сразу, увидит отказ |
run-options |
замерено |
| 9 | Строка бэклога 224 воспроизведена живьём: на банк-стопе .bank.json несёт terms: [], total: 0 и proposed[] с 69 термами; платформа читает terms ⇒ экран подписи видит 0 ровно тогда, когда открыт ради этих 69 |
улика evidence/bankstop-paid/ |
замерено |
| 10 | TM_PLATFORM_ENGINE_CEILING_ARG пустым старты не ломает — у переменной есть дефолт --ceiling-usd {{usd}}; прогон прошёл целиком, пока она не задана |
internal/config/config.go:550 |
замерено |
| 11 | Резюм после банк-стопа не берёт второй книжный бонд: холд 2 081 420 = 2 241 631 − 160 211, то есть остаток бюджета этого прогона | credit_ledger id 15 |
замерено |
| 12 | Улика банк-стопа уничтожается резюмом: sha256 .bank.json 8fdd7d54… на стопе → 0881055a… после резюма (и после двери правок она ещё цела) |
три sha подряд | замерено |
| 13 | Пин цены deepseek-v4-flash в models.yaml выше сегодняшней вендорской страницы (вход 0.44 против 0.30, cache-hit 0.014 против 0.006, выход 1.32 против 1.20); у pro совпадает точно. Этот прогон по вендорским числам стоил бы $0.397246 вместо $0.419423 — пин завышает на 5.6 % |
§16.1, вендор-дока снята 11.09 | замерено (что пин стал выше страницы) + прочитано (сама страница) |
| 14 | model_actual = deepseek-flash на 28 строках из 33, тогда как шлём deepseek-v4-flash и такого слага в вендорской прайс-таблице нет — нас считают под другим именем |
request_log, две колонки |
замерено (факт), не установлено (алиас или другая модель) |
| 15 | err пуст на всех 33 строках, включая четыре провальных — признак отказа живёт только в degraded. Аудит, написанный через err, прочитает прогон как чистый |
request_log |
замерено |
| 16 | Три вызова вернули РОВНО 0 символов (length(response_text) = 0 в чекпойнтах): $0.094835 = 22.6 % прогона. Флор min_max_tokens: 16000, поднятый именно против этого, дал ОДИН такой вызов на 16.9 % счёта — больше, чем инцидент, ради которого его поднимали |
checkpoints, models.yaml |
замерено |
| 17 | accept_rebill_micro = 2 241 631 на резюме — согласие на пере-оплату всего бюджета прогона при фактической пере-покупке $0.028742 (разрыв 78×); спасли чекпойнты |
runs |
замерено |
| 18 | Σ chunk_status.cost_usd = $0.354127, недостача — ровно терминология: таблица выглядит пятым путём счёта денег и им не является |
project.db |
замерено |
| 19 | ⭐ Подписанные термины доехали до файла: «горная крепость Гуюэ» 5 из 5, конкурирующие черновые формы 0; «Фан Юань» 38 + 20 склонений, конкурирующих транслитераций 0 | §16.8, счёт по book.txt |
замерено |
9. «Дыр нет» — замерено, а не промолчано
Дверь выгрузки СТРОИТ ВСЕГДА (--partial, D39.178), поэтому «файл собрался» само по себе не значит
ничего: неполная книга ушла бы тем же 200 и с теми же байтами, только с пометкой внутри. Пометка —
данные языка ЧИТАТЕЛЯ (configs/langpacks/ru/reader.txt), и она проверяется на отсутствие вместе с
контролем, который доказывает, что искали существующее:
| файл | строк с ⚠ |
«ещё не переведён» | «Перевод не завершён» | всего строк |
|---|---|---|---|---|
отгруженный book.txt |
0 | 0 | 0 | 330 |
| та же книга, собранная из её ПРЕД-ПРОГОННОЙ копии БД (контроль) | 5 | 4 | 1 | 20 |
Контрольная сборка — тот же бинарь, тот же langpack, та же книга, только БД из backups/ до прогона:
complete: false, pending_units: 4, и файл честно говорит читателю: «⚠ Перевод не завершён:
фрагментов с пропусками — 4 из 4. Каждый пропуск отмечен в тексте знаком ⚠». ⇒ ноль в первой строке
таблицы — измеренный ноль, а не молчащий прибор.
10. Что НЕ удалось, не проверено и не измерено
- ⛔ ВЕРНЫЕ ЧИСЛА ПРИ НЕВЕРНОМ МЕТОДЕ — и это худшее, что случилось в моей работе, потому что оно
не краснеет нигде. Разбивку попыток я строила по ВРЕМЕНИ (
tsпротивstarted_at), аtsв sqlite секундной гранулярности:01:40:45против01:40:45.012584— все шесть подстановок формально «раньше» старта своей же попытки. Числа при этом вышли правильные, по счастливому порядку строк. До этого тот же метод сломался грубее (пробел противTв разделителе дал 33/0), и я его «починила», не заметив, что он негоден в принципе. Настоящий различитель лежал в той же строке и не требует арифметики вовсе:trace_idнесёт номер попытки. Нашёл критик чисел; сама бы я не нашла — верный результат не даёт повода перепроверить способ, которым он получен. epubcheckне гонялся.javaна хосте нет, поставить без sudo не пробовала (пак это прямо разрешает — ИСПР. 6). EPUB судится структурно: zip ·mimetype·container.xml·nav· 3itemref· оглавление. Валидность по спецификации EPUB — не измерена.- Эскалация не исполнялась ни разу —
escalation.budget_usd: 0в боевом конфиге. Про её работу этот прогон не говорит НИЧЕГО. - Гейт
coverageвыключен (gates.coverage.enabled: false) — работали четыре гейта из пяти. Судейской стадии на этом пути нет вовсе. - Одна книга, одна пара, три главы, четыре юнита. Множитель «смета → факт» ×4.99 — это ОДНА точка (вторая в проекте). Двух точек мало для закона, и обе сняты на одном исходнике.
- Причина расхождения
term_consistency_fundedна старте не установлена (находка 7): замерено, что ответPOST /runsговоритfalse, когда строка прогона уже несётbond_funded = t; ПОЧЕМУ — подозрение (вероятно, ответ рендерится из состояния до допуска), кодом не подтверждено. - Нужен ли второй заход терминологического контура — не выяснено. Замерено, что он случился и сколько стоил; законен ли он после движения банка — вопрос к движку, не к этому прогону.
- Прибор расхождения форм видит 40 термов из 69 (§7). «0 расхождений» — утверждение о сорока.
- Книжный потолок ($1.25) и стоп-правила ни разу не срабатывали — трата $0.419. Значит их поведение этим прогоном НЕ проверено: они стояли, но не стреляли.
- Ручка
POST /runs/{id}/stopне трогалась вовсе. - Про качество перевода не сказано ничего и не может быть сказано — 蛊真人 в претрейне.
- Дымовая фаза считала НОМИНАЛЬНЫЕ деньги. Локальной модели дана цена (иначе книга не продаётся — находка 2), поэтому суммы дымового аккаунта — это арифметика механизма, а не траты. Платный аккаунт заведён отдельно, и в денежную сверку §5 дымовые строки не входят.
- ⛔ НИ ОДНО HTTP-ТЕЛО ПЛАТНОГО ПРОГОНА НЕ СОХРАНЕНО, и я узнала это от критика, а не от себя.
Под
evidence/61 файл, и ни в одном нетcovers_all,term_consistency_funded,affordable_chapters,accepted,ordered_chapters. Уцелели толькоcapabilities.jsonиbank-after.json. ⇒ висят без носителя: ответrun-options(узел 6; сам ХОЛД предъявлен строкойreservations, а тело — нет) ·202старта (узлы 7 и 13; вrunsи логе демона есть «run admitted … ordered_chapters:3» — это сильнее нуля, но не то тело) ·changed: trueиstate: appliedдвери правок (узел 12; уцелел ЗАПРОСstand/corrections.json, ответ — нет) · и целиком находка 7 §8, которая ТОЛЬКО из тела ответа и состоит. Драйвер печатал их на экран и не писал в файл — это дефект моего харнесса, а не прогона, и чинить его надо вdrive.sh(каждый ответ ручки — вevidence/http/<шаг>.json). - Слабость МОЕГО прибора живости:
drive.sh watchпечаталmax(last_seq)по попыткам, и во время второй попытки число выглядело замершим на 28 (значении первой), пока работа шла. Читать надо по попыткам — что я и делала во второй половине вахты.
11. Что я сама считаю слабым местом этого прогона
Первое и главное: счёт расхождения форм — самая новая и самая слабая цифра отчёта. Всё остальное здесь предъявлено механизмом, который писали не в этом паке; прибор §7 написан мной за час, и его правило сравнения форм разваливается ровно там, где русский язык делает то, что делает всегда, — склоняет первое слово. Его «0» я бы не понесла дальше без пере-строенного правила.
Второе: «сошлось семью путями» звучит сильнее, чем есть. Шесть из семи путей — одна и та же цепочка: движок посчитал, движок записал, платформа материализовала из его же потока. Настоящая независимость в этом отчёте одна — скачанные байты и их sha256; провайдерского биллинга у нас нет вовсе. ⛔ И вторую половину этой фразы я тоже переписываю после критика чисел: «$0.419424» — это даже не то, что нам сказал провайдер. Провайдер сообщил ТОКЕНЫ; доллары мы умножили сами, на свой пин, и пин на flash оказался выше вендорской страницы (§16.1). Настоящее число — «столько-то токенов»; доллары в этом отчёте — наша модель поверх них.
Третье: прогон прошёл слишком гладко, чтобы проверить свои же защиты. Стоп-правила, книжный потолок, отказ допуска — всё это стояло заряженным и ни разу не выстрелило. Я проверила их подсадками до денег (§4), но на боевой руке они остались непроверенными, и это надо помнить, а не записывать себе в актив.
12. Девиации от пака — объявлены, не подразумеваются
- Фриз-дерево — локальный КЛОН, а не
git worktree add. Причина замерена: бинарь из линкованного воркри несёт 0 строкvcs.*из 24 (контроль: та же сборка из главного дерева даётvcs.revisionиvcs.modified=true), и правило «отказать приvcs.modified=true» на нём выполняется ВСЕГДА. Клон даёт настоящий каталог.gitи штамп с зубами. Санкционировано оркестратором до первого цента. - Драйвер правлен ПОСЛЕ первого фриз-коммита — второй фриз
44b33d9: гейт должен был требовать слушателя на127.0.0.1:11434, что верно для дыма и ВРЕДНО для платной фазы (чужая заглушка, поглощающая вызовы, — ровно то, чего нельзя допустить). ⇒ бинари стоят наb0f5d89, харнесс — на44b33d9. Правка сделана ДО первого платного вызова; форма соблюдена (новый фриз), но расхождение двух sha названо здесь, а не подразумевается. - Дымовой стенд дал локальной модели номинальную цену (
models-smoke.yaml, отличается от боевогоmodels.yamlРОВНО одной строкой). Без этого дым через HTTP-дверь невозможен — находка 2. Платная фаза шла на боевомmodels.yamlфриза, и платный аккаунт заведён отдельно от дымового. epubcheckне гонялся —javaна хосте нет (§10 п.1), пак это разрешает.- ⛔ ДВА МОИХ ИНСТРУМЕНТА СОБРАНЫ НЕ ИЗ ФРИЗА, и гейт их не проверяет.
bin/stubиbin/zeropipeнесутvcs.revision=468ed4d…иvcs.modified=true(контроль: три гейтованных бинаря —b0f5d89…иfalse): они собраны из ГЛАВНОГО дерева, где лежит их исходник, аstep_gateсмотрит только наtmctl · tmplatformd · tmplatformctl(drive.sh). Денег это не касается — заглушка работала только в дыму, аzeropipe$0-рендер; но пин фазы 0 «0 достижимых платных моделей» произведён бинарём из грязного дерева, и это надо знать. ⚠ Смягчающее и проверяемое: ИСХОДНИК обоих закоммичен фризомbe53cc8, то есть код пинен, даже если штамп бинаря — нет. Нашёл критик полноты. - ⚠ У фриза ДВА разных числа, и путать их нельзя.
b0f5d89…— sha КОДА, которым собраны бинари (HEAD клона).be53cc8— КОММИТ, которым заморожены пре-регистрация и инструменты;44b33d9— второй такой коммит. Первое отвечает на «что исполнялось», второе и третье — на «чем судили». ⚠ И третье число, которое встречалось на стенде:~/tm-coldrun-a/FROZEN_SHA.txtдо конца смены нёс88f1344…— sha БРОШЕННОГО воркри, из которого для прогона не собрано ничего. Гейт этот файл не читает, так что он никого не обманул; исправлен и снабжён объяснением.
13. Заказ следующему: как чинить прибор расхождения форм
⛔ ПЕРВАЯ РЕДАКЦИЯ ЭТОГО ЗАКАЗА БИЛА МИМО, и это проверено исполнением, а не спором. Она велела
переписать правило сравнения (same_rendering) на пословную стеммизацию. Критик применил рецепт к
прибору на боевых данных: не вернулся ни один из 29 потерянных термов. Правило сравнения решает,
СКЛАДЫВАТЬ ли две уже найденные формы; термы теряются раньше.
Чинить надо ГЕНЕРАЦИЮ КАНДИДАТОВ. spread.py ищет формы регуляркой
[А-ЯЁ][а-яёА-ЯЁ\-]+(?:\s+[А-ЯЁ][а-яёА-ЯЁ\-]+)* — то есть только слова с ЗАГЛАВНОЙ буквы. Имена
она ловит, а «гу-мастера третьего оборота», «девчонку», «наложницей» — нет, потому что они строчные.
Правильный поиск: брать из целевого текста окна длиной в число слов известной передачи, в любом
регистре, и сравнивать их с известными формами — и только ПОТОМ складывать найденное. На тех же
данных это даёт 48 найденных термов вместо 40 (замерено мной, checks/spread-candidate-fix-probe.txt).
⛔ И сразу вторая половина рецепта, без которой первая вредна: окну нужен ФИЛЬТР, отвергающий
окна, чьи лишние слова не входят в передачу. Без него та же починка печатает девять «расхождений»,
из которых ни одно не расхождение («старейшины и», «Фан не»).
И второе, что заказ обязан нести: знаменатель, и он ДВОЙНОЙ. Движок уже печатает по каждому терму
и spread=N со списком черновых форм, и пометку INVENTED(no draft proposed it)
(<project_db>.bank-stop.txt), то есть САМ называет обе популяции вопроса. Прибор по отгруженному
тексту должен считать не «сколько разнобоя я вижу», а «что стало с теми, про кого известно, что
форма банка и форма черновика могли разойтись» — на этой книге 9 + 7 = 16 из 69. ⚠ На одном
spread половина случаев невидима: 凤雏 и 老嬷嬷 отданы черновиковой формой при spread=1
(§7.2), и прибор, построенный на одном знаменателе, их не увидит никогда.
Третье — устойчивость. Нынешний «0» не пере-снят ни при одном другом пороге складывания; под
пословным правилом терм 沈翠 распадается на «Шэнь»/«Шэнь Цуй» и заголовочное число становится 1.
Прибор обязан печатать свой порог и давать число при двух-трёх значениях.
Самотест уже несёт три клетки (вторая форма ловится, склонение не двоится, неотрендеренный терм даёт
ноль). К ним добавить две: строчную многословную передачу (на которой нынешний прибор слеп) и
терм из spread ≥ 2 движка, чтобы знаменатель тоже был под пином.
14. Разбор после критика полноты — что он нашёл и что с этим стало
Критик полноты прошёл по паку и по артефактам. Три его находки были про ПРИБОР и потребовали работы, а не текста; они исполнены здесь.
14.1. ⛔ tm_hit — разбивка по попыткам, которой требует ИСПР. 20 (исполнена)
Сборщик печатал СУММУ попаданий в чекпойнты (collect.py: tm_hit=1 …: 6 (control: rows = 33)), а
ИСПР. 20 называет единственным различителем именно РАЗБИВКУ: попадание ВНУТРИ одной попытки —
подозрение (прогон переигрывает сам себя и мог измерить пустоту), попадание второй попытки в
чекпойнты первой — норма резюма. Разбивка снята запросом к project.db (mode=ro):
попытка (по trace_id, который несёт её номер) |
строк | tm_hit = 1 |
Σ cost |
|---|---|---|---|
tm-stream-run_FTHA7S6SUCJIXS2A-1 |
16 | 0 | $0.160210 |
tm-stream-run_FTHA7S6SUCJIXS2A-2 |
17 | 6 | $0.259213 |
| контроль: всего | 33 | 6 | $0.419423 |
⇒ Внутри попытки не переиграно НИЧЕГО; все шесть попаданий — вторая попытка, читающая чекпойнты
первой, и все шесть стоят $0. Сверх того: суммы по попыткам ($0.160210 и $0.259213) ложатся на
две строки settlement платного аккаунта (160 211 и 259 213 µUSD) — с тем же ceil на первой (+1
µUSD), который §5 объясняет; на второй он совпал в ноль. Это не «совпадение», а сходимость с
названным правилом округления.
⛔ Две мои ошибки в методе этой самой таблицы, обе названы, потому что они одного класса — «верный
прогон при неверной гипотезе». (1) Сначала я делила попытки сравнением ts < '2026-09-11T01:40:45',
а колонка хранит '2026-09-11 01:40:45' — с ПРОБЕЛОМ, который сортируется раньше T: все 33 строки
оказались «меньше границы», и разбивка напечатала 33/0 — правдоподобно и неверно. (2) Починив
разделитель, я всё ещё делила по ВРЕМЕНИ, а ts в sqlite секундной гранулярности: 01:40:45 против
started_at попытки 01:40:45.012584 — то есть все шесть подстановок буквально «раньше» её старта.
Числа при этом вышли правильные по счастливой случайности порядка. Настоящий различитель лежал в
той же строке и не требует арифметики вовсе: trace_id НЕСЁТ номер попытки. Таблица выше
пере-снята по нему; вторую ошибку нашёл критик чисел, не я.
14.2. ⛔ Сборщик считает деньги ПО ВСЕМ учёткам сразу
collect.py спрашивает credit_ledger и reservations без фильтра по пользователю — поэтому в его
разделе C стоит grants: 5000000 µUSD (два гранта по $2.50: дымовой учётке и платной) и «резерваций
всех состояний 5» (три дымовых плюс две боевых). Пре-рег §1 развёл учётки именно для того, чтобы
этого не было, а прибор их всё равно смешал. Числа §5 этого отчёта сняты ОТДЕЛЬНЫМ запросом с
фильтром where user_id = 'u_ZWUVTETPZL2D6LML' (платная учётка) и потому верны; исправлять
замороженный прибор после денег я не стала — гап назван, и он в его же зоне ответственности.
Контроль, доказывающий, что речь о смешении, а не о лишних деньгах: у платной учётки ровно один
грант 2 500 000 µUSD и ровно две резервации, обе settled.
14.3. Шесть строк banknote_export — не ошибка, а бесплатный реплей
В списке «строк с err или finish_reason ≠ stop» их 6 из 10. Все шесть: tm_hit = 1, cost_usd = 0,
вторая попытка, ok = 1. Это извлечение банкнотного блока, взятое из чекпойнта первой попытки, а не
неудачный вызов. ⇒ денежный класс §5 п.4 — это ЧЕТЫРЕ строки length, а не десять; остальные шесть
названы здесь, чтобы никто не считал их дважды.
14.4. Прибор расхождения форм — второй прогон, на материале, названном паком
§4.0 п.5 велит строить прибор на coldrun-v16. Строился и самотестировался он раньше, а на этом
материале прогнан теперь (копия проекта, читающий верб, $0): 14 юнитов, 11 pending, 3 с текстом
(это и есть история 31.08: три юнита из четырнадцати до остановки снапшот-гардом), 50 канонических
термов, 49 с исходником в тексте, 11 отрендеренных, 0 отданных более чем одной формой.
⛔ И снова моя ошибка по дороге, названная: первый заход я сделала с book_id, который придумала
сама (v16-readonly), — а строки БД ключуются ИСХОДНЫМ guzhenren-coldrun-v16. Экспорт честно отдал
14 pending и 0 текста, и это выглядело как «в артефакте нет текста». Правильный book_id дал 3 юнита
с текстом. Ноль отрендеренных термов был свойством моего запроса, а не книги — ровно тот класс
ошибки, ради которого рядом с нулём печатается контрольная величина.
14.5. Артефакты проверок, которые раньше жили только в моём выводе
Сохранены в ~/tm-coldrun-a/evidence/checks/ — тринадцать файлов, список полный:
gate-paid.txt (гейт платной фазы целиком, включая «port 11434: nothing listens (control: 7 listeners
on this host)») · gate-negative-controls.txt (три подсадки и текст каждого отказа: чужая ревизия
с грязным деревом · бинарь БЕЗ штампа · неверный ожидаемый sha) · zeropipe-count.txt (8 достижимых
платных моделей в pipeline-c1.yaml против 0 в рендере) · pipeline-zero-recheck.yaml (сам рендер) ·
spread-selftest.txt · spread-v16.txt · poscontrol-collector.txt (подсадка банка/юнита/
резервации с откатом — сборщик краснеет по трём осям) · capabilities.json (непустой
export_formats) · bank-after.json · epub-structure.txt (7 записей, nav, 3 itemref,
testzip() = None) · run_FTHA7S6SUCJIXS2A-1.exit и -2.exit (маркеры systemd) · spread-candidate-fix-probe.txt
(моя проверка починки прибора: покрытие растёт, счёт расхождений — шум). Плюс
evidence/poscontrol-paid-holes/ — контрольная сборка книги с дырами.
14.6. Формула холда закрыта ТОЧНО, и расхождение пре-рега в 2 µUSD объяснено
Пре-рег предсказал холд 2 241 629 µUSD, факт — 2 241 631. Разница не в формуле, а в слагаемом:
я взяла ожидание из суммы глав манифеста (84 120), а платформа хранит его как
expected_micro_usd − book_once_micro_usd = 84 121. Проверено запросом к её собственной строке:
⌈84 121 × 1.25⌉ + step_max 136 479 + book_once 2 000 000 = 105 152 + 136 479 + 2 000 000 = 2 241 631
— и ровно 2 241 631 стоит в reservations.amount_micro_usd первой попытки. ⇒ холд = ⌈ожидание
текста × 1.25⌉ + step_max + книжный бонд, сходится до микро-доллара; формула пака
«грант ≥ 1.25×expected + step_max + 2.00» подтверждена точным замером, а не приблизительно.
14.8. Третий носитель следа — systemd-маркеры выхода
§4.3 называет третьим носителем <StateDir>/runs/<runID>-<attempt>.exit — маркер ЮНИТА systemd, а не
переводческого юнита. Оба сняты и сохранены (контроль: маркеров в каталоге состояния всего 5, из них
два — этого прогона):
run_FTHA7S6SUCJIXS2A-1.exit {"result":"exit-code","code":"exited","status":"3", "at":"…01:38:48Z"}
run_FTHA7S6SUCJIXS2A-2.exit {"result":"success", "code":"exited","status":"0", "at":"…01:54:44Z"}
⇒ Банк-стоп (3) и успех (0) подтверждены ОПЕРАЦИОННОЙ СИСТЕМОЙ, а не только строкой run_attempts,
которую платформа пишет сама. Это единственное место в отчёте, где выход прогона предъявлен
источником вне её собственной цепочки.
14.9. Файл — это ТОТ САМЫЙ текст, а не его пересказ
Последняя сверка, которой в первой редакции не было: каждый из четырёх переведённых юнитов взят из
units.target платформы и найден в скачанном book.txt дословно, подстрокой — 5761, 5558, 10 206
и 8361 знак, все четыре True. Арифметика сходится: Σ юнитов 29 886 знаков, файл 29 913, разница
27 — заголовок книги, три заголовка глав и пустые строки между ними. ⇒ между тем, что заплачено,
и тем, что скачано, ничего не потеряно и ничего не добавлено.
14.10. Журнал ДВИЖКА сохранён — без него половина §5.2 висела в воздухе
Критик полноты заметил: числа max_tokens на входе (8496 / 16000), потолки перевыпуска (16992 /
32000), строка «stage flagged, regenerating with a larger budget … reason=empty» и отказ по
langpack_root (exit 10) жили только в моём выводе — в evidence/ их не было. Журнал юнитов выгружен
и лежит в evidence/journal/: run-attempt-1.log (170 строк), run-attempt-2.log (246),
smoke-langpack-exit10.log. Проверено счётом, что цитируемое там есть: next_max_tokens=16992 — 3
(ровно три черновых перевыпуска), next_max_tokens=32000 — 1 (редакторский), max_tokens=8496 — 6,
max_tokens=16000 — 4, «bank-mining stopped on new terms» — 1, «cannot mine a bank» — 1.
⭐ И журнал подтверждает разметку флагов из БД независимым носителем: ровно четыре события
«stage flagged» — empty (draft ch1/0) · length (draft ch2/1) · empty (draft ch3/0) ·
empty (edit ch2/0), то есть та же четвёрка и те же причины, что в колонке degraded.
14.7. «Ноль до закрытия» предъявлен артефактом, а не выводом на экране
Критик справедливо заметил, что нуля проекции банка в момент awaiting_bank в файлах не осталось.
Он предъявлен сильнее — тем самым артефактом, ИЗ КОТОРОГО платформа этот ноль и берёт:
evidence/bankstop-paid/project.db.bank.json, снятый в 04:39:43, несёт terms: [], total: 0,
signed: 0 при proposed[] из 69 термов. Платформенный SaveBank читает terms, поэтому её
ноль — не пропажа, а точная проекция того, что ей дали. После закрытия прогона: bank-after.json
показывает total: 69, signed: 2 — те самые два терма, подписанные через дверь.
15. Где лежат артефакты
| Что | Где | В git? |
|---|---|---|
| Инструменты (драйвер, сборщик следов, прибор форм, $0-заглушка, рендер $0-конфига) | eval/door_to_file/ |
да, фризы be53cc8 и 44b33d9 |
| Пре-регистрация и этот разбор | docs/experiments/24-door-to-file.md |
пре-рег — да (be53cc8); результаты лендит оркестратор |
Сырые платные выходы: отгруженные book.txt/book.epub, улика банк-стопа, полный след, счёт форм, сохранённые проверки |
books/gu-zhenren/door-to-file/ |
отдельный репозиторий книг, НЕ коммитила — лендит владелец/оркестратор |
| Стенд, копии БД, контрольные сборки, дымовая фаза | ~/tm-coldrun-a/ (вне git, но не в /tmp — переживает уборку скретчпадов) |
нет |
Стенд оставлен ПОДНЯТЫМ для проверки: tmplatformd на 127.0.0.1:8097 (pid записан в
~/tm-coldrun-a/stand/daemon.pid), база tm_coldrun_door в кластере /tmp:55433, клон фриза —
~/tm-coldrun-a/freeze. Гасить по слову оркестратора; убивать ТОЛЬКО по pid.
16. Разбор после критика ЧИСЕЛ — что он опроверг и что добавил
Второй критик пере-вывел каждое число из сырья своими командами. Две мои формулировки он опроверг (обе сняты выше по тексту), и ещё девять вещей нашёл сам. Ниже — то, что я перепроверила своими руками, а не приняла на слово.
16.1. ⛔ ЦЕНА РАБОТЫ ПОСЧИТАНА ПО ПИНУ, А ПИН ПРОТУХ НА FLASH
Критик заметил, что $0.419424 — не счёт провайдера, а результат прайса из models.yaml, и что
DeepSeek держит пиковую и офф-пиковую цену. Проверено по вендор-доке (api-docs.deepseek.com/quick_start/pricing,
снято 11.09.2026, два независимых захода дали одни и те же числа):
«Off-peak rates are half of the peak rates. Peak hours are 01:00 - 04:00 and 06:00 - 10:00 UTC, Monday through Friday (all other hours are off-peak).»
Прогон шёл 01:29–01:54 UTC в пятницу ⇒ ВНУТРИ пикового окна, и пиковый прайс для него — верное основание. Это снимает половину тревоги. Но вторая половина осталась и она дороже:
| за 1M токенов | наш пин models.yaml |
вендор сегодня (пик) | расхождение |
|---|---|---|---|
| flash, вход (cache miss) | 0.44 | 0.30 | ×1.47 |
| flash, вход (cache hit) | 0.014 | 0.006 | ×2.33 |
| flash, выход | 1.32 | 1.20 | ×1.10 |
| pro, вход / cache-hit / выход | 1.32 / 0.044 / 3.96 | 1.32 / 0.044 / 3.96 | совпадает точно |
Пере-считала все 27 настоящих вызовов дважды. По пину сходится с движком до нуля микро-долларов (арифметика движка безупречна). По живым вендорским числам тот же прогон стоил бы $0.397246:
pinned $0.419423 (flash 22 вызова $0.188953 · pro 5 вызовов $0.230471)
vendor $0.397246 (flash $0.166776 · pro $0.230471)
⇒ пин ЗАВЫШАЕТ этот прогон на $0.022177 = 5.6 %; по flash — ×1.133, по pro — ×1.000
⇒ «$0.419424» — это то, что насчитала НАША модель цен; провайдер по своей сегодняшней странице
взял бы ≈$0.397. Разницу не чиню (не моя зона и не мой пак), но называю: у пина flash есть дата
(«ПИК с 16.08.2026 16:00 UTC», models.yaml:218), и за три недели вендор его сдвинул вниз.
16.2. ⛔ СЛАГ, КОТОРОГО НЕТ В НАШЕМ РЕЕСТРЕ
model_requested = deepseek-v4-flash (наш конфиг), model_actual = deepseek-flash — на 28
строках из 33 (у pro обе колонки совпадают). Слага deepseek-flash в models.yaml нет вовсе, а
вендорская прайс-страница называет модель именно так. То есть имя, под которым нам отвечают и по
которому вендор нас считает, отличается от имени, которое мы шлём и по которому считаем себя.
Правило проекта здесь однозначно — «слаг живой ≠ модель та же», — и это вопрос бэкенду, а не вывод
прогона. Замерено: счёт строк по паре колонок. Не установлено: алиас это или другая модель.
16.3. Отказы не видны через err — только через degraded
err пуст на всех 33 строках, включая четыре провальные (контроль: err <> '' → 0). Признак
отказа живёт в колонке degraded: empty ×3, length ×1, пусто ×29. ⇒ любой аудит денег или
отказов, написанный через err, прочитает этот прогон как идеально чистый — и не увидит четверти
траты. Мой сборщик спасся тем, что смотрел на finish_reason и ok, а не на err.
16.4. Три вызова из четырёх вернули РОВНО НОЛЬ символов
В checkpoints у их request_hash length(response_text): id 1 → 0, id 7 → 0, id 31 → 0,
id 5 → 4203 (обрезок, выброшен и перекуплен). ⇒ $0.094835 = 22.6 % прогона куплено за ноль знаков,
и ещё 2.8 % — за выброшенный обрезок. У id 31 ноль знаков стоил 16 000 оплаченных выходных токенов.
⚠ И самое неприятное: флор, поднятый ИМЕННО против этого, не помог. models.yaml у
deepseek-v4-pro несёт min_max_tokens: 16000, поднятый с 8000 после прошлого инцидента, и рядом
записана его цена: «$0.0177, то есть 15.5 % всего счёта прогона, ушло в две выброшенные генерации».
Здесь ОДИН вызов на поднятом флоре сжёг 16 000 токенов и вернул ноль: $0.071009 = 16.9 % счёта —
доля БОЛЬШЕ, чем у инцидента, ради которого флор поднимали.
16.5. chunk_status — четвёртый «путь счёта», который был бы неверен
Σ chunk_status.cost_usd = 0.354127 против 0.419423. Недостача — ровно терминологический
контур ($0.065297): в chunk_status 10 строк и только стадии draft и edit, строк терминологии там
нет по построению. Таблица напрашивается как ещё один «независимый» счёт денег и им не является.
16.6. Резюм выдал согласие на пере-оплату ВСЕГО бюджета
runs.resnapshot = true, runs.accept_rebill_micro = **2 241 631** ($2.24) — санкция на пере-покупку
всего, что прогон уже купил. Фактически пере-куплено $0.028742 (терминология), потому что все шесть
черновых единиц вернулись из чекпойнтов бесплатно. Разрыв между выданным согласием и потраченным —
78×. Промахнись хэши промптов — черновая волна была бы куплена заново по полной цене, и согласие на
это уже стояло в строке. Замерено; законен ли такой размах согласия — вопрос не этого прогона.
16.7. Мелочи, каждая с числом
bank_stop_presented= 70 при 69 предложенных (и 69 строкахglossary, и 69 вbank_terms). Лишняя предъявленная поверхность —方源的(терм + частица 的), строки глоссария за ней нет. «Предъявлено» и «предложено» — разные величины, и одна на единицу больше.- 6 черновых чанков → 4 редакторских юнита — это нарезка, а не потеря: манифест несёт
units_total 2 / chunks 2у главы 1 иunits_total 1 / chunks 2у глав 2 и 3. Проверено и по тексту: все четыреunits.targetвходят вbook.txtдословно. - Округление ВВЕРХ на каждом кадре
spend, а не только в конце (12044.12 → 12045 и так далее). На этом прогоне пере-плата +0.7 µUSD, но знак у неё постоянный. - Метод, которым я делила попытки, был слабым. Я сравнивала
tsсstarted_at, аtsв sqlite секундной гранулярности:01:40:45против01:40:45.012584— буквальное сравнение уводит все шесть подстановок в первую попытку. Правильный различитель лежал в той же строке:trace_idнесёт номер попытки (tm-stream-run_FTHA7S6SUCJIXS2A-2). Вывод §14.1 верен, метод в нём заменён наtrace_id.
16.8. ⭐ ПОДПИСЬ ДОЕХАЛА ДО ТЕКСТА — и это лучший результат прогона после самого файла
Вопрос, который я не задала, а критик задал: дошли ли подписанные термины до отгруженного файла?
Проверено по book.txt прямым счётом:
| термин | что было в ЧЕРНОВИКЕ | что в ОТГРУЖЕННОМ файле |
|---|---|---|
古月山寨 |
ТРИ формы, spread=3: «поселение Гуюэ» ×1 · «городище Гуюэ» ×1 · «горная крепость Гуюэ» ×1 (bank-stop.txt) |
«(г/Г)орная крепость Гуюэ» — 5 из 5; «поселение Гуюэ» — 0, «городище Гуюэ» — 0 |
方源 |
«Фан Юань» | «Фан Юань» 38 + склонения 20 (Юаня 17 · Юаню 2 · Юанем 1); конкурирующих транслитераций («Фань Юань», Fang Yuan) — 0 |
⇒ контур банка со стопом и подписью отработал свои $0.0287 живьём: разнобой, который черновик дал по месту, в файле читателя отсутствует. Это НЕ суждение о качестве перевода — это счёт форм.
⛔ Две поправки к этому же абзацу, обе от критика полноты. (1) Черновик дал 古月山寨 не две
формы, а три — я цитировала other proposals карты подписи (две) и не открыла bank-stop.txt
того же прогона, где стоит spread=3 и перечислены три черновика. ⚠ И тот же класс расхождения
нашёлся ВНУТРИ одного артефакта: у 开窍大典 стоит spread=4, а в строке drafts: рядом перечислены
три формы. Проверено по всем 69: у 68 термов spread=N равно числу перечисленных форм до
единицы, и 开窍大典 — единственное исключение. Дефект это или разные определения — НЕ
УСТАНОВЛЕНО; для §7.1 я брала число перечисленных форм, а не счётчик. Правильное число делает вывод
СИЛЬНЕЕ, а расхождение двух артефактов движка по одному терму (other proposals = 2 против drafts:
= 3) — разные определения или дефект, НЕ УСТАНОВЛЕНО. (2) Обобщать этот успех на книгу нельзя:
полный счёт по всем девяти разошедшимся терминам (§7.1) даёт 4 доехавших, 4 отданных не-банковской
формой и 1 отданный двумя.
17. Что сказал критик по КАЖДОЙ фазе
Критиков было два (оба — отдельные сессии-опровергатели, модель задана явно): критик полноты шёл по паку пункт за пунктом против артефактов, критик чисел пере-выводил каждое число из сырья своими командами. Ниже — по фазам, как требует §5 пака.
| Фаза | Что сказал критик | Что с этим стало |
|---|---|---|
| 0 — $0-дым | Позитивные контроли исполнены (подсадка банка/юнита/резервации, книга с дырой, две подсадки в гейт бинарей, самотест прибора форм), НО их вывод жил только в моём экране, а не в файлах. Прибор форм пинен на дымовых парах, а не на материале, названном §4.0 п.5 | Все контроли пере-сняты и сохранены в evidence/checks/ (§14.5); прибор прогнан на coldrun-v16 (§14.4), и по дороге вскрыта моя же ошибка с чужим book_id |
| 1 — предусловия | Закрыто артефактом: манифест до фриза, контраст-артефакт по sha, пять переменных (одна из пятёрки опровергнута — у CEILING_ARG есть дефолт), langpack-находка |
Без изменений; находки 2 и 3 (§8) заведены оркестратором рядами 411 и 412 |
| 2 — фриз | Форма верна: клон, три условия гейта, /tmp/.git, штамп по каждой попытке. Но девиация «драйвер правлен ПОСЛЕ фриза» (44b33d9) в отчёте не названа |
Названа отдельным пунктом §12.2 с обоими sha |
| 3 — пре-регистрация | Таблица есть, но исхода не было ни у одной строки (отчёт на момент проверки состоял из одного пре-рега) | Написан §6 — исход у всех 21 строки, с фактом и предъявлением |
| 4 — платный прогон | Числа денег верны, НО: «419 423 по движку» — мой floor, а не число движка; «33 вызова» — это 33 строки при 27 вызовах; разбивка tm_hit по попыткам не построена, хотя ИСПР. 20 называет её единственным различителем; агрегаты денег в сборщике не отфильтрованы по учётке |
Две формулировки сняты (§5, §16), разбивка построена и пере-снята по trace_id (§14.1), гап сборщика назван (§14.2) |
| 5 — $0-разбор | Цена посчитана по ПИНУ, а у DeepSeek есть пик/офф-пик — «прогон стоил» без вендор-сверки не заслужено; err пуст на всех строках; chunk_status недобирает терминологию; согласие на пере-оплату выдано на весь бюджет; не спрошено, доехала ли подпись до текста |
Вендор-дока снята (§16.1): окно пиковое, основание верное, но пин flash протух на 13 % — новая находка; остальное внесено §16.3–16.8, включая ⭐ проверку подписи по тексту |
17.1. Итог ТРЕТЬЕГО прохода — круги НЕ сошлись, и я этого не прячу
Третий проход шёл по ЗАМОРОЖЕННОМУ документу (857 строк, sha256 feac01e0…c8059; критик сверил sha
дважды — в начале и в конце). Он подтвердил внесение восьми находок предыдущих проходов «точно» и
пере-снял §7.1 целиком: девятка верна, исход по каждой из девяти клеток сошёлся. И дал четыре
новые находки:
- Второй знаменатель
INVENTED— 11 термов, 7 вне девятки, и среди них ещё ДВА случая не-банковской формы в файле. Внесено: §7.2, популяция стала 16, исход 9 · 6 · 1, §13 требует двойного знаменателя. - «Шесть строк
spread ≥ 2» — число без носителя. Я процитировала его от критика чисел дважды; моя собственная проверка даёт девять, и все девять — шум. Внесено: §7 и §13 переписаны, улика —checks/spread-candidate-fix-probe.txt. spread=4у开窍大典при трёх перечисленных формах — единственное расхождение счётчика со списком на 69 термов. Внесено: §16.8.- Пак требует «и в каких главах», атрибуции не было. Внесено: §7.1 — обе формы
开窍大典в одной главе, не-банковский «свайный дом» через главы 1 и 3.
Плюс две правки, внесённые НЕВЕРНО и теперь исправленные: §14.5 объявлял одиннадцать файлов,
перечисляя двенадцать при тринадцати на диске (теперь тринадцать и перечень полный), и запись в
docs/PROGRESS.md была снимком ДО обоих критиков — она несла три уже отозванных утверждения
(«шесть путей», «4 вызова из 33», «слепота из-за склонения первого слова»). Журнал читают РАНЬШЕ
отчёта, так что это была худшая из двух. Переписана.
⇒ Честный итог: круги не сошлись ни на первом проходе, ни на втором, ни на третьем. Каждый следующий критик находил меньше и мельче (13 → 4 содержательных), но НЕ ноль, и объявлять сходимость я не имею права. Четвёртого прохода не запускала — и это решение, а не забывчивость: находки третьего внесены, документ снова изменился, и следующий проход по изменённому документу снова найдёт опечатки; граница по существу пройдена там, где перестали находиться ошибки в ЧИСЛАХ и в МЕТОДЕ — третий проход не нашёл ни одной.
18. Фаза 0 и предусловия — исход по пунктам пака
Критик полноты заметил, что §4 ссылался на секцию «Фаза 0», которой не было: исход дыма был рассыпан по находкам. Собран здесь.
18.1. Чек-лист §4.0 п.2 — что дым обязан был доказать ДО денег
| Пункт | Исход | Чем предъявлен |
|---|---|---|
| стенд поднят и порт отвечает ТВОЕМУ pid | ✅ | ss -ltnp показывал tmplatformd моим pid на 8097 и stub моим pid на 11434 |
| гость заведён | ✅ | POST /auth/dev-login → 204, строка в users |
| книга принята | ✅ | POST /v0/books → 201, chapter_count: 3 |
| прогон стартовал | ✅ | POST …/runs → 202 · ⛔ и не с первой попытки: первый старт умер с exit 10 (нет langpack_root), второй — с 409 not_priced до того, как локальной модели дали цену |
| кадры доехали | ✅ | events.jsonl дымовой книги: 29 кадров шести типов |
| узел подписи ответил | ✅ | awaiting_bank, exit 3, .bank.json с proposed[] |
| резюм прошёл | ✅ | вторая попытка, exit 0 |
| выгрузка собралась и файл скачался | ✅ | txt 4522 Б complete = t, epub 2984 Б (7 записей zip, nav, 3 itemref) |
| все сборщики следов печатают обещанное | ✅ | collect.py прошёл по дымовой книге целиком; позитивный контроль — checks/poscontrol-collector.txt |
18.2. §4.0 п.4 — «дым меняет три фактора разом»
Пак предупреждает, что дым меняет провайдера, книгу и базу сразу, и потому при провале платной руки
не разделит причину. Мера принята и названа в записке-плане: базу из размена я убрала. Платная
фаза шла на ТОЙ ЖЕ базе, ТОМ ЖЕ демоне и ТЕХ ЖЕ трёх бинарях, что дым; сменились ровно два фактора —
пайплайн (pipeline-zero → pipeline-c1) и книга (синтетический дым → срез). Оба названы в §1 с sha.
⚠ Честная оговорка: вместе с пайплайном сменился и models.yaml (дымовой нёс номинальную цену
локальной модели), и учётка — то есть факторов всё-таки четыре, а не два. Первые два выбраны,
вторые два вынуждены находками 1 и денежной правкой оркестратора.
18.3. §4.1 п.8 — ключи провайдера
Исход: предусловие закрыто оркестратором, файл НЕ читался ни мной, ни платформой, живость доказана
первым платным вызовом. Путь TM_PLATFORM_ENGINE_KEYS_PATH=/home/ubuntu-26/projects/textmachine/backend/.env
выдан релеем; платформа не открывает этот файл, а передаёт путь движку аргументом --keys-file на
translate. Дым шёл БЕЗ переменной намеренно — чтобы никакая ошибка конфигурации не могла дотянуться
до платного провайдера; контроль этого выбора в логе: два дымовых бута несут WARN «no
TM_PLATFORM_ENGINE_KEYS_PATH: the engine is passed no provider keys», платный бут — не несёт, а
печатает путь с source=environment. Первый платный вызов прошёл без отказа по авторизации
(request_log.err пуст на всех 33 строках) ⇒ ключи живы.
⚠ Паковское «без него платного пути не существует» я прочитала в коде, но не замерила: без
переменной движок искал бы .env рядом с book.yaml, которого SaaS-путь не пишет, и отказал бы на
проверке ключей при загрузке конфига (CheckKeys внутри forWrite). Проверять это исполнением
значило бы купить заведомо провальный старт — не стала.
18.4. §4.2 — что печатается в отчёт без пере-фриза
- Грант: $2.50 платной учётке, одной строкой
credit_ledger.kind='grant'(2 500 000 µUSD). TM_PLATFORM_HOLD_FACTOR_PERCENT: 125, источникdefault(боевой лог бута); подтверждён арифметикой холда до микро-доллара в §14.6.- TTL выгрузки:
TM_PLATFORM_EXPORT_TTL = 24h0m0s, источникdefault; на обеих строкахexportsexpires_atровно на сутки позжеfinished_at(12.09 04:55 и 04:56).
19. Состояние сдачи
Сделано и предъявлено: книга проведена от двери до файла и прочитана; исход есть у каждой из 21 строки пре-рег-таблицы (§6) и у каждого пункта §4 пака (§18 и §12); деньги сведены семью путями с названной оговоркой про независимость (§5) и пере-проверены против вендорской страницы (§16.1); находки размечены «замерено / прочитано / подозрение» (§8, 19 строк); девиации объявлены (§12, шесть пунктов); что НЕ удалось — §10; слабое место прогона — §11; итог трёх проходов критиков — §17 и §17.1.
Что унесено в дерево: инструменты — eval/door_to_file/, закоммичены фризами be53cc8 и
44b33d9. Этот отчёт — docs/experiments/24-door-to-file.md; его результаты НЕ коммичены, лендит
оркестратор. Сырые платные выходы — books/gu-zhenren/door-to-file/ (33 файла), репозиторий книг
отдельный, тоже не коммичены. Запись в журнал — секция «Полигон» docs/PROGRESS.md.
Что оставлено включённым и почему: стенд жив (tmplatformd на 127.0.0.1:8097, база
tm_coldrun_door в кластере /tmp:55433, клон фриза в ~/tm-coldrun-a/freeze) — чтобы любое число
этого отчёта можно было пере-снять теми же командами. Гасить по слову оркестратора, и только по
pid.
Чего я НЕ делала и не буду: не чинила ничего из найденного — ни пин цены, ни прибор расхождения
форм, ни свой драйвер, ни langpack_root в рецепте стенда. Пак запрещает прогону чинить, и это
правильно: половина находок — чужих зон, а вторая половина требует замера, а не правки.
Работа завершена, править не планирую.