diff --git a/docs/BACKEND_CONSISTENCY_YOU_CAN_SHOW_SESSION_PROMPT.md b/docs/BACKEND_CONSISTENCY_YOU_CAN_SHOW_SESSION_PROMPT.md new file mode 100644 index 00000000..55639739 --- /dev/null +++ b/docs/BACKEND_CONSISTENCY_YOU_CAN_SHOW_SESSION_PROMPT.md @@ -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` промахом значило бы инвертировать контракт. ⛔ И ноль без знаменателя +прочитался бы как сокрытие восемнадцати — поэтому знаменатель стоит в таблице. + +⛔ **ИСПР. по опровергателю: «разница 84−66» и «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` к нему не относится, и у него 4–5 склонённых форм; `转` уже стоит с +`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 · **что ты сам считаешь слабым местом**. +⛔ Последний абзац отчёта — план или обещание? Значит работа не кончена: сделай сейчас.