textmachine/docs/archive/prompts/POLYGON_COLD_RUN_A_SESSION_PROMPT.md

48 KiB
Raw Blame History

Промт: полигон-пак «ХОЛОДНЫЙ ПРОГОН A — от двери до ФАЙЛА, настоящая книга, настоящие деньги»

АРХИВ — ЗАКРЫТО СЛОВОМ ВЛАДЕЛЬЦА 11.09: «полигон это вообще не наш скоуп». Заказ снят не по качеству промта и не по исчерпанию предмета: зона выведена из работы целиком. Инструкции отсюда НЕ ИСПОЛНЯТЬ (правило архива). Пере-открывается только новым словом владельца; до тех пор содержимое — история, а не задание. ⚠ Ссылки на этот файл из журнала решений и старых отчётов сознательно не правлены: тела нот не переписываются, и их адреса указывают в историю.

Редакция 2 (11.09). Первая редакция прошла опровергателя и получила двадцать находок, из них четыре денежных и три, обнулявших смысл прогона. Все внесены. Места, где я ошибался, помечены « ИСПР.» — читай их внимательнее прочего: там сказано, чему НЕ верить.

1. Какая проблема и что решит твой результат

Мы построили весь путь: гость заводит книгу → платформа берёт деньги в холд → движок переводит → человек подписывает банк терминов → редакторская волна → выгрузка → файл. Каждый кусок предъявлен по отдельности. Книги, прошедшей его ЦЕЛИКОМ до конца, не было ни разу. Это строка бэклога 16 дословно: «цена ДОВЕДЁННОЙ ДО КОНЦА книги не измерена». Ближайшая попытка — 04.09 — дошла до скачанного EPUB, но упёрлась в денежный потолок.

ИСПР. 1: СУДЬИ НА ЭТОМ ПУТИ НЕТ. Боевой конфиг pipeline-c1.yaml несёт ДВЕ стадии — draft и edit; role: judge живёт только в c2 и Фазой 0 прямо не исполняется (backend/internal/config/pipeline.go:506-508). Там же escalation.budget_usd: 0 ⇒ эскалация НЕ исполняется вовсе, и gates.coverage.enabled: false — один из пяти гейтов выключен. Путь, который ты проверяешь: черновик → редактор → четыре $0-гейта → выгрузка. Так и пиши в пре-реге; «судья» из моей первой редакции — моя ошибка.

Твой результат: одна настоящая книга (3 главы zh→ru) проведена от двери до файла, открытого человеком, и у каждого узла напечатано, ЧЕМ он предъявлен. Плюс честный список того, что на этом пути сломано: прогон ничего не чинит, он только называет.

2. Зона записи и git

Зона: eval/ + docs/experiments/, пинг оркестратору — секция «Полигон» в docs/PROGRESS.md. Сессия НЕ коммитит — КРОМЕ пре-рег-фризов (право полигона, единственное исключение в проекте). Канон git — CLAUDE.md §«Git-координация мультисессий». backend/ и platform/ — ЧИТАТЬ, не править; недостающие артефакты класть в worktree-копию, не в главное дерево. .env не читать.

ИСПР. 2 — АДРЕСАТ ФРИЗ-ОБЪЯВЛЕНИЯ. Канон говорит «объявляется ВЛАДЕЛЬЦУ вслух до коммита», но владелец отошёл, а §13 запрещает его беспокоить. Разрешаю так: объявление идёт мне по каналу; канала нет ⇒ объявление печатается ОТДЕЛЬНОЙ секцией отчёта ДО строки фриз-коммита, и это засчитывается.

Правка ЗАКАЗА на лету доезжает только РЕЛЕЕМ: я пере-передаю её отдельным сообщением, ты эхо-подтверждаешь своими словами и выносишь отдельным пунктом отчёта.

3. Карта чтения — ЗАКОН, дальше только по её ссылкам

  1. CLAUDE.md — цели владельца и гардрейлы.
  2. docs/experiments/09-pilot-protocol.md + eval/README.md — устройство полигон-зоны и пре-регистрация.
  3. docs/experiments/00-provider-quirks.mdоплаченные провайдерские факты; ДО первого платного вызова.
  4. platform/docs/STACK_DECISIONS.md §«Стенд разработчика» (строка 463) — рецепт стенда и инвентарь каналов.
  5. Строки бэклога 16 и 224 (docs/BACKLOG.md, греп ^| N |).

Ратифицированное и замеренное — в теле промта, не искать:

  • D39.144 — банк подписывается ВЕСЬ ОДНИМ ОК; резюм снимает стоп при ЛЮБОМ состоянии решений.
  • D39.178 — сборка выгрузки идёт --partial. ИСПР. 3: я огрубил ноту. Полностью: неполная книга уходит С ПОМЕТКОЙ и маркером на месте КАЖДОЙ дыры; «молчаливый полный файл на книге с дырой ПО-ПРЕЖНЕМУ ЗАПРЕЩЁН»; граница D25.1 осталась открытой. То есть дверь строит всегда, но обязана СКАЗАТЬ.
  • D39.194 п.1 — цикл замкнут живьём 04.09, EPUB прошёл epubcheck 5.3.0. ⚠ Слова complete в теле ноты нет: что книги, доведённой до complete = true, не было, говорит строка 16, а не нота.
  • Претрейн: 蛊真人 узнаётся моделями 4 из 5 ⇒ пак НЕ делает утверждений о КАЧЕСТВЕ перевода. Узлы судятся механизмом — кадрами, флагами, леджером.
  • Норма денег полигона: «не влезает в бюджет — СТОП и пинг, не резать молча»; подъём потолка просят при СРАБАТЫВАНИИ стопа, не по проекции. ⚠ Носитель — ролевой промт оркестратора; атрибуцию D39.108 п.1 я снял 11.09 фантом-гардом (в теле ноты формулировки нет).
  • Живость проверяется АКТИВНО: один вызов редактора законно идёт до ~21 минуты (attempt_max_s: 1240, backend/configs/models.yaml:78 — ⚠ это ПОТОЛОК уровня ПРОВАЙДЕРА, не типичная длительность). ИСПР. 4: events.jsonl и request_log — ОДИН носитель (диск одного процесса), и растущий лог не есть работа. Сторожи по РАЗНЫМ осям: число строк request_log (движок) и book_events / run_attempts.last_seq (платформа), плюс systemctl show юнита. Каденция — раз в 3040 минут, доклад «жив» — мне, одной строкой с двумя числами.

Какие полигонные нормы здесь действуют, а какие нет — ИСПРАВЛЕНО. «Пороги различимости» и «запрет судьи-родственника» не работают: судейской линзы и сравнения рук в паке нет. Но «арм без фактора» и «декой» работают, и я был неправ, объявив их неприменимыми — см. §4.0 п.3 и §5 п.10. Пре-регистрация ожидаемых исходов (§4.3) действует в полную силу.

4. Состав: четыре фазы. Порядок ЖЁСТКИЙ

4.0 Фаза 0 — $0-ДЫМ. Делай РОВНО так, и это первая работа пака

Ни одного платного вызова, пока дым не прошёл целиком.

  1. Инструмент заглушки — ОДИН, и он ШТАТНЫЙ: провайдер kind: local на 127.0.0.1:11434. ИСПР. 5 (две правки, вторая — МОЯ ОШИБКА, снятая полигоном 11.09). (а) Чужой ~/tm-p9-work/fake_provider.py не брать: это двухнедельный скрипт в чужом домашнем каталоге, а не механизм проекта. (б) Но моё «с local они несовместимы, разные адаптеры» — НЕВЕРНО, и вот чем предъявлено: заглушка живёт В РЕПО портированной — platform/internal/runner/translate_resnapshot_live_test.go:115, комментарий дословно «fakeProvider is the P9 live-probe's $0 stand-in (fake_provider.py), ported», — и обслуживает она ровно провайдера kind: local. Рядом лежит готовый рендер $0-конфига zeroCostPipeline (platform/internal/runner/bankapply_live_test.go:116), который выбирает первую модель с Providers[m.Provider].Kind == "local". ⇒ бери эти два носителя как образец.И «sed по model:» из рецепта стенда СЕГОДНЯ НЕДОСТАТОЧЕН — тот же рендер снимает сверх моделей стадий ещё четыре вещи: модели ГЕЙТОВ (model И classify_model — второй падает обратно на первый только когда ПУСТ, и его собственный комментарий называет это уже случавшимся провалом), escalate_to, label_models, escalation.budget_usd, и абсолютизирует mining.contrast_path. ⇒ пин фазы 0: после рендера напечатай счёт платных слагов в получившемся конфиге — ноль, при контрольном счёте тех же слагов в pipeline-c1.yaml — не ноль. Молчащий греп и чистый конфиг иначе неотличимы.
  2. Что дым обязан доказать ДО денег: стенд поднят и порт отвечает ТВОЕМУ pid · гость заведён · книга принята · прогон стартовал · кадры доехали · узел подписи ответил · резюм прошёл · выгрузка собралась и файл скачался · все сборщики следов печатают то, что обещали.
  3. ПОЗИТИВНЫЙ КОНТРОЛЬ КАЖДОГО СБОРЩИКА — обязателен, стоит $0 и снимает сразу три дыры пака. Засей в стендовую БД заведомо НЕНУЛЕВОЙ банк и заведомо удержанный юнит и потребуй, чтобы сборщики стали КРАСНЫМИ. Сборщик, не покрасневший на подсадке, в платную фазу НЕ ДОПУСКАЕТСЯ. Довод: критерии §5 п.1 и §4.4 одинаково удовлетворяются молчащим прибором — «счётчики нулевые» и «прибор ничего не прочитал» неотличимы, а банковый сборщик на платной руке работает первый раз в жизни (на заглушечной прозе банку неоткуда взяться).
  4. Дым меняет ТРИ фактора разом (провайдер + книга + база) — значит при провале платной руки он не разделяет причину. Держи это в голове и, где дёшево, меняй по одному.
  5. Прибор §4.5 п.2 (счёт расхождения форм) строится и пинится ЗДЕСЬ, на бесплатном материале (books/gu-zhenren/coldrun-v16/guzhenren-coldrun-v16.db.book.epub), а не после траты денег.

4.1 Предусловия стенда — делай РОВНО так; список пере-снят и ИСПРАВЛЕН

  1. Артефакта контраста майнинга на ФС нет ни одного (два независимых полных скана; контроль: под $HOME просмотрено 390 083 файла). CheckMiningContrast откажет на старте translate — $0, но останется failed-прогон, и следующий старт той же книги пойдёт как ПРОДОЛЖЕНИЕ. Рецепт и пин — docs/experiments/16-bank-mining.md:183: jieba 0.42.1 dict.txt, sha256 7197c3211ddd98962b036cdf40324d1ea2bfaa12bd028e68faa70111a88e12a8. ⚠ Ловушка имени: в конфигах файл зовётся mining-contrast.zh.txt (backend/configs/pipeline-c1.yaml:139) и резолвится ОТ КАТАЛОГА pipeline.yaml, а источник — jieba_dict_general_zh.txt. И ловушка проверки: гард делает только os.Stat — рядом на диске лежит ФАЛЬШИВЫЙ кандидат ~/tm-p9-work/cfg/contrast-zh.txt (992 байта, sha не тот), и гард им удовлетворится. Сверяй sha, а не имя.
  2. jieba ставится, это НЕ блокер (испр.: python3 -m venv есть, ensurepip даёт pip 25.1.1, pypi достижим).
  3. Кластер Postgres поднят, но БЕЗ TCP-порта: listen_addresses пуст, слушает только unix-сокет. Подключаться -h /tmp -p 55433 -U postgres (ОС-роль ubuntu-26 в нём не заведена). Кластер НЕ сносить, чужие базы не трогать — там данные платного прогона 04.09; заводи СВОЮ.
  4. ИСПР. 6: epubcheck/java на хосте нет, и поставить их сессия НЕ может — passwordless sudo отсутствует, а §13 запрещает беспокоить владельца. ⇒ валидатор EPUB НЕ обязателен. Узел судится txt-выгрузкой плюс структурным чтением EPUB (zip + container.xml + nav), и «файл ОТКРЫТ» значит человек прочитал первый абзац перевода и сказал, что это связный русский текст, а не cat. Ставишь epubcheck без sudo из тарбола в ~/.local — законно, версию назови числом.
  5. Порт может отвечать ЧУЖИМ процессом (PD-447): опознавай стенд по pid-на-порту. Сегодня стенд не поднят вовсе: tmplatformd-процессов 0, дефолтный 127.0.0.1:8080 свободен.
  6. Годится ТОЛЬКО бинарь из фриз-воркри. Настоящих стендовых копий tmctl/tmvet/tmmutate34 (вне $HOME и /tmp — 0); среди них бинарь от 24.08 на PATH (~/.local/bin/tmctl), носитель PD-432. Копии заводятся и в скретчпадах ⇒ негоден ЛЮБОЙ бинарь не из фриз-воркри.
  7. ИСПР. 7 — ПЯТЬ ПЕРЕМЕННЫХ ОКРУЖЕНИЯ РЕШАЮТ, СУЩЕСТВУЕТ ЛИ ПУТЬ ВООБЩЕ, и в первой редакции их не было. TM_PLATFORM_EXPORT_FORMATS по умолчанию ПУСТ ⇒ все три ручки выгрузки НЕ монтируются, и последняя треть пути для тебя не существует (404) · TM_PLATFORM_ENGINE_BIN пуст ⇒ нет ни прогонов, ни интейка · TM_PLATFORM_BOOKS_DIR пуст ⇒ нет POST /v0/books · TM_PLATFORM_ENGINE_KEYS_PATH — см. п.8. ИСПР. 19: TM_PLATFORM_ENGINE_CEILING_ARG из этой пятёрки ВЫЧЕРКНУТ — я был неправ. У переменной есть дефолт --ceiling-usd {{usd}} (platform/internal/config/config.go:550), демон печатает его на буте как source=default, и прогон стартует, стоит и завершается, пока она не задана вовсе. Замерено полигоном исполнением на стенде 11.09. Остальные четыре в силе. Пин ДО фриза: GET /v0/capabilities показывает непустой export_formats.
  8. Ключи провайдера. Значение TM_PLATFORM_ENGINE_KEYS_PATH даю я; в окружении его сейчас нет, и правдоподобного кандидата на диске тоже. Нет значения ⇒ СТОП ДО фриза — платного пути без него не существует, а .env читать запрещено гардрейлом.
  9. Субъект и деньги заводятся НА МАШИНЕ, не по HTTP: самореги нет (маршрутов с auth в таблице — 0 из 19), пополнения по HTTP нет (credit/grant/balance — 0 из 19). Путь: POST /auth/dev-login при TM_PLATFORM_DEV_LOGIN (тогда деплой не может быть с OIDC) либо tmplatformctl token issue; деньги — tmplatformctl grant --user <id> --usd <amount>.
  10. Каталог книги coldrun-v16/ УЖЕ занят прошлым прогоном — там project.db (68 строк request_log на $0.436), events.jsonl, сайдкары банка, bin/tmctl без VCS-штампа, и book.yaml, указывающий в ЧУЖОЙ домашний каталог. Исходник читается ТОЛЬКО как файл; рабочий каталог платной книги — новый и пустой; шаблон book.yaml оттуда НЕ переиспользовать.

4.2 Фриз — делай РОВНО так

Фриз = sha коммита ПЛЮС бинари, собранные из ЛОКАЛЬНОГО КЛОНА (git clone <репо> <путь>). Довод — не «дерево грязное», а главное дерево движут параллельные сессии: в нём прямо сейчас работают движковая и платформенная. Драйвер перед каждым платным шагом печатает go version -m и ОТКАЗЫВАЕТ при vcs.modified=true, чужом revision или ОТСУТСТВИИ строк vcs.*.

ИСПР. 18 — МОЙ ЦЕНТРАЛЬНЫЙ ГЕЙТ БЫЛ ПИНОМ, УТВЕРЖДАЮЩИМ МОЛЧАНИЕ. Замерено полигоном 11.09, я пере-проверил своим прибором. Первая редакция велела собирать из git worktree add. Бинарь, собранный в ЛИНКОВАННОМ воркри, не несёт VCS-штампа ВООБЩЕ — не vcs.modified=true, а НИ ОДНОЙ строки vcs.* (24 строки go version -m, из них vcs.* — 0). Причина: у линкованного воркри .git — ФАЙЛ, и поиск корня VCS в Go его пропускает; выше по дереву репозитория нет, поэтому сборка не падает, а тихо выходит без штампа — тот же результат, что от запрещённого -buildvcs=false, только без единого предупреждения. ⇒ правило «отказывать при vcs.modified=true» на воркри-бинаре выполнялось ВСЕГДА и не проверяло ничего. Контроль, доказывающий, что механизм на этом хосте жив: та же сборка из ГЛАВНОГО дерева даёт vcs.revision=… и vcs.modified=true. ⇒ Фриз-дерево — ЛОКАЛЬНЫЙ КЛОН: у него .git настоящий КАТАЛОГ, и бинари несут vcs.revision=<sha> · vcs.modified=false (проверено на всех трёх). Гейт получает зубы: «штампа нет» и «штамп чужой» становятся отличимы от «штамп мой и чистый». ⚠ И в клоне НЕТ books/ — внешний репозиторий держит их в .gitignore, книги версионируются ОТДЕЛЬНЫМ репозиторием. Исходник читается из главного дерева как ФАЙЛ (read-only), а его провенанс — пара sha256 (срез и оригинал) в пре-реге. Артефакт контраста кладётся в КЛОН, рядом с его pipeline.yaml.

ИСПР. 8 — ВТОРОЙ СПОСОБ ОБНУЛИТЬ ФРИЗ-ГЕЙТ, и он остаётся в силе для КЛОНА тоже. Напоровшись на посторонний /tmp/.git, сборка падает с «error obtaining VCS status», и штатное лечение GOFLAGS=-buildvcs=false стирает штамп целиком (эррата D39.202). ⇒ перед сборкой test ! -e /tmp/.git; -buildvcs=false в фриз-сборке ЗАПРЕЩЁН; фриз-дерево — вне репозитория и вне общего скретчпада. ⚠ И штамп снимается на КАЖДУЮ попытку, а не один раз: резюм может сменить бинарь под тем же прогоном (TM_PLATFORM_RESUME_MAY_CHANGE_ENGINE, колонка runs.engine_binary) — сверяй по run_attempts, а не по тому, что лежит на PATH в конце.

В фриз-коммит: docs/experiments/24-<имя>.md — пре-рег с таблицей ожидаемых исходов (§4.3), sha256 исходника и sha256 ФАКТИЧЕСКОГО pipeline-YAML (платформа берёт файл ЦЕЛИКОМ через TM_PLATFORM_BOOK_TEMPLATE, пер-полевого оверрайда нет ⇒ «прогон на c1» без sha — утверждение без носителя), список глав с units_total; eval/<каталог>/ — драйвер, сборщики следов и сверка; шаблон book.yaml с абсолютными путями в worktree. Без пере-фриза (но печатается в отчёт): грант, TM_PLATFORM_HOLD_FACTOR_PERCENT, TTL выгрузки. Граница: меняется ЧТО покупается или чем судится — новый фриз; меняется СКОЛЬКО тратить — объявление. ⚠ Правка собственного драйвера после фриза — тоже новый фриз.

4.3 Пре-регистрация ожидаемых исходов — главный рубеж пака

До первого платного вызова в фриз-коммите лежит таблица: узел → что ДОЛЖНО произойти, числом или строкой → чем предъявлено → что считается ПРОВАЛОМ узла.

Следы — по РАЗНЫМ носителям: (1) Postgres стенда (books·chapters·units·runs·run_attempts· reservations·credit_ledger·book_events·exports); (2) диск движка и systemd (events.jsonl с кадрами hello/progress/unit_done/bank_stop/ceiling/spend/finished; project.db/request_log — читать mode=ro можно НА ХОДУ, WAL это разрешает; сайдкары .bank.json, mined-signature.yaml, .bank-stop.txt; systemd-маркер выхода <StateDir>/runs/<runID>-<attempt>.exit — это маркер ЮНИТА systemd, не переводческого юнита); (3) HTTP и файл — ответы ручек, SSE, скачанные БАЙТЫ и их sha256.

ИСПР. 9 — И ЧЕСТНО ПРО НЕЗАВИСИМОСТЬ: следов не три. Postgres платформы материализуется из events.jsonl движка (Sink materializes a stream into the reporting database… not an event store), а текст, сверку и файл платформа получает теми же tmctl export/status/build. ⇒ «три следа сошлись» означает "одна БД согласна сама с собой". По-настоящему независимы только скачанные БАЙТЫ и их sha256; биллинга провайдера у нас нет. Так и напиши в пре-реге — это не отменяет сверку, но меняет, что она доказывает.

ИСПР. 10 — ДЕНЕЖНОЕ РАВЕНСТВО НАЗВАНО НЕТОЧНО. Кадр несёт committed_micro_usd (целые микро-доллары), а committed_usd — поле ДРУГОГО носителя, tmctl status --json; конверсия округляет ВВЕРХ. request_log объявлен ТЕЛЕМЕТРИЕЙ, а не источником денег («деньги живут в spend/checkpoints»), и редрайв удаляет чекпойнты — это законный класс расхождения. ⇒ печатай в МИКРО-долларах и как ПРОВЕРКУ, а не тождество: Σ request_log.cost_usdspend.committed_micro_usd ≈ Σ credit_ledger settlement ≈ (грант баланс); расхождение — назвать, а не подогнать. Открытых резерваций на конце — 0 (холд дебетует баланс отдельной строкой kind='hold').

4.4 Фаза 2 — платный прогон

Книга: books/gu-zhenren/coldrun-v16/guzhenren-ch1-10.gb18030.txt (57838 байт, sha256 0b5f9b0266d8c32ac717a41211d2ed15d4f2a07f37a701fb686e255ab6c89f37, 10 глав маркерами 第一节…第十节). ⚠ Имя эксперимента — НЕ coldrun-a: каталог занят прогоном 24.08.

ИСПР. 11 — ОБЪЁМ ЗАКАЗА БЫЛ ДВУСМЫСЛЕН, реши и объяви в пре-реге. Интейк главами резать НЕ умеет (форма несёт title/source_lang/target_lang), объём покупается членом chapters на старте прогона. Значит либо (а) режешь файл до 3 глав и грузишь срез — тогда units_total книги и заказ совпадают; либо (б) грузишь весь файл и заказываешь 3 главы — тогда узел выгрузки судится по ordered_chapters / delivered_chapters, а НЕ по units_total. Рекомендую (а): сверка честнее и дешевле. ⚠ И delivered — это finished.volume.delivered, а секции volume у цельнокнижного заказа НЕТ вовсе (платформа не передаёт --max-units); плюс Delivered считает только юниты, «never completed before» — после резюма это уже не units_total.

ИСПР. 12 — ГЛАВЫ 13 ТОЛЩЕ СРЕДНЕЙ. Замер по БД прошлого прогона того же исходника: глава 1 — 4 чанка, глава 2 — 3, глава 3 — 2, остальные по 2 (контроль: всего 23 строки chunk_status). 9 из 23 чанков = 39 % книги в 30 % глав. ⚠ И пин «≥1 глава с units_total ≥ 2» из первой редакции охраняет то, чего не бывает (таких глав все десять) и НЕ охраняет то, что случится — недооценку объёма. Замени пин на «сумма units_total по заказанным главам совпадает с пре-регом».

УЗЕЛ ПОДПИСИ БАНКА — самое ценное место прогона, и здесь я ошибался дважды.

ИСПР. 13a: читатель у секции предложений ПОСТРОЕН. Платформа считает bank_terms (count(*) и filter (where status='approved')), а строки туда пишет SaveBank из движкового сайдкара. Наблюдённый ноль объясняется МОМЕНТОМ обновления: банк пересчитывается, только когда книга «в покое» (нет прогонов с finished_at is null), а при банк-стопе статус уходит в awaiting_bank РАНЬШЕ закрытия строки прогона. ⇒ ожидаемый исход: платформа показывает ноль ПОКА строка прогона не закрыта и НЕнулевое ПОСЛЕ. Ноль после закрытия — дефект; ненулевое до — тоже факт. Прежняя формулировка («узел засчитан, только если платформа показала ноль») НАКАЗЫВАЛА исправное поведение — снята.

ИСПР. 13b: улику уничтожает резюм, который пак сам заказывает. proposed[] в .bank.json берётся из поля в памяти ОДНОГО процесса, а exportBank зовётся в том числе на СТАРТЕ каждого прогона и перезаписывает файл атомарно. ⇒ сними sha256 и КОПИЮ <project_db>.bank.json в момент awaiting_bank, ДО bank/corrections и ДО резюма. Более живучие улики того же факта — mined-signature.yaml и .bank-stop.txt: они пишутся при каждом заходе в майнинг.

ИСПР. 13c: банк-стопа может не случиться вовсе. Стоп требует трёх условий разом: флаг --verify-bank И наличие edit-волны И кластер, которого не показывал ни один прежний стоп (движок помнит показанные поверхности). Иначе — авто-продолжение с неподписанным банком, и второй прогон по той же книге не остановится никогда. Это девятый способ выродиться: узел не пройден не потому, что сломан, а потому, что не наступил. Назови исход явно.

Дверь решения зовётся POST /v0/books/{bookId}/bank/corrections, action ∈ approve|decline, пачкой (персональных ручек по терминам нет, таблица bank_decisions мертва). «Подпись» завершается одним POST /v0/runs/{runId}/resume. Решение, которое принимаешь ты: провести ОДНО настоящее решение через дверь (рекомендую — иначе дверь правок остаётся непройденной) либо резюмить неподписанным. Объяви ДО прогона.

Чего делать НЕЛЬЗЯ: чинить найденное · править backend//platform/ · менять срез или пайплайн после фриза без нового фриза · тихо пополнять баланс · интерпретировать провайдерскую аномалию без вендор-доки.

4.5 Фаза 3 — $0 после прогона

  1. Сверка каждой строки пре-рег-таблицы: ожидание → факт → сошлось/нет → чем предъявлено.
  2. Механический счёт расхождения форм по ОТГРУЖЕННОМУ тексту (прибор построен в фазе 0, §4.0 п.5): сколько канонических терминов отданы более чем одной передачей и в каких главах. ⚠ Это МЕХАНИЧЕСКИЙ счёт, не суждение о качестве. Он нужен, потому что такой меры по финальному тексту сегодня не существует вовсе (строка бэклога 406).
  3. Список сломанного — строкой на находку: что · где · чем предъявлена · «замерено / прочитано / подозрение». Ряды бэклога заведу я.

5. Как прогон вырождается — десять способов и их снятие

  1. Дверь выгрузки ВСЕГДА строит (--partial). Снятие: exports.complete = true И нулевые счётчики отчёта сборки И finished.outcome в списке успеха И все units.state='translated'. ИСПР. 14: ни complete, ни счётчики на API НЕ ОТДАЮТСЯ. wireExport несёт 7 полей, и запрет умышленный («what does NOT cross: … whether the file came out whole»). ⇒ complete читается из Postgres, счётчики — из stdout tmctl build или лога платформы. ⚠ И проверяй не пять полей, а семь: к pending/withheld/incomplete/stale/ghost добавь stale_unknown и config_drift — под дрейфом конфига stale_units механически 0, и complete: true при этом ЗАКОНЕН. Ноль без stale_unknown=false не доказывает ничего.
  2. Срез не тот, что в пре-реге. Снятие: $0-манифест ДО фриза (tmctl manifest --json даёт units_total и по книге, и по главе; ⚠ он ПЕРЕЗАПИСЫВАЕТ <project_db>.manifest.json и требует записываемого каталога), сверка после интейка, расхождение — стоп ДО оплаты.
  3. Узел подписи — §4.4, три исправления.
  4. Деньги мимо сверки — §4.3 ИСПР. 10; строки request_log с непустым err или finish_reason ≠ stop перечисляются поимённо. (На опорном прогоне 08.09 таких было 32 % трат.)
  5. ИСПР. 15 — СТОРОЖ ПОТОЛКА СМОТРЕЛ НА СТРОКУ, КОТОРОЙ НЕ БУДЕТ. credit_exhausted «больше не производится для собственного потолка прогона» — это счёт АККАУНТА; потолок прогона даёт run_limit_reached. Полный словарь: run_limit_reached · credit_exhausted · daily_ceiling · ceiling_unknown. ⇒ ЛЮБОЕ непустое paused_reason = СТОП и пинг. Прогон при этом не failed — контракт это запрещает.
  6. Чужой стенд и ложная зелень: порт чужого процесса · ничьи базы · старый tmctl · vcs.modified. Снятие: pid-на-порту · своя база · штампы по КАЖДОЙ попытке · контрольные числа и по runs, и по run_attempts (резюм после банк-стопа гарантирует вторую попытку — «прогонов = 1» этого не видит).
  7. Отказ на старте не бесплатен для ЭКСПЕРИМЕНТА (артефакт контраста): $0 по деньгам, но после failed книга уже не холодная. Снятие: дым и предусловия ДО загрузки платной книги; платной книге — свежий id.
  8. Претрейн — никаких суждений о качестве.
  9. НОВОЕ: прогон может НЕ КУПИТЬ НИЧЕГО и выйти успешным — реплей чекпойнтов. RequestHash адресует чекпойнт, попадание пропускает вызов провайдера и стоит $0 (колонка request_log.tm_hit — «ответ взят из чекпойнта»); гварда «project_db обязан быть новым» в коде НЕТ. Если платная книга ляжет на путь, где остались чекпойнты дыма под тем же снапшотом, прогон пройдёт зелёным почти бесплатно и измерит пустоту. Снятие: select distinct model_actual from request_log не содержит local-* — это НЕСУЩИЙ пин; tm_hit печатается с разбивкой по попыткам, а не суммой; test ! -e <project_db> до старта — дешёвая добавка. ИСПР. 20: «tm_hit = 0 после прогона» — НЕВЕРНО для прогона с банк-стопом, и это моя ошибка. Замерено полигоном на дыме: 3 строки из 13 пришли с tm_hit=1, и это ЗАКОННО — резюм переигрывает чекпойнты СВОЕЙ ПЕРВОЙ попытки, за которые уже заплачено. Суммарный ноль тут означал бы, что стопа не было. Различает не сумма, а разбивка: попадания внутри одной попытки — подозрение, попадания второй попытки в чекпойнты первой — норма.
  10. НОВОЕ: молчащий прибор удовлетворяет три центральных критерия сразу (§5 п.1, §4.4, §4.3). Снятие — позитивный контроль сборщиков в фазе 0 (§4.0 п.3). Если вносить в пак что-то одно, вносить это.

Мандат самопроверки ИСПОЛНЕНИЕМ: ревью СВОЕГО кода драйвера, СВОИХ запросов и ПОЛУЧЕННЫХ результатов. Субагентов спавнить РАЗРЕШЕНО и требуется, модель задавай ЯВНО. Отрицательный замер печатает КОНТРОЛЬНУЮ ВЕЛИЧИНУ рядом с нулём. Критик полноты — на КАЖДУЮ фазу.

6. Предметные оси ревью

Полигон/замеры: пере-вывод чисел из СЫРЬЯ; вывод на агрегате до вскрытия единиц запрещён; ⚠ про «независимость сигналов» — читай §4.3 ИСПР. 9: здесь она ограничена, и это надо не обходить, а назвать. Деньги: из сырого леджера двумя путями; леджер — нижняя граница.

7. Записка-план ДО работы

До первой команды — мне ≤15 строк: как ведёшь фазы · где ждёшь сопротивления · что считаешь спорным в заказе. Пре-рег-таблица §4.3 присылается ОТДЕЛЬНО и ДО фриза — я её читаю. Канала нет — обе идут секциями отчёта.

8. Заявление = команда

Каждое число и каждая категорика — с командой и её выводом. Число называет ДЕРЕВО и ПОПУЛЯЦИЮ.

9. Эхо-протокол старта

ДО первой команды — мне первым действием, по адресу из /tmp/textmachine-channel (SendMessage, роль ОРКЕСТРАТОР), ≤10 строк: скоуп · инварианты · не-делать — СВОИМИ словами.

10. Что НЕ удалось — обязательная секция отчёта

Что не проверено · что не воспроизвелось · где данных не хватило · какой узел объявлен непройденным и почему. «Не измерено» вместо догадки.

11. Канал вопросов и право отказаться

Конфликт промта с кодом — пинг мне, НЕ интерпретация. Право сказать «этого делать не надо» с аргументом — есть. Всё про деньги сверх названного — через меня.

12. Прямой канал

CLAUDE.md §«Связь между сессиями»: /tmp/textmachine-channel, свой блок первым делом, живость — ListAgents. Роли нет или имя не отвечает ⇒ КАНАЛА НЕТ, это НОРМАЛЬНЫЙ случай, вопрос — секцией в отчёт.

13. Критерий завершённости

Работа завершена, когда: каждая строка пре-рег-таблицы имеет исход · у каждого пункта §4 есть исход (сделано · не делаю с доводом · пинг) · круги СОШЛИСЬ — последний проход критика полноты не дал НОВЫХ находок · файл скачан и ПРОЧИТАН человеком (см. §4.1 п.4 — что это значит) · деньги сведены и расхождения названы · находки размечены «замерено / прочитано / подозрение» · фризы и девиации названы · артефакты в ДЕРЕВЕ · явное «работа завершена, править не планирую». Пак доводишь до конца ТЫ. Владельца не беспокоить, меня не тегать «просто так».

Деньги — ДВА числа, и первое ИСПРАВЛЕНО

ИСПР. 16: ожидание $0.30 было занижено дважды. (а) главы 13 несут 39 % книги, а не 30 %; (б) опорный замер 08.09 снят на стенде с книжным потолком терминологии $0.07, тогда как у c1 он $2.00 — в 28 раз выше. ⇒ ожидание $0.350.50, хвост до $0.65.

ИСПР. 17 — САМОЕ ДОРОГОЕ: «грант обязан покрывать холд, иначе допуск откажет» — НЕВЕРНО. При нехватке баланса холд САМ ужимается ровно на книжный бонд и прогон допускается с bondFunded = false (platform/internal/pricing/pricing.go:198-224: if base+bookOnce <= balance { … } return base, false; пин зоны — баланс $1.00, книга 5 глав, бонд $2.00 → covers_all, AffordableChapters = 5, BondFunded = false). Отказ достижим только при балансе ниже ≈$0.26. Следствие: грант $2.00 даёт стартующий прогон, чей --ceiling-usd не несёт бонда, и терминологическая консолидация с классификатором ловят отказ резерва — «потолок, слишком малый для них, стоит КАЧЕСТВА, а не прогресса». Пре-рег измерит пайплайн без фазы майнинга и не узнает об этом. ⇒ грант ≥ 1.25×expected + step_max + 2.00. $2.5 безопасно, $2.3 впритык, $2.0 — ТИХАЯ ДЕГРАДАЦИЯ. Пин пре-рега: term_consistency_funded: true в ответе ручки, иначе СТОП ДО оплаты.

Стоп-правила — каждое остановка и пинг, а не решение сессии:

  • фактическая трата дошла до $1.00 (порог поднят с $0.80: один оборванный ответ его сорвал бы);
  • paused_reason НЕПУСТО — любое из четырёх значений;
  • срез не совпал с пре-регом — стоп ДО оплаты;
  • term_consistency_funded: false — стоп ДО оплаты;
  • бинарь не из фриза — стоп до устранения.

Отчёт

docs/experiments/24-<имя>.md (пре-рег + результаты) + eval/<каталог>/ + секция «Полигон» в docs/PROGRESS.md + сообщение мне: таблица «узел → ожидание → факт → чем предъявлено» · деньги с названными расхождениями · список сломанного с разметкой уверенности · что сказал критик полноты по КАЖДОЙ фазе · секция §10 · что ты сам считаешь слабым местом прогона. Последний абзац отчёта — план или обещание? Значит работа не кончена: сделай сейчас.