Write the consistency pack around what the engine already counts, after a refutation moved its oracle, its paths and its motive

This commit is contained in:
heaven 2026-09-11 09:19:41 +03:00
parent 75e5c041ae
commit 7fe4204fb3

View file

@ -0,0 +1,305 @@
# Промт: бэкенд-пак «КОНСИСТЕНТНОСТЬ, КОТОРУЮ МОЖНО ПРЕДЪЯВИТЬ»
## 1. Какая проблема и что решит твой результат
Приоритет №1 владельца — **консистентные термины на всю книгу**. Сегодня спросить у движка «выполнен ли он»
нельзя, и это ощущалось как «меры нет». **Мера есть, и она ЧАСТЬЮ уже на поверхности** — вот замер.
⛔ **ЖИВОЙ ПЛАТНЫЙ ПРОГОН 11.09, книга 蛊真人, 3 главы, база `retrieval_state`:**
| величина | значение |
|---|---|
| показано неподписанных строк банка (`n_unverified_shown`) | **84** |
| из них модель последовала (`n_unverified_followed`) | **66** |
| разница | **18** |
| промахов перечислено поимённо в `postcheck_detail` | **18** |
| ⛔ счётчик `n_postcheck_miss` | **0****при знаменателе 2** — подписанных термов в прогоне ровно два (`方源`, `古月山寨`), и обе их формы отгружены |
Восемнадцать расхождений **найдены и записаны в деталь поимённо**; счётчик, который называется «промахи»,
говорит **ноль**, потому что промахом считается только ПОДПИСАННЫЙ термин (`internal/membank/mempostcheck.go`,
греп `Confirmed`), а все восемнадцать — `ambiguous`. ⚠ **Это ЗАМЫСЕЛ, а не баг:** комментарий там же прямо
говорит, что считать `ambiguous` промахом значило бы инвертировать контракт. ⛔ И ноль без знаменателя
прочитался бы как сокрытие восемнадцати — поэтому знаменатель стоит в таблице.
**ИСПР. по опровергателю: «разница 8466» и «18 в детали» — ОДНО число, а не две улики.** В коде
`Shown++`/`Followed++` и `append(Unverified, …)` стоят в одном цикле над одним предметом, поэтому
`Shown Followed ≡ len(Unverified)` **по построению**. Не выдавай это за схождение двух приборов.
**И главное ИСПР.: пара 84/66 УЖЕ ПЕЧАТАЕТСЯ штатным `tmctl report`** — строка
`UNSIGNED BANK: terms=… · rows-checked=84 · model followed=66 (79%)` (`backend/cmd/tmctl/render.go:612`), со
знаменателем и процентом. **Не доезжают ИМЕНА восемнадцати, и их держит ОДНА строка:
`render.go:491``if rs.NPostcheckMiss == 0 { continue }`.** Значит заказ не «построй поверхность», а
(а) провести имена мимо этого `continue` и (б) построить то, чего действительно нет — счёт по
ОТГРУЖЕННОМУ тексту КНИГИ ЦЕЛИКОМ.
Что это значит по существу: `家老` доехал до читателя как «старейшины» без «рода», `舅父` стал «дядей», и
движок **это видел**. Ручная сверка прогона по отгруженному файлу дала более широкую картину: движок сам
называет ДВЕ популяции вопроса — `spread ≥ 2` (9 термов из 69) и `INVENTED(no draft proposed it)` (11, из
них 7 вне девятки), итого **16 из 69**; исход — **9 доехали формой банка · 6 отданы НЕ банковской · 1 отдан
двумя формами**.
**Твой результат:** после пака у нас есть **ОДИН прибор по ОТГРУЖЕННОМУ тексту**, отвечающий на два вопроса
приоритета №1 числом и главами, и **запись, по которой можно отличить «банк не доехал» от «редактор его не
послушал»**. Прибор, а не гейт: решение включать ли гейт владелец отложил, и этот пак его не трогает (§4.6).
## 2. Зона записи и git
**Зона: `backend/`.** Расхождения и итоги — своя секция «Бэкенд» в `docs/PROGRESS.md` (**заведи СВОЙ
подзаголовок и пиши только под ним**; файл общий, чужой текст не трогать). **Сессия НЕ коммитит** — дерево
передаёшь мне. Канон git — `CLAUDE.md`. `.env` не читать. Чужие зоны читать можно, править нельзя.
**`books/` — ОТДЕЛЬНЫЙ репозиторий и НЕ твоя зона:** досев данных сида туда не входит в пак (§4.5).
⚠ Что должно пережить рестарт — в РЕПОЗИТОРИЙ, а не в скретчпад.
**Правка ЗАКАЗА на лету доезжает только РЕЛЕЕМ:** я пере-передаю её отдельным сообщением, ты
эхо-подтверждаешь своими словами и выносишь отдельным пунктом отчёта.
## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам
1. `CLAUDE.md` — цели владельца и гардрейлы.
2. `docs/architecture/18-bank-ontology.md` — РАТИФИЦИРОВАНА, обязательное пре-чтение перед всем, что трогает
банк.
3. Строки бэклога **406** · **407** · **417** · **418** (`docs/BACKLOG.md`, греп `^| N |`) — предмет; и
**408** только в части, названной §4.5.
4. `docs/research/34-memory-bank-quality-audit.md`**через ревю-шапку** (статус: ФАКТУРА; из 15 находок
верификация отвергла 14, почти все за ЗАВЫШЕННЫЙ ВЕС; синтез написан после неё).
5. `docs/experiments/24-door-to-file.md` §7 и §13 — что прогон измерил и где его прибор оказался слеп.
⛔ **И ВАЖНОЕ ПРО ДАННЫЕ (испр. по опровергателю): банк ПЕРЕ-КОНСОЛИДИРОВАН между 04:39 и 04:42, и
артефакты расходятся.** `~/tm-coldrun-a/evidence/bankstop-paid/…bank-stop.txt` несёт **INVENTED 11**, а
`~/tm-coldrun-a/stand/books/bk_ROEHZBD46ALFI43E/…bank-stop.txt`**INVENTED 14** (пере-считано мной
обоими файлами). У двух термов формы РАЗНЫЕ: `凤雏` «Молодой Феникс» против «Юный Феникс», `老嬷嬷`
«старая мамка» против «старая нянька» — и отгруженный текст согласен со ВТОРЫМ. ⇒ **оракул §4.1 сверяется
с ЗАМОРОЖЕННОЙ уликой** (`evidence/bankstop-paid/` + `books/gu-zhenren/door-to-file/book.txt`), а база из
§5 — ДРУГАЯ ревизия банка. **Расхождение по `凤雏` и `老嬷嬷` — ИЗВЕСТНОЕ, не находка.** Почему банк
изменился, не установлено (`corrections.json` несёт только два `approve`).
**Ратифицированное и замеренное — в теле промта, не искать:**
- **`D39.104` — закон банка:** строка на проводе есть закон для КАЖДОЙ роли и КАЖДОЙ строки **независимо от
статуса**. ⚠ **И здесь живёт открытое противоречие, которое пак НЕ решает:** пост-проверка считает отказом
только ПОДПИСАННЫЙ термин. Вопрос «обязателен ли закон для неподписанного» стоит у владельца
(`research/34` §4 п.3). ⇒ **пак печатает обе популяции РАЗДЕЛЬНО и не выбирает сторону.**
- **`D39.247`** — акт холодного прогона: числа выше, и там же названо, что прибор полигона трижды давал
ложный «0», не видя склонённых форм.
- **Ревью-вопрос проекта** (`CLAUDE.md` §Цели п.2): «заработает ли пара, которой в репо ещё НЕТ, без правки
Go?» У каждого твоего решения обязан быть на него ответ.
- **Число называет ДЕРЕВО и ПОПУЛЯЦИЮ** · рядом с нулём ПЕЧАТАЕТСЯ контрольная величина · мутация
засчитывается по ТЕКСТУ падения.
## 4. Состав и разметка свободы
### 4.1 ПРИБОР ПО ОТГРУЖЕННОМУ ТЕКСТУ — **центральное; форму решаешь сам, два счёта ЗАДАНЫ**
Приоритет №1 — это ДВА инварианта, и мерить надо оба **по финальному тексту**, а не по черновикам:
- **I1 — одна форма на термин по всей книге.** Сколько канонических терминов отданы более чем одной формой и
в каких главах.
- **I2 — где у банка есть форма, отгружена ОНА** (закон `D39.104`). Сколько терминов отданы формой, которой в
банке нет.
**Не пиши матчинг заново — переиспользуй банковский.** У банка уже есть ключи, алиасы, стеммер и фолд
вариантов (⚠ путь испр. по опровергателю: **`internal/terminology/terminology.go:245`**, `foldVariants`; в
`internal/pipeline/` такого файла НЕТ; плюс `internal/membank/mempostcheck.go`, греп `declinedFormPresent`).
**И ещё довод за переиспользование, замеренный опровергателем:** оракул воспроизводится только
РЕГИСТРОНЕЗАВИСИМЫМ счётом — регистрозависимо «горная крепость Гуюэ» даёт 3 вместо 5. Движок это уже закрыл
(`internal/text/norm.go`, греп `NormalizeTargetForm`); свой матчер на этом споткнётся. Прибор полигона писался регуляркой «слово с заглавной» и **трижды дал ложный ноль**,
не увидев склонённых строчных форм. Это и есть довод: то, чего не хватало полигону, у движка построено.
**ЗНАМЕНАТЕЛИ ПЕЧАТАЮТСЯ, и «не найден» — категория, а не ноль:** сколько строк банка судимо · у скольких
ключ не сработал в ИСХОДНИКЕ · у скольких `dst` пуст · сколько вхождений найдено. Прибор, который не смотрит,
и прибор, который посмотрел и не нашёл, обязаны быть различимы в выводе.
**ОРАКУЛ ЗАДАН, и он обязателен:** ручная таблица прогона A (`docs/experiments/24-door-to-file.md` §7) —
**9 доехали формой банка · 6 не банковской · 1 двумя**, поимённо, с числами вхождений (`高脚吊楼` — «свайный
дом» ×4 при «дом на сваях» ×0; `开窍大典` ×9 плюс развёрнутая ×1; `古月山寨` 5 из 5). **Твой прибор обязан
воспроизвести эту таблицу на тех же данных. Расхождение В ЛЮБУЮ сторону — находка, а не подгонка.**
**Где живёт результат — реши сам, аргументируй:** отчёт сборки, строка «глава → расхождения», отдельная
команда. ⛔ **Но мерило «попасть на поверхность» для пары 84/66 УЖЕ ВЫПОЛНЕНО** (§1): не строй третью
поверхность рядом с двумя существующими. Недостающего ровно два: **имена** неподписанных промахов (сегодня
их держит `render.go:491`) и **счёт по отгруженному тексту книги целиком** — вот его действительно нет.
### 4.2 ЗАПИСЬ ВЫБОРА РЕДАКТОРСКОЙ ВОЛНЫ — **делай РОВНО так в границе, свободен внутри**
Сегодня запись инъекции существует **наполовину**, и это надо знать до первой строки кода: `runEditUnit`
делает свежий `Select` по обогащённому банку и **сливает результат на строку ЧЕРНОВИКА** лидер-чанка
(`internal/pipeline/waverun.go`, греп `mergeUnitRetrievalState`): промахи и «показано/последовано» пишутся, а
`injected_ids` / `n_exact_hits` / `n_evicted` остаются черновыми, **и вытеснения редакторской волны не
записываются НИКУДА** — это сказано в коде прямым текстом (`internal/pipeline/chunkrun.go`, греп `evict`).
Ключ таблицы — `(book_id, chapter, chunk_idx)`, **оси волны нет**, и слияние обнуляет черновой пост-чек.
**Задача: сделать выбор редакторской волны отдельно наблюдаемым.** ⛔ **Границы:**
- **PK существующей таблицы НЕ менять.****Основание испр.: оно НЕ в «опасности миграции»** — соседняя
таблица бампает схему ровно так же. Настоящий разделитель: **смена PK ПЕРЕПИСЫВАЕТ существующие строки,
новая таблица — нет.** Форма, которую я считаю правильной, — соседняя аддитивная таблица с осью волны;
видишь лучшую — аргументируй.
- ⛔ **ЦЕНА, которой я не знал: ЛЮБАЯ новая миграция бампает схему 16 → 17, после чего `OpenReadOnly`
ОТКАЗЫВАЕТ базе прогона A** (`internal/store/store.go`, греп `SchemaMismatchError`; в базе прогона
`schema_version = 16`), а на ней живут все $0-приборы пака. ⇒ **пробы и прибор гоняй на КОПИИ базы**,
оригинал `mode=ro` и не трогать; `SchemaMismatchError{Found:16, Expected:17}` после §4.2 — это ВЕРСИЯ, а не
поломка.
- **«Слить сильнее» — запрещено:** слияние уже затирает черновой пост-чек, и усиление затрёт больше.
- ⚠ Это предусловие **АТРИБУЦИИ** («не доехал» против «не послушал»), а НЕ предусловие измерения: §4.1
меряется и без него. Порядок в паке — §4.1 первым.
### 4.3 ДЕШЁВАЯ ПОЛОВИНА ВОПРОСА ПОСТ-ПРОВЕРКИ — **делай РОВНО так**
Пост-проверка спрашивает «есть ли принятая форма ГДЕ-НИБУДЬ в куске» вместо «какой формой отрендерён термин
НА МЕСТЕ срабатывания», и про конкурирующую форму рядом не спрашивает никогда (ряд **407**). Дешёвая
половина: **алиас-ключ сверяется с СОБСТВЕННОЙ канонной формой записи.** Замерено на копии: ряд `方源` с
алиасом `古月方源` пропускает выход «Гу Юэ Фан Юань» при подписанном каноне `古月 → Гуюэ`.
⛔ **Дорогая половина — детектор значения по исходнику (ряд 286) — ВНЕ пака.**
⚠ И у экземпляра ДВА корня: второй — подавление вложенного ряда равнотрастовым длиннейшим матчем
(`internal/membank/memory.go`, греп `suppressContained`), и оно МОЛЧИТ. Смена вопроса его не закрывает;
**ИСПР. — цена пункта названа замером:** в прогоне A `n_trust_gated_suppress` = **0 на всех шести
строках** (подавитель не срабатывал ни разу), алиасов в базе **0 при 69 рядах**, ряда `古月` нет вовсе. ⇒
**пример выше на данных прогона A НЕ ВОСПРОИЗВОДИТСЯ — демонстрировать придётся на синтетической фикстуре, и
это законно.** Знай до того, как потратишь час на поиск носителя.
### 4.4 ТРЕТЬЕ ОПРЕДЕЛЕНИЕ `spread` ЗАВОДИТЬ НЕЛЬЗЯ — **делай РОВНО так**
Два уже расходятся (ряд **418**): на 69 термах прогона счётчик `spread` равен длине списка форм у 68, и один
терм даёт 4 при трёх формах; плюс `other proposals` карты подписи даёт 2 там, где `drafts:` даёт 3. **Твой
счёт обязан идти тем же `foldVariants`, что и существующий**, и иметь пин равенства на данных прогона A.
**Пин вешай на ЗАМОРОЖЕННЫЙ артефакт** (`~/tm-coldrun-a/evidence/bankstop-paid/`): в живой карте подписи
ряда `古月山寨` уже НЕТ — он подписан и вышел из карты предложений.
Иначе пак добавит третье число к двум расходящимся.
### 4.5 ЛИНТ СИДА — **только Go-половина; данные НЕ трогать**
Точность глоссарного класса чекера — **0.067** (одно верное срабатывание на 14 ложных, n=258;
`books/gu-zhenren/labels/metrics.json`, ключ `k6`), и ложные сконцентрированы: `转` ×6, `蛊虫` ×4. ⛔ **ИСПР. — МОЙ МОТИВ ОПРОВЕРГНУТ ДАННЫМИ, и это надо знать до работы.** Я написал «причина в ДАННЫХ:
пустые формы и односимвольный ключ». Опровергатель просканировал все три сид-файла за размеченными прогонами:
термов с ПУСТЫМИ `decl.forms`**0**, без `decl`**0** (49 · 58 · 57 термов). `蛊虫` — ДВУХсимвольный, то
есть порог `minKeyLenHan = 2` к нему не относится, и у него 45 склонённых форм; `转` уже стоит с
`allow_short: false` и авторской пометкой «не стреляет», и прикрыт вторым рубежом. ⇒ **причина ложных
срабатываний НЕ УСТАНОВЛЕНА**, и заказ ниже — гипотеза, а не следствие.
**Досев данных — НЕ твой пак** (`books/` — другой репозиторий и другая зона).
**Твоё — правила `SeedLint`**, и они **СОВЕЩАТЕЛЬНЫЕ, а не обвиняющие**: пустые формы у
многословного/глагольного термина · односимвольный ханьский ключ без `allow_short`. Формулировка правила —
«не выстрелит → подтверди умысел», а не «ошибка». У каждого — фикстура, где оно ОБЯЗАНО сработать.
**Предупреждение:** существующая фикстура `TestSeedLintCleanPasses` несёт `方源 → Фан Юань` — двусловный
`dst` без `decl`; при наивной формулировке «многословный» она ПОКРАСНЕЕТ. Это обслуживание по заказанной
смене поведения — ОБЪЯВИ его, а не подгоняй тест.
**И раз причина не установлена — первым делом назови, ЧТО на самом деле даёт 14 ложных.** Это дешевле
любого правила: данные размечены, `fp_ids` в `metrics.json` перечисляет их поимённо. ⚠ `SeedLint` зовётся только из `tmctl seed-lint` и на путь `translate` не выходит — ужесточение
существующие книги не ломает; проверь это утверждение сам прежде, чем на него опереться.
⛔ Пере-замер точности 0.067 — работа ПОЛИГОНА после досева, не твоя.
### 4.6 ЧЕГО В ПАКЕ НЕТ**не делай**, и это объявленные сужения
- ⛔ **Флип `gates.glossary.postcheck_gate`** — владелец отложил его до замера ложных срабатываний
(`D39.205`), а 0.067 и есть их источник. Гейт не включать, значения по умолчанию не трогать.
- ⛔ **Ряд 409 целиком** (выбор черновой волны по БАЗОВОМУ банку с исключением намайненного; потеря липкости
между правочными единицами при 86 % многоединичных глав). Обе правки двигают провод/снапшот ⇒ пере-покупка
книги; инцидентов ноль наблюдений, замерена только экспозиция. **Прибор из §4.1 — именно то, чем это
мерить**, поэтому сперва прибор.
- ⛔ **Актуатор точечной перегенерации** (ряд 296).
- ⛔ **Решение «считать ли законом неподписанный термин»** — вопрос владельца, см. §3.
- ⛔ **Всё должно быть $0 и СНАПШОТ-НЕЙТРАЛЬНО** — но ⚠ **ИСПР.: «докажи байт-равенством снапшотов» было
ВЫРОЖДЕННЫМ требованием.** В полезной нагрузке снапшота банковых строк НЕТ вовсе (`internal/pipeline/snapshot.go`,
греп `snapshotPayload`) — прибор в отчёте их физически не двинет, и «доказательство» было бы пустой
процедурой. **Настоящий рычаг назван опровергателем: в снапшот входит `PostcheckGate`** — то есть флип
гейта И ЕСТЬ пере-покупка книги, и это механическое основание запрета выше, которого у меня не было.
- ⛔ **И ИСПР. про `Select`:** запрещено **МЕНЯТЬ ПОВЕДЕНИЕ** `Select` и рендереров. **Звать `Select` из
офлайн-прибора внутри `internal/membank`НОРМА**, так делают существующие пины (греп
`postcheckdenominator_test`). Прежняя формулировка «не в `Select`» читалась как «не звать», и это
отрезало единственный легальный путь: `PickedEntry` несёт неэкспортированное поле, и накормить
`Bank.Postcheck` извне пакета нечем.
## 5. Мандат самопроверки ИСПОЛНЕНИЕМ — «перечитал сам» не считается
Механизм НАЗВАН: **`make battery` целиком** (не подмножество `-run`) · **`make mutations`** с посадками на
СВОИ новые пины · **выброшенные пробы** на данных прогона A (база `~/tm-coldrun-a/stand/books/bk_ROEHZBD46ALFI43E/project.db`,
читать `mode=ro`, НЕ править). Субагентов спавнить **РАЗРЕШЕНО и требуется**, модель задавать ЯВНО.
**Интервальная самопроверка** субагентом примерно на середине против явных критериев §4.
⛔ **Где у ЭТОГО пака мягко — четыре места; адверсариальный проход веди по ним:**
1. **ПРИБОР, КОТОРЫЙ НЕ СМОТРИТ.** Три «нуля» подряд у полигона были артефактом невидения, и последний нашёл
не он. Твой прибор обязан печатать знаменатели (§4.1) и воспроизвести ОРАКУЛ; «0 расхождений» без
знаменателя — не результат, а отсутствие вопроса.
2. **ПОРЯДОК СЛОВ И ПАДЕЖИ.** Сверка идёт окном в порядке слов со стеммером: «горная крепость Гуюэ» против
«Гуюэ, горная крепость» и трёхсловные формы дадут и ложные промахи, и ложные попадания. Единственный
оракул — размеченный корпус с точностью 0.067, **и его нельзя подгонять**: печатай precision ДО и ПОСЛЕ
на ОДНИХ И ТЕХ ЖЕ метках.
3. **СЛИЯНИЕ НА СТРОКУ ЧЕРНОВИКА.** Любая «маленькая» правка слияния рискует затереть ещё что-то черновое —
оно уже затирает пост-чек. Посадка, ломающая запись редакторского выбора, обязана краснеть ТЕКСТОМ про
незаписанную инъекцию редакторской волны, а не про соседнее поле.
4. **ТРЕТЬЕ ОПРЕДЕЛЕНИЕ `spread`** (§4.4): пин равенства обязателен, иначе пак добавит число к двум
расходящимся.
Плюс общее для кодового пака: **пин на УСЛОВНОЕ сообщение обязан иметь фикстуру, где оно ОБЯЗАНО
прозвучать** · **перед отчётом сверь каждый клейм с результатом инструмента ЭТОЙ сессии** · **дифф
`^func Test` — исполнением, не памятью** · **править или удалять тест ради зелени НЕДОПУСТИМО**; правка от
ЗАКАЗАННОЙ смены поведения — обслуживание, и она ОБЪЯВЛЯЕТСЯ.
⛔ **Слово владельца, оно же отдельная ось приёмки: никаких велосипедов, воркэраундов и хаков ВОКРУГ
проблемы.** Нужно логически правильное решение задачи. Для этого пака оно звучит буквально: **не строй
второй матчер рядом с банковским** — переиспользуй построенное, а где форма не тянет, скажи это и назови
цену.
## 6. Предметные оси ревью
**Код** — тест утверждает не то, что думает: часы как способ синхронизации там, где предмет НЕ время; ассерт
по подстроке в буфере, куда пишет кто-то ещё. Обе формы дают тихо-зелёное, а оно дороже ложно-красного.
**И вторая ось, купленная сегодня:** **комментарий, описывающий ГАРАНТИЮ, обязан иметь посадку, которая эту
гарантию ломает** — иначе он документирует замысел, а не код.
**Замеры** — пере-вывод чисел из СЫРЬЯ, а не из чужой сводки; вывод на агрегате до вскрытия единиц запрещён.
**Ты вправе заменить ось с аргументом** — это право канона, и оно здесь действует.
## 7. Записка-план ДО работы
До первой строки кода пришли мне ≤15 строк: что берёшь по каждому пункту §4 · где ждёшь сопротивления · что
считаешь спорным в самом заказе. Канала нет — записка идёт первой секцией твоей части журнала.
## 8. Заявление = команда
Каждое число и каждая категорика — с командой и её выводом. Рядом с НУЛЁМ ПЕЧАТАЕТСЯ контрольная величина.
`go test ./...` без `-v` скипы не печатает: печатай счёт скипов рядом с числом `ok` и называй условие.
## 9. Эхо-протокол старта
ДО первой правки пришли **мне первым действием, по адресу из `/tmp/textmachine-channel`** (`SendMessage`,
роль `ОРКЕСТРАТОР`) ≤10 строк: скоуп · инварианты · не-делать — **СВОИМИ словами**, плюс **что считаешь в
заказе опасным и что неверным**. Дословный пересказ подтверждает канал, но не понимание.
## 10. Что НЕ удалось — обязательная секция отчёта
Что не проверено · что не воспроизвелось · где данных не хватило. **«Не измерено» вместо догадки.**
## 11. Канал вопросов и право отказаться
Конфликт промта с кодом — **пинг мне, НЕ интерпретация**. Право сказать «этого делать не надо» с аргументом
есть, и такие развилки поощряются: за смену три сессии принесли по возражению, и все три были приняты.
## 12. Прямой канал
`CLAUDE.md` §«Связь между сессиями»: `/tmp/textmachine-channel`, свой блок первым делом, живость — `ListAgents`.
Нужной роли в файле нет, файла нет или имя не отвечает ⇒ **КАНАЛА НЕТ, и это НОРМАЛЬНЫЙ случай: НЕ опрашивай
сессии подряд.** Вопрос — секцией в отчёт, работа продолжается.
## 13. Критерий завершённости
Работа завершена, когда: у каждого пункта §4 есть исход (сделано · не делаю с доводом · пинг) · **прибор
воспроизвёл ОРАКУЛ прогона A НА ЗАМОРОЖЕННОМ АРТЕФАКТЕ** (§3 п.5), и расхождения названы — ⚠ кроме двух
ИЗВЕСТНЫХ (`凤雏`, `老嬷嬷`), которые объясняются пере-консолидацией банка, а не прибором · круги самопроверки СОШЛИСЬ — последний не дал НОВЫХ
находок, прежние закрыты таблицей «находка → что сделано → чем предъявлено» · таблица мутаций полная,
выжившие названы поимённо · **снапшот-нейтральность доказана байт-равенством** · числа сняты ПОСЛЕ последней
правки · ⚠ **ряды бэклога НЕ ПЕРЕВОДИШЬ — `docs/BACKLOG.md` моя зона** (испр.: прежняя редакция противоречила
§2 этого же пака); **назови их в отчёте, перевод мой** · всё живое в ДЕРЕВЕ, а не в письме · явное **«работа
завершена, править не планирую»**.
**Сходимость не достигнута — говори это прямо, не выдавай круг за сходимость.** За эту смену два пака из
трёх закрыты БЕЗ сходимости, правилом остановки, и оба приняты: честное «не сошлось» с доводом лучше
объявленного «сошлось».
**Пак доводишь до конца ТЫ.** Владельца не беспокоить, меня не тегать «просто так».
## Деньги
**Пак — $0.** Платных вызовов нет: пост-проверка, отчёт и пробы на уже оплаченной базе прогона A. Упрёшься в
«это предъявляется только платным прогоном» — пинг за санкцией, не своё решение.
## Отчёт
Секция «Бэкенд» в `docs/PROGRESS.md` под своим подзаголовком + сообщение мне: что сделано по каждому пункту ·
чем предъявлено (команда и вывод) · **таблица прибора против ОРАКУЛА** · таблица «находка → что сделано → чем
предъявлено» · что сказал твой адверсариальный проход · секция §10 · **что ты сам считаешь слабым местом**.
⛔ Последний абзац отчёта — план или обещание? Значит работа не кончена: сделай сейчас.