diff --git a/docs/BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md b/docs/BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md index 883d79f2..9c47f8f0 100644 --- a/docs/BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md +++ b/docs/BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md @@ -125,6 +125,30 @@ ⚠ И общее, стоившее трёх смен подряд: **зелёная батарея плюс полный мутационный каталог сходимостью НЕ являются.** В последних трёх паках направленный второй читатель находил 6, 7 и 9 дефектов при полной зелени. +### ⭐ Адверсариальная стойка — способ смотреть, не правило пака + +- ⛔ **Автор и ревьюер — разные роли, даже когда это один ты.** Перечтение своей работы рубежом не + считается: поднимай читателя, которому НАЗВАНО, где мягко. +- ⛔ **Спрашивай у аномалии, о ЧЁМ она — о предмете или о твоём приборе.** +- ⛔ **Верный результат при неверном методе не краснеет нигде.** «Сошлось» — не доказательство. +- ⛔ **Утверждение о молчании вакуумно** без фикстуры, где оно ОБЯЗАНО прозвучать. +- ⛔ **Заимствованное число проверяется не на существование, а на ТУ ЛИ КЛЕТКУ:** та же роль, та же модель, + та же стадия, тот же режим? +- ⭐ **Главный вопрос отчёта — не «что не получилось», а «что ты знаешь и не сказала».** + +### ⭐ Находки ВНЕ заказа — отдельный заказ владельца + +Слово владельца 11.09: **находить проблемы даже там, где мы не ждём.** Задавай себе в каждой фазе вопрос, у +которого нет заранее известного ответа: **что здесь стоит дороже, работает хуже или ведёт себя страннее, +чем должно бы, — и о чём никто не спрашивал?** Ради чего он заведён: удорожание из-за падающих запросов на +НАШИХ настройках никто не искал — просто кто-то посмотрел в леджер без гипотезы и увидел 25.4 % цены книги +в выброшенных попытках, при зелёных тестах и молчащих гейтах. + +**Докладывай отдельной секцией: криты · мажоры · регрессии · баги · жёсткие точки улучшения** — каждое +аргументированно, с носителем (`file:line`, число, команда) и с ценой в деньгах, тексте или доверии +читателя. ⚠ Секция обязана быть непустой ИЛИ нести строку «искал вот так, не нашёл» с перечислением мест: +«находок нет» и «не смотрел» в отчёте выглядят одинаково. + ## 6. Предметные оси ревью Выбери 1–3 и назови какие. Мой приор: **деньги под гонкой** · **терминальное состояние прогона** (что @@ -144,7 +168,11 @@ **Первым действием** — ≤10 строк СВОИМИ словами: что понял · что считаешь опасным · что считаешь неверным. Не пересказ: дословный пересказ подтверждает канал, но не понимание, и ошибку промта повторяет вместе с -ним. Отправь мне (`textmachine-11`) через `/tmp/textmachine-channel`. +ним. + +**Адрес бери из `/tmp/textmachine-channel`** — блок с `role=оркестратор`, — а не из этого промта: имя сессии +не переживает рестарт окружения. Перед отправкой сверься с `ListAgents`: файл переживает смерть сессии, а +`ListAgents` — нет. ## 10. Что НЕ удалось — обязательная секция отчёта diff --git a/docs/COLD_RUN_B_SESSION_PROMPT.md b/docs/COLD_RUN_B_SESSION_PROMPT.md index 8e3248d1..eda183b4 100644 --- a/docs/COLD_RUN_B_SESSION_PROMPT.md +++ b/docs/COLD_RUN_B_SESSION_PROMPT.md @@ -12,17 +12,24 @@ **Твой прогон B покупает четыре вещи, которых нет ни у кого, и каждая — не «ещё раз то же самое»:** -1. **ДВЕ миграции схемы ни разу не шли на живом прогоне** — только в тестах. `v17` (`wave_selection`: - что каждая волна ВИДЕЛА в банке — ось, которой у `retrieval_state` нет) и `v18` (`reasoning_tokens` - получили смысл: «размышление, оплаченное СВЕРХ completion», на DeepSeek это 0 по определению, и - колонка всю жизнь проекта несла ноль, выглядящий замером). Первое живое исполнение обеих — твоё. +1. **ДВЕ миграции схемы ни разу не шли на живом прогоне** — только в тестах, и база прогона A стоит на + `schema_version` **16**. `v17` — `wave_selection` (`backend/internal/store/migrate.go:484`): что каждая + волна ВИДЕЛА в банке, ось, которой у `retrieval_state` нет. `v18` — **`reasoning_in_completion`** + (`migrate.go:519`), и ⛔ **это НЕ `reasoning_tokens`**: тот лежит в базовой схеме как + `INTEGER NOT NULL DEFAULT 0` (`migrate.go:94`) и на DeepSeek равен нулю ПО ПОСТРОЕНИЮ — адаптер + намеренно оставляет его нулём и уводит присланное провайдером число в новую колонку + (`provider_openai.go`, ветка `ReasoningSubset`). Новая колонка **НУЛЛАБЕЛЬНА и трёхзначна: `NULL` — + вопрос не задан · `0` — измеренный ноль · `>0` — думанье**, и `DEFAULT 0` не поставлен намеренно, иначе + дефект вернулся бы первой же строкой. **Приёмка спрашивает ТРЁХЗНАЧНОСТЬ, а не «не ноль».** 2. **Прибор консистентности впервые даст числа С ЖИВОГО ПРОГОНА.** Сегодня все `I1`/`I2` получены ПОВТОРНЫМ чтением одной и той же сохранённой базы прогона A. Пере-скан не то же, что прогон: он не проходит через запись. 3. **Платформенный пак (идемпотентный резюм, терминальное состояние) проверяется СКВОЗЬ,** а не юнитами. -4. ⛔ **Вторая точка по денежной дыре — и она нужна по НОРМЕ, а не для красоты.** Весь довод «четверть - денег купила пустоту» стоит на ОДНОМ прогоне, а квирки §3д прямо говорят: смета DeepSeek с одиночного - вызова ошибается на порядок, сметы строятся на ПОВТОРАХ. ⇒ у числа есть знак и нет величины. +4. **Вторая точка по денежной дыре — но ЧЕСТНО о том, что она даёт.** Весь довод «четверть денег купила + пустоту» стоит на ОДНОМ прогоне. ⚠ И не обманывайся ссылкой на квирки §3д: там сказано, что парный + дизайн ловит эффект ×2.5 за **13 пар**, ×2.0 за 22, ×1.4 за 93 — **n = 2 этой нормы не выполняет и + выполнить не может**. ⇒ B покупает не величину, а **пре-регистрированный знаменатель и проверку ЗНАКА**. + Написать в отчёте «25.4 % подтверждено» по двум розыгрышам — ошибка, и я её не приму. ⛔ **И вот чего твой прогон НЕ покупает, чтобы ты не потратил на это ни цента:** он **НЕ** отвечает на вопрос «безопасно ли редактору думать меньше» (ряд 433). Это парный дизайн на повторах с армом без @@ -66,21 +73,46 @@ Дым обязан доказать: стенд поднят и порт отвечает ТВОЕМУ pid · гость заведён · деньги начислены · книга принята · прогон стартовал · кадры доехали · узел подписи ответил · резюм прошёл · **выгрузка собралась и -файл скачался**. Инструмент заглушки — ШТАТНЫЙ провайдер `kind: local`; образцы рендера $0-конфига лежат в -репо (`platform/internal/runner/bankapply_live_test.go`, греп `zeroCostPipeline`). +файл скачался**. -⛔ **Пин фазы 0, без которого дым вырожден:** после рендера **напечатай счёт платных слагов в получившемся -конфиге — ноль**, при контрольном счёте тех же слагов в `backend/configs/pipeline-c1.yaml` — **не ноль**. -Молчащий греп и чистый конфиг иначе неотличимы. +⛔ **И вот ловушка, на которой этот пункт разваливается, если о ней не сказать: `zeroCostPipeline` +(`platform/internal/runner/bankapply_live_test.go`) только ПЕРЕПИСЫВАЕТ конфиг на провайдера `kind: local` — +он никого не ОБСЛУЖИВАЕТ.** Единственный слушатель на `127.0.0.1:11434` в дереве — внутритестовая заглушка +(`platform/internal/runner/translate_resnapshot_live_test.go`, греп `net.Listen`), а на хосте локальной +модели нет вовсе. ⇒ **тебе РАЗРЕШЕНО поднять свою заглушку на 11434** (портировав ту же, или исполнив +несущий её живой тест) — и это не обход, а штатный путь. ⚠ Не сделав этого, ты упрёшься в отказ соединения +посреди дыма, и дешёвым выходом станет «дым неприменим, иду за деньгами» — ровно то, ради предотвращения +чего §4.0 существует. + +⛔ **Пин фазы 0 — ЗАГРУЗЧИК, а не текстовый скан.** Счёт платных слагов в получившемся конфиге оставь +КОНТРОЛЬНОЙ величиной (ноль против ненулевого счёта тех же слагов в `backend/configs/pipeline-c1.yaml`), но +**сам пин — движок, который этот файл ЗАГРУЗИЛ бесплатным глаголом**. Довод замерен и стоил платформенной +зоне круга приёмки: её рецепт был «проверен гардом» — сканом имён — и производил файл, который движок +отказывается грузить (`escalate_to must differ from the primary model`, `EXIT=10`). Имя в конфиге и +загружаемый конфиг — разные предметы. ### 4.1 Предусловия — **проверь КАЖДОЕ своим прибором, список от прогона A мог устареть** Известное на 11.09 (справка, не истина): локальной модели на машине НЕТ (ни `ollama`, ни слушателя на 11434) ⇒ настоящие узлы проходятся только платно · кластер Postgres поднят на `-h /tmp -p 55433 -U postgres`, -ОС-роль `ubuntu-26` в нём НЕ заведена · артефакт контраста майнинга нужен `CheckMiningContrast` и сверяется -**по sha256, а не по имени** (рядом на диске лежит фальшивый кандидат) · четыре переменные окружения решают, -существует ли путь вообще (`TM_PLATFORM_EXPORT_FORMATS` пуст по умолчанию ⇒ ручки выгрузки не монтируются, -и последней трети пути для тебя нет) · `epubcheck`/`java` на хосте нет и поставить их нельзя. +ОС-роль `ubuntu-26` в нём НЕ заведена · четыре переменные окружения решают, существует ли путь вообще +(`TM_PLATFORM_EXPORT_FORMATS` пуст по умолчанию ⇒ ручки выгрузки не монтируются, и последней трети пути для +тебя нет) · `epubcheck`/`java` на хосте нет и поставить их нельзя. + +⛔ **АРТЕФАКТ КОНТРАСТА МАЙНИНГА — и здесь я в первой редакции ПЕРЕВЕРНУЛ факт, поймал опровергатель.** +`CheckMiningContrast` делает **ТОЛЬКО `os.Stat`** (`backend/internal/config/pipeline.go:558`=`func (p *Pipeline) CheckMiningContrast`) — +никакой sha он не сверяет и **удовлетворится фальшивым кандидатом**, который лежит рядом на диске +(`~/tm-p9-work/cfg/contrast-zh.txt`, 992 байта). ⇒ **sha256 сверяешь ТЫ, руками**: рецепт и эталон — +`docs/experiments/16-bank-mining.md:183` (jieba 0.42.1 `dict.txt`, +`7197c3211ddd98962b036cdf40324d1ea2bfaa12bd028e68faa70111a88e12a8`). ⚠ И ловушка имени: в конфигах файл +зовётся `mining-contrast.zh.txt` и резолвится ОТ КАТАЛОГА `pipeline.yaml`, а источник — +`jieba_dict_general_zh.txt`. **Неверный артефакт молча меняет контур банка, то есть портит ровно те числа +консистентности, ради которых B и покупается.** + +⛔ **ПИН ДО ФРИЗА, дешёвый и обязательный: `GET /v0/capabilities` показывает НЕПУСТОЙ `export_formats`.** +Выгрузка гейтится ТРЕМЯ условиями сразу (`platform/internal/config/config.go`, греп `ExportsEnabled`), а не +одной переменной, и проба возможностей — единственный дешёвый способ узнать, что выполнены все три, ДО того +как двинутся деньги. ⛔ **Ключи провайдера.** Значение `TM_PLATFORM_ENGINE_KEYS_PATH` даю я по твоему пингу. **Нет значения ⇒ СТОП ДО фриза.** `.env` читать запрещено гардрейлом. @@ -99,6 +131,20 @@ ⚠ Штамп снимается **на КАЖДУЮ попытку**, а не один раз: резюм может сменить бинарь под тем же прогоном — сверяй по `run_attempts`, а не по тому, что лежит на PATH в конце. +⛔ **ПОРЯДОК ЖЁСТКИЙ, и он важен потому, что пре-рег обязан НАЗЫВАТЬ тот самый sha, который поедет:** +клон → записал sha и собрал бинари → написал пре-рег, НАЗЫВАЮЩИЙ этот sha → отдал мне → **я коммичу** → +ты сверил, что заландженный пре-рег называет твой sha → и только теперь первый платный вызов. + +⚠ **Что делать, если я молчу.** Канал может отсутствовать — это нормальный случай, а не авария. **Ждёшь +меня до конца своего хода, потом ОСТАНАВЛИВАЕШЬСЯ и пишешь отчёт** с готовым пре-регом и пометкой «жду +лендинга фриза и значения `TM_PLATFORM_ENGINE_KEYS_PATH`». ⛔ **Без обоих платная фаза не начинается ни при +каких обстоятельствах** — и это не формальность: пре-рег, не заландженный ДО денег, перестаёт быть +пре-регом. + +⚠ **Что фриз НЕ запрещает:** потолки правятся **БЕЗ пере-фриза** — фриз-гейт смотрит на ПОКУПАЮЩИЙ файл, а +не на кассу. Меняется ЧТО покупается или чем судится — новый фриз; меняется СКОЛЬКО тратить — объявление в +отчёте. Правка собственного драйвера после фриза — тоже новый фриз. + ### 4.3 Пре-регистрация — **главный рубеж пака, и он дороже самого прогона** ⛔ **ЗНАМЕНАТЕЛЬ ПРЕ-РЕГИСТРИРУЕТСЯ ДО ДЕНЕГ, иначе B ответит числом на другой вопрос.** B — ЕЩЁ ОДИН @@ -108,28 +154,66 @@ **Мера задана мной, делай РОВНО так** (я снял её на прогоне A своим прибором, числа ниже — твой базис сравнения): -- **единица** = `(chapter, chunk_idx, stage, role)`; -- **знаменатель** = единицы, за которые заплачено хоть раз (`sum(cost_usd) > 0`); -- **числитель** = единицы, где есть хоть одна оплаченная и НЕ принятая попытка (`ok = 0 AND cost_usd > 0`); -- **прогон A: 4 из 17 = 23.5 %**, тогда как по ВЫЗОВАМ то же событие даёт 4 из 27 = **14.8 %**. Две меры - расходятся в полтора раза — вот почему мера объявляется заранее. +- **единица** = `(chapter, chunk_idx, stage, role)`. ⚠ **Единица ОХВАТЫВАЕТ попытки и охватывает их + намеренно** — номера попытки в ключе нет. И знай асимметрию: у стадии `terminology` все строки прогона A + несут `chapter = 0`, то есть `chunk_idx` там — индекс майнинг-батча, а не чанк главы. Одно слово + «единица» покрывает два разных предмета; называй, какой именно, в каждом числе. +- **знаменатель** = единицы, за которые заплачено хоть раз (`sum(cost_usd) > 0`). ⚠ На прогоне A этот + фильтр **не отсеял НИЧЕГО** (17 единиц всего и 17 платных) — значит его поведение ни разу не проверялось, + и на B единица из одних чекпойнтов может появиться впервые. Печатай ОБА счёта. +- **ЧИСЛИТЕЛЬ ПЕРВЫЙ — выброшенная покупка:** единицы, где есть хоть одна оплаченная и НЕ принятая попытка + (`ok = 0 AND cost_usd > 0`). **Прогон A: 4 из 17 = 23.5 %**, тогда как по ВЫЗОВАМ то же событие даёт + 4 из 27 = **14.8 %**. Две меры расходятся в полтора раза — вот почему мера объявляется заранее. +- ⛔ **ЧИСЛИТЕЛЬ ВТОРОЙ, и первая редакция этого промта его СЛЕПО ПРОПУСКАЛА** (нашёл опровергатель, я + пере-снял сам): **единицы, за ПРИНЯТЫЙ результат которых заплачено больше одного раза** (`ok = 1`, + ячейка куплена дважды). На прогоне A это вся стадия терминологии, пере-купленная на резюме: + **$0.028742 = 6.9 % цены книги**, и мера «выброшенная первая попытка» этого НЕ ВИДИТ вовсе — строки + `ok = 1`. ⚠ Черновик на том же резюме приехал бесплатно (6 строк `tm_hit = 1`), терминология — нет. + **Обе доли печатаются отдельно; складывать их в одно «потеряли N %» НЕЛЬЗЯ — это разные беды.** -⚠ **Второй путь к тому же числу обязателен и считается НЕЗАВИСИМО** (без колонки `degraded`): у меня оба -пути на A дали ровно $0.106472 = 25.4 % цены книги. Сойдутся у тебя — число крепкое; разойдутся — это -находка, а не помеха. +⚠ **ДВА ПУТИ К ДЕНЕЖНОМУ ЧИСЛУ — и честно о том, чего их совпадение стоит.** Путь 1 — по колонке +`degraded`; путь 2 — по `ok = 0 AND cost_usd > 0`, колонки `degraded` не касаясь. У меня на A оба дали +ровно **$0.106472 = 25.4 %** цены книги. ⛔ **Но на A они совпадают ПО ПОСТРОЕНИЮ**, а не независимо: +`degraded` там принимает ненулевое значение ровно на тех же четырёх строках. ⇒ совпадение на B — слабая +улика, а вот РАСХОЖДЕНИЕ — сильная находка: оно означает, что классификатор и признак приёмки разъехались. +⚠ И не путай числа: **25.4 % — доля ДЕНЕГ, 23.5 % — доля ЕДИНИЦ.** Это разные величины, и подменять одну +другой в отчёте нельзя. В пре-рег идут также: **ожидаемый исход КАЖДОГО шага, написанный ДО прогона** · sha256 исходника · sha256 ФАКТИЧЕСКОГО pipeline-YAML (платформа берёт файл ЦЕЛИКОМ, пер-полевого оверрайда нет ⇒ «прогон на c1» без sha — утверждение без носителя) · список глав с `units_total` · грант, TTL выгрузки. -⛔ **Претрейн:** `蛊真人` узнаётся моделями 4 из 5 ⇒ пре-рег объявляет, что клеймов О КАЧЕСТВЕ пак не делает -вовсе. Узлы судятся механизмом (кадры, флаги, леджер), а не чтением текста. +⛔ **ПРЕТРЕЙН — И ЭТО ТЕПЕРЬ НЕ ЗАПРЕТ, А ПРОЦЕДУРА (слово владельца 11.09 отменило прежнюю редакцию).** +`蛊真人` узнаётся моделями 4 из 5. Прежняя редакция этого промта на этом основании запрещала клеймы о +качестве вовсе — **владелец отменил запрет: он хочет увидеть качество на боевой книге.** Но опасность +никуда не делась и становится СИЛЬНЕЕ, когда читатель — большая модель: она способна «увидеть» в +переводе то, что помнит из претрейна, и не заметить того, чего в переводе нет. ⇒ процедура вместо +запрета: **каждая находка о качестве обязана нести ДВЕ цитаты рядом — фрагмент ОРИГИНАЛА и фрагмент +ПЕРЕВОДА.** Находка, которая не может показать место в исходнике, — не находка, а воспоминание. ### 4.4 Платная фаза -**Реши сам и аргументируй:** какую книгу и сколько глав брать. Мой приор, опровергается замером: те же -главы 1–3 той же книги, что и в A (`books/gu-zhenren/coldrun-v16/guzhenren-ch1-10.gb18030.txt`) — тогда -числа сравнимы поединично. Возьмёшь другое — сравнение A↔B становится слабее, и это надо назвать. +**Реши сам и аргументируй:** какую книгу и сколько глав брать. ⛔ **Глав немного — слово владельца.** + +Мой приор, опровергается замером: те же главы 1–3 той же книги, что и в A. ⛔ **И вот ловушка, которая +стоила бы тебе ТРОЙНОГО бюджета, — первая редакция промта в неё попадала.** Файл +`books/gu-zhenren/coldrun-v16/guzhenren-ch1-10.gb18030.txt` — это **10 глав, 57838 байт**. Прогон A ел не +его, а **СРЕЗ в 17564 байта**, sha256 `ed870ba6065ce3eb…`, сохранённый как +`/home/ubuntu-26/tm-coldrun-a/material/guzhenren-ch1-3.gb18030.txt` (срез байт-в-байт равен первым 17564 +байтам целого файла — проверено мною обеими sha). **Интейк главами резать НЕ умеет**: загрузишь целый файл — +купишь ×3.3 текста против объявленных ≈$0.42. ⇒ **режешь файл сам и кладёшь его sha в пре-рег.** + +⛔ **ДВА ПОТОЛКА, а не один, и первая редакция называла только платформенный.** Холд платформы ≈$2.5 — и +**движковые потолки в `book.yaml`**: у прогона A стояло `book_usd: 1.25`, `day_usd: 2.50`. Прогон +остановится на ДВИЖКОВОМ потолке раньше, чем на платформенном, и «упёрся в потолок» будет про число, +которого ты не ждал. Назови в пре-реге ОБА и скажи, какой ставишь ты. + +⛔ **A↔B СРАВНИМЫ НЕ ПО КНИГЕ — И ЭТО НАДО ЗАПИСАТЬ ОГРАНИЧЕНИЕМ, А НЕ ЗАМОЛЧАТЬ.** Между фризом прогона A +(`b0f5d89`) и сегодняшней головой — **107 коммитов и 52 файла движка** (+7678/−85), включая `stagerun.go`, +`disposition.go`, `quality.go`, `httpllm.go`, `provider_openai.go`, `requestlog.go` и `models.yaml`, то есть +ровно денежный путь. **B меряет ДРУГОЙ движок.** Одинаковая книга делает сравнимыми ТЕКСТЫ, но не числа +денег. ⇒ в пре-рег: sha движка B, число коммитов между ним и A, и прямая строка «двойная оплата могла +измениться из-за наших правок, а не из-за провайдера». ⛔ **Приёмка каждого узла — по ТРЁМ независимым следам** (Postgres · диск и systemd · HTTP), не по самоотчёту движка. @@ -138,15 +222,127 @@ sha — утверждение без носителя) · список глав рост числа вызовов и трат по леджеру ДВУМЯ чтениями. **Зависшая задача от идущей по сигналу завершения неотличима, и у зависания нет цвета.** +⛔ **СЛЕДИ ЗА ЛОГАМИ И ЛОГИКОЙ ЖИВЬЁМ, а не только по итогу (слово владельца 11.09).** Прогон — это не +«запустил и жди файл»: смотри, что движок пишет, пока он это пишет. Каждое предупреждение, каждый флаг, +каждая регенерация, каждый незнакомый `finish_reason` — читаются ТОГДА, а не в разборе. Вопрос к каждому: +**согласуется ли поведение с тем, что, по твоему чтению кода, должно было произойти?** Расхождение логики и +лога — находка, даже если прогон кончился успешно. Веди это списком по ходу: «время · что увидел · чего +ожидал · что это значит». + ⛔ **Деньги: ждём ≈$0.42, кап ≈$2.5 холда.** Упёрся в потолок — **СТОП и пинг мне**, не режь молча и не проси подъёма «по проекции»: прогнозный запрос оставляет ложный след «владелец согласился на пере-оплату», которой не было. -### 4.5 Фаза 3 — $0 после прогона +### 4.5 ⭐ ВЫЧИТКА ВСЕГО ПЕРЕВОДА — отдельным опус-агентом с МИЛЛИОННЫМ контекстом -Прибор консистентности по ОТГРУЖЕННОМУ тексту (`I1`/`I2` с печатаемыми знаменателями), выгрузка, структурное -чтение EPUB (zip + `container.xml` + `nav`), и **обе новые миграции предъявлены данными**: `wave_selection` -несёт строки обеих волн, `reasoning_tokens` — то, что провайдер прислал, а не ноль. +⛔ **Это заказ владельца дословно, и это главная качественная работа пака.** + +**Делай РОВНО так в части формы:** + +1. Подними **отдельного агента на opus** (модель задавай ЯВНО) и **загрузи ему в контекст ЦЕЛИКОМ**: + **(а)** весь получившийся перевод и **(б)** весь исходный китайский текст тех же глав. + ⛔ **Контекст НЕ ЭКОНОМИТЬ** — слово владельца: «пусть не экономит контекст, ему должно на всё хватить». + Никаких выжимок, никаких «первых N абзацев», никакого пересказа вместо текста. Режешь текст — режешь + находки, и молча. +2. Его мандат — **искать МАЖОРЫ, которые жёстко критуют по тексту и его качеству**, в ПОРЯДКЕ ПРИОРИТЕТА + владельца (он назвал его сам, и порядок несущий): + 1. **КОНСИСТЕНТНОСТЬ банка памяти и терминов** — один и тот же термин/имя/титул, приехавший в разных + местах по-разному; термин, разошедшийся с банком; забытая форма. + 2. **ОТСУТСТВИЕ ВЫДУМОК** — текст, которого в оригинале НЕТ: дописанные предложения, пояснения от себя, + «додуманные» связки, исчезнувшие куски (пропуск — та же выдумка, только с другим знаком). + 3. **ХУДОЖЕСТВЕННОСТЬ И ЧИТАЕМОСТЬ** получившегося русского текста. + 4. **ОТСУТСТВИЕ TRANSLATIONESE** — кальки, порядок слов оригинала, «китайский синтаксис русскими словами». +3. ⛔ **Форма КАЖДОЙ находки — две цитаты рядом:** фрагмент ОРИГИНАЛА и фрагмент ПЕРЕВОДА, плюс глава/юнит, + плюс какой из четырёх приоритетов нарушен, плюс severity. **Находка без цитаты из исходника не + принимается** — см. абзац о претрейне выше: модель знает эту книгу и способна «вспомнить» то, чего в + нашем переводе нет. +4. **Решаешь сам и аргументируешь:** сколько таких читателей поднять и как разделить между ними работу + (один на всё · по приоритетам · по главам с перекрытием). Мой приор, опровергается доводом: **один агент + на ВЕСЬ текст сразу** — консистентность банка по построению не видна тому, кто читает главу отдельно. + Если делишь — объясни, чем компенсируешь потерю сквозного взгляда. + +⚠ **И назови ОТРИЦАТЕЛЬНЫЙ результат тоже:** «выдумок не нашёл» — это результат, но только рядом с +контрольной величиной («прочитано столько-то знаков перевода против стольких-то знаков оригинала»). + +### 4.6 ⭐ СВЕРКА ПРИБОРОВ С ВЫЧИТКОЙ — ради этого прогон и стоит своих денег + +У движка есть СВОИ приборы качества: детерминированные $0-гейты, отчёт качества, счёт расхождения форм +(`I1`/`I2`), флаги и колонка `degraded`, банк памяти и пост-проверка. **Все они утверждают что-то о тексте. +Твоя работа — спросить, совпадает ли их мнение с тем, что увидел читатель.** + +Построй таблицу 2×2 и заполни её именами находок: + +| | **читатель нашёл** | **читатель не нашёл** | +|---|---|---| +| **прибор сказал** | подтверждение | ложная тревога прибора | +| **прибор смолчал** | ⛔ **СЛЕПАЯ ПОВЕРХНОСТЬ** | согласие | + +⛔ **Интересны ДВЕ клетки, и левая нижняя — самая дорогая: это дефект, который сегодня уезжает читателю +молча.** Каждую такую назови отдельно: что именно прошло мимо, какой прибор обязан был это поймать, и +почему не поймал — нет механизма, есть но выключен, есть но смотрит не туда. + +### 4.7 КОД, КОТОРЫЙ ОТРАБОТАЛ — читать с оглядкой на получившийся текст + +**Не ревью движка вообще, а ревью ТОГО ПУТИ, который реально исполнился на этой книге.** Порядок обратный +обычному: сначала находка в тексте, потом код, который её пропустил. + +Назови: какие стадии и гейты реально бежали · какие не бежали и почему · где в коде живёт механизм, +отвечающий за каждый найденный мажор. ⚠ Пример связи, которую ждут: читатель нашёл разъехавшийся термин ⇒ +читается путь инъекции банка и пост-проверка ⇒ ответ «механизма нет» / «механизм есть, но решает по +единице, которой в продукте нет» / «механизм есть и промолчал вот здесь». + +⛔ **Кода НЕ ПРАВИТЬ** (§2). Находка = пинг мне со строками. + +### 4.8 ДЁРГАТЬ API ПЛАТФОРМЫ ПО-РАЗНОМУ — не один счастливый путь + +Слово владельца: «пусть подёргает по-разному апишку через платформу». Один проход по счастливому пути +доказывает, что дверь открывается, и ничего не говорит о том, что за ней. + +**Решаешь сам, что дёргать; мой приор — не менее шести РАЗНЫХ форм:** заказ в главах против заказа в +ЗНАКАХ (это разные ветки контракта и разные счётчики) · повтор того же запроса (идемпотентность) · резюм +посреди прогона · старт второго прогона при идущем первом · выгрузка во ВСЕХ смонтированных форматах · +узел подписи банка · отказные пути (несуществующая книга · нехватка баланса · курсор с мусором). + +⛔ **Ожидаемый исход КАЖДОГО дёрганья пишется ДО него.** Иначе это не проверка, а экскурсия: любой ответ +двери задним числом выглядит правильным. + +### 4.9 Фаза 3 — $0 после прогона. **Состав задан РОВНО так; чем именно предъявлять — решаешь сам** + +Прибор консистентности по ОТГРУЖЕННОМУ тексту существует и строить его НЕ НАДО — он живёт в +`backend/internal/pipeline/bookconsistency.go` и достаётся как `QualityReport().Consistency`; печатает его +`backend/cmd/tmctl/render.go`. Снимай `I1`/`I2` **с печатаемыми знаменателями** (число без знаменателя в +этом паке не принимается). + +Дальше: выгрузка · структурное чтение EPUB (zip + `container.xml` + `nav`; `epubcheck` на хосте нет, и это +законно) · **обе новые миграции предъявлены ДАННЫМИ**: `wave_selection` несёт строки ОБЕИХ волн (они +выбирают над РАЗНЫМИ банками — черновик над базовым с исключёнными намайненными, редактор над обогащённым), +а `reasoning_in_completion` предъявляется **ТРЁХЗНАЧНО**: сколько строк `NULL`, сколько `0`, сколько `>0`. +⛔ Не гонись за «не нулём»: `0` здесь — законный измеренный ответ, и отличать его от `NULL` — весь смысл +миграции. + +### 4.10 ⭐ НАХОДКИ ВНЕ ЗАКАЗА — и это отдельный заказ владельца, а не приятный побочный эффект + +Слово владельца 11.09: **«важно, чтоб она находила проблемы даже там, где мы не ждём»**. Поэтому здесь стоит +вопрос, у которого НЕТ заранее известного ответа, и он задаётся в КАЖДОЙ фазе, а не один раз в конце: + +> ⛔ **Что в этом прогоне стоит дороже, работает хуже или ведёт себя страннее, чем должно бы, — и о чём +> НИКТО не спрашивал?** + +⭐ **Ради чего вопрос заведён — реальный случай, и он стоил четверти цены книги.** Удорожание из-за падающих +запросов НА НАШИХ СОБСТВЕННЫХ настройках никто не заказывал искать: просто кто-то посмотрел в леджер без +гипотезы и увидел, что 25.4 % денег ушло в выброшенные первые попытки. Ни один тест не был красным, ни один +гейт не сработал, в отчёте стояла зелень. **Находка такого рода ценнее исполнения заказа**, потому что +заказанное найдут и без тебя. + +**Что докладывать (слово владельца, дословно по составу):** **криты · мажоры · регрессии · баги · жёсткие +точки улучшения.** Каждое — **АРГУМЕНТИРОВАННО**: что видел · чем предъявлено (`file:line`, строка лога, +запрос и ответ, число из леджера) · почему это именно крит/мажор, а не вкусовщина · чего это стоит в +деньгах, тексте или доверии читателя. + +⚠ **И следи за КОДОМ, а не только за выдачей.** Ты читаешь логи и результаты движка — значит у тебя в руках +единственная в проекте позиция, с которой видно и поведение, и его причину сразу. Увидел странность в +выдаче — иди в код, который её произвёл, и назови место. Увидел в коде путь, который на этой книге НЕ +исполнился, хотя должен был, — это тоже находка. ⛔ **Кода не править** (§2): находка = пинг мне со строками. ## 5. Где этот пак мягкий — четыре места, назвал я, веер выбираешь ты @@ -164,6 +360,32 @@ sha — утверждение без носителя) · список глав вопрос (номер попытки живёт в `trace_id`), любой ВЫВОД ответа — по времени, по порядку, по соседству — уже дефект метода, даже когда сходится. +### ⭐ Адверсариальная стойка — то, чем оркестратор судит чужую работу; суди ею свою + +Владелец просил передать это прямо. Ниже не правила пака, а СПОСОБ СМОТРЕТЬ, и он ловит то, чего не ловят +ни тесты, ни второй круг: + +- ⛔ **Автор и ревьюер — разные роли, даже когда это один ты.** Перечтение собственной работы рубежом НЕ + считается. Поднимай отдельного читателя, которому НАЗВАНО, где мягко, и не показывай ему свои выводы + раньше, чем он прочтёт предмет. +- ⛔ **Спрашивай у аномалии, о ЧЁМ она — о предмете или о твоём приборе.** Вмешательство в замер производит + ложные улики, похожие на находки: у прошлой смены запись «непонятный исход» оказалась здоровой, а сломан + был цикл того, кто мерил. +- ⛔ **Верный результат при неверном методе не краснеет нигде.** «Сошлось» — не доказательство: сходятся и + по счастливому порядку строк. Спрашивай «чем это НАЗВАНО в самой строке?» прежде, чем вычислять. +- ⛔ **«Не воспроизвелось» — не «недостижимо».** Верный прогон при неверной гипотезе неотличим от «дефекта + нет». Назови ЦЕПЬ звеньев от входа к следствию и проверь каждое, прежде чем писать «не воспроизводится». +- ⛔ **Утверждение о молчании вакуумно.** «Ошибки не было», «лишнего не купили», «предупреждений нет» — + проверяемо только рядом с фикстурой или контролем, где это ОБЯЗАНО было прозвучать. +- ⛔ **Заимствованное число проверяется не на существование, а на ТУ ЛИ КЛЕТКУ.** Та же роль, та же модель, + та же стадия, тот же режим? Прошлый пак чуть не включил денежный механизм по замеру из чужой роли. +- ⛔ **Зелёная батарея плюс полный каталог мутаций сходимостью НЕ являются.** Три смены подряд направленный + второй читатель находил 6, 7 и 9 настоящих дефектов при полной зелени. +- ⭐ **И главный вопрос отчёта — не «что не получилось», а «что ты знаешь и не сказала».** На прямой вопрос + сессия однажды назвала ДВЕНАДЦАТЬ слепых поверхностей своего прибора вместо одной, и две из двенадцати + не прозвучали бы без вопроса: одну она видела в собственном выводе и прошла мимо, вторую знала из своего + же комментария в коде. + ## 6. Предметные оси ревью Выбери 1–3 и назови какие: **деньги под гонкой** · **граница «холодности»** (что в прогоне перестало быть @@ -181,8 +403,11 @@ sha — утверждение без носителя) · список глав ## 9. Эхо-протокол старта **Первым действием** — ≤10 строк СВОИМИ словами: что понял · что считаешь опасным · что считаешь неверным. -Дословный пересказ подтверждает канал, но не понимание, и ошибку промта повторяет вместе с ним. Отправь -мне (`textmachine-11`) через `/tmp/textmachine-channel`. +Дословный пересказ подтверждает канал, но не понимание, и ошибку промта повторяет вместе с ним. + +**Адрес бери из `/tmp/textmachine-channel`** — блок с `role=оркестратор`, — а не из этого промта: имя сессии +не переживает рестарт окружения, и вписанное сюда имя однажды окажется мёртвым. Перед отправкой сверься с +`ListAgents`: файл переживает смерть сессии, а `ListAgents` — нет. ## 10. Что НЕ удалось — обязательная секция отчёта @@ -190,6 +415,11 @@ sha — утверждение без носителя) · список глав не чинил · чем закрывается. ⭐ Формулировка прошлой смены, идущая нормой: **«в коде названо, в отчёте нет — значит для следующей смены НЕ названо».** +**И ОТДЕЛЬНОЙ секцией — находки вне заказа (§4.10):** криты · мажоры · регрессии · баги · жёсткие точки +улучшения, каждая аргументированно и с носителем. ⚠ Эта секция обязана быть непустой ИЛИ нести строку +«искал вот так, не нашёл» с перечислением того, где искал: «находок нет» и «не смотрел» в отчёте выглядят +одинаково. + ## 11. Канал вопросов и право отказаться Конфликт промта с кодом или доками — **пинг мне, не интерпретация**. И у тебя есть право сказать «этого