textmachine/docs/archive/reports/BANK_CONSILIUM_2026-09-16/r2-critique-K5.md

46 KiB
Raw Blame History

R2 · K5 — критика консилиума «Банк памяти», линза «адвокат общности»

Роль: «заработает ли пара, которой в репо ещё НЕТ, без правки Go?» Код — /home/ubuntu/tm-verify-1509 (5dbb5cb). Метод — мысленный прогон каждого механизма на ja→ru, ko→ru, en→ru, zh→en, ru→de (три рода в цели), плюс исполнение $0-проверок там, где утверждение можно проверить чтением/грепом без платных вызовов. Отметка ведущего о финале r1-facts-K1.md учтена: мои находки не опираются на p1p6 K1 (те — про механику тождества/покупок/платформы, не про межъязыковую общность); норм.go-якоря K1 (F2 #1318) совпадают с тем, что я перепроверил сам.

Сводка

A («минимум на построенном») — самый дисциплинированный по цене и по «чего НЕ решаю», честно называет, где свёртки написания сегодня зашиты в ядро и что вынос — только в окне перекроя. Проседает там же, где и B: считает существующий нормализационный субстрат уже нейтральным к языку, не проверив это чтением. Одна находка — искажённая атрибуция (research/24 про off-language дрейф ОТВЕТА модели прочитана как дефект СВЁРТКИ ключа). B («банк решает сам, в точке банка») — по этой линзе самый слабый: прямо утверждает «свёртки написания исходника — данные, не код», что неверно при чтении кода (см. B1), и строит на этом же основании довод об универсальности собственных новых механизмов. Класс 5 (голос/обращения) заявлен как часть «единственного универсального механизма» без упоминания, что для целей без ты/вы-оси он попросту инертен. C («книга во времени») — самый внимательный к П8 из трёх: единственный, кто цитирует Register is ABSTRACT и явно называет ряд 14. Проседает на менее заметном: его собственный N4 («$0 по построению») стоит на том же непроверенном допущении об идемпотентности нормализации для нового письма, а гендерный словарь (classify.go:51) он называет долгом П8, но не связывает с собственным N1. Общее для всех трёх, и это главная находка линзы: ни один проект не заметил, что весь механизм подачи банка модели (RenderGlossaryBlock/RenderEditorConstraintBlock) сегодня молча гейтится на injection.txt, где заполнен только ключ ru; для любой другой цели обе стены закона рендерятся в 0 байт — без ошибки, без WARN, без падения гейта. Деньги на майнинг/классификацию/терминологию для такой книги тратятся, а результат до модели не доезжает никогда. Ни A, ни B, ни C не называют эту цену явно (D39.104 «банк на проводе = закон» — для не-ru цели сегодня не закон, а пустая строка).

Находки — проект A

# серьёзность проект и раздел что утверждает проект (цитата) почему это неверно или опасно (грунт) что исправит
A1 серьёзное §2 П2 «Универсальность — не заплатка под язык» «В правиле нет ни одной языковой ветки: тождество — тот же ключ, по которому матчер решает, выстрелил ли термин... Пара, которой нет в репо и которой не нужна новая свёртка, работает без Go» Опора — NormalizeSourceKey. Чтением (text/norm.go:136-155): функция БЕЗУСЛОВНО прогоняет ЛЮБОЙ источник через трад→упрощ.-таблицу И katakana→hiragana сдвиг, независимо от пары; для en/ko/ru-источника это молчаливый no-op, а не пропуск ветки — ветка ЕСТЬ и исполняется всегда, просто не находит совпадений. Утверждение «нет языковой ветки» описывает НОВЫЙ код A-4, а не субстрат, на который он опирается, и субстрат языковую ветку несёт: сам файл заявляет о себе text/norm.go:8 «pure, deterministic and free of language policy: no pair data, no book canon, no configuration» — а десятью строками ниже (:47, :136-155) хранит ИМЕННО такую политику для двух конкретных языков Назвать явно: «без Go» держится потому, что чужой скрипт проходит через фолд как no-op, а не потому, что фолд пар-агностичен по конструкции; для НОВОЙ орфографической свёртки (пример A сам приводит — серб. кириллица/латиница) правка norm.go всё ещё нужна, и это расходится с доктриной lang/langpack.go «add a pair = drop a directory, no recompile, no pipeline/ edits»
A2 минор §0 «Что показали ресёрчи» «research/24:348 — ja-ключи уходят в упрощённый китайский» Чтением docs/research/24-bank-arbitration.md:344-348: «family-тест ja … поймал важнее: батч 0 вернул термы упрощённым китайским (魔術→魔术) — off-language класс на не-родной паре; парослепой экран ParseReply/OffLanguage эти строки отбил бы». Это дрейф ОТВЕТА модели (термин, который вернул терминолог/классификатор) на непривычной паре, а не свёртка src-КЛЮЧА нормализацией. «Ключи» и «термы-ответы» — разные объекты в этом же коде (глоссарий vs response). Некорректная атрибуция могла бы навести читателя (как навела меня на первом проходе) на мысль, что NormalizeSourceKey измеренно портит японский источник — чего замер не показывает В цитате указать верный предмет (дрейф ответа модели, ловится off-language экраном) либо снять клейм и, если гипотеза о свёртке ja-ключей нужна, дать ей отдельный $0-замер (сегодня такого нет ни у A, ни в дереве)
A3 серьёзное §5.6 A-5, «Данные языка источника: классы местоимений (他/她 для zh)» «Строке движка типа name ставится gender=hidden поверх ответа классификатора... Данные языка — классы местоимений, окно, ширина корзины, минимальный счёт» Мысленный прогон на ja/ko-источнике: счёт 他/她 работает для zh, потому что оба местоимения ПИШУТСЯ по-разному при одинаковом произношении (омофоны) — сигнал в письме плотный и надёжный. Японский и корейский — pro-drop языки: персонаж часто не сопровождается НИКАКИМ местоимением на протяжении глав, и тот же «счёт he/she рядом с именем» может не сработать вовсе, оставляя раскрытие пола незамеченным именно там, где он мандатно нужен (мой брифинг требует ja/ko как тестовые пары). Важно — сама ратифицированная нота, на которую опирается A-5, называет ДВА разных механизма неоднозначности, не один: «омофонное ta / pro-drop без дизамбигуации» (D5 п.1, docs/archive/architecture/05-decisions-D1-D38.md:119) — то есть pro-drop уже был назван владельцу как ОТДЕЛЬНЫЙ класс, а A сводит оба к одному счётчику местоимений и мерит его (§3, М3) только на zh-источнике (guzhenren-utf8.txt) Назвать pro-drop языки как случай, где нужен ДРУГОЙ детектор (например: плотность именных/титульных обращений и почётных суффиксов вокруг имени, а не счёт местоимений) — сегодня такого детектора нет и в плане A он не появляется; иначе рекомендация «да, после бесплатного замера точности» (вопрос 2) не покрывает ровно те пары, ради которых консилиум просил проверку
A4 блокер весь пак A-0…A-5 «Проект A меняет в этом абзаце одно слово: строки движка пересматриваются только при смене улики или при событии владельца» — то есть весь механизм действует НА ЗАКОНЕ, который «едет редактору» Чтением: RenderGlossaryBlock и RenderEditorConstraintBlock (backend/internal/membank/memory.go:746, :842) обе начинаются с if !tx.HasData() { return "" }; HasData() (backend/internal/lang/embedded.go:406) — t.GlossaryHeader != ""; injection.txt несёт РОВНО один целевой ключ ru (грепом по файлу — 8 строк, все ru\t...). Сегодня в дереве нет НИ ОДНОГО langpack с целью, отличной от ru (backend/configs/langpacks/ — только ru, zh, zh-ru). Значит для ЛЮБОЙ пары, которую A-1…A-5 должны бы обслуживать без правки Go (это и есть заявленная цель проекта), обе стены закона рендерятся в 0 байт МОЛЧА — ни ошибки, ни WARN, ни гейта; деньги на майнинг/классификацию/терминолог при этом уже потрачены. Ни A-0…A-5, ни §6 (трейдоффы), ни §8 (замеры) этого не называют Явный гейт (WARN или отказ прогона) на «bank enabled AND !InjectionTextsFor(target).HasData()», плюс перенос ряда 14 и заполнение injection.txt для минимум одной проверочной не-ru цели ДО того, как A-1…A-5 признаются «работающими без правки Go»

Находки — проект B

# серьёзность проект и раздел что утверждает проект (цитата) почему это неверно или опасно (грунт) что исправит
B1 серьёзное §2 П8 «Общность» «Свёртки написания исходника — данные, не код (internal/text/norm.go:47)» Неверно как общее утверждение. norm.go:47 — это ТОЛЬКО эмбед таблицы trad2simp.txt (реальные данные). Но МЕХАНИЗМ, который решает, КАКИЕ руны и КАК свернуть, — Go: NormalizeSourceKey (:136-155) безусловно гоняет katakana→hiragana сдвигом диапазона (не таблица, арифметика над Unicode-блоком) для любого источника; а NormalizeTargetForm — функция, которую вызывает СОБСТВЕННЫЙ split-детектор B через terminology.Merge (terminologist.go:278), — жёстко хардкодит if r == 'ё' { r = 'е' } (norm.go:190-193) БЕЗ единого файла данных вообще (в отличие от trad2simp у неё нет ни эмбеда, ни отдельной версии хеша — только memoryNormAlgoVersion). Своим тезисом «данные, не код» B оправдывает вывод «family-анкер и split-детектор... спроектированы по тому же правилу: без пар-данных — инертны, никакой Go-ветки по паре» (§2 П8) — но опорный пример для этого правила сам нарушает правило Разделить явно: таблица (data, версионируется хешем байтов) vs Unicode-арифметика (код, но script-обусловленная, не пар-обусловленная) vs хардкод одного символа (код, НЕ данные, нет вообще пути «добавить пару без Go»); не использовать norm.go как прецедент, доказывающий, что split-детектор «инертен по конструкции» — это два разных объекта
B2 серьёзное §3 итог, класс 5 «Обращение ты↔вы и голос» / формула проекта «мой единственный универсальный механизм — split-детектор на окно (since_ch, until_ch)... не три разных починки» Класс 5 у самого B честно помечен «НЕ строю сейчас», но заявление «единственный универсальный механизм» (в единственном числе, покрывающий все классы §3) не называет условие вырождения: seed/seed.go — «Register is ABSTRACT (informal formal): which target surfaces realise it is target data, so a target language without a T/V distinction activates nothing» (эту же цитату верно приводит C, у B её нет). Для EN-цели (пара из моего мандата: zh→en) окно ты/вы-регистра, которое split-детектор должен был бы расщеплять по своей же формуле §3, ставить попросту НЕЧЕГО — весь класс молча пуст, и «универсальность» механизма для него означает «ничего не делает», а не «решает»
B3 блокер §0, §2 П5, весь проект Проект прямо заявляет курс «банк... максимально качественными АВТОНОМНЫМИ переводами» (D39.59 (2)) как цель, которую его механизмы должны приблизить Тот же гейт, что A4: HasData()-проверка в RenderGlossaryBlock/RenderEditorConstraintBlock (membank/memory.go:746, :842) молча обнуляет ОБЕ стены закона для любой цели ≠ ru. Автономность банка нулевая не потому, что решение банка плохое, а потому что оно НЕ ДОЕЗЖАЕТ до модели физически — а именно «доехать до модели» и есть предмет доктрины D39.104, на которую B опирается (§1) См. A4
B4 серьёзное §3, класс 1 «Смена пола» «Split-детектор сравнивает КЛАСТЕРЫ местоименных улик (他/她-счётчики, research/20 §B4 Z4) ранних и поздних KWIC-пулов» То же, что A3: 他/她-счётчик — китайско-специфичный сигнал (омофоны, разошедшиеся только на письме); B переносит его на «split-детектор для ЛЮБОГО класса ЛЮБОЙ пары» без единого слова о pro-drop источниках (ja, ko), где сигнала может просто не быть в нужной плотности. B не измеряет и не называет это ограничение нигде — ни в §3, ни в §8 (все арм-дизайны §8 — на корпусе A/B, оба zh-источник) См. A3

Находки — проект C

# серьёзность проект и раздел что утверждает проект (цитата) почему это неверно или опасно (грунт) что исправит
C1 серьёзное §5 N4, §6.1 «редакторская волна: репин $0 по построению (§5 N4)»; «since_ch = минимальная глава, где нормализованный ключ содержится в нормализованном тексте (mining.go:80-82 и memory.go:574 — один и тот же NormalizeSourceKey), значит в главах ниже него ключ сработать не может, и отклонение окном ничего не меняет в байтах» Довод верен ТОЛЬКО если NormalizeSourceKey идемпотентна и одинаково ведёт себя для НОВОГО письма — а она безусловно прогоняет katakana→hiragana и trad→simp таблицу для любого источника (см. A1). Для CJK-источника (zh, ja) это уже проверенное поведение; для en/ko/латиницы/кириллицы источника — не проверено НИКЕМ, включая C: собственные арм-дизайны M1/M2 (§8) используют только guzhenren-utf8.txt (китайский источник). Сам C честно помечает M2 как «$0-по-построению, требует пина», но не называет, что «по построению» опирается именно на CJK-специфичную функцию, а не на что-то доказанно пар-агностичное Пин M2 прогнать (или спроектировать) на НЕ-CJK синтетическом источнике, прежде чем считать N4 «$0 по построению» универсальным выводом, а не выводом для zh/ja
C2 минор §2 П2 «Языко-специфична только таблица свёртки, и это ДАННЫЕ: trad2simp.txt для zh, свёртка каны для ja, ё/е для цели ru (ряд 14)» Три сущности не равноценны: trad2simp.txt — реальный эмбед-файл (563 строки, версионируется хешем байт, norm.go:52-56); katakana→hiragana — Unicode-арифметика в коде (сдвиг диапазона, norm.go:150-152), не таблица; ё→е — единственный if-литерал (norm.go:190-193) БЕЗ какого-либо файла данных и без отдельной версии (в отличие от trad2simp, для которой ноты D39.16/R1-FL-C специально ставили версию НА содержимое файла). Открытая строка бэклога 14 так и называет это «ё-фолд → target-данные» — то есть НЕ построено, а планируется; называть уже сейчас «и это ДАННЫЕ» — точнее было бы «и это должно стать данными» В П8 явно развести: перенос trad2simp — перенос СУЩЕСТВУЮЩЕЙ таблицы (дёшево, прецедент есть); перенос ё/е — ПРОЕКТИРОВАНИЕ НОВОЙ схемы «таблица замен для целевой орфографии» с нуля (для немецкого target понадобится, например, ß/ss и умляуты — формат которых сегодня нигде не описан)
C3 серьёзное §2 П8 (каталог долга) + §5 N1/§3.1 «Что привязано к Go и это долг угла: ... словарь рода закрыт в Go (classifier.md:8-9)» — назван как отдельный долг, отдельно от N1 terminology.Genders (backend/internal/terminology/classify.go:51) — Go-карта РОВНО с четырьмя значениями male/female/neuter/none, без пути расширения через langpack. N1 (§5, §3.1) — механизм «преемник с главы N» для смены пола — представляет ТОЛЬКО категории из этого закрытого словаря. Для цели с ДРУГИМ набором грамматических родов (двухродовая common/neuter-система, или система именных классов, не совпадающая с male/female/neuter) N1 не сможет представить нужную категорию до правки Go — то есть ru→de «случайно» работает (в немецком тоже 3 грамматических рода), но НЕ потому, что механизм пар-агностичен, а по счастливому совпадению числа категорий. C сам называет словарь долгом, но не связывает его с собственным N1 в §3.1/§5, где N1 заявлен универсальным механизмом смены сущности В §3.1/§5 явно отметить, что N1 наследует ограничение закрытого словаря рода, и что генерализация категорий (не только «кто её ставит») — отдельная работа П8
C4 блокер §2 П5, §7 «Событие смены НЕ требует нового поля и нового читателя: преемник виден платформе как две строки одного src... оба поля уже на проводе» — то есть весь проект считает «на проводе» синонимом «модель это увидит» C ближе всех подошёл к находке (§2 П8: «файл несёт только ru (13 строк)»), но остановился на гендерной ноте, не на ВСЁМ механизме подачи закона. Тот же HasData()-гейт (см. A4) обнуляет RenderGlossaryBlock/RenderEditorConstraintBlock целиком — не только родовую ноту, а САМ закон-блок с переводами терминов — для любой цели ≠ ru. Формулировка C «файл несёт только ru» верно фиксирует факт, но C не проверяет (и не называет) следствие: ВЕСЬ аппарат N1N4 действует на строках, чей перевод в закон для читателя (модели) не попадёт вовсе, если цель не ru См. A4; отдельно — исправить формулировку §2 П8, чтобы она называла масштаб («не только родовая нота — весь закон-блок»)
C5 серьёзное §3.1, §9 вопрос 4 «движок считает сигнал неоднозначности (счётчики он/она вокруг имени — как улику, не вердикт) и при неоднозначности ставит hidden по умолчанию» Тот же класс, что A3/B4: счётчик «он/она» вокруг имени — сигнал, плотный для zh (омофоны 他/她) и, возможно, для en (частые lexical pronouns), но структурно РЕДКИЙ для pro-drop источников (ja, ko), которые мой мандат прямо требует прогнать мысленно. C, в отличие от A, честно называет метод «улика, не вердикт», но не называет условие, при котором улики физически недостаточно (текст без местоимений вообще) Назвать pro-drop как случай с иной, не пока не спроектированной уликой (плотность титулов/суффиксов вежливости), а не молчаливо полагаться на тот же счётчик

Сквозное

Сходятся ли A/B/C, и почему. Все три верно фиксируют, что таблица trad2simp.txt и весь классификатор рода — сегодня язык-специфичны в ядре, и все три правильно опираются на ОДИН и тот же положительный прецедент, который в дереве уже сделан верно: family-morphology.txt (backend/internal/lang/bankdata/, скрипт-ключирован, «A script with NO rows here leaves the family channel INERT … a pair that has not been measured never silently changes what it buys») и Register в seed/seed.go («is ABSTRACT … a target language without a T/V distinction activates nothing»). Это НЕ совпадение по недосмотру — оба места процитированы максимум двумя проектами из трёх (C — оба; A — только первое; B — ни одного явно), то есть сходимость частичная и по факту чтения одного и того же файла, а не по независимому выводу.

Где расходятся, и чью сторону я держу. A и C верно называют, что вынос свёрток в данные — работа ОКНА перекроя (NormVersion в теге нарезки), B в §6 вообще не обсуждает цену выноса норм-таблиц отдельно от цены family-анкера. По моей линзе прав C: он единственный, кто отдельно оценивает, что П8 — это не одна работа, а минимум две разных (перенос уже готовой таблицы vs проектирование новой схемы для ё/е-класса), хотя даже он не доводит это различение до конца (C2 выше).

Главный сквозной пробел — «ложноположительная общность». Все три проекта (в разной степени, C меньше) принимают за доказательство пар-агностичности то, что существующий код НЕ ЛОМАЕТСЯ на новой паре — но код не ломается ПОТОМУ, что незнакомый скрипт проходит фолды как молчаливый no-op, а не потому, что фолды спроектированы данными. Различие принципиальное: no-op-генеральность не защищает от NormalizeTargetForm ё/е-хардкода, который «работает» для НЕ-кириллических целей только потому, что в них никогда не встретится буква ё, а НЕ потому, что для их собственных орфографических особенностей (ß/ss, диакритика, регистр) есть хоть какой-то путь без правки norm.go.

Второй сквозной пробел — детектор неоднозначности пола на местоимениях (A3/B4/C5). Все три опираются на счёт 他/她 (research/20 §B4 Z4) как на универсальный сигнал, ни один не проверяет его на pro-drop источниках (ja, ko — обе явно требуются моим мандатом), при том что сама ратифицированная нота D5 п.1 называет «омофонное ta / pro-drop без дизамбигуации» как ДВА разных случая, а не один.

Третий, менее острый — классификатор несёт книжный канон в общем пар-слое. Ни один проект не упоминает research/34-memory-bank-quality-audit.md:104: «Классификатор типа термина — тот, что решает «транслитерировать или переводить» — обучен на каноне 蛊真人 прямо в общем промте пары (backend/prompts/zh-ru/classifier.md, шесть книжных поверхностей плюс два few-shot-ответа). Смещение на другой zh→ru книге не мерил никто.» Важная деталь для владельца: это НЕ архитектурное нарушение — D39.70 явно санкционирует «книжные примеры в classifier.md» как легитимный модуль-данные («языко-/книго-специфичное ДЕЛАТЬ МОЖНО — но выносить в данные/отдельные модули, встраиваемые архитектурно чисто (пар-промпт = легитимный модуль)»). Находка — не в законности, а в том, что все три проекта строят механизмы (гендер-детекторы, split-детекторы, dropBankSettled-расширения), которые молчаливо ДОВЕРЯЮТ выходу классификатора, а эмпирическую цену смещения на ВТОРОЙ книге той же пары никто не называет как условие своих же оценок точности (§8 M3 у A, §8 у B, M1M6 у C).

Что я оцениваю положительно (не находка, для баланса). Ни один из трёх проектов не ПРЕДЛАГАЕТ новую Go-ветку по языку — все новые механизмы (A-1…A-5, family-anchor+split у B, N1N4 у C) в своей СОБСТВЕННОЙ конструкции пар-агностичны или явно инертны без данных. Слабое место — не то, что они строят, а то, что они ОПИРАЮТСЯ на существующий субстрат (norm.go, injection.txt, classify.go), не проверив его чтением на собственную же линзу. Отдельно стоит назвать ЕЩЁ ОДИН хороший прецедент, который ни A, ни B, ни C не цитируют (я нашёл его сам, проверяя ряд 408 по просьбе ведущего, см. ниже): lang.TargetStemmer (backend/internal/lang/stemmer.go:22-31) — «The ALGORITHM is generic; the ending REGISTRY is target data (decl_suffix in data/target-.txt), so a target with none gets an inert stemmer (exact match only)». Это ТРЕТИЙ (после family-morphology.txt и Register) случай, где движок уже сделал ровно то, чего требует владелец («как сделать универсально») — жаль, что ни один проект его не заметил и не привёл как образец.

Дозасыпка по запросу ведущего (после K2-финала) — четыре пункта, линза общности.

  1. Смена пола, «при неизбежности — мужские». K2 нашёл: injection.txt:12 (данные ЦЕЛИ ru) велит «при неизбежности — мужские», а D5 п.1 прямо требует «а не дефолтить в мужской (TACL-биас)». Для моей линзы важно не САМО расхождение (это находка «хранителя ратифицированного», не моя), а то, что оно ЯЗЫКО-АГНОСТИЧНО по природе: маскулинный дефолт при неопределённости пола — известный класс переводческого смещения, воспроизводимый на ЛЮБОЙ цели с грамматическим родом (de, pl, fr...), не специфика ru. Сегодня верная политика («не дефолтить в мужской») нигде не закреплена, кроме как в тексте одной строки одного целевого файла — писавший injection.txt для СЛЕДУЮЩЕЙ цели с нуля с равной вероятностью повторит ту же ошибку, потому что схема данных не несёт этого урока (ни комментария-предостережения, ни линтера, проверяющего директиву против D5.1). Ни A, ни B, ни C не называют это как риск ПОВТОРА при новой цели — каждый обсуждает hidden только как факт текущей ru-директивы.
  2. Голос/обращения — «заполняет кто?» (ряд 24). Не даёт новой находки для моей линзы сверх уже отмеченного B2/C-разбора: Register уже абстрактен и инертен без данных (см. Сквозное выше); вопрос «кто пишет строки» — про производителя (человек/модель), а не про язык, им отвечает не моя линза.
  3. Тождество — R1R4 из research/20, язык-агностичны ли. Прочтением (docs/research/20-bank-mining.md:403-414): R1 (правило «вложение поверхности»: X строго содержится в Y при |X|≥2, пример 方源 ⊂ 古月方源) — это RUNE-substring, осмысленный для Han-письма; на словоделимых письменностях (латиница, кириллица) содержательное вложение работает на уровне СЛОВ, а не рун (условное «Юань» внутри «Гу Юэ Фан Юань» — это про токены, не про побайтовую подстроку) — правило в буквальном прочтении неявно предполагает Han. R2 (правило «фамильный якорь + композиция») и R4 пункт (i) («общая фамилия + РАЗНЫЕ имена ⇒ НЕ мержить», пример 方源≠方正) опираются на схему «однорунная фамилия спереди + имя», которая уже правильно вынесена в данные ОДНИМ реальным построенным местом — family-morphology.txt (строка family_affix han name prefix 2, комментарий «the asymmetry is DATA, not a Go branch»); если R1/R2/R4(i) реализуют когда-нибудь через ТУ ЖЕ таблицу — они наследуют уже доказанную генеральность; реализованные ОТДЕЛЬНО (как в тексте research/20, ad hoc) — унаследуют CJK-форму. R4 пункты (ii) («разный подтверждённый пол») и (iii) («разные approved dst») язык-агностичны без оговорок. R4 пункт (iv) (ко-презенция в одном предложении/ диалоговом обмене) зависит от детектора границы предложения — в lang/langpack.go уже упомянут pair-14 файл sentence-terminator, то есть инфраструктура ДЛЯ данных под это есть; не проверял, покрывает ли она классы SOV/CJK-пунктуации без правки Go (не входит в мою карту чтения этого раунда). R4(v) «титул-вложение» — тот же RUNE-substring риск, что R1. ⚠ Это ЗАМЕЧАНИЕ НА БУДУЩЕЕ, не находка против A/B/C: все три ПРАВИЛЬНО не строят алиас-кластеризацию сейчас (закрыто D39.102 п.2 в части консилиума моделей; сам R1R4 не ратифицирован, ряд 339 — «якорная половина» открыта) — ни у кого нет утверждения, которое эта проверка бы опровергла. Стоит записать это ТУДА, куда ряд 339 в итоге попадёт.
  4. Гейт глоссария и decl-форма (ряд 408). Проверил чтением: сам МЕХАНИЗМ уже хорошо обобщён — lang.TargetStemmer (stemmer.go:22-24,29): «The ALGORITHM is generic; the ending REGISTRY is target data … so a target with none gets an inert stemmer (exact match only)». Это НЕ «decl — данные цели ru» в смысле «работает только для ru» — для цели БЕЗ падежей (en, zh) стеммер корректно становится инертным (точное совпадение), а для цели С падежами (de, pl) достаточно заполнить data/target-<tgt>.txt — правки Go не требуется. Настоящая цена ряда 408 — не архитектурная, а РЕДАКЦИОННАЯ: decl-формы — «seed-only with no automatic producer at all» (decisions.go:81), то есть КАЖДАЯ новая склоняемая цель наследует ТУ ЖЕ нехватку данных, что и сегодняшняя ru (никто их системно не досевает), а не новую Go-работу. Это стоит иначе, чем у меня было в исходном брифинге предположено, — записываю как поправку себе, а не как находку против проектов.

Что я не проверил и почему

  • Живое поведение NormalizeSourceKey на реальном ja/ko/en тексте. Проверено ЧТЕНИЕМ кода (безусловные фолды) и КОСВЕННО (майнер-субстрат research/34:92: zh 48/120, en 0/504, ko 0/200, катакана 0/160 — подтверждает, что детерминированный канал почти не эмитирует кандидатов на этих скриптах, но не проверяет корректность/безопасность самого фолда). Не построил синтетический ja/ko/en corpus и не прогнал go test с ним — это было бы новым тест-файлом сверх мандата линзы (наблюдение, не измерение точности). Контрольная величина: файлов internal/text/*_test.go в дереве, дающих не-CJK кейс для NormalizeSourceKey, — не искал целенаправленно (не входит в мою карту чтения).
  • Правда ли, что добавление реальной не-ru цели в injection.txt — чисто $0 (данные) без сопутствующей правки Go. Прочитал parseInjection/InjectionTextsFor (embedded.go:414-460) — парсер и структура данных пар-агностичны по виду (просто TAB-строки), но не проверил исполнением: добавил бы я строку de\t... и прогнал ли go test — тест не писал (в рамках «без кода» пака и однокопийной дисциплины делать это не стал, так как не относится к спорному утверждению, а прямому чтению кода доверяю здесь больше, чем обычно, — гейт слишком прост, чтобы прятать сюрприз).
  • Насколько высок РЕАЛЬНЫЙ риск смещения классификатора на второй книге пары (research/34:104). Это вопрос эмпирики (нужна вторая zh-ru книга и платный прогон), санкции на платный вызов у меня нет и не просил — называю это как открытый вопрос синтеза, не как измеренный факт.
  • **Проекты B и C о голосе/обращениях цитируют research/34 §2(5) — числа там (по моей пере-сверке чтением): «22 с секцией голосов, 21 из них пустая, непустых живых — 0» (:92) и «0 непустых секций voices: из 47 сид-файлов дерева» (:54) — я эти два числа (22/47 сидов и 21/22 пустых секций) взял на веру у B/C и не пересчитывал сам по сид-файлам; seed/seed.go читал только цитируемый фрагмент (Register is ABSTRACT...), не файл целиком.
  • verify_quotes.py прогнан по этому файлу дважды (после черновика и после правок). Итог второго прогона: 98 отмеченных строк, из них подавляющее большинство NOTFOUND/ATTR_MISS — это цитаты ИЗ ПРОЕКТОВ A/B/C (r1-project-A/B/C.md), которые инструмент СТРУКТУРНО не видит (весь docs/research/35-bank-memory- consilium* исключён из корпуса по правилу самого консилиума) — это не свидетельство неточности, а граница инструмента для этого раунда; я сверял такие цитаты вручную по своим же чтениям Read-тулом (см. протокол сессии). Цитаты, которые инструмент МОГ проверить (код 5dbb5cb, research/24, research/34, D39.70, family-morphology.txt, seed/seed.go, stemmer.go), дали EXACT/FRAGS с ATTR_OK или ATTR_WEAK(в абзаце, не в строке) — ни одного NOTFOUND по факту наличия строки. Контроль: корпус на момент прогона — repo=800 файлов, frozen=766, owner=7, что доказывает непустой прибор.