# Бэкенд-пак: КУПЛЕНО — ЗНАЧИТ ДОСТАВЛЕНО. Юнит, который не доделается НИКОГДА > Выдан оркестратором №23 (сессия `textmachine-11`) 11.09. Пак **$0** — платных вызовов в нём нет. > Предмет решён владельцем 05.09 (`D39.204`); ты строишь решённое, а не выбираешь между вариантами. ## 1. Какая проблема и что решит твой результат Читатель заплатил за главу. Движок купил первую попытку, получил флагуемый результат, пошёл за второй — и **вторую ему не продали**: потолок книги или дня не вмещает резерв регенерации. ⚠ **И тут точность несущая, первая редакция промта её теряла:** `maxTokensForAttempt` удваивает **только ВЫХОДНОЙ** бюджет, а резерв считается оценкой по цене, промпту, потолку и буферу размышления (`backend/internal/pipeline/stagerun.go`, греп `EstimateUSD`) — промпт и аддитивный буфер НЕ удваиваются. Значит «попытка 1 стоит ×2» — неправда, и окно, в котором отказ неизбежен на ≥1 и невозможен на 0, считается по РЕАЛЬНОЙ оценке. Дальше происходит вот что, и это проверяется одной строкой: **`backend/internal/pipeline/stagerun.go:204`=`infra failure; the cancelled-position mark`** — ЛЮБАЯ ошибка попытки уходит наверх из цикла, **РАНЬШЕ `UpsertChunkStatus`**. **Следствия два, и оба стоят денег читателя:** 1. **Юнит не доделается НИКОГДА.** Чекпойнт попытки 0 есть (реплей за $0), строки `chunk_status` НЕТ ⇒ читающие модели видят юнит как `pending`, экспорт не отдаёт ничего. Каждый резюм реплеит попытку 0 за $0 и умирает на попытке 1. **Прогон уходит `exit 4` при ПОЛНОСТЬЮ доставленных купленных юнитах.** 2. **Волну нельзя продолжить без ДЫРЫ в непрерывном префиксе** — то есть за это платят и соседние юниты, которые в бюджет влезали (разброс резервов внутри волны замерен ×2.976). **Решение владельца (`D39.204`, и оно НЕ обсуждается):** отказ резервации на РЕТРАЕ **деградирует во ФЛАГ**, причина которого ОТЛИЧНА от исчерпания регенераций; текст попытки 0 оплачен и **отгружается**; волна идёт дальше. ⛔ Вариант «минимальная покупка ≥ `step_max_usd`» **СНЯТ** владельцем — он стоил бы покупателю входного порога в пять глав. Не реализуй его и не предлагай. ⚠ **И канон здесь сильнее, чем кажется:** `D2` п.2 уже ТРЕБУЕТ тегировать `flag_reason`. Значит новая причина — не добавка к контракту, а его ИСПОЛНЕНИЕ. (Ссылка «смена `D2.3`», гулявшая по бэклогу, **неверна дважды**: `D2` и так кончается флагом, а `D2.3` — про детектор вырождения перед удвоением.) ## 2. Зона записи и git - Зона — **`backend/`**, и только она. `platform/` не трогать: её половина едет ОТДЕЛЬНЫМ промтом, но **ОДНИМ АКТОМ с твоим** (см. §4.3). - **Ты не коммитишь.** Готовое дерево передаёшь мне, я лендлю. `git add -A` запрещён каноном. - Свою секцию итогов пиши в `docs/PROGRESS.md` — это единственное исключение из «`docs/` — зона оркестратора». Чужие незакоммиченные файлы в дереве не трогай. ## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам 1. `CLAUDE.md` — целиком. 2. **Тело `D39.204`** в `docs/architecture/05-decisions-log.md` (решение владельца) и **`D2` п.2** — он в закрытой эре, тело в `docs/archive/architecture/05-decisions-D1-D38.md`, греп `^## D2\.`. ⚠ Подномер собственного тела не имеет: `D2.3` — это ПУНКТ 3 тела `D2`. 3. **Ряд 291** в `docs/BACKLOG.md` — там весь разбор, включая **опровергнутую посылку прошлого оркестратора**: «ретрай оставляет ФЛАГОВАННЫЙ юнит» — ЛОЖЬ, зона опровергла по строкам. Не наступи второй раз. 4. `backend/internal/pipeline/stagerun.go` (цикл попыток и `runAttempt`), `escalation.go` (`errReserveCeiling` и кто на нём УЖЕ деградирует), `disposition.go` (словарь `FlagReason`). 5. `docs/architecture/12-go-style-notes.md` — нормативы стиля, только больные места. Код-факты добывай сам; `file:line` выше — отправные точки. **Код первичен.** ## 4. Состав ### 4.1 ⛔ КОНСТРУКЦИЯ ПЕРЕ-РЕШЕНА ВЛАДЕЛЬЦЕМ 11.09 — читай это ПЕРЕД кодом **Слово владельца дословно:** «Надо о таком просто сообщать в виде метаданты, которая сейчас и пишется предупреждением, и иметь возможность поднять просто потолок и возобновить прогон, так как **это ситуация всё же СТАНДАРТНАЯ СО СТОПОМ, просто он произошёл по какой-то другой причине**». ⛔ **Это отменяет обе половины прежнего заказа — и моего, и `D39.204` п.4.** Ни «деградировать во флаг», ни «волна идёт дальше» больше НЕ строится. Прежний план заводил новый исход; новый — **возвращает ситуацию в УЖЕ ПОСТРОЕННЫЙ штатный путь остановки**, из которого она сегодня выпадает. **Что это значит механически (моё чтение; спорь, если код скажет иначе):** 1. **Прогон ОСТАНАВЛИВАЕТСЯ, как при любом отказе по потолку.** Не продолжается с флагом. ⭐ И это заодно снимает то, чем ряд 291 пугал: «продолжить волну нельзя без ДЫРЫ в непрерывном префиксе» — при остановке дыры не возникает вовсе. 2. **Отказ ретраю публикует ту же метадату, что и любая остановка по потолку** — кадр `Ceiling{Halted, Scope, ShortfallMicroUSD}` (`backend/internal/runevents/runevents.go`, греп `ShortfallMicroUSD`). ⭐ **Он уже несёт ровно то, что владелец просит:** «пополни хотя бы на столько, и тот же вызов будет допущен» — и это **ратифицировано им же, `D39.203`**. Строить новый носитель не надо. ⚠ **И твоя находка №2 этим РАЗРЕШАЕТСЯ, а не отменяется:** ты была права, что `ceilingReached` идемпотентен по прогонному флагу и съел бы событие настоящей остановки — но теперь съедать НЕЧЕГО: эта остановка И ЕСТЬ настоящая. Публикуй через штатный путь. 3. ⛔ **НАСТОЯЩИЙ ДЕФЕКТ — УЖЕ, чем я написал, и он назван в самом дереве.** Механизм «отметить остановленную позицию» построен ИМЕННО против невидимых дыр: `backend/internal/pipeline/stagerun.go:142`=`THE MARK FOR A STOPPED POSITION IS ATTACHED TO EVERY EXIT`, и его комментарий приводит замер прежнего инцидента — «прогон, остановленный на эскалационном хопе, рассчитал деньги и не оставил строки вовсе: `committed=0.001176`, `chunk_status_rows=0`». **Но метка — no-op для всего, что не «доставленный вызов, который остановил человек»** (`recordCancelledStage`). Отказ по потолку под это не подпадает ⇒ юнит остаётся без строки. **Вот дыра, и вот что ты закрываешь.** 4. **Поднял потолок → резюм ДОДЕЛЫВАЕТ юнит.** Значит строка, которую ты пишешь, обязана быть НЕ-ТЕРМИНАЛЬНОЙ для резюма — по образцу `FlagCancelled`, единственной причины, у которой `resolvedForResume` ложен (`backend/internal/pipeline/cutcall.go:293`=`FlagReason(cs.FlagReason) != FlagCancelled`), и ложен именно потому, что это «оплачено, но не сделано». Твой случай той же природы. **Делай РОВНО так:** остановка штатная · метадата через уже построенный кадр с недостачей · **юнит получает строку, а не пустоту** · строка НЕ терминальна для резюма · после пополнения резюм доделывает. **Решаешь сам и аргументируешь:** как назвать причину в строке юнита (или взять существующую) · где ставится метка · как отличить «остановлено на ретрае» от «остановлено на попытке 0» в носителе, и надо ли отличать. ⛔ **Попытку 0 не трогать:** её отказ и сегодня останавливает книгу штатно — ратифицировано. ⛔ **КТО ПЛАТИТ — НЕ ПРЕДМЕТ ЭТОГО ПАКА.** Слово владельца 11.09: «пока платит за всё ЮЗЕР, потом будем решать эту проблему». Механизм «платит продукт» не строить; существующее биллинговое поведение не трогать ни в какую сторону, даже где оно выглядит непоследовательным. ⚠ И отдельной строкой отчёта НАЗОВИ (не чини): объёмный леджер сегодня считает флагованный юнит НЕ доставленным, то есть грант за него не съеден — это расходится со словом владельца и существует ДО твоего пака. Он объявил вопрос отложенным. ⚠ **Отгрузка обрезанного текста не строится** — `D2` запрещает отгружать загрязнённое, и это не зависит от того, кто платит. ### 4.2 Пин, ради которого пак существует **«ОСТАНОВКА, КОТОРАЯ ЛЕЧИТСЯ ПОПОЛНЕНИЕМ».** Три утверждения, и они про разное: 1. **Юнит, на ретрае которого отказал потолок, ПОЛУЧАЕТ СТРОКУ.** Сегодня её нет — это и есть невидимая дыра. Пин обязан печатать величину, доказывающую, что деньги были потрачены, а строка появилась: пустой `chunk_status` рядом с ненулевым `committed` — ровно тот замер, которым дерево описывает прошлый инцидент. 2. **Остановка несёт НЕДОСТАЧУ.** `ShortfallMicroUSD` ненулевой и таков, что пополнение на него допускает тот же вызов. ⚠ Пин на «событие вообще есть» вырожден — утверждай ЧИСЛО. 3. **Пополнил потолок → резюм ДОДЕЛАЛ юнит.** Два прогона в одном тесте: без пополнения резюм не делает свежих платных вызовов и не уходит в бесконечный цикл; после пополнения — доделывает и отдаёт текст. ⛔ Это и есть главный пин пака: сегодня второй прогон умирает вечно. ⚠ **Про коды выхода.** Прежняя редакция промта требовала `exit 2` вместо `exit 4`. **Снято:** при штатной остановке код остаётся тем, каким он и был для остановки по потолку. Предмет пака — не смена кода выхода, а то, что за ним стоит: **строка вместо пустоты и лечимость пополнением.** ⚠ **Два гейта поймают тебя сами — назову, чтобы не терять круг:** `TestEveryFlagReasonIsRanked` потребует завести новую причину в `flagSeverity` (`backend/internal/pipeline/status.go`), если ты её заводишь, а `TestEveryOperatorMessageIsCatalogued` — внести новое сообщение в `backend/internal/pipeline/testdata/operator-messages.txt` (сегодня в каталоге 134 строки, из них о потолке уже говорят четыре — посмотри их прежде, чем писать пятую). ### 4.3 ⛔ ДЕФЕКТ, КОТОРЫЙ ТВОЙ ПАК НАКОРМИТ — и он НЕ латентный. Чинить ЗДЕСЬ Нашла исполняющая сессия, посылку я пере-проверил и **она у неё неверна в СТОРОНУ МЯГКОСТИ**. `backend/internal/pipeline/quality.go` (греп `draftEchoRecovered`) считает эхо ВОССТАНОВЛЕННЫМ по одному признаку — `FirstFlagReason == cjk_artifact`, — **не спрашивая, флагована ли строка сейчас и чем**. Денежный отказ эхо-рероллу даст ровно эту картину: первый флаг — эхо, итоговый — денежный, реролла не было, а отчёт скажет «восстановлено». ⛔ **Сессия назвала это латентным «потому что ключ 0». Ключ НЕ ноль:** `regenerate_echo_before_escalate: 1` стоит **во всех ЧЕТЫРЁХ боевых конфигах** (`backend/configs/pipeline-c1.yaml`, `-c2`, `-arm-glm`, `-arm-mistral` — сверено мною по каждому). ⇒ дефект оживает **в день лендинга твоего пака**, а не когда-то потом. **Чини его в этом паке и пинь** — «диспозиция в отчёте» здесь недостаточна. ### 4.4 Платформенная половина — **твоё дело назвать, не построить** Карта заметок платформы **РУКОПИСНАЯ** (`platform/internal/ingest/notes.go`) и уезжает независимо от словаря движка. Цена несделанного **замерена**: `PD-246` — минор 0.10.0 сутки жил ЛОЖНЫМ на проводе, причина доезжала читателю как `unspecified`, и поймала это зона своей пере-проверкой ПОСЛЕ слов оркестратора «приёмка закончена». ⇒ **отдельным пунктом отчёта** назови мне: точное значение новой причины на проводе · что платформа обязана записать прогону, который кончился флагом вместо `exit 4` · какой её пин это стережёт. Я передам это платформенной сессии, и **акт будет один на две половины**. ⚠ **И следствие, которое стоит назвать сразу, потому что оно про деньги читателя:** объёмный леджер считает флагованный юнит НЕ доставленным (`backend/internal/pipeline/volume_test.go`, греп `TestAFlaggedUnitIsNotReportedAsDelivered`). Значит грант за него не съеден, а книга честно короче — это хорошая новость, но она обязана быть СКАЗАНА в отчёте, иначе следующая смена откроет её заново. ### 4.5 Приложение — ДВА пина, краснеющих по УДАЧЕ (ряд 379, ОБЕ половины) Отдельная от §4.1 работа; делай её ПОСЛЕ основной. ⛔ **И мой диагноз здесь был НЕВЕРЕН — опровергнут замером, а не мнением. Читай, чем именно, иначе повторишь мою ошибку.** **Половина (б).** Запись каталога `CUTCALL-a-refusal-pays-when-the-reply-outruns-the-write` стережёт самую дорогую половину денежного бита `delivered()` (`backend/internal/llm/attemptcut.go:189`=`answered && t.firstByte.Load()`): провайдер ОТКАЗЫВАЕТ и рвёт коннект, пока наше тело ещё пишется — байт ответа есть, статуса в руках нет, и чтение «байт = доставка» оплачивает сметой каждый отказ (замер прежнего пака: 22 отказа из 25, один на $0.80). **Два независимых замера на посадке (снятие `answered &&`), и они расходятся:** мой — **7 красных из 8** (снят на нагруженной машине, рядом шла батарея); опровергателя на спокойной — **8 из 8**, а на сорока процессах **39 FAIL / 1 PASS**. ⇒ пин краснеет по УДАЧЕ, это подтверждено обоими; частота зависит от нагрузки, и поэтому «восемь красных подряд» **не является критерием приёмки**: сегодня, без единой правки, восьмёрка выпадает примерно в 82 случаях из 100. ⛔ **А вот ПРИЧИНА не та, что я написал.** Я заказывал «сделать приход байта ответа НЕИЗБЕЖНЫМ до обрыва». Зонд опровергателя (40 итераций, печать того, что реально получил клиент) дал **39 × обрыв с отказом записи и 1 × ПОЛНЫЙ `401`**, и ни разу — «ни куска, ни статуса». То есть байт приходит практически всегда, а мутант выживает в ДРУГОМ случае: клиент успевает вычитать `401` ЦЕЛИКОМ, `Do` возвращает не ошибку записи, а ОТВЕТ, и `delivered()` не спрашивают вовсе — ошибка уходит статусной веткой. **Моё лекарство било по половине, которая и так держится, и увеличивало вероятность ровно того исхода, в котором мутант выживает.** (И «~6 МБ тела» тоже неверно: 11.0 МБ — Go не эскейпит кириллицу в JSON.) **Задача — делай РОВНО так в части ЧТО, способ твой:** 1. **Тест утверждает СВОЮ ПОСЫЛКУ и печатает её:** что `Do` вернул ошибку ЗАПИСИ и что трасса видела первый байт. **Сценарий не состоялся ⇒ тест КРАСНЫЙ**, а не зелёный «мимо предмета». Сегодня он зелен и на полном `401`, то есть на другом предмете. 2. **Прямой табличный пин на сам `delivered()`** — он убивает посадку `answered &&` детерминированно, без гонки вообще. 3. ⚠ У фикстуры `MaxAttempts: 3` — до трёх бросков кости на один `Complete`; **границу утверждай ПО ПОПЫТКЕ**, а не по итогу вызова. **Половина (а) — её первая редакция промта не заказывала вовсе.** Тот же ряд 379 несёт вторую половину: две строки таблицы девяти в `backend/internal/pipeline/cutcall_test.go:402`=`time.Sleep(50 * time.Millisecond)` разводятся ОКНОМ СТЕННЫХ ЧАСОВ, и по какую сторону границы заголовков сел `cancel()`, не утверждается ничем — замер приёмки дал **2 красных из 8**. **Ряд закрывается ТОЛЬКО вместе с этой половиной.** ⛔ **Критерий приёмки берётся из самого ряда 379, он сильнее моего:** «каждый из двух пинов **ПЕЧАТАЕТ величину, доказывающую пройденную границу, и ПАДАЕТ, когда сценарий не состоялся»**. ## 5. Где этот пак мягкий — четыре места, назвал я, веер и глубину выбираешь ты Мандат самопроверки — **исполнением**; субагенты разрешены явно. Адверсариальный проход по СВОЕЙ ГОТОВОЙ работе обязателен. 1. ⛔ **Пин, утверждающий только молчание, вакуумен ровно там, где сообщение ложно.** «Ошибка не вышла наверх» — утверждение о молчании. Фикстура обязана быть такой, где новая причина ОБЯЗАНА прозвучать, и тест утверждает её ИМЯ. 2. ⛔ **Фикстура обязана сделать отказ резервации НЕИЗБЕЖНЫМ на попытке ≥1 и НЕВОЗМОЖНЫМ на попытке 0** — и окно считается по РЕАЛЬНОЙ оценке резерва, а не по «×2» (см. §1). Денежный пин, флейковый на мутанте, измеряет пустой сценарий: у нас уже был пин, дававший 2 красных из 8, потому что деньги были ВЕРОЯТНЫ, а не неизбежны. Гоняй свой не один раз. 3. ⛔ **Посадка обязана бить в тот же слой, что стережёт пин.** За прошлый пак мутация трижды оказалась не про то: недостижимое условие в фикстуре · не собирающаяся посадка (НЕизмеренная — хуже выжившей) · код против гейта над данными. 4. ⛔ **Новая причина — факт ПРОВОДА, а не словаря.** Тест, проверяющий только, что константа добавлена в `FlagReason`, не доказывает, что читатель её увидит. Скажи, чем предъявлена дорога от флага до отчёта/экспорта. ⚠ И общее, стоившее трёх смен подряд: **зелёная батарея плюс полный мутационный каталог сходимостью НЕ являются.** В последних трёх паках направленный второй читатель находил 6, 7 и 9 дефектов при полной зелени. ### ⭐ Адверсариальная стойка — способ смотреть, не правило пака - ⛔ **Автор и ревьюер — разные роли, даже когда это один ты.** Перечтение своей работы рубежом не считается: поднимай читателя, которому НАЗВАНО, где мягко. - ⛔ **Спрашивай у аномалии, о ЧЁМ она — о предмете или о твоём приборе.** - ⛔ **Верный результат при неверном методе не краснеет нигде.** «Сошлось» — не доказательство. - ⛔ **Утверждение о молчании вакуумно** без фикстуры, где оно ОБЯЗАНО прозвучать. - ⛔ **Заимствованное число проверяется не на существование, а на ТУ ЛИ КЛЕТКУ:** та же роль, та же модель, та же стадия, тот же режим? - ⭐ **Главный вопрос отчёта — не «что не получилось», а «что ты знаешь и не сказала».** ### ⭐ Находки ВНЕ заказа — отдельный заказ владельца Слово владельца 11.09: **находить проблемы даже там, где мы не ждём.** Задавай себе в каждой фазе вопрос, у которого нет заранее известного ответа: **что здесь стоит дороже, работает хуже или ведёт себя страннее, чем должно бы, — и о чём никто не спрашивал?** Ради чего он заведён: удорожание из-за падающих запросов на НАШИХ настройках никто не искал — просто кто-то посмотрел в леджер без гипотезы и увидел 25.4 % цены книги в выброшенных попытках, при зелёных тестах и молчащих гейтах. **Докладывай отдельной секцией: криты · мажоры · регрессии · баги · жёсткие точки улучшения** — каждое аргументированно, с носителем (`file:line`, число, команда) и с ценой в деньгах, тексте или доверии читателя. ⚠ Секция обязана быть непустой ИЛИ нести строку «искал вот так, не нашёл» с перечислением мест: «находок нет» и «не смотрел» в отчёте выглядят одинаково. ## 6. Предметные оси ревью Выбери 1–3 и назови какие. Мой приор: **деньги под гонкой** · **терминальное состояние прогона** (что видит платформа и что видит человек) · **обратная совместимость словаря причин**. ## 7. Записка-план ДО работы Перед первой правкой — записка: что меняешь, чем предъявишь, где ждёшь сопротивления. Комплектность против заказа сверяй механически. ## 8. Заявление = команда Каждое число и каждая категорика отчёта — **с командой, которой получены**. Дифф `^func Test` — **исполнением, не памятью**. Приёмка пере-снимает. ⛔ **И три нормы кодового пака, каждая ловит свой класс:** - **перед отчётом сверь КАЖДЫЙ клейм с результатом инструмента ЭТОЙ сессии** — не с памятью о прогоне; - **последний абзац отчёта оказался планом или обещанием? Сделай его СЕЙЧАС** — обещание в отчёте не переживает смены; - **в длинной сессии — интервальная самоверификация субагентом против ЯВНЫХ критериев** (`D39.121`), а не в конце: проверка, отложенная до сдачи, проверяет уставшую работу уставшим взглядом. ## 9. Эхо-протокол старта **Порядок двух первых действий:** сперва впиши свой блок в `/tmp/textmachine-channel` (§12), потом отправь эхо — эхо без блока некуда адресовать. **Эхо** — ≤10 строк СВОИМИ словами: что понял · что считаешь опасным · что считаешь неверным. Не пересказ: дословный пересказ подтверждает канал, но не понимание, и ошибку промта повторяет вместе с ним. **Адрес бери из `/tmp/textmachine-channel`** — блок с `role=оркестратор`, — а не из этого промта: имя сессии не переживает рестарт окружения. Перед отправкой сверься с `ListAgents`: файл переживает смерть сессии, а `ListAgents` — нет. ## 10. Что НЕ удалось — обязательная секция отчёта И вторая её половина: **«где прибор слеп и я это знаю»** — что невидимо · почему не чинил · чем закрывается. ⭐ Норма прошлой смены: **«в коде названо, в отчёте нет — значит для следующей смены НЕ названо».** ## 11. Канал вопросов и право отказаться Конфликт промта с кодом или доками — **пинг мне, не интерпретация**. Право сказать «этого делать не надо» с аргументом у тебя есть и им пользовались: в двух случаях из трёх правы были сессии, а не я. ⛔ **Тесты и гейты под зелень не подгонять.** Правка, вызванная ЗАКАЗАННОЙ сменой поведения, — обслуживание, и протухший тест держать не нужно; но она **ОБЪЯВЛЯЕТСЯ** в отчёте: что изменилось, какой тест это описывал, куда уехала гарантия. ### ⭐ Старший коллега — Fable 5. **Разрешён ОДИН на сессию (слово владельца 11.09)** У тебя есть право поднять **одного** агента на модели **`fable`** и держать его как СОВЕТЧИКА при сомнениях — тем же способом, каким это делает оркестратор. Владелец разрешил ровно одного на сессию. **Как с ним работать, и форма здесь важнее числа:** - **Поднимаешь ОДНОГО и держишь его весь пак.** Ценность этого агента — в НАКОПЛЕННОМ контексте смены: он помнит, что ты уже решил и почему. ⛔ **Второго не поднимай** — вопросы ДОСЫЛАЮТСЯ первому (`SendMessage` по его id), а не адресуются свежему. Свежий агент вместо накопленного — потеря именно того, ради чего он заведён. - **Модель задавай ЯВНО** (`model: "fable"`), иначе она унаследуется и ты не будешь знать, что у тебя работает. - **О чём его спрашивать:** сомнение в решении · развилка, где оба пути выглядят законными · «не заказываю ли я уже построенное» · «не противоречит ли это ратифицированному» · спорная формулировка в отчёте. ⚠ **Спрашивай С КОНТЕКСТОМ и со СВОЕЙ рекомендацией** — вопрос без твоего варианта ответа даёт совет ни о чём. - ⛔ **Он советчик, а не источник истины: его ответ проверяется деревом.** У оркестратора он за смену ошибся дважды на фактах (называл платный прогон бесплатным, объявлял ряд новым предметом) — и оба раза его ВЫВОД оставался верным. Проверяй посылки, принимай выводы по существу. - **Что он дал оркестратору за эту смену** — для калибровки, чего от него ждать: поймал, что я собирался завести новый ряд бэклога под предмет, у которого ряд уже был; развернул порядок паков доводом, который я не назвал; и назвал условие, без которого два прогона стали бы несравнимы. ## 12. Прямой канал Механизм — `CLAUDE.md` §«Связь между сессиями». Впиши свой блок в `/tmp/textmachine-channel` ПЕРВЫМ действием. Нужной роли нет ⇒ канала нет, и это нормальный случай: НЕ опрашивай сессии подряд. ## 13. Критерий завершённости У каждого пункта заказа — исход (сделано · не делаю с доводом · пинг) · круги СОШЛИСЬ (последний не дал НОВЫХ находок; прежние закрыты таблицей «находка → что сделано → ЧЕМ ПРЕДЪЯВЛЕНО») · **таблица мутаций полная, выжившие названы, и КАЖДАЯ новая запись помечена `battery`** (прошлый пак этого не сделал, и его «21/21 RED» оказался разовым прогоном смены, а не гейтом проекта) · числа сняты ПОСЛЕ последней правки · всё живое в ДЕРЕВЕ, а не в письме · явное **«работа завершена, править не планирую»**. Без последнего пак считается идущим.