402 lines
47 KiB
Markdown
402 lines
47 KiB
Markdown
# Промт: полигон-пак «ХОЛОДНЫЙ ПРОГОН A — от двери до ФАЙЛА, настоящая книга, настоящие деньги»
|
||
|
||
> ⚠ **Редакция 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` юнита. Каденция — раз в 30–40 минут, доклад
|
||
«жив» — мне, одной строкой с двумя числами.
|
||
|
||
⚠ **Какие полигонные нормы здесь действуют, а какие нет — ИСПРАВЛЕНО.** «Пороги различимости» и «запрет
|
||
судьи-родственника» не работают: судейской линзы и сравнения рук в паке нет. **Но «арм без фактора» и «декой»
|
||
работают, и я был неправ, объявив их неприменимыми** — см. §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`/`tmmutate` — **34**
|
||
(вне `$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_usd` ≈ `spend.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 — ГЛАВЫ 1–3 ТОЛЩЕ СРЕДНЕЙ.** Замер по БД прошлого прогона того же исходника: глава 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 было занижено дважды.** (а) главы 1–3 несут 39 % книги, а не 30 %; (б) опорный
|
||
замер 08.09 снят на стенде с книжным потолком терминологии **$0.07**, тогда как у `c1` он **$2.00** — в 28 раз
|
||
выше. ⇒ **ожидание $0.35–0.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 · **что ты сам считаешь слабым местом прогона**.
|
||
⛔ Последний абзац отчёта — план или обещание? Значит работа не кончена: сделай сейчас.
|