diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index eb4c6596..5d29597a 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -351,10 +351,10 @@ | 432 | **СТЕНД-СТУПЕНЬ ГЕЙТА НЕ МОЖЕТ БЫТЬ ЗЕЛЁНОЙ НА ЭТОМ ХОСТЕ: одному её измерению нужны данные, которые НАМЕРЕННО не версионируются, и после вывода полигона из скоупа их некому доставить.** Замер 11.09 при приёмке: `TM_MINER_PARITY=1 go test -race ./internal/miner/` даёт FAIL с текстом «required data is missing: `eval/exp16/data/jieba_dict_general_zh.txt`» — и в МОЕЙ копии, и в НАСТОЯЩЕМ дереве. Причина названа самим репозиторием: `.gitignore:39` исключает `eval/exp16/data/` с комментарием «exp16 versioned contrast corpus (jieba 0.42.1 dict.txt, 5MB) — SHA pinned in the report, reproducible». ⇒ **это НЕ дефект пака и НЕ дефект дерева**, а дыра провизионирования: флаг `TM_MINER_PARITY=1` по замыслу превращает скип в падение («missing data FAILS instead of skipping»), и на хосте, куда корпус не доставляли, он падает по назначению. ⚠ **Вторая половина хуже первой: владельцем `eval/` был полигон, а зона выведена из скоупа (`D39.248`)** — значит доставлять корпус теперь некому, и ступень будет падать у каждого, кто исполнит рецепт. ⭐ Различать надо ДВА измерения стенда: **корпус разметки** (`books/gu-zhenren/labels`, 6 записей) — на месте, ступень идёт, и именно она защищает прибор консистентности; **контраст майнера** — отсутствует. ⇒ закрытие ряда: либо рецепт доставки корпуса с пинованным SHA в носителе стенда, либо честное объявление «измерение контраста майнера на этом развёртывании не бежит», но не молчаливое красное | бэкенд/оркестратор | **скоро** | рецепт доставки корпуса ЛИБО объявленное отсутствие измерения | приёмка пака консистентности, 11.09 | | 433 | ⛔ **ЛЕКАРСТВО ОТ ДВОЙНОЙ ОПЛАТЫ ПОСТРОЕНО И СТОИТ ВЫКЛЮЧЕННЫМ — и помогает ОДНОМУ случаю из четырёх.** Пак 11.09 закрыл НАБЛЮДАЕМОСТЬ (видно, сколько и на что) и построил ЛЕЧЕНИЕ (ступень усилия ниже при том же бюджете на классе `FlagEmpty`), но ручка `retries.lower_effort_on_empty` лендится с дефолтом `false`: **деньги продолжают течь**, и ничто в дереве этого не остановит, пока ключ не поставят в `true`. ⚠ Дефолт выбран не из робости: включение двигает форму попытки ≥1, а бамп версии политики потолка стоил бы пере-перевода **989 единиц на 24 книгах, $9.99 уже оплаченного** (дедуплицированный замер зоны). ⛔ **И охват уже — из четырёх двойных оплат прогона A лекарство достаёт ОДНУ:** `edit` ($0.071009 = 67 % потери) стоит на `off`, у которого шаг вниз есть; три черновых ($0.035463 = 33 %) уже на `low` — **дне эмитирующей шкалы, и лекарства для них в паке НЕТ**. ⇒ условие включения одно и измеримое: **эхо-контроль ИМЕННО В РЕДАКТОРСКОЙ РОЛИ на плотном CJK, парным дизайном на повторах.** ⚠ Прежняя оценка риска цитировала НЕ ТУ РОЛЬ: «1 чистый китайский выход из 16» — это `flash` как ПЕРЕВОДЧИК, а единственная стадия, которую ручка двигает, — РЕДАКТОР, и квирки прямо говорят, что его эхо-безопасность при `low` на CJK **не мерена**. Ошибку нашёл направленный читатель зоны, не я и не она. ⚠ Вторичный исход того же замера, стоящий $0 сверх прогона: **растёт ли размышление вместе с потолком на `low`** — ровно тот вопрос, который `D39.90` п.9 объявил непроверенным, и он решает, рычаг ли флор | бэкенд/владелец | **скоро** | эхо-контроль в РЕДАКТОРСКОЙ роли на CJK ⇒ ручка в `true`; плюс лечение для дна шкалы | пак «за одну единицу платим дважды», 11.09 | | 434 | ⛔ **ПРИБОР КОНСИСТЕНТНОСТИ НЕ НАХОДИТ ПЕРЕДАЧУ У 26 ТЕРМОВ ИЗ 69 И МОЛЧА СЧИТАЕТ ИХ КОНСИСТЕНТНЫМИ.** Замер оркестратора 11.09 на артефактах прогона A (`~/tm-coldrun-a/evidence/spread.json`, 69 записей; контроль печатает сам прибор: «terms rendered at all: 40, control: terms considered 69»): у **29** термов `renderings={}`, и для **26 из 29** ФИНАЛЬНАЯ форма банка РЕАЛЬНО стоит в отгруженном тексте — `三转` «третий оборот» · `三转蛊师` · `丫头片子` · `五更天` · `仙师` · `侧室` · `十大奇蛊` · `古月一族` · `唐诗宋词` · `四更时` · `宗族祠堂` · `宗祖祠堂` · `开窍` · `怀璧之罪` · `方之一脉` · `方家` · `更夫` · `梆子` · `正派` · `白家寨` · `老嬷嬷` · `话事人` · `邪魔` · `雪盐` · `魔道` · `魔道巨擘`. ⇒ **`spread=0` у них значит «передачи НЕ НАШЁЛ», а читается как «форма одна»**, и итоговая строка «TERMS SHIPPED IN MORE THAN ONE SHAPE: 0» посчитана по 40 термам, а не по 69. ⚠ Матчер ловит СЛОВО, а не форму: у `高脚吊楼` он вернул «Свайные», тогда как текст несёт «свайного дома / свайные дома / свайных домов». ⛔ Это приоритет №1 владельца и ЕДИНСТВЕННЫЙ прибор, который его меряет; сегодня он отвечает за 58 % книги, а отчитывается за 100 %. Носитель разбора — эррата 11.09-з | бэкенд | **скоро** | знаменатель печатается ВСЕГДА («нашёл у M из N»), ненайденные проверяются текстом, а не засчитываются в консистентные; матчер сверяется формой, а не словом | приёмка прогона A, пере-снято 11.09 | -| 435 | **ЭСКАЛАЦИЯ НЕ МОЖЕТ ИСПОЛНИТЬСЯ НИ НА ОДНОМ БОЕВОМ КОНФИГЕ — построена, ратифицирована и выключена данными.** `backend/configs/pipeline-c1.yaml:223`=`budget_usd: 0`, и комментарий строкой выше говорит прямо: «budget_usd=0 ⇒ эскалация НЕ исполняется (НИ chains, НИ stage.escalate_to)… **Приёмочная сессия 蛊真人 ОБЯЗАНА выставить budget_usd>0**, иначе echo-эскалация черновика (D18) не выстрелит. Дефолт 0 держит CI/Ф0 зелёными без gemini/mistral-ключей». ⇒ дефолт выбран под ЗЕЛЕНЬ CI, а не под продукт, и требует ручного оверрайда, которого не сделал ни прогон A (его §10 п.2 честно пишет «эскалация не исполнялась ни разу»), ни прогон B (решение оркестратора 11.09: НЕ трогать, чтобы сохранить байт-в-байт тождество покупающего файла A↔B — сравнимость денег дороже одного непроверенного пути). ⛔ Значит путь эскалации не исполнялся живьём ДВА прогона подряд, и его первое живое исполнение стоит отдельного дешёвого замера, а не контаминации сквозного прогона. ⚠ Класс тот же, что у ряда 433: **механизм лендится выключенным, и выключенность живёт в ДАННЫХ, где её не видит ни один гейт** ⚠ **16.09 (`D39.254` п.2):** владелец назвал фоллбек на другую модель ОЖИДАЕМЫМ механизмом банка. ⇒ `budget_usd: 0` перестал быть безобидным умолчанием: для банк-ролей это отсутствие фоллбека вовсе.| бэкенд | скоро | адресный $0.03-замер пути эскалации отдельным прогоном ЛИБО решение владельца о боевом дефолте | прогон B, пре-рег 11.09 | +| 435 | **ЭСКАЛАЦИЯ НЕ МОЖЕТ ИСПОЛНИТЬСЯ НИ НА ОДНОМ БОЕВОМ КОНФИГЕ — построена, ратифицирована и выключена данными.** `backend/configs/pipeline-c1.yaml:223`=`budget_usd: 0`, и комментарий строкой выше говорит прямо: «budget_usd=0 ⇒ эскалация НЕ исполняется (НИ chains, НИ stage.escalate_to)… **Приёмочная сессия 蛊真人 ОБЯЗАНА выставить budget_usd>0**, иначе echo-эскалация черновика (D18) не выстрелит. Дефолт 0 держит CI/Ф0 зелёными без gemini/mistral-ключей». ⇒ дефолт выбран под ЗЕЛЕНЬ CI, а не под продукт, и требует ручного оверрайда, которого не сделал ни прогон A (его §10 п.2 честно пишет «эскалация не исполнялась ни разу»), ни прогон B (решение оркестратора 11.09: НЕ трогать, чтобы сохранить байт-в-байт тождество покупающего файла A↔B — сравнимость денег дороже одного непроверенного пути). ⛔ Значит путь эскалации не исполнялся живьём ДВА прогона подряд, и его первое живое исполнение стоит отдельного дешёвого замера, а не контаминации сквозного прогона. ⚠ Класс тот же, что у ряда 433: **механизм лендится выключенным, и выключенность живёт в ДАННЫХ, где её не видит ни один гейт** ⚠ **16.09 (`D39.254` п.2):** владелец назвал фоллбек на другую модель ОЖИДАЕМЫМ механизмом банка. ⇒ `budget_usd: 0` перестал быть безобидным умолчанием. ⛔ **ИСПР. 16.09, СВЕРЕНО ДЕРЕВОМ: включение бюджета банк-ролям НЕ ПОМОЖЕТ, а заденет черновик.** У внутренних вызовов хоп нулевой НАМЕРЕННО — `backend/internal/config/internal_call.go:80`=`no escalation hop` («maybeEscalate is reached from runStage, not from the internal-call paths, and these calls degrade by leaving their work unchanged rather than by paying a second model»); сам `maybeEscalate` выходит на пустом хопе (`backend/internal/pipeline/escalation.go:125`=`st.ResolvedHop == ""`), а банк-роль зовёт попытку напрямую, мимо `runStage`. Все ТРИ боевых `escalate_to` стоят у стадии `draft` (`backend/configs/pipeline-c1.yaml:91`=`escalate_to: deepseek-v4-pro`, а также arm-glm:42 и arm-mistral:46) ⇒ `budget_usd>0` включает эхо-эскалацию ЧЕРНОВИКА (D18) и только её. **Фоллбеку банка нужны три отдельные вещи:** свой хоп во внутреннем вызове (это смена ратифицированного поведения шва, не настройка), свой бюджет либо явно названное разделение общего пула (`escalation.go:91-99` читает ОДИН пул на книгу), и вызов через петлю, а не через `runAttempt`. Нашёл советчик-фабл, проверено деревом оркестратором.| бэкенд | скоро | адресный $0.03-замер пути эскалации отдельным прогоном ЛИБО решение владельца о боевом дефолте | прогон B, пре-рег 11.09 | | 436 | ⛔ **ИМЯ ВЕРДИКТА `split` УТВЕРЖДАЕТ БОЛЬШЕ, ЧЕМ МЕРЯЕТ ЕГО ПРЕДИКАТ — и первым же живым прогоном он оболгал подписанное имя героя.** Предикат (`backend/internal/pipeline/bookconsistency.go`, греп `func (v *verdictAcc) observe`) ставит `split`, когда в главе **попаданий МЕНЬШЕ, чем срабатываний** источника, либо не найдено ни одного. Читающий отчёт видит «термин разъехался», а сказано «нашли не каждое срабатывание» — это РАЗНЫЕ утверждения. ⛔ Замер прогона B: вердикт `split` по `方源` во всех трёх главах, тогда как в отгруженном тексте **58 вхождений в четырёх падежах и НОЛЬ конкурирующих транслитераций** (пере-снято оркестратором; голые «Фан» принадлежат другим термам банка — `方正`, `方之一脉`, `方家`, `方老魔`). ⇒ **самая тревожная строка приоритета №1 оказалась артефактом**, и владельцу её понесли бы как расхождение. ⚠ Родня ряду **434** (прибор не находит передачу у 26 термов из 69): вместе они означают, что **числа консистентности прогона B базовой линией НЕ являются до починки** | бэкенд | **скоро** | вердикт зовётся тем, что утверждает («не каждое срабатывание покрыто»), либо предикат усиливается до настоящего разъезда; падеж не считается второй передачей | прогон B, акт `D39.252` п.3 | | 437 | **САМАЯ КРУПНАЯ ХУДОЖЕСТВЕННАЯ ПОТЕРЯ ПРОГОНА ИЗМЕРИМА ОДНИМ ВЫЧИТАНИЕМ, КОТОРОГО НИКТО НЕ ДЕЛАЕТ.** Замер оркестратора на прогоне B: абзацев в оригинале **233**, в отгруженном переводе **162** — сжатие **−30 %** (контроль: 9021 знак оригинала против 30 283 перевода). Движок печатает `sentences/narrative-paragraph` и знает число абзацев только В ПЕРЕВОДЕ; числа абзацев ИСХОДНИКА у него нет, поэтому порога нет и флага нет. ⚠ Для ранобэ, где абзац — единица ритма и реплики, схлопывание трёх абзацев в один меняет темп сильнее, чем любая лексическая правка, и читатель это чувствует раньше, чем термины. ⇒ дешевле всех прочих приборов качества: две величины и одно деление | бэкенд | скоро | счёт абзацев ИСХОДНИКА рядом со счётом перевода + порог, при котором сжатие флагуется | прогон B, акт `D39.252` п.5 | -| 438 | ⛔ **БАНК-РОЛИ ИДУТ МИМО ОБЕИХ ВЕТВЕЙ ЛЕЧЕНИЯ: у черновой стадии лекарство есть, у терминолога нет ни лекарства, ни счётчика.** Обе ветви живут в цикле `runStage` (`backend/internal/pipeline/stagerun.go`, греп `regenerating with less thinking` и `regenerating with a larger budget`), а `terminologist.go` (греп `return r.runAttempt`) зовёт попытку НАПРЯМУЮ. ⛔ Замер прогона B: на попытке 1 классификатор дал `asked=22 answered=4` (`length`, $0.012646) и `asked=24 answered=0` (`empty`, $0.012133) — **42 терма из 66 без машинного типа, оба провальных батча ОПЛАЧЕНЫ, регенерации не было**; у черновой стадии та же мина вылечена 5 раз из 5. ⚠ **Это СТОХАСТИКА, а не регрессия** (сказала сама зона): на резюме тот же классификатор ответил 22/22 · 19/19 · 24/24, у прогона A все три батча чисты. ⚠ И вторая половина — НАБЛЮДАЕМОСТЬ: итоговая строка печатает `classify_batches_dropped=0 unanswered=0`, и это не ложь, а ОТСУТСТВИЕ — счётчик считает батчи, выброшенные БЮДЖЕТОМ (комментарий `terminologist.go` сам предупреждает, что «unanswered читается как вердикт о ТЕРМАХ, когда он отчасти вердикт о ДЕНЬГАХ»), а счётчика доли ОТВЕТОВ нет ни одного; единственный носитель факта — WARN посреди прохода ⚠ **16.09 (`D39.254` п.2):** владелец ожидает у банк-ролей ретрай и отдельный переспрос как штатный механизм, а не как улучшение. Предмет входит в первый банк-пак вместе с N-1.| бэкенд | **скоро** | банк-роль получает ту же ветвь регенерации, что черновая стадия, ПЛЮС счётчик доли ответов в итоговой строке | прогон B, акт `D39.252` п.9 | +| 438 | ⛔ **БАНК-РОЛИ ИДУТ МИМО ОБЕИХ ВЕТВЕЙ ЛЕЧЕНИЯ: у черновой стадии лекарство есть, у терминолога нет ни лекарства, ни счётчика.** Обе ветви живут в цикле `runStage` (`backend/internal/pipeline/stagerun.go`, греп `regenerating with less thinking` и `regenerating with a larger budget`), а `terminologist.go` (греп `return r.runAttempt`) зовёт попытку НАПРЯМУЮ. ⛔ Замер прогона B: на попытке 1 классификатор дал `asked=22 answered=4` (`length`, $0.012646) и `asked=24 answered=0` (`empty`, $0.012133) — **42 терма из 66 без машинного типа, оба провальных батча ОПЛАЧЕНЫ, регенерации не было**; у черновой стадии та же мина вылечена 5 раз из 5. ⚠ **Это СТОХАСТИКА, а не регрессия** (сказала сама зона): на резюме тот же классификатор ответил 22/22 · 19/19 · 24/24, у прогона A все три батча чисты. ⚠ И вторая половина — НАБЛЮДАЕМОСТЬ: итоговая строка печатает `classify_batches_dropped=0 unanswered=0`, и это не ложь, а ОТСУТСТВИЕ — счётчик считает батчи, выброшенные БЮДЖЕТОМ (комментарий `terminologist.go` сам предупреждает, что «unanswered читается как вердикт о ТЕРМАХ, когда он отчасти вердикт о ДЕНЬГАХ»), а счётчика доли ОТВЕТОВ нет ни одного; единственный носитель факта — WARN посреди прохода ⚠ **16.09 (`D39.254` п.2):** владелец ожидает у банк-ролей ретрай и отдельный переспрос как штатный механизм, а не как улучшение. Предмет входит в первый банк-пак вместе с N-1. ⛔ **ДОБАВКА 16.09, СВЕРЕНО ДЕРЕВОМ — у петли регенерации есть денежная мина, и её надо заказать вместе с петлёй:** тождество запроса включает индекс попытки и `maxTokens` (`backend/internal/pipeline/stagerun.go:485`=`attemptRequest is the ONE definition`), а проба «уже оплачено» у банк-батча спрашивает ТОЛЬКО попытку 0 с базовым бюджетом (`backend/internal/pipeline/terminologist.go:811`=`paidAfterBurns(st, st.Model`). ⇒ попытка с другим бюджетом пробе НЕВИДИМА, и доккомментарий рядом сам называет исход: ложное «оплачено» пропускает покупку мимо ролевого суб-бюджета, «under nothing but the book ceiling». **Петля обязана расширить пробу на лестницу попыток (attempt × maxTokens), иначе кап пожизненного пула на повторы не действует.** Нашёл советчик-фабл, проверено деревом оркестратором.| бэкенд | **скоро** | банк-роль получает ту же ветвь регенерации, что черновая стадия, ПЛЮС счётчик доли ответов в итоговой строке | прогон B, акт `D39.252` п.9 | | 439 | ⛔⛔ **БАНК КНИГИ НЕДЕТЕРМИНИРОВАН ПО ПОСТРОЕНИЮ: он есть функция ЧЕРНОВИКА, а черновик — стохастический выход модели.** Замер сессии прогона B, пере-снятый оркестратором СВОИМ запросом и сошедшийся дословно: `retrieval_state.banknote_detail` двух прогонов на ОДНИХ И ТЕХ ЖЕ шести чанках, побайтно один исходник (sha среза сверена) и тождественный покупающий конфиг (sha `pipeline-c1.yaml` совпал) — предложений **A 98 · B 93 · общих 74 ⇒ ЖАККАР 0.63**. ⛔ **Расходится не только СОСТАВ, но и ГРАНУЛЯРНОСТЬ ключа:** на `ch3/1` прогон A предлагает СОСТАВНЫЕ (`丙等资质` · `族长家老` · `舅父舅母`), а B — их СОСТАВЛЯЮЩИЕ (`丙等` · `资质` · `族长` · `家老` · `舅母` · `舅父`); на `ch2/0` предложение B — строгое ПОДМНОЖЕСТВО A, беднее на восемь. Отсюда же исчезновение `舅父舅母`, которое встречается в исходнике **14 раз** и есть в банке A при отсутствии в B — частотным порогом это не объясняется. ⛔ **СЛЕДСТВИЕ СТАРШЕ РЯДА 436: консистентность мерится ПО СТРОКАМ БАНКА, а строки между прогонами разные ⇒ у `I1`/`I2` двух прогонов РАЗНЫЕ ЗНАМЕНАТЕЛИ, и они несравнимы не потому, что прибор плох, а по построению.** ⚠ И это прямо задевает цель 6 («воспроизводимый прогон — повторение без сюрпризов»): снапшот и голден стерегут ВХОД, а состав банка в них не заперт. ⚠ Границы замера названы сессией: одна книга, три главы, шесть чанков, ОДНА пара прогонов — установлен РОД расхождения (состав + гранулярность), не его обычная величина; как из предложений собирается финальный банк, не читал никто ⛔ **ПОСЫЛКА «ТОЖДЕСТВЕННЫЕ ВХОДЫ» НЕВЕРНА, снято 12.09 опровергателем и пере-проверено оркестратором.** Совпадение sha `pipeline-c1.yaml` было выдано за тождество входов: `diff -rq` двух фриз-деревьев даёт **52 расходящихся пути** (`chunkrun.go`, `stagerun.go`, `waverun.go`, `disposition.go`, `quality.go`, стеммер), и снапшоты РАЗНЫЕ (`cfd53cc0…` против `fef36e1d…`). ⚠ **Что при этом устояло и держит вывод:** `internal/miner` и `internal/terminology` между фризами **побайтно идентичны** (0 различий), langpack идентичен, `bankParseVersion` совпал, диф `models.yaml` — только комментарии. ⇒ **детерминированная половина не двигалась, двигалась ЧЕРНОВАЯ сторона — а она и производит банкноты.** ⛔ Но ДОЛЯ расхождения, приходящаяся именно на температуру, ЭТОЙ парой прогонов не измерена и измерима быть не может: нужен повтор на ОДНОМ движке, и такого прогона нет. ⚠ И метод числа назвать обязательно: 0.63 — это сумма ПОЧАНКОВЫХ пересечений (74 из 98+93−74); книго-уровневые множества дают 53 из 82 = **0.65**. Вывод переживает оба, число без метода — нет | бэкенд | **скоро** | состав банка воспроизводим при повторе прогона ЛИБО названо и ратифицировано, что банк стохастичен, и тогда числа консистентности сравниваются только ВНУТРИ прогона | прогон B, дописка 12.09 | | 440 | ⛔ **МАЙНЕР ОТСЕКАЕТ ЦЕНТРАЛЬНЫЕ ТЕРМИНЫ КНИГИ ПО ПОСТРОЕНИЮ, А НЕ ПО ПОРОГУ — и это несовпадение ДВУХ РАЗНЫХ ВОПРОСОВ.** Формулировка сессии прогона B, принята дословно: **контраст спрашивает «характерно ли слово для ЭТОГО текста на фоне китайского вообще», а продукт спрашивает «нужна ли слову ОДНА закреплённая передача на всю книгу».** Для `家族` ответ на первый — НЕТ, на второй — ДА. Замер (контроль напечатан: словарь-контраст jieba 0.42.1, **349 046 строк**): `家族` · `族` · `炼制` · `楼阁` · `先机` · `老妈子` — **ЕСТЬ в словаре-контрасте и потому НЕТ в банке ни одного из двух прогонов**, тогда как `方源` · `古月山寨` · `丫头片子` · `怀璧之罪` в словаре отсутствуют и в банк попали. ⇒ **шесть из восьми терминов, на которых читатель поймал разнобой, отсечены ПОТОМУ ЧТО ОНИ ОБЫЧНЫЕ КИТАЙСКИЕ СЛОВА.** ⛔ Цена названа текстом: `族` встречается в срезе **29 раз**, `家族` — **9**, и «род ↔ клан» есть КРУПНЕЙШАЯ находка приоритета №1 за оба прогона. ⚠ Лечится в ПОЛНОТЕ МАЙНИНГА, а не в гейте: энфорсер не молчал — ему не о чем было говорить ⛔⛔ **ПРИЧИННОСТЬ ЭТОГО РЯДА ОПРОВЕРГНУТА 12.09 ЧТЕНИЕМ КОДА — механизм НЕ контраст.** `backend/internal/miner/miner_emit.go`, функция `emissionEligible`: **первым** стоит `if !hasAnyType(c.Types, "name", "place", "title") { return false }`, **вторым** — `if c.Freq < emitMinFreq \|\| subsumed[c.Src] \|\| runeLen(c.Src) < 2`. ⇒ **`族` отсечён БЕЗУСЛОВНО как ОДНОРУННЫЙ**, к контрасту это отношения не имеет; **`家族` отсечён ТИПОМ** — у него 2 руны и freq 9 при `emitMinFreq` 5, то есть он проходит всё, на что ряд указывал, и падает на том, о чём ряд молчал. ⭐ **И настоящая находка ШИРЕ прежней: детерминированный канал по построению эмитирует ТОЛЬКО `name\|place\|title`.** Обычное существительное, несущее в книге (`家族` «род/клан», `炼制` «выплавить»), не может войти в банк этим каналом НИКОГДА — сколько бы раз оно ни встретилось. Это же объясняет, почему строк с провенансом `mined`-без-банкноты **ноль в обоих прогонах**: тип-фильтр так узок, что всё им пропущенное черновик называет и так. ⚠ Прежняя формулировка («ЕСТЬ в словаре-контрасте и ПОТОМУ НЕТ в банке») выдавала корреляцию 6 из 8 за механизм — класс назван и в `CLAUDE.md`. Нашёл опровергатель промта, пере-проверено оркестратором чтением функции | бэкенд | **скоро** | решение владельца: имеет ли право обычное существительное входить в банк детерминированным каналом, и если да — каким признаком, кроме типа | прогон B, §18.1(а) + дописка 12.09 | | 441 | **Громкий гейт: банк включён, а у цели НЕТ текстов инъекции.** Сегодня это молчание при потраченных деньгах банк-ролей: рендер закона гейтится `HasData()` (`backend/internal/membank/memory.go:746`, `:842`), в `injection.txt` 8 строк данных, все `ru`, и на любой другой цели оба банк-блока рендерятся в 0 байт (замерено `research/34`). Гейт ставится там же, где построенный образец, — до первого платного вызова | бэкенд | скоро | гейт + пин | `research/35` N-4 |