textmachine/docs/BACKEND_OPERATOR_TRUTH_SESSION_PROMPT.md

316 lines
39 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Пак бэкенда: «ПРАВДА ОПЕРАТОРУ И ДЕНЬГИ» — живой остаток движка
## 1. Какая проблема и что решит твой результат
Движок сегодня **говорит оператору не то, что делает, и платит за то, что уже купил**. Оба свойства
измерены, у каждого есть носитель в трекере, и ни одно не является регрессом — это незакрытые места,
которые предыдущие паки нашли и не взяли.
- **Деньги.** Роль и классификатор оплачиваются за поверхности, которые банк УЖЕ несёт: фильтр
«поверхность уже в банке» стоит на ЭМИССИИ (`mining.go`, guard в `reverseSectionTerms`), а платный путь
терминолога проходит раньше. Итог: прогон майнинга платит за часть выброшенного. ⚠ «За всё» сказать нельзя — это верно для банкованных поверхностей, ДОШЕДШИХ до кандидатов, и их доля не измерена ни разу. Доля не измерена ни разу.
- **Правда.** Описание банкового контура лжёт оператору в четырёх местах; операторские сообщения не
запинены как класс, и расширение правила делает их текст ложным молча; путь записи статуса не читается
по коду — автор прошлого пака трижды подряд назвал не тот механизм, и каждый раз ловила мутация.
- **Шов.** Ключи `Contradictions`/`Conf` пересекают границу файла тем же способом, что уже убранная карта,
и мутация любого из трёх переживает три полных пакета.
**Что покупает твой результат.** (1) Деньги: прогон майнинга перестаёт платить за уже купленное, и
экономия названа ЧИСЛОМ, а не словом. (2) Правда: оператор, читающий предупреждение движка, понимает, что
произошло, и может это проверить. (3) Шов закрыт способом, а не заплатой. Плюс — и это заказ владельца —
работа предъявляется **живым прогоном на нескольких главах**, а не только батареей.
## 2. Зона и git
**Зона записи — `backend/`** плюс своя секция в `docs/PROGRESS.md`. Чужие зоны (`platform/`, `frontend/`,
`eval/`, `books/`) не трогаешь ни строкой; `docs/` кроме своей секции — тоже.
**Ты НЕ коммитишь**: дерево готовишь и передаёшь оркестратору (канон — `CLAUDE.md`
§«Git-координация мультисессий»). Никаких `git add -A`, `reset --hard`, переписывания истории.
В `docs/PROGRESS.md` заведи СВОЙ подзаголовок `#### Пак «правда оператору и деньги»` внутри секции
«Бэкенд» и пиши только под ним: файл коммичу я, и чужой текст уедет под моим сообщением.
⚠ Что должно пережить рестарт — в РЕПОЗИТОРИЙ, не в скретчпад. `.env` не читать никогда.
## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам
1. `docs/BACKLOG.md` — строки **333 · 334 · 335 · 336 · 337 · 338**, и отдельно **353** (что уже запинено
в соседней секции и где проведена граница). Греп: `^| 335 |`. Строка — носитель заказа; расхождение
строки с этим промтом — пинг, не интерпретация.
2. `docs/architecture/18-bank-ontology.md`**нормативная страница банковых проекций**: три правила
дисциплины проекции и два класса дефектов. Ты правишь описания и артефакты банка ⇒ читаешь её ДО работы.
⚠ Она названа здесь потому, что прошлый пак её не назвал, и это стоило приёмке отдельного разбора
(`D39.225` п.6).
3. `docs/architecture/12-go-style-notes.md` — норматив формы: «least mechanism», размер не критерий сплита,
интерфейс объявляет потребитель, комментарий режется по воде, код английский.
4. `backend/cmd/tmmutate/main.go`**шапка файла целиком**: контракт мутационного инструмента (`-root`
только на КОПИИ, выживший мутант — находка, ненулевой выход) плюс `backend/Makefile` цели `battery` и
`mutations`.
5. Отчёт прошлой смены в `docs/PROGRESS.md`, подзаголовок «Пак «гейт вместо прозы»» — **только разбор шва-близнеца**
(носитель заказа 333) — ищи греп-токеном `ШОВ-БЛИЗНЕЦ`, НЕ номером пункта: нумерация в отчёте уехала.
Файл целиком не читать.
Ратифицированное, нужное по существу, вложено сюда и похода в журнал решений НЕ требует:
- **`D39.216`** — где форма не тянет, её переписывают; «дешевле подпереть» доводом не является. Это прямое
указание по строке 333: нужен ход, а не четвёртая заплата.
- **`D39.183`** — запрет править тесты «чтобы прошло» — про МОТИВ. Правка от ЗАКАЗАННОЙ смены поведения —
обслуживание, но ОБЪЯВЛЯЕТСЯ в отчёте: что изменилось, какой тест это описывал, куда уехала гарантия.
- **`D39.208` п.5** — фикстура, где две различные величины совпали, делает весь их класс расхождений
невидимым. Мера качества твоих собственных новых фикстур.
- **`D39.104` п.1** — банк есть закон для КАЖДОЙ строки: неподписанные инъектируются наравне с
подписанными. Отсюда цена лжи в описаниях банка: оператор подписывает, читая неверное.
- **`D39.225`** — что уже построено соседним паком и переиспользуется: гейт мутаций `make mutations`
(подмножество выводится из каталога полем `battery`), паритет арм-конфигов, секция предложений в
сайдкаре банка и её пины. Не строй второй такой механизм.
## 4. Состав и разметка свободы
### 4.1 Деньги: перестать платить за то, что банк уже несёт — **состав РОВНО так, форма фильтра — реши сам**
Сегодня guard «поверхность уже в банке» живёт на ЭМИССИИ (`internal/pipeline/mining.go`, докблок
`reverseSectionTerms`: «an existing seed surface is skipped (it is already in the bank)»), а платный путь
терминолога — слияние кандидатов, KWIC, скоринг, вызов роли, вызов классификатора — проходит ДО него.
**Три шага, и первый обязателен:**
- **(а) ЗАМЕР ДО.** Доля кандидатов, которых банк уже несёт, на доступном корпусе — числом, с командой.
Без этого шага строка обещает экономию, которой никто не видел. Замер $0. ⚠ **Артефакты лежат на уровень
глубже, чем ищут:** `ls books/*/` даёт ноль, а `find books -iname '*bank-stop*' -o -iname
'*mined-signature*' -o -iname '*.bank.json'` — 37 файлов (`books/gu-zhenren/coldrun-v16/…`, `coldrun-a/…`).
Без этого «замер по артефактам» кончается выводом «артефактов нет».
- **(б) ФИЛЬТР ДО ОПЛАТЫ — и ТОЛЬКО в узкой форме, потому что широкая УБИВАЕТ §4.3 этого же пака.**
⛔ Роль спрашивают о банкованных поверхностях НАМЕРЕННО: банк читается один раз на всю роль, и её ОТВЕТ
даёт `CanonConflicts` и `ConsolidationKeyConflicts`, а те уезжают в строку листа подписи
(`mining.go:451-452``Contradicts`, `BankHolds`). Слепой фильтр «банк держит — не платим» снимет ровно
те пометки спора, которые §4.3 велит довезти до владельца.
**Пропускать до оплаты ТОЛЬКО кандидата, у которого выполнены ОБА условия:** банк держит его поверхность
approved-строкой — предикатом тем же, что у стража эмиссии (`unsignedEngineSurfaces`, `mining.go:143`), а
не новым своим; И каждое наблюдённое предложение черновика после `text.NormalizeTargetForm` равно dst
банка. Расходится хоть одно — ПЛАТИМ: это и есть спор, ради которого фаза построена.
**Диффом глоссария это НЕ доказывается:** предложение на сид-поверхность в банк не попадает и СЕГОДНЯ
(`membank/memseed.go:812` — «A proposal on a SEED surface never reaches the bank: pipeline.reverseSectionTerms
drops it at emission»). Равный глоссарий — вакуумная истина, а не улика.
**Доказательство — на фейк-провайдере, ДВУМЯ фикстурами:** (i) банкованная поверхность с СОГЛАСНЫМ
наблюдением ⇒ вызова НЕТ, таблица стопа и карта подписи равны исходным минус пропущенные строки, число
пропущенных напечатано при контрольной величине «кандидатов всего M»; (ii) банкованная с РАСХОДЯЩИМСЯ
наблюдением ⇒ вызов ЕСТЬ, `BankHolds` и `Contradicts` на месте.
**ХЕШ ЗАПРОСА БЭНК-РОЛИ ДВИНЕТСЯ, И ЭТО ВНУТРИ САНКЦИИ — но с двумя обязанностями.** Батчи пакуются
жадно по рунному бюджету, поэтому удаление хоть одного кандидата меняет состав хотя бы одного выжившего
батча, а с ним и его `RequestHash`. Снапшот книги при этом НЕ движется: `terminologyVersion`
(`terminologist.go:59`) документирован как «deliberately NOT snapshot-folded» — запрет §4.8 про
снапшот-фолженые хеши, и этот случай в него не попадает. **Обязанности:** (1) назови это в отчёте прямо,
а не умолчи; (2) ⛔ **ловушка РЕЗЮМА:** уже оплаченный чекпойнт бэнк-роли ищется по хешу
(`bankCheckpointExists`), и после смены состава батча он перестанет матчиться — резюм-прогон ПЕРЕПЛАТИТ.
Реши, как это лечится (фильтр не применяется на резюме · чекпойнт ключуется иначе · иное), назови решение
и предъяви его тестом; молча оставить нельзя — это ровно тот узел, который §4.7 велит искать.
**И второе следствие, тоже операторское:** стоп-ТАБЛИЦА рендерится по ПОЛНОМУ `cands`
(`bankStopRows`), поэтому у отфильтрованных кандидатов из неё исчезнут `dst` и классификация, которые
там сегодня есть. Скажи в отчёте, что владелец увидит на листе после твоей правки, и почему это не потеря.
- **(в) ЗАМЕР ПОСЛЕ** — сколько вызовов и сколько денег ушло из прогона; число берётся из ЛОГА самого
фильтра («пропущено N из M»), а не из второго платного стопа.
**Строгое равенство содержимого ЛОЖНО на книге, где режет бюджет,** и требовать его нельзя: роль идёт
батчами и обрывается там, где бюджет кончился (`terminologist.go:406`; живой прогон 04.09 имел
`batches_dropped=5`). Убрав банкованные из батчей, ты освобождаешь бюджет, и роль консолидирует БОЛЬШЕ —
это выигрыш, а не дефект. Мерило поэтому такое: **на ОБЩЕМ множестве кандидатов консолидация побайтово та
же; прогон ПОСЛЕ может консолидировать надмножество, и разница печатается как выигрыш бюджета.**
⚠ Форму фильтра (где именно стоит, чем ключуется, как переиспользует существующий предикат) выбираешь ты;
второго носителя правила «что банк уже несёт» заводить нельзя — сведи к тому, который уже есть.
### 4.2 Четыре описания банкового контура, лгущих оператору — **делай РОВНО так**
Поведение везде ВЕРНО; лжёт описание. Приведи описание к поведению и **запинь тексты**, иначе следующая
правка сделает их ложными опять:
1. `internal/pipeline/mining.go:654``loadAutoBank(signed []store.GlossaryEntry)`: имя параметра, дока и
текст оператору говорят «подписанная», а популяция — сид+ruby+mined ЛЮБОГО статуса. Зовётся из
`internal/pipeline/bankmaterialize.go:125`.
2. `bankmaterialize.go:132` — ремарка оператору «the signed term wins», тот же обман.
3.**СНЯТО ПЕРЕД ВЫДАЧЕЙ — утверждения не было.** Строка 334 п.3 говорила, что комментарий вызова
(`bankmaterialize.go:139`) расходится с докой `ApprovedSharedKeyCollisions`. Сверено: дока
(`membank/memseed.go:251-258`) говорит «two approved terms with DIFFERENT dst and OVERLAPPING spoiler
windows» — ровно то же, что комментарий, и реализация согласуется с обоими. Неточность унаследована
строкой и скопирована мной; носитель исправлен. **Не трать на это время.**
4. `internal/membank/mempostcheck.go:91` (`Shown`, дока `:81`, инкремент `:130`) — обещает «сколько
неподписанных строк реально показано модели», а sticky-перенос `continue`-ится раньше счёта.
⚠ Адреса сняты 08.09 на `cae3e59`; перед правкой пере-снимай командой — соседний пак двигал эти файлы.
### 4.3 Разногласие, не доезжающее до листа подписи — **форму реши сам, пин обязателен**
`internal/membank/memseed.go`: сид-строка с окном ПО УМОЛЧАНИЮ и без sense делит UNIQUE-кортеж с
banknote-предложением; пропуск по кортежу срабатывает раньше, и владелец не видит спора в артефакте, по
которому подписывает. Это САМАЯ ЧАСТАЯ форма сид-строки — не на глаз: в авторских сидах владельца ненулевых `since_ch` три из
сорока девяти (`research/33` Д8), то есть окно по умолчанию несут почти все строки, и дыра штатная, а не краевая.
Лечение — либо правило «заменённая строка движется», либо иной разрез кортежа: выбираешь ты, аргументируешь
в отчёте. ⛔ Что не обсуждается: **пин на лист подписи** — тест, который краснеет, если спор перестанет
доезжать. ⚠ Прошлый автор признал, что его же e2e обходил дыру подобранным `until_ch: 20`; фикстура,
случайно обходящая предмет, — тот самый класс `D39.208` п.5.
### 4.4 Тексты операторских сообщений как КЛАСС — **реши сам, аргументируй форму**
Носитель — `internal/pipeline/seeding.go:73`. Пины есть, но узкие: подстрока стерегла одно словосочетание,
а локализующая половина (обе строки, оба окна, firing-ключ) не закрыта ничем; расширение правила 06.09
сделало прежний текст ложным, и поймала это БАТАРЕЯ, а не пин.
**Мерило заказа:** после твоей работы правка, меняющая смысл операторского сообщения, обязана ломать ПИН, а
не всплывать где-то ещё. Сколько сообщений взять в класс и чем их пинить — твоё решение; предъяви границу:
какие сообщения покрыты и какие сознательно нет.
### 4.5 Путь записи статуса — **реши сам: один читаемый путь ЛИБО дока, называющая обоих писателей**
`internal/store/chunkstatus.go` вместе с `internal/pipeline/waverun.go`: писателей несколько —
`recordSkippedStages` (`waverun.go:786`) и флагнутая ветвь `runStageSequence` (`:505`), вторая берётся
только при ≥2 стадиях в одной волне, и какой сработает, решает раскладка волны.
**Пункт СУЖЕН перед выдачей:** прошлый пак уже назвал обоих писателей в доке пина, поэтому «написать доку»
здесь куплено. Заказ узкий: **мутацией доказать, что дока называет именно тот путь, который сработает**, и
завести запись каталога с `battery`. Разрез на один читаемый путь — по твоему суждению и с аргументом, но он
НЕ обязателен; если берёшь — он не должен двигать снапшот.
⛔ Предъявление здесь обязано быть МУТАЦИЕЙ, а не чтением: автор прошлого пака назвал не тот механизм ТРИ
раза подряд, и каждый раз его ловила посадка.
### 4.6 Шов-близнец `Contradictions`/`Conf` — **делай РОВНО так: ход, а не заплата**
Три ключа пересекают границу файла тем же способом, что уже убранная карта; мутация любого переживает
`pipeline` + `terminology` + `tmctl`. Стороны сегодня согласованы — это не регресс, а незакрытая дыра.
⭐ Цена измерена прошлым автором на себе: **три круга самопроверки ушли на починку ТОЧКИ вместо ШВА**, и
только на третьем стало видно, что чинить надо способ. Лечение соседа: убрать карту и свести выбор ключа в
ОДНО место, после чего один пин ловит все три мутации плюс «продакшн обходит сопоставитель». Сделай тот же
ход (`D39.216`), а не четвёртую заплату. Разбор — карта чтения п.5 (греп-токен `ШОВ-БЛИЗНЕЦ`; ⚠ номер пункта
в отчёте уехал, поэтому ищи токеном, а не номером).
**Пин обязателен В ЛЮБОЙ форме лечения, и он должен ловить именно расхождение ключей:** писатели кладут
`res.Conf[k]` и `res.Contradictions[cf.Src]`, а читатель берёт `confOrAbsent(tres.Conf, c.Key)` и
`tres.Contradictions[c.Src]` — то есть `Key` против `Src`. Фикстура обязана давать термин, у которого
`Key != Src` (традиционное или кана-написание); на равных ключах мутация не покраснеет.
### 4.7 Холодный прогон на нескольких главах — **разрешён владельцем, делай РОВНО так**
После реализации и всех фиксов прогони живой перевод на **нескольких главах** и последи за узлами
исполнения. Это заказ владельца, а не твоя инициатива, и он проверяет то, чего батарея проверить не может.
-**Потолок пака — $3, и он ставится МАШИНОЙ, а не обещанием.** У движка есть свой гейт: `ceilings.book_usd`
в `book.yaml` пробной книги и `--max-units N`; выставь их (`book_usd` ≤ 3.00, лучше 1.50) — отказ резервации
защёлкивает волну (`D39.206`). «Назови смету ДО прогона» остаётся, но это дополнение к гейту, а не замена.
Вывод сметы, чтобы ты не гадал: замер строки 16 на 10 главах даёт ≈ $0.054 на юнит плюс ≈ $0.05 фиксированного
⇒ «несколько глав» ≈ **$0.6**; $3 — пятикратный запас.
-**ЛОВУШКА, КОТОРУЮ ТЫ ВСТРЕТИШЬ В САМОМ КОНФИГЕ.** `configs/pipeline-c1.yaml` в комментарии к
`escalation.budget_usd` говорит: «Приёмочная сессия ОБЯЗАНА выставить budget_usd>0». **К ЭТОМУ ПАКУ ЭТО НЕ
ОТНОСИТСЯ: эскалация остаётся 0.** Она добавляет премиум-хоп и съест потолок молча.
- **Что происходит ПОСЛЕ банк-стопа — назови в отчёте, не импровизируй.** `--verify-bank` ОСТАНАВЛИВАЕТ прогон;
дальше законны ровно два пути: подпись владельца (`tmctl bank-apply`) — **не твой акт** (`D39.104`), либо
повторный запуск БЕЗ флага, то есть авто-продолжение с неподписанным банком. Подпись владельца не имитируй.
-**Между двумя запусками код не менять.** Чекпойнты черновика реплеятся по хешу за $0 только при неподвижном
снапшоте; правка между запусками превращает бесплатный реплей в повторную покупку.
- Прогон идёт ПОСЛЕ зелёной батареи и зелёного `make mutations`, не вместо них.
-**Три узла перерасхода, которые называет сам денежный путь** (`docs/architecture/15-money-path.md`) и
которые прогон съест молча, если за ними не следить: эскалационный кап хоп НЕ прицениваает (перелёт ≤1
хопа) · порог согласия на пере-оплату пропускает переоплату МОЛЧА, если она дешевле `min($0.50, 5 %)`
а ты будешь перезапускать прогон после дофиксов · книго-широкие суб-бюджеты терминолога и классификатора
откалиброваны под ИЮЛЬСКИЕ цены и уже режут оплаченную работу по протухшему числу. ⚠ Последний бьёт прямо
по твоему замеру §4.1(в): часть «экономии» может оказаться артефактом обрезки бюджета, а не фильтра —
раздели эти два эффекта числом, иначе замер не значит ничего.
- **Следи за узлами:** банк-стоп и его артефакты · экономия §4.1 на живых числах (вызовы и деньги ДО/ПОСЛЕ)
· операторские сообщения — читаются ли они человеком · запись статуса · леджер трат.
- **Найденное в прогоне рапортуешь МНЕ** — это отдельная секция отчёта, а не строка в общем списке.
- ⚠ Провайдерские ловушки перед платным вызовом — `docs/experiments/00-provider-quirks.md`; проба ведёт
себя странно — идём в вендор-доку, не гадаем.
### 4.8 Чего в паке НЕТ — **не делай**, и это ОБЪЯВЛЕННЫЕ сужения
- **Строка 339** (роли не показывают существующую форму поверхности): лечение МЕНЯЕТ ЗАПРОС к модели ⇒
деньги и снапшот ⇒ отдельное решение, не прицеп.
- **Строка 320(б)** (`internal/lang/data/injection.txt`): двигает `EmbeddedVersion` ⇒ живёт в окне
перенарезки.
- **Всё, что двигает** снапшот, хеш запроса, ключ манифеста или версию встроенных данных. Единственная
заказанная смена поведения — §4.1(б), и она обязана быть ВЫХОДНО-эквивалентной.
- **Переписывание `Runner` и дробление `internal/pipeline`** — ЗАПРЕЩЕНЫ `D39.224` §7. ⚠ **Новый детектор
границ — не запрет, а УСЛОВИЕ** той же ноты (не строится, пока не назван счёт за бамп `chunkerVersion`);
к задачам §4 он не относится, но силу пункта не путай — нота эти два класса разводит специально.
- **Секция предложений сайдкара** — запинена соседним паком, граница проведена строкой 353; не трогай.
## 5. Мандат самопроверки ИСПОЛНЕНИЕМ — «перечитал сам» не считается
1. **Каждая новая гарантия предъявляется МУТАЦИЕЙ**, и краснота читается ПО ТЕКСТУ падения: говорит ли он
про сломанное тобой. Правый вердикт по неправой причине — дыра, а не поимка.
2. **Мутации — ТОЛЬКО на копии дерева, без секретов и бинарей:**
`d=$(mktemp -d) && trap 'rm -rf "$d"' EXIT INT TERM && tar -cf - --exclude=./bin --exclude='./.env*' -C backend . | tar -xf - -C "$d"`,
затем `-root "$d"`. Рабочее дерево не правится никогда, в том числе «на секунду».
3. **Мутируй и СВОИ новые фикстуры**, не только боевой код: фикстура, которую ты только что написал и
считаешь сильной, — типовое место второго вырождения.
4. **Новые записи — в каталог** `cmd/tmmutate/mutations.json` с полем `battery`, и `Package` — пакет
ПИНА, а не пакет правки: инструмент гоняет один пакет.
5. **BASELINE НА ВХОДЕ** (снят оркестратором 08.09 на `cae3e59`): `make battery` → 19 `ok` · 0 `FAIL` ·
4 «no test files» · 4 скипа поимённо; `make mutations` → 21 запись · 0 unexpected · `anchors swept:
0 of 232`. Красное на входе — находка и пинг, а не твоя работа.
6. **Субагенты РАЗРЕШЕНЫ ЯВНО**, и владелец отдельно разрешил **воркфлоу-ревью** этого пака. Направление,
что здесь уязвимее всего: (1) выходная эквивалентность §4.1 — легче всего заявить и труднее всего
доказать; (2) невырожденность фикстур §4.3 после того, как прошлый автор обходил дыру подобранным
числом; (3) §4.5, где предъявление чтением уже трижды обмануло.
7. **Проверяемый артефакт** — таблица мутаций в отчёте: `мутация → где посажена → красный тест → ТЕКСТ
падения`, и отдельной строкой **выжившие**, если такие есть.
## 6. Оси ревью — характер «Код», плюс деньги
Тест утверждает не то, что думает (`D39.171`): часы как способ синхронизации там, где предмет не время, и
ассерт по подстроке в буфере, куда пишет кто-то ещё. Обе формы дают и ложное красное, и **тихо-зелёное** —
оно дороже: зелёное, не проверившее ничего, не перечитывает никто. Третья ось твоя: **деньги** — любое
число экономии выводится из СЫРОГО леджера, и леджер есть нижняя граница, а не оценка.
## 7. Записка-план ДО работы
До первой правки — короткая записка в отчёт: что берёшь, в каком порядке, что считаешь рискованным. После
работы — сверка комплектности против §4 МЕХАНИЧЕСКИ (таблицей), не перечитыванием.
## 8. Заявление = команда
Каждое число и категорика отчёта — с командой, которой получены. Отрицательный замер печатается ВМЕСТЕ с
контрольной величиной, доказывающей, что вопрос задан существующему предмету. Сверх этого, про код:
- **перед отчётом сверь каждый клейм с результатом инструмента ЭТОЙ сессии**, а не с памятью и не с этим
промтом: адреса §4 сняты 08.09 и могли уехать;
- **дифф `^func Test` — исполнением**, не разностью счётчиков: снимай ИМЕНАМИ;
- **последний абзац отчёта оказался планом или обещанием? сделай это СЕЙЧАС**;
- ⛔ править или удалять тест/голден/гейт, чтобы он прошёл, — НЕДОПУСТИМО; исключение — правка от
заказанной смены поведения (§4.1б), и она объявляется отдельным пунктом;
- сессия длинная — поставь себе интервальную самоверификацию субагентом против ЯВНЫХ критериев §13.
## 9. Эхо-протокол старта
ДО работы — ≤10 строк **СВОИМИ словами**: скоуп · инварианты, которые не имеешь права сломать · что НЕ
делаешь. Дословный пересказ промта подтверждает канал, но не понимание, и ошибку промта повторяет вместе с
ним. Отправь эхо оркестратору по адресу из прямого канала (§12); канала нет — эхо идёт первой секцией
отчёта, и работа продолжается.
## 10. Что НЕ удалось — обязательная секция отчёта
Что не вышло, что не проверено, где сомневаешься. Пустая секция при непустой работе — сама по себе
находка; «не проверено» и «опровергнуто» — РАЗНЫЕ исходы.
## 11. Канал вопросов и право сказать «этого делать не надо»
Конфликт промта с кодом или доками — **пинг, а не интерпретация**: промт мог устареть, и в этом проекте это
случается. Считаешь пункт ненужным — скажи с доводом; такие возражения ценнее послушного исполнения.
Решение владельца требуется, если работа упрётся в деньги сверх потолка §4.7, скоуп или продукт.
## 12. Прямой канал
Механизм — `CLAUDE.md` §«Связь между сессиями». Впиши СВОЙ блок в `/tmp/textmachine-channel` первым делом,
чужие блоки не трогай. ⚠ Адрес из файла не доказывает, что сессия жива: сверься с `ListAgents`. Нужной роли
нет или имя не отвечает ⇒ **канала нет, и это НОРМА: не опрашивай сессии подряд** — вопрос секцией в отчёт.
## 13. Критерий завершённости — по нему тебя примут
Работу доводишь до конца САМ; приёмка идёт последней и вторым кругом твоей самопроверки не служит.
Готово — это когда:
- у КАЖДОГО пункта §4 есть исход: сделано · не делаю с доводом · пинг;
- круги СОШЛИСЬ: последний проход не дал НОВЫХ находок, прежние закрыты таблицей
«находка → что сделано → ЧЕМ ПРЕДЪЯВЛЕНО»;
- таблица мутаций полная, выжившие названы;
- **экономия §4.1 названа числом ДО и ПОСЛЕ, и выходная эквивалентность предъявлена**;
- **холодный прогон исполнен, его узлы описаны, найденное вынесено отдельной секцией**;
- числа сняты ПОСЛЕ последней правки, а не вспомнены;
- всё живое — в ДЕРЕВЕ, а не в письме;
- сказано явно: **«работа завершена, править не планирую»**. Без этой фразы пак считается идущим.
## Деньги
Батарея, мутации, замеры §4.1(а) — **$0**. Единственные платные вызовы — холодный прогон §4.7, потолок
**$3**, стоимость называется ДО прогона, стоп и пинг при упоре в потолок. Никаких других платных вызовов.
## Отчёт
Секция **«Бэкенд»** в `docs/PROGRESS.md`, подзаголовок `#### Пак «правда оператору и деньги»`: исход по
каждому пункту §4 · таблица мутаций · таблица «находка → что сделано → чем предъявлено» · числа экономии ·
**отдельная секция про холодный прогон и найденное в нём** · объявленные правки тестов по `D39.183` ·
§10 «что не удалось» · вопросы оркестратору.