From bbbea009b54bcc8eb20372dd2f70a1fea8c960ae Mon Sep 17 00:00:00 2001 From: heaven Date: Wed, 16 Sep 2026 00:34:59 +0300 Subject: [PATCH] Add the bank memory consilium prompt with its archived evidence, mark the earlier bank design withdrawn, and point the plan and prompt table at it --- ...WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md | 5 +- docs/BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md | 432 +++++ docs/NEAR_TERM_PLAN.md | 2 +- docs/README.md | 1 + .../01-premises-verification.json | 332 ++++ .../02-design-v1-fable.md | 37 + .../03-design-v1-verification.json | 430 +++++ .../04-design-v2-and-owner-proposal.md | 50 + .../05-prior-art-map.json | 1702 +++++++++++++++++ .../06-owner-words-and-freeze-answers.md | 273 +++ .../README.md | 126 ++ docs/orchestrator-norms-scratchpad.md | 6 +- 12 files changed, 3391 insertions(+), 5 deletions(-) create mode 100644 docs/BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md create mode 100644 docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/01-premises-verification.json create mode 100644 docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/02-design-v1-fable.md create mode 100644 docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/03-design-v1-verification.json create mode 100644 docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/04-design-v2-and-owner-proposal.md create mode 100644 docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/05-prior-art-map.json create mode 100644 docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/06-owner-words-and-freeze-answers.md create mode 100644 docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/README.md diff --git a/docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md b/docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md index cec530f8..a662cb02 100644 --- a/docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md +++ b/docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md @@ -5,8 +5,9 @@ > доставлено». Приём «по разнобою» ВАКУУМЕН — все термы со `spread ≥ 2` уже лежат в финальном банке (прогон A: 9 из 9, > B: 8 из 8; `bank.json` стопа против `glossary` полных баз). Настоящий дефект консистентности — ПЕРЕ-РЕШЕНИЕ банка > терминологом на подписи и, по коду, на каждой следующей покупке глав: у неподписанных строк сменились передачи -> A 12 из 69, B 14 из 66. Пример «две разные вещи — одно имя» (`宗族祠堂` / `宗祖祠堂`) — один и тот же зал. Пак -> переписывается под вопрос владельцу «копить ли решения банка между прогонами». +> A 12 из 69, B 14 из 66. Пример «две разные вещи — одно имя» (`宗族祠堂` / `宗祖祠堂`) — один и тот же зал. +> ⛔ **Испр. 15.09: пак НЕ переписывается.** Проект, под который его собирались переписать, оркестратор отозвал; предмет +> передан консилиуму — `BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md`. Бэкенд-пак по банку пишется заново по его итогу. > Выдан оркестратором №23 (сессия `textmachine-11`). Пак **$0** — платных вызовов в нём нет. > Предмет куплен двумя платными прогонами; разбор состава банка сделан старшим коллегой по коду. diff --git a/docs/BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md b/docs/BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md new file mode 100644 index 00000000..c7a7c0e8 --- /dev/null +++ b/docs/BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md @@ -0,0 +1,432 @@ +# Консилиум: БАНК ПАМЯТИ ДЛИННОЙ КНИГИ — как его строить + +> Выдан оркестратором №23 (продолжение, сессия `textmachine-main-75`) 16.09 по слову владельца 15.09: «передавай дела +> сессии, пусть наследуется от тебя». Ты наследуешь работу этой смены по банку. Всё, что она выяснила, спроектировала и +> опровергла, лежит уликой в `docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/`. +> **Пак без кода и без денег проекта:** платных вызовов моделей пайплайна нет. Агенты Claude разрешены — из них +> консилиум и состоит. Якоря `file:line` здесь сняты по дереву `5dbb5cb`. + +## 1. Какая проблема и что решит твой результат + +Приоритет №1 владельца — консистентный художественный перевод длинной книги: ранобэ на сотни и тысячи глав, +купленное частями. Держит его **банк памяти** — словарь «исходный термин → перевод, род, окно глав», который редактор +обязан соблюдать как закон. Конвейер: дешёвый черновик → банк памяти → редактор. + +**Что случилось 15.09.** Оркестратор с советчиком Fable 5 дважды спроектировал банк заново, и оба раза предложение +оказалось неверным по одной причине. Проект опирался примерно на десятую часть того, что репозиторий уже решил, +построил, исследовал и измерил по банку. Сплошная сверка нашла 12 расхождений с решённым, замеренным и собственным +планом, а в предложении не было названо ни одного. Предложение отозвано. + +**Твой результат — ОДНО проектное решение банка, выработанное советом агентов.** Требования к нему: +- стоит на построенном и ратифицированном; +- честно называет трейдоффы и цену; +- ставится в очередь относительно перекроя глав; +- приносит владельцу не больше пяти вопросов в верном статусе. + +Код не пишется, стройки нет. + +**Проблемы, которые решение обязано пройти** (улики — README входов): +- **П1. Банк пере-решается.** Авто-банк переписывается целиком из текущего прогона (`research/34` §4 п.4, ряд 130). + - **На подписи — замерено.** Между стопом банка и финалом передачи неподписанных строк сменились у 12 из 69 (A) и + у 14 из 66 (B). + - Между стопом и финалом был второй проход терминолога после человеческой подписи двух термов. + - Эррата 11.09-и называет это ценой пере-майнинга после подписи: «Хороши ли эти 12 замен — вопрос КАЧЕСТВА» + (греп `Эррата 11.09-и` в `docs/architecture/05-decisions-log.md`). + - **На следующей покупке глав — выведено из кода, живьём не наблюдалось.** + - Покупка сперва доставляет новые юниты и только потом пере-делывает отгруженные, чьи байты сдвинул банк + (`backend/internal/pipeline/volume.go:410-427`, `DELIVERY BEFORE REWORK`). + - Пере-делка идёт с согласием на пере-оплату (`:351`). + - Пока в книге есть непереведённые юниты, отгруженные главы остаются со старыми передачами. +- **П2. Тождество термина.** + - Подбор строк сравнивает нормализованную форму (`backend/internal/membank/memory.go:574`). + - Хранилище и часть дверей намеренно сравнивают сырую строку: «族長 and 族长 with one sense and window are two + accepted rows, not one» (`backend/internal/membank/memseed.go:874-876`). Это традиционное и упрощённое написание + одного слова. + - Что редактор получает при этом два закона, показала проба `01` (R2) по коду; живьём не наблюдалось. + - Владелец спросил, тот ли это вообще термин (§1, рамка) — ответ нужен человеческими словами. +- **П3. Исходы решения.** Отказ терминолога (⟦TM-NO-DST⟧ или молчание) оставляет строке передачу из черновика, и она + едет редактору законом (`01` T4 и B2; `backend/internal/miner/miner_emit.go:261-268`). Исхода «это не термин банка» + нет. +- **П4. Сущность меняется по ходу книги.** Классы: персонаж сменил пол после N глав · термин сменил смысл · тёзки · + имя, совпадающее с обычным словом (`方正`) · обращение ты↔вы и голос меняются по сюжету. + - **Ответ на класс смены пола уже ратифицирован — D5 п.1.** Когда в загруженных главах видна намеренная + неоднозначность, ставится `gender=hidden`, и безродовые конструкции идут до раскрытия. Плюс ретро-патч «с тома N — + так» с показом стоимости пере-перевода вмороженных глав. + - **Для обращений — D7 правка 1.** Ты/вы — «журнал событий переходов», «а не статичная матрица пар (переход ты↔вы — + сюжетное событие». Там же `gender` — «с проактивной установкой `hidden` Analyst-ом на неоднозначности (D5.1)». + Голос входит в приоритет №1 (D39.248 п.1). + - **У этой же книги хрестоматийный случай — `白凝冰`:** первые главы «он», канон female — D19 п.3(в) (греп + `хрестоматийный кейс механизма D5.1` в `docs/archive/architecture/05-decisions-D1-D38.md`). + - **Построена ручная половина, проактивной нет.** + - `hidden` — поле сида, и у этой книги оно выставлено (греп `сид финализирован (白凝冰` в + `docs/architecture/05-decisions-log.md`). + - Классификатор его не ставит (`backend/prompts/zh-ru/classifier.md:10-11`). + - Расхождение ратифицированного (D5 п.1, D7 правка 1) с построенным — пункт §13 (д). + - Терминолог видит три ПЕРВЫХ вхождения по книге, ±40 знаков (`backend/internal/pipeline/terminologist.go:75-76`, + `backend/internal/terminology/terminology.go:340-349`). Раскрытие в поздней главе он не видит. + - Редактору велено: «Род и форму имён и терминов сверяй по глоссарию» (`backend/prompts/zh-ru/editor.md:10`). + Значит, устаревший род в банке может переписать верный текст — это вывод, не замер. + - Окно одним решением двери не правится, а отказ снимает все окна поверхности + (`backend/internal/membank/decisions.go:90-92`). + - **Окон у движковых строк почти нет.** В базах A/B `since_ch` > 0 только у 2 строк на книгу, `until_ch` = 0 у всех. + Нижнюю границу по первому появлению ставит только детерминированный канал майнера + (`backend/internal/miner/miner_emit.go:210`, `:387-399`); кандидаты только из банкноты идут с `SinceCh: 0` + (`backend/internal/pipeline/mining.go:612`). Решение, опирающееся на окно «с главы N», опирается на то, чего у + движковых строк сегодня нет. +- **П5. Сигналы без читателя.** + - Движок по умолчанию на подпись не останавливается (`backend/cmd/tmctl/invocation.go:141`). На платформе + остановка — обязательное поле заказа `stop_for_signing` (`platform/internal/httpapi/v0.go:655`). + - Платформа читает из банк-экспорта только `terms` (`platform/internal/ingest/bank.go:58-70`), у секции `proposed` + читателей ноль (ряд 224). + - Фронт заморожен. +- **П6. Номинация.** Обычные слова в банк не попадают: `族` встречается в срезе 29 раз, `家族` — 9. Отсекает их фильтр + типа, а не контраст (ряд 440, причинность пере-названа 12.09). Пускать ли их — решение владельца. +- **П7. Закон задним числом.** Термин решён в поздней покупке, а встречался и в уже отгруженных главах. Ратифицированные + опоры: D39.42 п.5 и ретро-патч D5 п.1. +- **П8. Общность.** Свёртки написания исходника (трад.→упрощ. китайский, катакана→хирагана) зашиты в ядро и + применяются к любому языку (`backend/internal/text/norm.go:47`). Вынос в данные двигает `NormVersion`, а он входит в + тег нарезки и в ключ манифеста (`backend/internal/pipeline/manifest.go:282`, `:384`). + +### Рамка владельца — дословно + +Первоисточник и долговечная выписка — §5 п.2 и вход `06`. + +**Из разговора с прежним оркестратором (с 12.09):** +- «банк памяти сразу должен идти законом»; «у редактора нет знаний о том что с этим термином сделают другие + редакторы, поэтому так оставлять его опасно». +- «принимать решение -- в точке банка памяти»; «делать на такие вот термины запросы с контекстом пожирнее». +- «запросы перевода намайненого банка памяти очень дешевые относительно всей книги, мы можем на них не экономить». + - ⚠ Оговорка оркестратора: на коротких прогонах A и B терминология — 15.6% и 21.0% цены, то есть заметная доля, а не мелочь. +- 12.09: «такой банк памяти по spread может обеднять очень сильно язык. Потому что термин который можно перевести + по-разному это вообще то нормальная составляющая художественного перевода»; «у нас начнут переводиться все слова в + книге одинаково которые вовсе не обязаны переводится одинаково и даже плохо что они переводятся одинаково». +- «если мы начнем майнить такие термины то это взорвет кардинальность банка памяти». +- «возможно модель терминолог захочет выкинуть термин который выкидывать точно нельзя». +- «редактору дано задание более живой язык предоставить, если не гейтануть его терминами, то он может переписать их + часть просто под горячую руку попав». +- 12.09, о двух его августовских записях, которые оркестратор привёл из его файла: + - «МАЙНИНГ ЗАМЕЧАНИЙ … Заставить критика жаловаться, а не чинить» (ПТ-41; дословно в файле владельца `START_PROMT.MD`, который в репозиторий не коммитится); + - безLLM-анализатор книги, считающий повторы слов и упоминания имён (строки ПТ нет). Это пересказ оркестратора; в + файле это вопрос, а не идея. + - Ответ владельца: «Пусть они останутся идеями, потому что самая оптимальная штука которая есть сейчас по цене + качеству это черновик -> банк памяти -> редактор переписыватель полный. Если мы будем сюда внедрять всяких + критиков то это уже начнет сильно дорожать перевод»; «Нам бы вот на текущей архитектуре разрулить проблему эту». +- «у нас есть алгоритм в бэкенде который скипает подпись банка»; «надеяться что это отловит человек довольно + ненадежно». + +**Из носителей:** +- «у неподписанного термина тоже обязан быть ОДИН перевод» — слово владельца, записанное в ряду 330. +- «надо давать везде одинаково; если кто-то ошибся — это уровнем выше» — D39.104 п.1, 04.08. + +**15.09, в этой смене:** +- «Меня вот интересует как банк памяти решает проблему которая по идее должна быть общей»; «у нас перосонаж был + мужским первые 10 глав, затем поменял пол, вот на докупке новых 10 глав, как с этим банк памяти справляется?»; + «есть ли еще подобные кейсы?». +- «То что как то замораживать банк памяти и каждый раз не переводить его это понятно, представь если там что то + изменится на перевод это же пол книги может перегенерировать.» +- «Ну вариант где замораживаем звучит логично, так а что тут не так пойти может? Форма как то перевода поменяться или + что?»; «только я спрашивал скорее какой алгоритмический фикс и какие трейдоффы тут могут произойти». +- «族长 и 族長 это точно одинаковый термин? Я китайский не знаю, но выглядит это как разные слова». +- «Ты тут не упарываешься в конкретное решение на моих замечаниях? Нам бы придумать что то качественное вместо каких + то заплаток»; «как сделать универсально»; «У нас не получается антипаттерн заплатка под конкретный язык?». +- «может быть мы уже запланировали в бэклог что то умное что решает нашу проблему». + +⚠ **Что именно владелец назвал логичным — и почему это не решение.** +- **Предмет — не заморозка как идея и не ряд 130, а предложение оркестратора** (выписка `06`, строка 870): «**Заморозка.** + Перевод, который уже ушёл в отгруженные главы, замораживается. При следующих покупках модель про него больше не + спрашивают, а спрашивают только про новые термины». К ней шли бесплатная сверка и право менять замороженное только + человеку. +- **Это ровно та посылка, которую README входов велит не повторять:** «Первое решение живёт до правки человеком» — против + риска B1 и D39.69. +- **Вопрос владельца «что тут не так пойти может?» — о цене этой посылки.** Оркестратор ответил рисками и уточнениями + (выписка `06`, строки 896, 920, 1038). Часть его утверждений не держится — баннер `06`. +- **Позже владелец предостерёг не упираться в решение по его замечаниям.** Значит, заморозка — кандидат с известной + ценой, а не принятое решение. Связь с рядом 130 — прочтение оркестратора. + +## 2. Зона записи и git + +- Пишешь **ТОЛЬКО** итог `docs/research/35-bank-memory-consilium.md` и рабочие файлы в каталоге + `docs/research/35-bank-memory-consilium/`: протоколы раундов, пробы, таблицы. + - `docs/` — зона оркестратора, и эта запись — исключение, выданное этим промтом. + - Прецедент: ревью контракта `docs/archive/prompts/CONTRACT_REVIEW_SESSION_PROMPT_2026-08-15.md` → + `docs/research/28-contract-review.md`, лендинг оркестратором (D39.138). + - Лендит итог оркестратор. +- Входы `docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/` — только чтение. +- **Ты не коммитишь.** Код, конфиги, промпты, бэклог, журнал решений, план, README и прочие доки не правишь. Нужные + правки носителей даёшь списком в итоге (§13 (д)). +- ⛔ В главном дереве `/home/ubuntu/projects/textmachine-main` лежит незакоммиченная сдача бэкенд-сессии, ждущая + приёмки: индекс и рабочие правки `backend/`. + - Git в главном дереве — только чтение (`status` · `log` · `show` · `diff` · `grep`). + - Запрещены `add` · `commit` · `reset` · `restore` · `checkout` · `stash` · `clean` · `apply` · `worktree`. +- **Код читай из замороженного дерева `/home/ubuntu/tm-verify-1509`** (`HEAD` `5dbb5cb`, отцеплен; `backend/` и + `platform/` там те же, что в `9241934`). + - State-changing git запрещён и в нём. + - Пробы — `go test` в этом дереве или на tar-копии в своём скретчпаде + (`tar --exclude=./bin --exclude='./.env*'`). + - После прогонов `git -C /home/ubuntu/tm-verify-1509 status --short` должен быть пуст; вывод печатаешь в протоколе. +- ⛔ **Платные вызовы моделей проекта запрещены:** `tmctl translate`/`redrive` и любые провайдеры пайплайна. Замер, + которому нужны деньги, проектируешь с ценой и отдаёшь в итог. Санкцию у владельца берёт оркестратор. +- Базы прогонов (`~/tm-coldrun-a`, `~/tm-coldrun-b`) — только `python3` + `sqlite3` с `mode=ro&immutable=1`. +- `books/` — только чтение, git в нём не трогать: это отдельный репозиторий, в нём лежат сайдкары стопа банка. +- `.env` не читать никогда. + +## 3. Карта чтения — ЗАКОН; ратифицированное — в теле промта + +1. `CLAUDE.md` — целиком. +2. Этот промт. +3. `docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/README.md`. Там же в `05-prior-art-map.json` — раздел + `synthesis` целиком; находки сверщиков `S1`–`S3` — по мере вопроса. +4. `docs/architecture/18-bank-ontology.md`. +5. `docs/research/34-memory-bank-quality-audit.md` — через ревью-шапку. + +**Справочник по мере вопроса** (в счёт карты не входит): +- входы `01`–`04` и `06`; +- `docs/research/`: `14-adaptive-memory.md` · `17-external-critique.md` · `20-bank-mining.md` · + `24-bank-arbitration.md` · `31-harness-independent-critique.md` · `32-harness-architecture-alternatives.md` · + `33-backend-debt.md`; +- `docs/experiments/18-editor-wire-probe.md` · `docs/architecture/06-memory-risk-registry.md` · + `backend/docs/CHAPTER_STRUCTURE_DESIGN.md` §4.2; +- `docs/product-requirements.md`: ПТ-4 · ПТ-5 · ПТ-8 · ПТ-9 · ПТ-24 · ПТ-41 · ПТ-42; +- ряды `docs/BACKLOG.md`: 14 · 38 · 47 · 130 · 131 · 161 · 192 · 221 · 223 · 224 · 233 · 322 · 330 · 339 · 406–409 · + 434 · 436 · 438–440; +- ноты ниже. + +Журнал решений целиком не читать: +- тело — греп `^## D<номер>` в `docs/architecture/05-decisions-log.md` и в слайсах `docs/archive/architecture/`; +- статус одним хопом — `docs/architecture/05-decisions-index.md`; +- подномер живёт пунктом родителя. + +### Ратифицировано — сверь тело ноты до пункта, прежде чем опираться + +- **D5.** Бриф заморожен, новые термины дописываются, принятое молча не пересматривается. П.1 — проактивный + `gender=hidden` и ретро-патч «с тома N — так» (подробно — П4). +- **D7 правка 1.** Ты/вы — журнал событий переходов; `gender` — с проактивной установкой `hidden` (подробно — П4). +- **D39.42.** Банк майнится по черновикам всей книги сразу. П.5: смена банка после оплаты — пере-редактура ТОЛЬКО + затронутых юнитов, со сметой до согласия. +- **D39.59 (2).** «БАНК — КУРС НА АВТОНОМНОСТЬ: подпись владельца ОПЦИОНАЛЬНА»; «банк обязан приходить с максимально + качественными АВТОНОМНЫМИ переводами». +- **D39.69.** «Гипотеза первенства ОПРОВЕРГНУТА»: терминолог ре-решает контекстом. Риск B1 + (`docs/architecture/06-memory-risk-registry.md:44`): «первый (наименее информированный) перевод имени лочится на 1000 + глав». +- **D39.102 п.2.** Закрыты «по нужности» целиком: равноправный консилиум как прод-механизм · кросс-модельное + взвешивание уверенностью · self-consistency N прогонов · селекция «выбери из вариантов» · отказ-сигнал ⟦TM-NO-DST⟧ · + эмбеддинг-фетч (закрыт D39.69). Совет моделей как механизм банка не предлагается; к формату этой сессии пункт не + относится. +- **D39.104 п.1.** Банк на проводе — ЗАКОН для всех ролей, независимо от статуса строки. Право «перевести иначе» + упразднено. Свобода — узкая оговорка ОБЛАСТИ употребления. + - Принятая цена: «неверная авто-строка едет консистентно до ревью (чинится одной правкой банка + ре-эдитом; + разнобой не чинится ничем)». + - П.2: единый закон-блок редактора вместо двухсекционки. Ряд 134, которым п.2 заказывал внесение, закрыт D39.195 + п.2. + - Проба (`docs/experiments/18-editor-wire-probe.md:621`): «Не подтверждено: оговорка области §B … В движок не + вносить.» +- **D39.144 п.1.** Банк подписывается целиком, пер-термная подпись — не модель продукта. Механику пост-ридинговых правок + не проектировать до полигонных итогов. + - D39.165 сужает этот пункт (греп `ОБЛАСТЬ D39.144 п.1 СУЖЕНА ЯВНО`): открыть дверь к построенному движковому + механизму — не то же, что проектировать продуктовый цикл. + - Полигон выведен из скоупа (D39.248 п.4), поэтому триггер ряда 192 «итоги фазы Д» не наступит. Это вывод + оркестратора. +- **D39.193.** П.1: род производит классификатор. П.3 — дедуп ЗАКОН-БЛОКА редактора: ключ уникальности банка — + `(src, sense, since, until)`; уступает неподписанная строка и только подписанной; подпись не роняется никогда. +- **D39.205.** П.4: гейт глоссария не включается до замера ложных срабатываний. П.5: направление владельца «или + флагать, или ПЕРЕГЕНЕРИРОВАТЬ проблемный участок» — такой работы сегодня нет. +- **D39.245.** Акт ратифицирует ПРЕДМЕТ структуры глав, а не механику. П.7: перечеканка экспортных id уронила бы + КАЖДЫЙ банк-экспорт платформы — отсюда `bankTermID` не двигать (`backend/docs/CHAPTER_STRUCTURE_DESIGN.md:693`). +- **D39.248.** П.1: голос входит в приоритет №1. П.2: Fable 5 — 1–2 агента на сессию. П.4: полигон вне скоупа. + +### Открытые решения владельца — вопросы, а не запреты + +- **Ряд 130** = `research/34` §4 п.4: копить ли авто-банк между прогонами. + - Это СТОП-решение; материал — WARN второго прогона. + - 15.09 владелец назвал логичным близкий, но не тот же предмет — предложение «заморозка + сверка» (§1, рамка). + Считать это его позицией по ряду 130 — прочтение оркестратора. +- **Ряд 440:** пускать ли обычные существительные в банк детерминированным каналом. +- **`research/34` §4:** + - п.1 — стоп или флаг на разъехавшемся термине; + - п.3 — один перевод у неподписанного термина: оба выхода стоят денег; + - п.5 — остановка на подпись: опция или свойство продукта. +- **Ряд 192:** пост-ридинговый цикл правок банка (триггер недостижим — см. D39.144 выше). + +## 4. Разметка свободы: как работает консилиум + +Слово владельца дословно: «на протяжении всей работы это скорее не прям ресерч а ресерч консилуум где идет совет о +том как строить между разными агентами (разрешаю 1-2 фабла по необходимости для этой сессии)». + +**Делай РОВНО так** (отступление — пинг): +1. **Совет, а не один автор.** Порядок работы: + - не меньше ТРЁХ независимых проектов от агентов с разными заданными углами; каждый пишется до знакомства с + другими; + - перекрёстная критика: каждый проект судит агент, который его не писал; + - сведение в одно решение; несогласие записывается, а не усредняется. +2. **Роли совета обязательны.** Роль может нести один агент, но не автор проекта, который она судит. + - Адвокат рамки владельца (§1). + - Адвокат денег и детерминизма. + - Адвокат общности: «заработает ли пара, которой в репо нет, без правки Go». + - Хранитель построенного и решённого — сверяет каждый механизм с картой `05` и деревом. + - Опровергатель фактов кода — исполнением. +3. **Fable 5 — не больше двух агентов на всю сессию.** + - Модель задаёшь явно (`model: "fable"`). + - Вопросы по тому же предмету досылаешь уже поднятому агенту. Второй Fable — только под другой предмет, с доводом + в протоколе. + - Fable — советчик, а не источник истины: его посылки проверяются деревом. + - Субагенты и воркфлоу на других моделях разрешены явно; сколько их работает, ты знаешь. +4. **Сначала «не построено ли уже» и «не решено ли уже», потом любой новый механизм.** У каждого нового механизма в + итоге: + - таблица «что по этому предмету уже есть: решено · отложено · в плане · построено · выключено · исследовано · + опровергнуто»; + - довод, почему нужен новый. + + Отсутствие этого шага — ровно причина отзыва двух прошлых проектов. +5. **Правило остановки проверки итога.** + - Не больше трёх кругов. + - Сходимость — круг, не давший НОВЫХ находок (любой серьёзности). + - Миноры последнего круга закрываются ещё одним кругом — или остановкой. + - Не сошлось за три — стоп: итог с таблицей остатка и строкой §13 (м) во второй форме. +6. **Формат утверждений:** о коде — `file:line` по `5dbb5cb`; о решении — D-номер с пунктом; о замере — источник, + прибор и популяция. + +**Решаешь сам и аргументируешь:** +- число раундов до проверки итога; +- углы проектов; +- формат протоколов; +- какие $0-пробы нужны; +- нужен ли второй Fable (в границах п.3); +- давать ли авторам проектов тексты отозванных `02`, `04` и ответов оркестратора из `06` — если да, только вместе с + баннером. + +Мои приоры по углам — по карте `05`, этой сменой не проверены, опровергаются доводом: +- **«минимум на построенном».** Включить и расширить уже построенное: + - `dropBankSettled` — на решения движка, плюс адресуемые по содержимому чекпойнты партий (ряды 38, 233); + - спящий журнал `glossary_revisions` (ряд 221); + - семейный пере-запрос с якорями решённых членов (`research/24`, ряд 339); + - ранжирование очереди человека по уверенности. +- **«журнал решений с окнами».** Направление отозванных `02`/`04`, которое критик `03` признал годным как направление. +- **«продукт без человека в петле».** Всё решается в точке банка, без подписи. +- **«сначала замер».** Как растёт пере-решение на 10 → 50 → 200 глав, прежде стройки (`research/31`, `research/24`). + +## 5. Самопроверка исполнением — и где этот пак мягкий + +**Механизм назван:** +1. Каждое несущее утверждение о коде проверяет агент-опровергатель ИСПОЛНЕНИЕМ: проба или `go test` в замороженном + дереве, `python3` по базам, греп с печатью контрольной величины. +2. **Цитаты итога проверяются скриптом — и скрипту не верят на слово.** + - Из поиска исключается ВСЁ, что породила эта сессия: итог, протоколы, черновики агентов в + `docs/research/35-bank-memory-consilium*`. Иначе каждая цитата найдёт сама себя. + - Проверяется АТРИБУЦИЯ, а не только наличие строки: цитата стоит в НАЗВАННОМ источнике и говорит о том же + предмете. + - Число дословных — ВЕРХНЯЯ ОЦЕНКА; остаток закрывается чтением. Подстрочный поиск меряет наличие строки, а не + происхождение утверждения. + - Пример из `05`: 180 цитат → 178 дословных, но у 2 из них неверная атрибуция; 1 не найдена; 1 сводчиком не + учтена. + - **Слова владельца сверяются по первоисточнику, а не по этому промту.** Промт и выписку `06` писал оркестратор, и + сверка по ним круговая. + - Первоисточник — транскрипт сессии оркестратора + `/home/ubuntu/.claude/projects/-home-ubuntu-projects-textmachine-main/6bf42f99-b840-4396-80ac-ab93384b11dc.jsonl`. + - Строки файла считаются с 1: строка 17 — вставка разговора с прежним оркестратором; строки 878, 1042, 1094, + 1296, 1362 и 1456 (сообщение из очереди) — слова 15.09. + - Транскрипт вне репозитория и умрёт с машиной; долговечная копия — `06`, сделанная скриптом. + - Цитаты владельца в этом промте опровергатель сверил с транскриптом в трёх кругах. + - В итоге называешь, по чему сверил. +3. Итог судят агенты, не участвовавшие в сведении, и хотя бы один из них — ДРУГОЙ моделью, чем автор сведения. + +Проверяемый артефакт — таблица §13 (з). + +**Где мягко — сюда смотри в первую очередь:** +1. ⛔ **Изобрести построенное, решённое или опровергнутое** — класс, из-за которого отозваны оба прошлых проекта. + - Карта `05` — отправная точка, а не потолок: сверщики читали не всё (`synthesis.obstacles`). + - Живой пример — D5 п.1: ратифицированный ответ на заглавный кейс владельца. Карта его нашла, а ни один из двух + проектов его не использовал. +2. ⛔ **Сфабрикованная сходимость.** Агенты одной модели на одном входе сходятся потому, что читали одно. Разнообразь + модели и входы. Несогласие пиши в протокол. +3. ⛔ **«$0» и «центы» без прибора.** + - Что двигают `memory_version`, `NormVersion`, снапшоты волн, перекупка банк-ролей и пере-редактура — у каждого + шага цена с механизмом и файлом. + - Отдельно — порядок относительно перекроя глав: окна по ординалам, идентичность термина и главы, нормализация. + Сверка — с `CHAPTER_STRUCTURE_DESIGN.md` §4.2, рядом 161 и D39.245. +4. ⚠ **Якорь на отозванном.** Тексты `02`, `04` и ответы оркестратора в `06` сильные и неверные. Автор, прочитавший их + первыми, склонен их повторить. Отдельно — «владелец назвал логичным» не делает кандидата решением (§1, последний + абзац рамки). + +## 6. Оси проверки + +Таблица приёмки роли оркестратора. Заменить ось можно с доводом. +- **Ресёрч / текст.** Claim-fidelity: цитаты — дословные подстроки первоисточников. Типовой провал — ОВЕР-АТРИБУЦИЯ, + а не фабрикация. Пере-открыть выборку улик. Опровергатель — другой моделью. +- **Доки.** Утверждения сверяются с кодом и живыми носителями, а не с памятью агента. +- **Замеры** (для плана §13 (г)). Пере-вывод чисел из сырья, независимость сигналов, контрольная величина рядом с + каждым нулём. + +## 7. Записка-план ДО первого агента + +В начале итога — раздел «План консилиума»: углы проектов, роли, раунды, пробы, что считаешь сходимостью. + +## 8. Заявление = команда; дисциплина ответа + +- Каждое число и каждая категорика — с командой или прибором, деревом и популяцией. +- Отрицательное утверждение («не построено», «нет читателя», «ноль») печатается с контрольной величиной рядом. +- Числа входов частью сняты только оркестратором (README входов). Опираешься на них — пере-сними тем же прибором. +- Эрудиция — не улика. У утверждения есть грунт (`file:line`, замер, D-номер с пунктом) или пометка «мнение». Мнению + не место под видом факта. +- Плотность, а не объём. Без шаблонных оговорок. +- Перед итогом сверь каждый клейм с результатом инструмента ЭТОЙ сессии. Последний абзац оказался планом — сделай + его сейчас. + +## 9. Эхо-протокол старта + +1. Первое действие — свой блок в `/tmp/textmachine-channel` с `role=консилиум`. Роль `оркестратор` в файле уже занята, + и второй блок с ней сделает адрес эха неоднозначным. +2. Второе — эхо на адрес блока `role=оркестратор session=textmachine-main-75`, сверив его с `ListAgents`. Не больше 10 + строк СВОИМИ словами: скоуп · инварианты · чего не делаешь · что в этом промте считаешь неверным или опасным. + +## 10. Что НЕ удалось и где прибор слеп — обязательная секция итога + +Форма пункта: что осталось невидимым · почему не закрыл · чем закрывается. Спрашивай себя не «что не получилось», а +«что я знаю и не сказал». В коде названо, в отчёте нет — значит для следующей смены не названо. + +## 11. Канал вопросов, право отказаться и правки на ходу + +- Конфликт промта с кодом или ратифицированным — пинг оркестратору, а не интерпретация. +- Право сказать «этого делать не надо» с доводом у тебя есть. +- Решения владельца не принимаешь — ставишь их вопросами в итоге. +- **Правки заказа на ходу доезжают ТОЛЬКО релеем:** владелец пере-передаёт правку отдельным сообщением, ты + подтверждаешь её эхом и записываешь отдельным пунктом итога. Ответы оркестратора на твои вопросы по прямому + каналу — не правки заказа. + +## 12. Прямой канал + +Механизм — `CLAUDE.md` §«Связь между сессиями». Дословно: **канала нет ⇒ НЕ искать.** Нужной роли в файле нет, файла +нет или имя не отвечает — это нормальный случай. Не опрашивай сессии подряд: вопросы идут секцией итога, работа +продолжается. + +## 13. Критерий завершённости + +Итог `docs/research/35-bank-memory-consilium.md` содержит: +- **(а)** Решение одним документом: + - что банк есть; + - как проходит каждая проблема П1–П8; + - как проходит каждый класс из рамки владельца и П4, включая ответ на «есть ли еще подобные кейсы» — перечнем + классов; + - как решение не обедняет язык: какие слова остаются свободными и чем это держится; + - как оно не взрывает кардинальность банка; + - как оно не даёт терминологу выкинуть термин, который выкидывать нельзя; + - что берётся из построенного (`file:line`) и что строится нового — с таблицей §4 п.4. +- **(б)** Трейдоффы с ценой и механизмом. Обязательно — что ломается при заморозке банка: вопрос владельца «что тут не + так пойти может?». Разбор рисков из `06` — какие держатся, какие нет и почему. +- **(в)** Порядок паков относительно перекроя глав (ряд 161, D39.245), с зонами. +- **(г)** Замеры до стройки: вопрос · арм-дизайн · популяция · контроль · цена. Каждый помечен «$0» или «нужна санкция + владельца». +- **(д)** Нужные ратификации (ноты, эрраты) и правки носителей (ряды бэклога: открыть, закрыть, дописать) — списком + предложений. Среди них — расхождение D5 п.1 и D7 правки 1 с построенным: ручная половина есть, проактивной нет. +- **(е)** Не больше пяти вопросов владельцу. Каждый — по-человечески, без трекер-жаргона, со статусом (открытое + решение с номером · отложенное · новое) и с рекомендацией. +- **(ж)** Протокол консилиума: проекты · критика · записанное несогласие · кто сошёлся и почему. +- **(з)** Проверка итога: таблица «находка → что сделано → чем предъявлено». Последний круг не дал новых находок — или + остановка правилом §4 п.5 с таблицей остатка. +- **(и)** У каждого пункта этого заказа — исход: сделано · не делаю с доводом · пинг. +- **(к)** Секция §10. +- **(л)** Числа итога сняты после последней правки. Всё живое лежит в дереве, а не в письме. Мутаций нет: пак без кода. +- **(м)** Явная строка «работа завершена, править не планирую» или «работа завершена по правилу остановки, круги не + сошлись — остаток в таблице». + +**Сдача** — одно сообщение оркестратору по прямому каналу: путь итога и строка (м). Канала нет — итог и строка (м) +лежат в дереве, владелец прочитает и пере-передаст. diff --git a/docs/NEAR_TERM_PLAN.md b/docs/NEAR_TERM_PLAN.md index 1eb4afcc..01707ff1 100644 --- a/docs/NEAR_TERM_PLAN.md +++ b/docs/NEAR_TERM_PLAN.md @@ -50,7 +50,7 @@ | 7 | ~~полигон~~ | ⛔ **ЗОНА ВНЕ СКОУПА — слово владельца 11.09**; четыре промта уведены в `archive/prompts/` с баннерами | — | снято | | 8 | **бэкенд/деньги** | ⛔ **«ПАДЕНИЕ, КОТОРОЕ ВИДНО»** — четверть COGS в одном механизме (**415**), слепые приборы отказа (**414**, **422**), молчащая подстановка цены. ⚠ Пин цены **413** из пака ВЫНУТ: это данные и отдельное решение | пак, $0 | ✅ **ЗАКРЫТ АКТОМ `D39.251`** (испр. 15.09; дальше — запись 11.09) · ✍️ **НАПИСАН 11.09** — `BACKEND_FAILURE_YOU_CAN_SEE_SESSION_PROMPT.md`; выдаётся СВЕЖЕЙ сессии сразу по закрытии 4 ⛔ **КРИТЕРИЙ ПРИЁМКИ ПАКА — МЕХАНИЗМ, А НЕ ПРОПОРЦИЯ** (поправка старшего коллеги 11.09): лекарство есть распространение ратифицированного образца `D2` п.3 на вторую причину, и оно верно при 25 % и при 5 % — пропорция задаёт очерёдность, не форму. ⇒ судить по строкам «ни одного удвоения без вердикта о вырождении; каждая выброшенная попытка — строкой леджера с причиной», а не по «с 25.4 % до X». Значит прогон B пак не гейтит и паком не гейтится.| | 9 | **платформа+бэкенд** | ⭐ **ХОЛОДНЫЙ ПРОГОН B — платформа → бэкенд → файл, ВТОРОЙ раз.** Уточнение владельца 11.09: спрашивая «перепрогоны нужны», он имел в виду именно сквозной прогон, а не пере-запуск тестов. Покупает ЧЕТЫРЕ вещи, которых нет ни у кого: **(1)** миграция **v17** (`wave_selection`) пака консистентности ни разу не шла на живом прогоне — только в тестах; **(2)** прибор консистентности впервые даст числа с ЖИВОГО прогона, а не с пере-скана сохранённой базы прогона A — сегодня все `I1`/`I2` получены повторным чтением одних и тех же данных; **(3)** платформенный пак (идемпотентный резюм, терминальное состояние) проверяется сквозь, а не юнитами; **(4)** ⛔ **вторая точка по денежной дыре, и она нужна по норме, а не для красоты** — весь довод «четверть денег купила пустоту» стоит на ЧЕТЫРЁХ одиночных розыгрышах, а квирки §3д прямо говорят: смета DeepSeek с одиночного вызова может ошибиться на порядок, сметы строятся на ПОВТОРАХ. ⇒ у числа 25.4 % есть знак и нет величины, пока прогон не повторён. **Цена ≈$0.42 по образцу прогона A, машинный кап ≈$2.5.** ⛔ **ПРЕ-РЕГИСТРАЦИЯ ЗНАМЕНАТЕЛЯ, иначе B ответит числом на другой вопрос** (поправка старшего коллеги 11.09): B — ЕЩЁ ОДИН одиночный прогон, и две точки распределением не станут. Настоящая ценность B не «вторая точка к 25.4 %», а `request_log` ВСЕХ единиц прогона ⇒ **доля выброшенных первых попыток ПО ЕДИНИЦАМ, а не по вызовам.** Это и пре-регистрируется. ⚠ И идёт B **ПАРАЛЛЕЛЬНО** паку о падениях, а не после: они в РАЗНЫХ слотах (бэкенд против платформы), и правило «один промт на зону» их не сталкивает | ≈$0.42 | ✅ **ЗАКРЫТ АКТОМ `D39.252`**, факт $0.396657 | -| 10 | **бэкенд** | ⛔ **БАНК: РЕШЁННОЕ ОСТАЁТСЯ РЕШЁННЫМ** — предмет пере-определён проверкой 15.09. Пак 12.09 «в банк по разнобою» (`BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md`) снят баннером: все термы со `spread ≥ 2` уже в банке (A 9 из 9, B 8 из 8). Настоящий дефект приоритета №1 — пере-решение банка терминологом: на подписи замерено (у неподписанных строк сменились передачи A 12 из 69, B 14 из 66), на каждой следующей покупке глав выведено из кода — отгруженные главы по порядку слотов остаются со старыми передачами (`backend/internal/pipeline/volume.go`, греп `DELIVERY BEFORE REWORK`). Ряды 130 · 330 · 438 · 440 | $0 + центы перекупки банк-ролей | ⏳ ждёт слова владельца «копить ли решения банка между прогонами» (ряд 130, `research/34` §4 п.4) и слота бэкенда. Предложен порядок: РАНЬШЕ 5(в) — перекрой глав без якоря пере-решил бы банк платной книги | +| 10 | **бэкенд** | ⛔ **БАНК: РЕШЁННОЕ ОСТАЁТСЯ РЕШЁННЫМ** — предмет пере-определён проверкой 15.09. Пак 12.09 «в банк по разнобою» (`BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md`) снят баннером: все термы со `spread ≥ 2` уже в банке (A 9 из 9, B 8 из 8). Настоящий дефект приоритета №1 — пере-решение банка терминологом: на подписи замерено (у неподписанных строк сменились передачи A 12 из 69, B 14 из 66), на каждой следующей покупке глав выведено из кода — отгруженные главы по порядку слотов остаются со старыми передачами (`backend/internal/pipeline/volume.go`, греп `DELIVERY BEFORE REWORK`). Ряды 130 · 330 · 438 · 440 | $0 + центы перекупки банк-ролей | ⛔ **ПРОЕКТ ОРКЕСТРАТОРА ОТОЗВАН 15.09.** «Банк — журнал решений с окнами» (две редакции Fable 5) расходился с 12 пунктами решённого, замеренного и этого же плана и опирался примерно на десятую часть относящегося; улики — `archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/`. ⏳ **Предмет у консилиума** — `BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md`, сессия `textmachine-main-1e`, итог `research/35`. Вопросы владельцу, в том числе ряд 130 (`research/34` §4 п.4), ставит его итог; он же решает порядок относительно 5(в). Довод «перекрой глав без якоря пере-решил бы банк платной книги» остаётся входом | ⛔ **ПОЧЕМУ 4 ВСТАЛ ПЕРЕД 5 (решение 11.09 по мерилу владельца).** Мерило — «качественный КОНСИСТЕНТНЫЙ перевод длинных книг». Аудит банка 11.09 показал, что **книжного вопроса о консистентности не задаёт ни один diff --git a/docs/README.md b/docs/README.md index 61a87699..4ce1587e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -27,6 +27,7 @@ | **Бэкенд · КУПЛЕНО — ЗНАЧИТ ДОСТАВЛЕНО** | [BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md](BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md) | ⛔ **ВЫДАН 15.09 СВЕЖЕЙ СЕССИИ `textmachine-main-b1`** — разделом ПЕРЕДАЧИ (ред. 5) в начале того же промта; жду эхо. Сессия `textmachine-b1` построила пак почти целиком и ПОТЕРЯНА при переезде окружения, не объявив работу завершённой; сдача лежит застейдженной в индексе. Предмет решён владельцем — `D39.204` **с эрратой 15.09-а**: отказ резервации на ретрае — СТАНДАРТНАЯ ОСТАНОВКА (кадр `ceiling` с недостачей, не-терминальная метка позиции, пополнение и резюм доделывают юнит), а не флаг. Платформенная половина пуста по замеру сессии, акт один. $0 | | Сквозной · ХОЛОДНЫЙ ПРОГОН B | активного НЕТ | пак ОТРАБОТАН и **ПРИНЯТ 11.09** — акт **D39.252**; промт в [archive/prompts/](archive/prompts/COLD_RUN_B_SESSION_PROMPT.md) с баннером-исходом. Книга второй раз от двери до ФАЙЛА, факт **$0.396657**. ⭐ Две меры денежной дыры разошлись в РАЗНЫЕ стороны на одних данных; **85.7 % оплаченного выхода — размышление, а не текст**. ⛔ Прибор приоритета №1 солгал вердиктом по подписанному имени героя. Качество впервые судилось по ОРИГИНАЛУ рядом с переводом: 26 находок, 1 крит | | Оркестратор | [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) | роль и нормы; счётчик роли — CURRENT-STATE | + | Консилиум · БАНК ПАМЯТИ ДЛИННОЙ КНИГИ | [BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md](BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md) | ⛔ **ВЫДАН 16.09 сессии `textmachine-main-1e`** словом владельца 15.09 «передавай дела сессии, пусть наследуется от тебя»; жду эхо. Не пак кодовой зоны: совет агентов (Fable 5 — 1–2), $0 по моделям проекта, пишет только `research/35-bank-memory-consilium.md` и одноимённый каталог. Входы — [archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/](archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/README.md): отозванный проект оркестратора и сверка того, что репозиторий уже решил и построил по банку | | Бэкенд · ДВЕ ОСТАНОВКИ | активного НЕТ | пак ОТМЕНЁН ВЛАДЕЛЬЦЕМ 10.09 до лендинга — акт **D39.240**; промт в `archive/prompts/` с баннером. Причина — размах правки, не качество. ⚠ Предмет ЗАМЕНЁН и сузился: остановка остаётся жёсткой, **деньги терять допустимо**, но она обязана быть КОРРЕКТНОЙ (без гонок, без половинчатых состояний, верное возобновление). ⭐ Пак успел купить `D39.236`–`D39.238` и строку **385** | | Платформа · ДВЕ ОСТАНОВКИ | активного НЕТ | пак ОТМЕНЁН ВЛАДЕЛЬЦЕМ 10.09 до лендинга — акт **D39.240**; промт в `archive/prompts/` с баннером. Причина — размах правки, не качество. ⚠ Предмет ЗАМЕНЁН и сузился: остановка остаётся жёсткой, **деньги терять допустимо**, но она обязана быть КОРРЕКТНОЙ (без гонок, без половинчатых состояний, верное возобновление). ⭐ Пак успел купить `D39.236`–`D39.238` и строку **385** | | Бэкенд · ВЫЗОВ, КОТОРЫЙ ОБОРВАЛИ МЫ | активного НЕТ | пак ОТРАБОТАН и **ПРИНЯТ 10.09** — акт **D39.232** (`3f05fab`, 28 путей, $0); промт в `archive/prompts/` с баннером-исходом. Движок перестал платить дважды за одну генерацию; закрыты строки 360 · 369 · 78. Восемь кругов ревью; приёмка двумя рубежами нашла пять выживших мутаций на носителях ВИДИМОСТИ денег. Живое из остатков — **375** · **376** · **377** (⚠ форма испр. 10.09: здесь стоял ДИАПАЗОН «374–377», а 374 закрыта — диапазон о закрытии ряда внутри себя не узнаёт, поэтому в этой таблице только перечисления) | diff --git a/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/01-premises-verification.json b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/01-premises-verification.json new file mode 100644 index 00000000..a4de3498 --- /dev/null +++ b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/01-premises-verification.json @@ -0,0 +1,332 @@ +{ + "A": { + "verdicts": [ + { + "id": "T1", + "verdict": "PARTIAL", + "evidence": "True: default and c1 value. terminologist.go:74 `terminologyDefaultBatchRunes = 6000`. c1 sets no batch_runes: grep across configs/ finds 0 hits for batch_runes|kwic_per_term|kwic_width. The langpack can only size KWIC (langpack.go:769, keys kwic_per_term|kwic_width), and zh-ru ships no terminology.txt (0 of 16 langpack .txt files). The frozen run-B code is the same: baa06ce..5dbb5cb changes 0 backend files, and pipeline-c1.yaml sha a46b33ee… equals the purchasing-file sha in 25-door-to-file-b.md:42. Caveat: 6000 caps the rendered CANDIDATE BLOCK (unitRunes via RenderBatch, terminology.go:1253-1259), not the call. The system prompt (3093 chars stripped) is outside the cap, and a series/family unit may go over it (terminologist.go:457-466). Counts, from request_log in paid-final-project.db (copied, sha 90097e39…): terminologist 8 rows = 7 fresh + 1 tm_hit; classifier 6 fresh; 13 fresh in total. Split by pass: attempt 1 (bank stop) is classifier ids 12-14 plus terminologist ids 15-18 (chunk_idx 0..3). Attempt 2 (resume after signing) is classifier ids 25-27, terminologist ids 28-30 fresh, and id 31 = batch 3 replayed (tm_hit=1, same request_hash f9fbb1bc38, $0).", + "correction": "Batches cap the candidate block at ≤6000 runes (system prompt excluded; a unit can exceed it). On B one pass is 4 terminologist batches + 3 classifier batches. '7 and 6' (13) are paid calls summed over TWO passes: the stop and the re-mining on resume (+1 free replay). A 'batch #5' does not exist within one pass on B." + }, + { + "id": "T2", + "verdict": "PARTIAL", + "evidence": "True: a batch does not know what other batches assigned. All batch messages are built BEFORE any call (terminologist.go:925-933), and the call loop comes later (1005-1028). Wrong kinship in the claim: CANON carries no other-batch decisions at all. approvedNeighbours takes `e.Status == \"approved\" && e.Dst != \"\"` rows from the store (terminologist.go:329). CanonFor keeps only rows related to the batch by source containment or a shared rune, capped at 40 (terminology.go:856-907); an empty result sends no message (821-826). Non-empty on a first run: yes, whenever the book has a seed (memseed.go:129-131 `if status == \"\" { status = \"approved\" }`). The auto path means only 'no --verify-bank' (mining.go:27-35) and does not rule out a seed. Run B, attempt 1: glossary 0 rows (control: the same bankstop DB has bank_stop_presented=67 and a glossary table with 21 columns), so CANON was empty in all 4 batches. B's resume pass, which built the shipped bank: glossary holds approved 方源→Фан Юань and 古月山寨→крепость Гу Юэ (final DB: approved 2, draft 64). Candidates sharing runes exist (方家, 古月一族, 古月族长), so by code CanonFor was non-empty for their batches. Request bodies are not stored; indirect support: batch 3's hash is identical across attempts while batches 0-2 changed. Other things a batch sees: `related:` (only KEYS of mined surfaces it contains or is contained in, terminology.go:309-323,779-781), `aliases:`, `drafts:` from the whole book, `type:` from the classifier pass, and co-batching of series/families in ONE batch (terminologist.go:443-448). None of these carry the terminologist's renderings from other batches.", + "correction": "A batch sees nothing of other batches' renderings. ⟦TM-CANON⟧ is not a channel between batches but the book's approved rows that relate to the batch by source. It is empty on a cold book with no seed and no signatures (B attempt 1). It is non-empty with a seed or after a signature, including on the auto path (B's resume pass had 2 signed rows)." + }, + { + "id": "T3", + "verdict": "PARTIAL", + "evidence": "True: 3 contexts × 40. Defaults KWICPer=3 and width=40 (terminologist.go:75-76); c1 and the zh-ru langpack override nothing (see T1). 40 is PER SIDE and in RUNES: terminology.go:336 'up to maxPer contexts of ±width runes'; window() uses lo=rStart-width, hi=rEnd+width over rune offsets, then TrimSpace (398-413). So one ctx is ≤80 runes + the term. Measured in B's stop table, which prints the same c.KWIC (mining.go:464,568-569) that RenderBatch puts on the wire (terminology.go:796-798): 126 ctx for 66 terms, at most 3 per term (25 terms have 3). Window minus term is ≤80 (4 exactly 80, 114 in 70-79 after edge trimming). Request bodies are in no evidence: request_log has no request-text column and checkpoints keep only response_text. Frequencies: the slice is door-to-file/poscontrol-paid-holes/source.txt (sha ed870ba6… = the manifest's source_sha256, GB18030, 9021 chars = the control in 25-door-to-file-b.md:138). Counts: 家族 9, 族 29 (20 outside 家族); controls 方源 63, 古月 14. So the pack is right and the conversation ('家族 29') is wrong. More important: 家族 is NOT a candidate in either run (B: 0 of 66, A: 0 of 69), so the model never sees 家族 at all. The 族 terms in B are 九族, 古月一族, 古月族长, 宗族祠堂, 族长.", + "correction": "≤3 contexts, each ±40 runes around the occurrence (≤80+term). 家族 occurs 9 times and 族 29 times (20 outside 家族). 家族 is not in the candidate list of either run, so the terminologist gets no contexts for it at all." + }, + { + "id": "T4", + "verdict": "REFUTED", + "evidence": "Literally true: the prompt has 0 hits each for отклон, не термин, пропуст, отказ (control: TM-NO-DST 1 hit; prompt has 57 lines). But the prompt does give a decline: terminologist.md:36-37 'Если по данным контекстам ты не можешь выбрать перевод уверенно — верни ⟦TM-NO-DST⟧. Это нормальный ответ'. Parser: isNoDst sets out[key]=\"\", counted as Declined (terminology.go:1115-1121; terminologist.go:552-553). A skipped term is counted as Unanswered (549-551). A malformed line counts as Bad and its term stays unanswered. A batch never fails; an empty completion only raises a WARN (509-516, 534-537). Downstream, a term without a consolidated dst becomes status \"auto\" (miner_emit.go:251). It still receives st.Dst = props[0].Dst, the top DIRECT draft proposal (miner_emit.go:263-266); only a consolidated dst gives \"draft\" (279). So a declined term does not drop out: it keeps the draft's rendering in an auto row. Probe on a scratch copy of the package (go run), replies parsed: `家族\\tне термин\\t0` → dst \"не термин\"; `山寨\\tпропустить` → dst \"пропустить\"; `族长\\t\\t90` → dst \"90\" (OffLanguage returns false for a letterless string, script.go:31-46); `花酒` and `春秋蝉\\t—\\t10` → bad and unanswered; NO-DST → declined. Not every rendering becomes a bank row: alias-origin candidates are asked but not emitted (terminology.go:33-36); the reverse section needs a KWIC hit and is capped (mining.go:602,620-624); loadAutoBank drops rows whose UNIQUE key is taken. On B's resume, 65 consolidated gave 64 draft rows (古月山寨 is held by the signed row), with 0 declined and 0 unanswered.", + "correction": "The terminologist does have a way to decline, but only on the rendering: ⟦TM-NO-DST⟧ or silence. The term then stays status:auto and still carries the draft's top rendering. It has no verdict 'not a bank term'. A refusal written in words ('не термин', 'пропустить'), or an empty rendering column with a confidence ('90'), is accepted by the parser AS the rendering." + }, + { + "id": "T5", + "verdict": "CONFIRMED", + "evidence": "backend/prompts/zh-ru/terminologist.md:12-13: 'Ты видишь всю книгу сразу; черновики видели её по кускам и потому расходятся. Твоё дело — выбрать / ОДИН вариант на термин, единый для всей книги.' Lines 23-24: 'Расхождение вариантов — сигнал, что термин / трудный, а не подсказка, какой ответ правильный.' Word for word; the only difference is the line break (the / marks). Side note: 'видишь всю книгу' does not match the mechanism, which is ≤3 contexts of ±40 runes per term (T3)." + }, + { + "id": "T6", + "verdict": "CONFIRMED", + "evidence": "Measured on request_log in paid-final-project.db (engine ledger; provider-reported tokens × the models.yaml price pin, peak pricing per 25-door-to-file-b.md §6 п.5-6). Population: both passes (stop + resume re-mining) and both bank roles. Cost: classifier $0.045313 + terminologist $0.038026 = $0.083339, out of $0.396657 over 35 rows = 21.0%. Calls: 6+7 = 13 fresh, plus 1 tm_hit. prompt_tokens: classifier 28150 + terminologist 27445 = 55595; editor 22553 (4 calls); draft 18973 (17 rows, 11 fresh). Doc 25 prints neither '$0.083 = terminology' nor 55 595: grep for 595 gives 0 token hits; 553 appears only in µUSD 2 004 553. Its '$0.083587 = 21.1 %' (line 236) is NUMERATOR 1 (paid attempts that were thrown away), a different quantity that happens to land next to this one. Its line 254 'терминология книги $0.034726 (7)' is a third definition, from the engine's MONEY BY WHAT IT BOUGHT. On the input: per call terminology is ~4.2k vs the editor's ~5.6k. Even one pass (attempt 1: 28 728) exceeds the editor, and each bank role on its own exceeds the editor.", + "correction": "The numbers hold, but only from request_log (sum over two passes and two roles). Do not cite them as '21.1 % from doc 25': that row is thrown-away purchases, not terminology." + }, + { + "id": "T7", + "verdict": "REFUTED", + "evidence": "Role swapped: both numbers belong to the CLASSIFIER. From request_log (reasoning_in_completion / completion_tokens): classifier 27097/27754 = 97.6% (25-door-to-file-b.md:290); terminologist 19799/21394 = 92.5% (line 291); the whole terminology stage 46896/49148 = 95.4%. '2 of 6': the classifier has ok=0 on id 12 (length, $0.012646) and id 14 (finish length, degraded empty, $0.012133) out of 6 calls; that is 2 of 3 on attempt 1 and 0 of 3 on resume. The terminologist has 7 fresh calls and ok=0 on 0 of them. Backlog row 438 (BACKLOG.md:359) likewise describes the classifier ('классификатор дал asked=22 answered=4 … asked=24 answered=0').", + "correction": "On B, 97.6% of the CLASSIFIER's output was reasoning and 2 of its 6 calls failed (both on attempt 1). The terminologist: 92.5% reasoning, 0 failures out of 7." + }, + { + "id": "P1", + "verdict": "REFUTED", + "evidence": "(a) Batches run SEQUENTIALLY: terminologist.go:1005-1028 is a plain loop; the file has 0 goroutines and 0 errgroup/WaitGroup (control: 2 'for i := range batches' loops). But every batch's messages are built before the first call (925-933), because the estimate and the per-batch paid-probe/admission (970-994, 'decided BEFORE the first call' 947-964) read msgsPer[i]. If batch i depends on the reply of i-1, both the up-front budget cut and bankCheckpointExists for later batches cannot be computed ahead; the pass has to be restructured. (b) RequestHash folds every message's content (render.go:374-377 `w(m.Role, m.Content, …)`), and the CANON block is an injection message (terminologist.go:640-642). The mechanism is visible on B: batch 3 kept hash f9fbb1bc38 and replayed for $0 (id 31); batches 0-2 changed and were bought again. Under P1 a resume that replays ALL earlier batches keeps the later hashes (a replay returns the stored text). But any re-bought earlier batch changes every later hash and re-buys them all: a burned/empty/length checkpoint is walked past, a budget-cut batch gets bought, or the composition changes. On B, classifier batches 0 and 2 were exactly such attempts. 'Zero new requests' holds for the call count, not for input tokens. (c) CanonFor sorts by containment(2) > shared rune(1) > number of shared runes > src, then `picked = picked[:max]` (terminology.go:890-901): the least related rows are cut silently. There is one use site (terminologist.go:642), with no log and no counter. The selection is also by SOURCE relatedness, so a name already taken by a source-unrelated term never reaches the block at all. (d) Only probabilistic: CANON is a prompt instruction (terminologist.md:25-28). ParseReply does not check renderings against CANON (terminology.go:1078-1151). CanonConflicts is containment-only and 'REPORTS, and only reports' (924-928); ConsolidationConflicts is also containment-only. The only same-rendering check, InjectivityCollisions, is approved-only and log-only (membank/memory.go:1237-1262, called at seeding.go:64). The code itself records a live violation with the block on the wire (terminology.go:918-921: 一代族长 → «Первый глава рода» against the signed «глава клана»).", + "correction": "Putting this run's renderings into the block is possible without new calls, but only by rebuilding the pre-built messages and the budget admission. Every later batch's hash then depends on earlier replies, so re-buying one batch cascades. Truncation at 40 is silent, and selection by source relatedness does not surface a collision between unrelated sources. The result is lower collision probability; a guarantee would need a $0 post-check (for example an injectivity check over this run's consolidations), because the prompt alone does not deliver it." + }, + { + "id": "P3", + "verdict": "PARTIAL", + "evidence": "No per-term knob exists: AttachKWIC(cands, chunks, maxPer, width) applies one pair of values to all candidates (terminology.go:340-361; terminologist.go:279-280). The only sources are the gate's kwic_per_term/kwic_width, per book and not snapshot-folded (config/pipeline.go:342-346), then the pair's langpack terminology.txt (lang/langpack.go:133-137), then the defaults. So 'rich context only for spread>=2' needs new code, not a config change. Spread is known before the calls: ScoreVariants runs in buildBankCandidates (terminologist.go:282-285). What dominates the input: a full batch is ~4.2-4.8k prompt_tokens (request_log ids 12-17, 25-30), the smallest batch is 1446 (id 18), and the stripped system prompt is 3093 chars. By reconstruction from B's stop table (≈, without evidence/related lines), ctx is ≈62.5% of the candidate block's runes (10 576 vs ~6 358). So the KWIC contexts are the largest single part. The classifier ships the same RenderBatch with ctx (terminologist.go:727-730), so wider contexts cost in BOTH roles. Target population on B: spread>=2 for 8 of 66 (distribution 1:58, 2:4, 3:3, 4:1); conventions>=2 also 8. Note: widening ctx changes the rune packing of batches and thus the hashes (a one-time re-buy on books that already paid).", + "correction": "There is no per-term knob today, only per book/pair; the targeted variant needs code. Spread is available before the call. On B, spread≥2 covers 8 of 66, so the targeting is real. Widening applies to both roles and changes the batching." + } + ], + "extra_findings": [ + { + "title": "A refusal written in words, or an empty rendering column, is banked AS the rendering", + "evidence": "On a scratch copy of internal/terminology (go run), ParseReply accepted `家族\\tне термин\\t0` → «не термин», `山寨\\tпропустить` → «пропустить», and `族长\\t\\t90` → «90». Why: replyColumns drops the empty field, so the confidence moves into the dst slot (terminology.go:722-731). wellFormedLemma passes for 2 runes (643-655). OffLanguage returns false for a string with no letters (script.go:31-46). Such a term counts as Consolidated, gets status:draft (miner_emit.go:279) and goes to the editor as this book's canon.", + "why_it_matters": "The target construction adds a 'binary right to refuse'. If the refusal is expressed in words, or the model leaves the rendering column empty, today's parser turns the refusal into a bank row with a garbage rendering, with zero bad_lines. Refusal needs a sentinel and a guard against letterless/numeric renderings; otherwise 'not in the bank' becomes 'in the bank as law with the text «не термин»'." + }, + { + "title": "A 'declined' term does not leave the bank: it keeps the draft's rendering in an auto row", + "evidence": "DeltaFile: `st := seed.Term{… Status: \"auto\" …}`; then `if props[0].Via == \"\" { st.Dst = props[0].Dst }` (miner_emit.go:251, 263-266). This happens regardless of whether the terminologist answered ⟦TM-NO-DST⟧. loadAutoBank loads auto/draft rows into the bank (mining.go:676-700), and mining.go:34 says undecided rows ride to the editor as unsigned auto-bank surfaces.", + "why_it_matters": "'Not into the bank at all' is not achievable through today's decline: a banknote candidate (62 of 66 on B) always has a direct draft proposal, so its row keeps a rendering. A new refusal must cut the emission, not only the consolidated dst." + }, + { + "title": "CANON is non-empty on the auto path too (seed / earlier signature), and the shipped bank on B came from a pass with a non-empty block", + "evidence": "memseed.go:129-131 (seed status defaults to approved); final B glossary: approved 2 (方源, 古月山寨), draft 64; the resume pass re-bought batches 0-2 (new hashes) and replayed batch 3 (hash f9fbb1bc38 unchanged).", + "why_it_matters": "The premise 'on the default path the block is always empty, so filling it with this run's renderings changes nothing else' is false. Once signed rows exist, they and this run's renderings share the 40 cap, and the silent truncation (terminology.go:899-901) then cuts one of the two sources with no signal." + } + ], + "obstacles": "1. The request bodies of the bank roles are stored nowhere in the evidence: request_log has no request-text column and checkpoints keep only response_text. So what exactly went into ⟦TM-CANON⟧ on B's resume pass is inferred from code plus the glossary plus the hash change, not read off the wire. KWIC was measured on the stop-table projection, which prints the same c.KWIC.\n2. The complete runs A/B on the other machine (~/tm-coldrun-a/b) were not needed: the 35-row request_log and the 66-row glossary for B are in books/gu-zhenren/door-to-file-b/paid-final-project.db, read from a copy in scratch (sha matches). Run A was not checked for the numbers in T6/T7, as it was not required.\n3. The 66→65 candidate drop on resume and the 22/19/24 split come from the log lines quoted in live-journal/doc 25; the engine log of the resume attempt is not in the evidence (daemon-paid.log has 0 terminolog lines out of 88).\n4. The ctx share in the input (≈62.5%) is a rune-level reconstruction without the evidence/related lines and without a tokenizer; it gives the order of magnitude, not the token share.\n5. The ParseReply probe ran on a copy of the package in scratch, not through go test in the tree; behaviour is identical because the package is pure stdlib.\n6. I did not check whether status:auto rows with a dst are injected to the editor on the current wire; I relied on the comment at mining.go:34 and D39.104 п.2.\n7. Frequencies were counted on the raw GB18030 slice, not on normalized NSource, so they can differ from the miner's freq for traditional-character forms." + }, + "B": { + "verdicts": [ + { + "id": "B1", + "verdict": "PARTIAL", + "evidence": "Цитата дословна: backend/internal/pipeline/bookconsistency.go:31-32 `the engine's default is to auto-continue with an unsigned bank, and `--verify-bank` is a pause / to look, not a march down the rows`.\n\nДвижок и CLI:\n- cmd/tmctl/invocation.go:141 `fs.Bool(\"verify-bank\", false, \"... Default: never stop\")`.\n- pipeline/runner.go:64-67 `Default OFF: the run consolidates what it mined, carries it forward marked-unverified, and finishes`.\n- Стоп бывает только при `r.VerifyBank && editWave` (mining.go:216) и только на новом кластере (`stopping = hasUnpresentedCluster(...)`, :221). Иначе срабатывает авто-провод :234-250 с логом `bank-mining: auto-continuing with an UNSIGNED bank`.\n- Подписи не делает ни одна ветка: подпись — отдельный акт bank-apply.\n\nПлатформа: дефолта на проводе НЕТ.\n- platform/internal/httpapi/v0.go:349 `StopForSigning *bool`; :654-655 `if req.StopForSigning == nil { Invalid(... ItemMissing)`.\n- openapi.yaml:2650 `required: [stop_for_signing]`.\n- При true `--verify-bank` уходит в argv каждой попытки (runs/spawn.go:182, runner/engine.go:119-120).\n- frontend/src: 0 упоминаний stop_for_signing в 113 файлах, UI-дефолта нет вообще.\n\nПрогон B:\n- на стопе bankstop/project.db.bank.json `total 0, signed 0, as_of bank-mining/signature-stop`;\n- финальный paid-final-project.db: 66 строк, draft 64, approved 2.", + "correction": "В движке (CLI) флаг по умолчанию выключен: прогон авто-продолжает с неподписанным банком. `--verify-bank` — пауза только на НОВЫХ кластерах, и она ничего не подписывает. На пути платформы дефолта нет: `stop_for_signing` — обязательный булев параметр каждого прогона. false даёт ту же авто-семантику, true передаёт `--verify-bank` на все попытки." + }, + { + "id": "B2", + "verdict": "REFUTED", + "evidence": "(1) Статус.\n- miner_emit.go:251 ставит `Status: \"auto\"`, но :278-279 `if m.Dst != \"\" { st.Dst, st.Status = m.Dst, \"draft\"`.\n- То есть строка с dst, консолидированным терминологом, пишется как draft; auto остаётся только строке без dst.\n- Карты подписи: у A 69 из 69 `status: draft`, у B 66 из 66 `status: draft`.\n\n(2) Строка становится термином без подписи.\n- mining.go:234-245 `if !stopping { ... r.writeAutoBank(...) ... r.seedGlossary(ctx)`: строки пере-сидятся в глоссарий в той же границе, с `e.Source = \"mined\"` (mining.go:734).\n- Прогон B: снимок на стопе — glossary 0 строк (таблица есть, всего 17 таблиц). Финал paid-final-project.db — 66 строк: draft 64, approved 2.\n\n(3) Как неподписанное доходит до редактора.\n- Волна правки выбирает по обогащённому банку: waverun.go:717 `editSel = r.memory.Select(...)`.\n- editorLines рендерит каждую строку с непустым dst как `\"- \" + src + \" → «\" + dst + \"»\"` (memory.go:935), без пометки.\n- Пропускаются только пустой dst (:916-918) и неподписанная строка при подписанной с тем же src (:925-927).\n- memory.go:762: `NO ⟨проверить⟩ MARKER, and no fork by status at all (D39.104 п.2, backlog row 134)`.\n- Заголовок блока звучит как закон: lang/data/injection.txt:7 `КАНОНИЧЕСКИЕ ПЕРЕВОДЫ ... ДОЛЖЕН быть передан именно указанной формой справа`.\n- Снапшот прогона B несёт `render_format_version: renderfmt-v4-one-law-block+no-unverified-marker+draft-gender-on-match`.\n- dst-пустые auto-строки не инжектируются.\n\n(4) Сверка с решениями.\n- D39.42 п.3 (05-decisions-log.md:271: «с маркером ⟨проверить⟩») на проводе снят D39.104 п.2 (05-decisions-log.md:357: «маркер ⟨проверить⟩ с провода снимается»); п.1 — «ЗАКОН для всех ролей, независимо от статуса строки».\n- Строка реестра D39.42 сама ссылается: «маркер/двухсекционка на проводе → доктрина D39.104».\n- Устаревшие описания пометки живы: mining.go:212; invocation.go:141 (`ride to the editor marked`); platform runs/spawn.go:176-177 (`marked ⟨проверить⟩`); bankmaterialize.go:118-119 (`separately-headed unverified section`); injection.txt:6 — заголовок черновика до сих пор про «строки с пометкой ⟨проверить⟩».\n\n(5) Что подпись ещё решает: пост-чек считает промах только для Confirmed (mempostcheck.go:154), а Confirmed = approved (memory.go:700-707).", + "correction": "Строки с dst терминолога ложатся как status: draft; auto — только строки без dst. В каждом прогоне, который не останавливается, они сразу попадают в глоссарий и едут редактору ЗАКОНОМ в одном блоке с подписанными, без пометки: D39.104 п.2 отменил пометку из D39.42. Не инжектируются только auto-строки без dst. Подпись нужна не для инжекта, а для Confirmed в пост-чеке и для приоритета при коллизии с тем же src." + }, + { + "id": "B3", + "verdict": "REFUTED", + "evidence": "Петли «банк → черновик → Spread → приём» в коде нет ни на одном прогоне.\n\n(1) Внутри прогона черновая волна заканчивается ДО майнинга: стоп стоит после волны (waverun.go:178-179).\n\n(2) Черновик всегда выбирает по базовому банку.\n- bookrun.go:207 `precomputeSticky(chunks, r.baseMemory, ...)`.\n- bankmaterialize.go:321 `if row.Source == \"mined\" {` — такие строки исключаются из базового банка.\n- Source mined получают и авто-банк (mining.go:734), и подписанная владельцем дельта (mining.go:984).\n- Снапшот черновой волны сворачивает baseMemoryVersion (snapshot.go:229-233).\n- Исполнение: `go test ./internal/pipeline -run TestWaveMinedSignDoesNotRebillDraft -v` → `--- PASS (0.27s)`. Тест утверждает, что ContentHash черновика не меняется после подписанной mined-строки.\n- Прогон B: снапшот черновика fef36e1dd642 с memory_version a47d11ec… одинаков в базе на стопе (0 строк банка) и в финальной базе (66 строк). Снапшот правки 9ae4e88aa354 несёт другой memory_version 15a142bf….\n\n(3) Spread в приёме не читается — см. B5.\n\nКто прав. Ряд 409 прав по механизму, но «на первом прогоне» сужает: условие действует на КАЖДОМ прогоне, резюме и следующем заказе. В черновик попадают только glossary_seed и ruby, а bank-apply seed не пишет (18-bank-ontology.md:15).\n\nС кодом расходятся D39.42 п.3 («и черновикам следующих прогонов») и комментарий mining.go:236-237 `and the next run's drafts do too`.\n\nРеальная обратная связь есть только через ПОДПИСЬ:\n- approved-строки остаются seed-поверхностями майнера (mining.go:98 `unsignedEngineSurfaces(seed)`) и гасят свои кластеры (miner_emit.go:177-181);\n- в журнале A (подписано 2, checks/bank-after.json `signed 2`) попытка 2 даёт `eligible=4 … emitted_by_miner=2` против `eligible=5 … emitted_by_miner=4` на попытке 1.", + "correction": "Прав ряд 409, и шире, чем он записан. Черновая волна никогда не видит Source:mined-строк — ни авто-банка, ни подписанной дельты — ни на первом прогоне, ни на резюме, ни на следующем; в черновик идёт только glossary_seed/ruby. Разнобой черновиков от добытого банка не зависит. На приём банк влияет только через подписанные строки (они становятся seed-поверхностями майнера), а не через Spread." + }, + { + "id": "B4", + "verdict": "PARTIAL", + "evidence": "Код процитирован верно:\n- miner_emit.go:346 `if !hasAnyType(c.Types, \"name\", \"place\", \"title\")`;\n- :349 `if c.Freq < emitMinFreq || subsumed[c.Src] || runeLen(c.Src) < 2`;\n- третье условие isFragment (:352) в утверждении опущено;\n- emitMinFreq=5 (:27).\n\nНо фильтру предшествует срез: miner_emit.go:126-129 `if len(ranked) > emitRankCap { ranked = ranked[:emitRankCap] }` (emitRankCap=200), и emissionEligible зовётся только по этому срезу (:132-137).\n\nИсполнение: go test -overlay в /home/ubuntu/tm-verify-1509/backend, харнесс лежит в scratchpad, git status после прогона — 0 строк. Контроли:\n- `pack.Version()=langpack-v2-43b3ebed3362` — совпадает со снапшотом B;\n- `chapters=3 chunks=6 per-chapter=map[1:2 2:2 3:2]` — совпадает с манифестом;\n- `funnel ranked=1670 after_cap=200 eligible=5 emitted=4` — совпадает с door-to-file/journal/run-attempt-1.log;\n- emitted `古月山寨(place), 方正(name), 方源(name), 沈翠(name)` — это те же 4 строки channel both в bank.json A и B.\n\nПробы:\n- `家族: raw=9 freq=9 rank=981 inTop200=false types=[]`;\n- `族: raw=29 freq=29 rank=1021 inTop200=false types=[]`;\n- `族长: freq=12 rank=473 types=[title] eligible=true` — отсечён только срезом.\n\nПорог среза `ranked[199].Score=180.0000`. V-A-скор: 家族 33.72, 族 18.56. Контрфактуал без словарной статьи контраста: 家族 → 67.24, всё ещё < 180. `top-200: with name|place|title type=189, without=11`.\n\nВывод: ни 族, ни 家族 до emissionEligible не дошли. Окажись они в срезе, оба пали бы на ПЕРВОМ условии (types=[]), так что «族 — как одноруний» неверно даже контрфактуально. Частоты 9 и 29, две руны у 家族 и порог 5 — верны.", + "correction": "Оба термина отсечены ДО emissionEligible — срезом top-200 по скору: ранги 981 и 1021 из 1670. Порог 180 держат кандидаты с паттерн-бонусом: у 189 из 200 есть тип name|place|title. Внутри среза оба пали бы на типе (первое условие). Вывод «детерминированный канал эмитирует только name|place|title» верен, атрибуция «族 — по длине, 家族 — по типу» — нет. Если убрать словарную статью 家族 из контраста, он в срез всё равно не входит (67 < 180)." + }, + { + "id": "B5", + "verdict": "CONFIRMED", + "evidence": "Нули с контролем (grep -ci):\n- miner_emit.go (425 строк): spread=0, convention=0; контроль `Freq`=5.\n- miner_detect.go (160 строк): spread=0, convention=0; контроль `Freq`=22.\n- В пакете miner «spread» встречается только в комментариях о снятом λ-множителе (miner.go:19, 27, 61).\n\nВызовов Spread()/Conventions() вне тестов во всём backend — один: mining.go:463 (bankStopRows). Оттуда значения идут только в проекции: .bank-stop.txt и секцию proposed в bank.json (bankexport.go:249).\n\nДвери приёма без Spread:\n- эмиссия майнера, miner_emit.go:126-212;\n- reverseSectionTerms, mining.go:601-627: origin banknote + есть KWIC + не seed и не reject + срез по Freq.\n\nГде участвуют ВАРИАНТЫ черновиков (не Spread):\n- dropBankSettled/bankSettles (terminologist.go:1173-1240) решают, какие кандидаты ПЛАТНО идут терминологу. Banknote-кандидат на подписанной seed-поверхности пропускается, если все варианты равны банку; код сам называет это `output-equivalent for the delta`.\n- ScoreVariants задаёт порядок предложений.\n- Строка `drafts:` в RenderBatch уходит на провод терминолога (terminology.go:785-795) и влияет на dst, а не на допуск.\n\nПлатформа: «spread» в 3 файлах про бюджет и цену (books/parse.go:51, pricing/pricing.go:48, httpapi/v0.go:282), не про банк. frontend/src: 0 из 113 файлов.", + "correction": "Верно шире, чем сформулировано: Spread и Conventions — только проекции (таблица стопа и bank.json), и нигде в отборе не читаются. Варианты черновиков влияют на то, кого оплачивают терминологу, и на dst, но не на допуск в дельту." + }, + { + "id": "B6", + "verdict": "CONFIRMED", + "evidence": "Критерий «обычный термин»: тип строки банка == term, то есть не name, place, title или nickname.\n\nПрогон B, финальный глоссарий (paid-final-project.db, после резюме с чистой классификацией):\n- 66 строк: term=30, title=18, name=11, place=7;\n- все 30 term-строк — channel banknote (джойн с bankstop bank.json: `banknote: 30`);\n- строк both=4: name 3 + place 1.\n\nНа стопе B (попытка 1): kind term 33 из 66, все banknote.\n\nПрогон A, стоп: term 34 из 69, все banknote (kind×channel: term/banknote 34); both=4, это name 3 + place 1.\n\nСтруктурно:\n- майнер допускает только кандидата с паттерн-типом name|place|title (miner_emit.go:346);\n- вторая дверь — reverseSectionTerms, пропускающий только banknote (mining.go:602 `c.Origin != terminology.OriginBanknote` → skip).", + "correction": "«30 из 66» — это финальный глоссарий B после пере-классификации на резюме. На стопе того же прогона было 33 из 66, у A на стопе — 34 из 69. «Только через банкноту» верно для обоих прогонов. Но тип сам LLM-стохастичен (см. B7), и майнерская строка структурно может стать term после пере-классификации (attachClassifiedType, terminologist.go:1110-1122) — в этих прогонах не наблюдалось." + }, + { + "id": "B7", + "verdict": "CONFIRMED", + "evidence": "Предохранитель действительно держится на типе, но тип — не свойство источника. Цепочка:\n\n(а) Майнерская строка: первый паттерн-тип из langpack, детерминирован (miner.go:98-121; miner_emit.go:204-207).\n\n(б) Банкнотная строка: kind из строки банкноты ЧЕРНОВИКА, первый увиденный. banknote.go:500 `a = &bankAgg{src: src, typ: p.Type, ...}` → Observed.Type (:532) → Merge (terminology.go:186, 205). Это LLM-выход переводчика; допустимый словарь включает nickname (terminology/classify.go:27 `CandidateTypes = {... \"nickname\": true}`).\n\n(в) Классификатор-LLM перезаписывает тип, если ответил: applyTypes (terminologist.go:734-744), attachClassifiedType (:1110-1122). У провального батча остаётся тип черновика: terminologist.go:693 `its terms keep the draft heuristic type`.\n\nПровал в B по сырью, bankstop request_log:\n- classifier batch0: `finish_reason=length completion=8000 cost=0.012646 ok=0`;\n- batch2: `length 8000 0.012133 ok=0`;\n- batch1: `stop ok=1`.\n\nСчёт «asked=22 answered=4 / asked=24 answered=0» есть только в live-journal.md:22-23; в daemon-paid.log 0 строк classify из 88. Журнал называет причину батча 2 `empty`, а request_log пишет `length`.\n\nСтохастика внутри B: стоп → финал, 7 из 66 сменили тип:\n- 凤雏, 卧龙, 方老魔: nickname→name;\n- 丙等, 更夫, 甲等: term→title;\n- 沈嬷嬷: title→name.\n\nМежду прогонами: A-стоп (классификатор ответил полностью) против B-финала (тоже полностью). Из 53 общих src тип разный у 7, у 6 — через границу {name,place,title}↔term:\n- 三转蛊师 term→title;\n- 侧室 title→term;\n- 方家 term→name;\n- 更夫 term→title;\n- 老嬷嬷 title→term;\n- 魔道巨擘 title→term.", + "correction": "Тип — метка двух LLM (сначала банкнота черновика, потом классификатор), и на резюме её перезаписывают. У провального батча остаётся метка черновика, включая nickname вне тройки name|place|title. Между двумя прогонами одной книги с полностью ответившим классификатором 6 из 53 общих терминов перешли границу «есть право отказа / нет права отказа». Предохранитель на типе ограждает не набор сущностей, а стохастическую метку." + }, + { + "id": "P2", + "verdict": "REFUTED", + "evidence": "Что двигает версию памяти:\n- memory_version = ComputeVersionScopedIn по ВСЕМ строкам, поля Status, Src, Dst, Sense, Type, Gender, Decl, окна, AllowShort, алиасы (memory.go:413-470).\n- Версий две, обогащённая и базовая (memory.go:366-367): волна правки сворачивает обогащённую, черновая — базовую без Source:mined (snapshot.go:229-233).\n- Любая смена состава, dst или типа добытых строк двигает снапшот волны правки.\n- Данные langpack сворачиваются в снапшоты ОБЕИХ волн (snapshot.go:477 `LangpackVersion: r.packVersion()`) → moveOther, $0-перепина нет (repin.go:44-50).\n\nПочему пере-покупаются банк-роли:\n- батч адресован хешем запроса (terminologist.go:1160; bankCheckpointExists :809-811);\n- запрос = RenderBatch (тип, origin, freq, алиасы, related, evidence, drafts, ctx; terminology.go:771-800) + канон;\n- значит, смена входа = пере-покупка.\n\nЗамер на самом B (без лендинга; вход поменяли две подписи между стопом и резюме). В request_log финала ids 25-30 — классификатор 3/3 и терминолог 3/4 куплены заново; id 31 — $0 и 0 токенов. Сумма $0.033792.\n\nГард задания:\n- stagerun.go:54-62: при `job.SnapshotID != snapID` и без `--resnapshot` — ошибка `re-run with --resnapshot`.\n- UpdateJobSnapshot зовётся только под флагом (stagerun.go:63, единственный вызов вне тестов).\n- $0-перепин при сдвиге только банка относится к chunk_status и срабатывает ПОСЛЕ гарда (stagerun.go:94).\n- Согласие на пере-оплату спрашивается один раз, до волн (bookrun.go:229; вне тестов есть ещё только status.go:1217), а майнинг пере-сидит банк посреди прогона (mining.go:241-245).\n\n(а) Новая книга: заданий и чекпойнтов нет — бесплатно, меняется только содержимое банка.\n\n(б) Резюме после лендинга:\n- на стопе подписи заданий правки ещё нет (в bankstop B jobs: draft×3 + terminology×1) → пере-покупка банк-ролей (центы, как в B);\n- посреди волны правки задания закреплены за старым снапшотом → без `--resnapshot` движок отказывает;\n- платформа повторяет argv допуска (reconcile.go:1601-1603), а первый прогон книги допускается с resnapshot=false (runs.go:447 `resnapshot := book.BankMoved || book.HasPriorRun`) → прогон падает.\n\n(в) Уже переведённые книги:\n- следующий translate или пере-проход пере-майнит;\n- платформа ставит resnapshot при HasPriorRun, пере-проход — всегда с `Resnapshot: true` и согласием в размере холда (runs.go:472-473);\n- юниты, где срабатывают изменённые строки, пере-редактируются за деньги, остальные перепиниваются за $0;\n- банк-роли покупаются заново.", + "correction": "Бесплатно только для новых книг. Смена приёма или входа терминолога двигает memory_version волны правки везде, где меняется состав банка. На резюме и на следующем прогоне банк-роли пере-покупаются (центы). Посреди волны правки без --resnapshot прогон падает на гарде; на платформе это первый прогон книги. У переведённых книг следующий прогон пере-редактирует затронутые юниты — с согласием, в пределах холда. Если правка приёма ляжет данными langpack, сдвигаются снапшоты ОБЕИХ волн у всех книг пары, и $0-перепин не применим." + } + ], + "extra_findings": [ + { + "title": "Срез top-200 стоит ДО любого критерия приёма майнерского канала, и порог держат типизированные кандидаты", + "evidence": "miner_emit.go:126-129 режет ranked[:emitRankCap] до emissionEligible (:132-137). Прогон харнесса (go test -overlay, контроли совпали: 1670/200/5/4):\n- порог `ranked[199].Score=180.0000`;\n- `top-200: with name|place|title type=189, without=11`;\n- 家族 на ранге 981 (скор 33.7), 族 на 1021 (18.6), 族长 на 473 (types=[title], eligible=true — отсечён ТОЛЬКО срезом).\nВторая дверь, reverseSectionTerms, тоже режется на 200 по Freq (mining.go:625-627).", + "why_it_matters": "Если заменить emissionEligible критерием референтности, 家族, 族 и 族长 на этой книге всё равно не попадут в майнерский канал: они не проходят в срез, а порог 180 создаёт паттерн-бонус, то есть тот же тип. Для конструкции единственной дверью таких слов остаётся банкнота черновика, у которой тоже свой срез." + }, + { + "title": "«Закон для редактора» — свойство провода, а не гейта: неподписанные строки не проверяются пост-чеком как Confirmed", + "evidence": "mempostcheck.go:154: `case p.Disp == Confirmed:` — только такой промах считается. dispositionFor (memory.go:700-707) даёт Confirmed только approved. bookconsistency.go:36-42 сам называет, что `n_postcheck_miss = 0` при 18 отклонениях. В финальном банке B 64 из 66 строк неподписаны.", + "why_it_matters": "Конструкция объявляет банк законом для редактора всегда. Сегодня нарушение закона на авто-строке (это 97% банка B) не даёт Confirmed-промаха и не флагирует юнит, то есть закон ничем не принуждается." + }, + { + "title": "Если ⟦TM-CANON⟧ понесёт передачи этого же прогона, батчи терминолога станут цепочкой хешей, и один сгоревший батч пере-покупает всё ниже", + "evidence": "Сейчас канон читается один раз на весь проход: в runTerminologist `bank := r.glossaryRows()` / `canon := approvedNeighbours(bank)` под комментарием `The bank is read ONCE for the whole role, not per batch`. Батч адресован хешем запроса (terminologist.go:1160). Сгоревший батч `recorded money with no result and cannot be replayed` (terminologist.go:498). В B на попытке 1 сгорели 2 батча классификатора (request_log ok=0, finish_reason=length), и на резюме пере-куплено 6 из 7 батчей банк-ролей ($0.033792).", + "why_it_matters": "В целевой конструкции байты батча N зависят от ответов батчей 1..N-1. Стохастический или сгоревший ранний батч меняет хеши всех последующих, и резюме пере-покупает весь проход. Новый консолидированный банк затем двигает memory_version волны правки (P2). Сегодняшняя независимость батчей ограничивает ущерб одним батчем." + } + ], + "obstacles": "Проверено:\n- Весь код читал только в /home/ubuntu/tm-verify-1509 (HEAD 5dbb5cb).\n- go test запускал только там: TestWaveMinedSignDoesNotRebillDraft и собственный харнесс майнера через `-overlay`. Файл харнесса лежит в scratchpad/verify-B; после прогонов git status замороженного дерева — 0 строк.\n- Базы B копировал в scratchpad и открывал только mode=ro.\n\nЧего не хватало и где прибор слеп:\n1) Каталоги /mnt/d/tm-coldrun-b/mirror/cfg и material были видны один раз и затем исчезли (монтирование в движении). Контраст из самого прогона (mining-contrast.zh.txt) я не хешировал. Вместо него — /home/ubuntu/projects/textmachine/eval/exp16/data/jieba_dict_general_zh.txt: тот же размер 5071852 байт и 349046 строк. Langpack взят из замороженного дерева, его версия langpack-v2-43b3ebed3362 равна снапшоту B. Воспроизведение майнера подтверждено контролями: воронка 1670/200/5/4 и тот же набор из 4 emitted-терминов. Байтовое равенство контраста не доказано.\n2) В daemon-paid.log B нет строки воронки майнера (0 совпадений из 88 строк). Контроль воронки взят из журнала A — источник тот же (sha ed870ba6…), версия чанкера та же. У B совпадает косвенно: 4 строки channel both.\n3) Полная база A недоступна: checks/bank-after.json — страница из 3 термов. Типы A взяты со стопа A (по live-journal.md классификатор там ответил полностью), финальных типов A нет.\n4) Счёт ответов классификатора B (22/4, 24/0) есть только в live-journal.md. В сыром request_log видно лишь finish_reason=length у двух оплаченных батчей, ok=0; число «42» напрямую из сырья не пересчитано.\n5) Вопреки ожиданию, база B с полным глоссарием (66 строк) и request_log (35 строк) лежит в books (door-to-file-b/paid-final-project.db). Поэтому B6, B7 и P2 для B проверены по ней, а не признаны непроверяемыми.\n6) P2 (б) и (в) выведены из путей кода: гард задания, согласие на пере-оплату, argv допуска на платформе. Резюме после реального лендинга, меняющего приём, я не исполнял. Утверждение, что главы вне нового заказа не пере-редактируются, не проверял и в вердикт не включал.\n7) Путь платформы проверен только чтением кода. Во frontend/src параметр stop_for_signing не встречается ни разу, поэтому UI-дефолт проверить нечем." + }, + "C": { + "verdicts": [ + { + "id": "S1", + "verdict": "CONFIRMED", + "control": "python по door-to-file-b/bankstop/project.db.bank.json: proposed=66, из них 66 строк несут поле conventions. По прогону A (door-to-file/bankstop-paid/project.db.bank.json): proposed=69, поле conventions есть у 0 из 69 строк, поэтому для A распределение conventions снято с project.db.bank-stop.txt (разобрано 69 блоков из 69).", + "evidence": "B: распределение spread [(1,58),(2,4),(3,3),(4,1)]. spread>=2 у 8 из 66 = 12.1%: 丙等, 古月山寨, 家老, 开窍大典, 甲等资质, 舅母, 蛊师, 高脚吊楼. conventions дал то же [(1,58),(2,4),(3,3),(4,1)]; строк, где conventions!=spread, 0 из 66.\nA: 69 строк, spread [(1,60),(2,6),(3,2),(4,1)]. spread>=2 у 9 из 69 = 13.0%: 三转蛊师, 古月山寨, 家老, 开窍大典, 甲等资质, 舅母, 舅父舅母, 高脚吊楼, 魔道巨擘. conventions в bank-stop.txt: [(1,60),(2,6),(3,3)]. Расхождение в одной строке: 开窍大典 spread=4 conventions=3.\nОпределения: terminology.go:665-680 `func (c Candidate) Spread() int` считает сырые формы черновиков; terminology.go:686 `func (c Candidate) Conventions() int { return len(c.Variants) }` — число решений после свёртки формы.\nПопуляция — строки таблицы стопа: bank.json as_of=\"bank-mining/signature-stop\", consolidation {consolidated:66, declined:0, never_asked:0}. Копия stopB.db, retrieval_state.banknote_detail (поле \"s\"): 6 чанков, 93 предложения по чанкам, 66 различных src на книгу. Все 66 есть в таблице стопа, лишних 0.", + "correction": "Верно про B. В B таблица стопа совпадает с объединением всех банкнот-предложений черновика (93 по чанкам → 66 уникальных, фильтр до стопа не отсёк ни одной). Значит, «не все поверхности черновика» верно только в одном смысле: сюда не входят слова, которые переводчик банкнотой не назвал (家族, 族 — ряд 440). В A равенства spread и conventions нет: 9/69 (13%), conventions 60/6/3 против spread 60/6/2/1, расхождение на 开窍大典. Spread — метрика черновика; последующая пере-консолидация dst её не меняет." + }, + { + "id": "S2", + "verdict": "PARTIAL", + "control": "Проверено пар dst: A 2346, B 2145. Различных dst: A 68 при 69 строках, B 66 при 66. В финальных банках (строк: A 69, B 66) различных dst: A 69, B 65.", + "evidence": "Банк на стопе (bank.json), вопреки утверждению: A — 1 точная коллизия, B — 0.\n- A: 'родовой храм предков' ← ['宗族祠堂','宗祖祠堂'] (оба place/banknote/spread 1); в mined-signature.yaml:436,452 то же.\n- B: 宗族祠堂→«родовой храм предков», 宗祖祠153→«храм предков», в bank-stop.txt помечен `INVENTED(no draft proposed it)`, черновик давал «родовое святилище»; mined-signature.yaml:357 `dst: храм предков`.\n- После нормализации регистра, ё и пробелов: A 1, B 0. Грубый стем (срез двух последних букв): A 1 (та же пара), B 0.\nФинальные банки: числа утверждения сходятся.\n- B: копия paid-final-project.db, glossary 66 строк; точная коллизия {'родовой храм предков': ['宗族祠堂','宗祖祠堂']}, обе строки draft/mined. То же в checks/shipped-B.json.\n- A: checks/shipped-selfcheck-A.json (bank_rows 69 = found 65 + empties 4) — коллизий 0; 宗祖祠堂→«храм предков-основателей».\nПочти-коллизии (кандидаты, не коллизии; подстрока): A — 10 пар, все композиционные (蛊⊂蛊师, 方源⊂古月方源, 舅父⊂舅父舅母). B — 18 пар, среди них 宗族祠堂«родовой храм предков» ⊃ 宗祖祠堂«храм предков»; прочие композиционные (嬷嬷/沈嬷嬷, 魔头/魔道, 资质/甲等资质).\nОдна ли это сущность: door-to-file-b/reader/original.zh.txt, 8782 знака, 宗族祠堂 1, 宗祖祠堂 1, 祠堂 3.\n- @1597: «一时间,宗族祠堂中尽是额头碰撞地板的轻响。大典完毕,众人…静静地走出庄严的祠堂。在走廊中,众家老默默地舒了一口气»\n- @2141: «古月族长最后一个走出宗祖祠堂,慢慢地关上门,便听到走廊中家老们的议论声音»\nЭто одна сцена: все выходят из зала в коридор, глава выходит последним и закрывает дверь. Значит, зал ОДИН. По всей книге guzhenren-utf8.txt: 宗族祠堂 11, 宗祖祠堂 2 — авторский разнобой написания.", + "correction": "Правильно так: «В ФИНАЛЬНЫХ банках коллизий dst: A 0, B 1 (宗族祠堂 и 宗祖祠堂 → «родовой храм предков», обе draft). На таблице стопа наоборот: A 1 (та же пара), B 0». Порядок перевернула вторая консолидация после подписи. Главное: это не «две разные вещи — одно имя». В тексте это один и тот же храм рода в одной сцене, и одинаковая передача здесь верна по критерию референтности. Как пример дефекта эта пара не годится." + }, + { + "id": "S3", + "verdict": "CONFIRMED", + "control": "Каналы, которые допускает код: mined | banknote | both (bankexport.go:129 `Channel is which detector found the row: mined | banknote | both`; terminology.go:30-32). В данных встречены только {banknote, both}; суммы по каналам 65+4=69 (A) и 62+4=66 (B).", + "evidence": "Множества src строк bank.json по полю channel:\n- both: A 4, B 4, общих 4, объединение 4, Жаккар 1.00 (古月山寨, 方正, 方源, 沈翠 в обоих).\n- banknote: A 65, B 62, общих 49, объединение 78, Жаккар 0.628 → 0.63.\n- только майнер (channel=mined): A 0, B 0.\n- Все каналы вместе: 53/82 = 0.65. bank-stop.txt тех же прогонов даёт те же origin: A banknote 65 / both 4, B 62 / 4.\nМеряна популяция: книго-уровневые множества src таблицы стопа, по каналам. Это НЕ retrieval_state.banknote_detail по чанкам. Для B по stopB.db сумма поуровневых предложений = 93 (сходится с рядом 439), а их Жаккар 74/(98+93−74) = 0.632.", + "correction": "Верно. Предупреждение: 0.63 по книжному каналу banknote (49/78) численно совпадает с почанковым 0.63 ряда 439 (74/117), но популяции разные. Книго-уровневый Жаккар по всем строкам — 53/82 = 0.65." + }, + { + "id": "R1", + "verdict": "PARTIAL", + "control": "`go test ./internal/pipeline/ -run TestCorpusBankKeyConflicts$` без TM_CORPUS → `SKIP: corpus instrument: set TM_CORPUS to the books tree`: прибор существует и компилируется. Сейчас в дереве книг `find -L books -name '*.db'` = 171 (06.09 было 162, дерево выросло) и `*.sqlite` = 5 — их обход не берёт.", + "evidence": "backend/internal/pipeline/bankconflict_corpus_test.go:33 `func TestCorpusBankKeyConflicts`. Opt-in — :34-37. Обход только `strings.HasSuffix(p, \".db\")` — :40.\nЧто спрашивает: :81 `all := membank.UnverifiedKeyConflicts(g)`. Форма — memseed.go:714-749: общий нормализованный ключ срабатывания (src или алиас), разный dst, перекрывающиеся окна, КРОМЕ approved×approved (:732-734 `continue // ApprovedSharedKeyCollisions' fail-loud owns this pair`).\nПодсадка :108-117: `Src: seed.Src, Dst: seed.Dst + \"-ПОДСАДКА\", Status: \"draft\", Sense: seed.Sense, SinceCh: seed.SinceCh, UntilCh: seed.UntilCh + 1000`. Это в памяти, мимо дверей сидинга.\nАрифметика ряда сходится: 1093+11399+858 = 13350; неподписанных 12257 = 91.8%.", + "correction": "Прибор есть на 5dbb5cb и мерит ровно форму UnverifiedKeyConflicts. Но ряд 330 приписывает ему больше, чем он спрашивает:\n(1) «книг с ЛЮБЫМ конфликтом — 0» не охватывает approved×approved и вообще не спрашивает «разные src → одна dst»;\n(2) 142 из 142 доказывает, что детектор реагирует на строку в памяти, но не что двери такую строку в хранилище пропускают;\n(3) объяснение нуля «двери роняют дубль по ПОЛНОМУ ключу» прибор не мерит, и код его опровергает (см. R2).\nСами числа 162/161/142/13350/0 здесь не пере-сняты (запрет TM_CORPUS)." + }, + { + "id": "R2", + "verdict": "REFUTED", + "control": "Исполнено: `go test ./internal/pipeline/ -run 'TestUnsignedConflictIsReportedByTheRun$|TestAutoBankKeyCollisionDoesNotCrashTheRun$'` → оба PASS. `go test ./internal/membank/ -run 'TestUnverifiedKeyConflicts$|TestConsolidationTupleSkipMirrorsTheStoreKey$|TestApprovedSharedKeyCollisions$'` → PASS. Финальный банк B (копия): 66 строк, 66 различных src, алиасов 0, непустых sense 0, нестандартное окно у 2 строк (方正 since 2, 沈翠 since 3). То есть ни одна из форм ниже в B не возникла.", + "evidence": "Дубль ПОЛНОГО кортежа не представим:\n- migrate.go:203 `UNIQUE (book_id, src, sense, since_ch, until_ch)`;\n- memseed.go:119-127 (term-duplicate);\n- bankmaterialize.go:110 MinedDeltaSeedCollisions → ошибка;\n- mining.go:717-733: loadAutoBank роняет строку, держатель выигрывает.\nНо «одна передача на поверхность в главе» этим не обеспечена:\n(а) подписанная × неподписанная при одном src и sense, окна перекрываются. Достижимо сквозь двери: miningstop_join_test.go:1700-1726, approved 方源 [ch1..end] + auto-bank draft 方源 `since_ch: 2`, комментарий «a different spoiler window, so ReplaceGlossary accepts both rows and BOTH are injected». Прибито только WARN (seeding.go:72-75). Переводчик: RenderGlossaryBlock memory.go:745-785 без форка по статусу и без дедупа → две строки. Редактор: editorLines `if p.entry.status != \"approved\" && signedSrc[src] { continue }` → одна (подписанная).\n(б) 族長/族长. UNIQUE на СЫРОМ src (migrate.go:180 `source key (raw; normalized in Go for matching`); loadAutoBank ключует сырой src (mining.go:717-730); гвард перекрытия в загрузчике сравнивает сырое `a.Src != b.Src` (memseed.go:212). При этом NormalizeSourceKey делает trad→simp (text/norm.go:136-156) → ключ срабатывания один. memseed.go:874-876: «族長 and 族长 with one sense and window are two accepted rows, not one»; TestConsolidationTupleSkipMirrorsTheStoreKey PASS. Прибито: approved×approved — fail-loud (memseed.go:265-309, bankmaterialize.go:146), иначе WARN. Редактор: signedSrc ключуется сырым src → неподписанный 族长 НЕ уступает подписанному 族長 → две строки закона. У переводчика тоже две.\n(в) Перекрывающиеся окна: UNIQUE пропускает. Внутри ОДНОГО документа сида — fail-loud без оглядки на статус (memseed.go:209-219). Между документами (seed / mined-delta / auto-bank) — только approved×approved fail-loud, остальное WARN. Законна только НЕперекрывающаяся смена: memseed.go:293-295, 735; memseed_test.go:519-531.\n(г) Алиасы: glossary_aliases `UNIQUE (book_id, term_id, alias)` (migrate.go:213) — уникальность в пределах термина, не книги. Ключи срабатывания включают алиасы (memseed.go:315-333). Прибито так же: approved×approved fail-loud, иначе WARN. editorLines дедупит по `src + \"\\x00\" + dst` → два разных src на одной поверхности дают две строки в обоих блоках.", + "correction": "Двери гарантируют ОДНУ строку на ТОЧНЫЙ кортеж (src, sense, since_ch, until_ch), а не одну передачу на поверхность в главе. Перекрывающиеся окна, 繁/简-варианты, общие алиасы и разные sense дают две живые передачи одной поверхности. Роняется это только для approved×approved, всё остальное лишь варнится. Неподписанная пара и 繁/简-вариант даже при подписи доходят до редактора двумя строками закона, а переводчику любая такая пара приходит двумя строками. Формула «правило исполнено структурно полным ключом, остаток — законное окно» неверна: законна только смена в НЕперекрывающихся окнах." + }, + { + "id": "R3", + "verdict": "REFUTED", + "control": "Поиск: grep `^func [A-Za-z(][^{]*(Collision|Conflict|Collapse|Injectiv|Contradict|Consisten|Duplicate|Dup|Clash|Homonym|Polysem)` по не-тестовым .go backend → 17 строк деклараций, из них 9 — детекторы банка. Встроенные гварды найдены чтением memseed.go, mining.go, bankmaterialize.go. Знаменатель: 722 декларации func в не-тестовых файлах membank/pipeline/terminology/store. `go test -run TestInjectivityCollision$` → PASS.", + "evidence": "Детекторы и ловимая форма:\n1. store UNIQUE (migrate.go:203) — тот же сырой кортеж.\n2. LoadGlossarySeed term-duplicate (memseed.go:119-127) — тот же кортеж внутри документа, fail-loud.\n3. term-window-overlap (memseed.go:209-219) — сырой src + sense, окна перекрываются, dst разный; внутри документа, fail-loud без учёта статуса.\n4. term-polysemy D16.1 (memseed.go:221-233) — сырой src, разные sense, перекрытие, dst разный.\n5. ApprovedSharedKeyCollisions (memseed.go:265-309) — approved×approved, общий нормализованный ключ, dst разный, перекрытие → fail-loud (bankmaterialize.go:146).\n6. UnverifiedKeyConflicts (memseed.go:714-749) — то же, кроме approved×approved → WARN (seeding.go:72).\n7. ConsolidationKeyConflicts (memseed.go:849-904) — предложение против строки банка на общем ключе, dst разный → репорт (terminologist.go:583); это «детектор схлопывания» из журнала решений, 05-decisions-log.md:2932.\n8. MinedDeltaSeedCollisions (memseed.go:945-969) — тот же кортеж seed×delta → fail-loud.\n9. Дроп в loadAutoBank (mining.go:717-733) — тот же кортеж.\n10. InjectivityCollisions (memory.go:1237-1262): «two distinct source terms mapped to the SAME dst (one Russian surface for two entities…)» — `if r.Status != \"approved\" || … { continue }`, `key := text.NormalizeTargetForm(r.Dst)` → WARN (seeding.go:64-67, «B2: two source terms share one Russian surface»).\n11. terminology.CanonConflicts (terminology.go:929-954) — вложение: подписанный src внутри ключа, слова подписанного dst должны уцелеть.\n12. terminology.ConsolidationConflicts (terminology.go:999-1022) — то же вложение внутри одного прогона.\n13. refuseSeedConflicts (decisions.go:341) — дверь правок против подписанного сида.\n14. bookconsistency / ScanShipping (memconsistency.go:119) — форма в отгруженном тексте; коллизии банка не ищет.\nПо совпадению dst у разных src работает ровно один — №10.\nВ B: пара 宗族祠堂/宗祖祠堂 в финальном банке — draft/mined; approved там 2 из 66 (方源, 古月山寨) → №10 слеп. run_Q6DSXGS7TW52TFNO-2.exit: `\"result\":\"success\" … \"status\":\"0\"`. В таблицах стопа строк `⚠ contradicts:` (render.go:329) 0 из 69 и 0 из 66 блоков.", + "correction": "Детектор формы «разные src → одна dst» существует: InjectivityCollisions (B2). Но он смотрит только approved-строки и только варнит, поэтому на draft-паре прогона B был слеп, и прогон B прошёл штатно. Вдобавок единственная пойманная пара — не две вещи, а один храм (S2), так что голое сравнение dst дало бы здесь ложное срабатывание." + } + ], + "extra_findings": [ + { + "title": "После подписи терминолог прогоняется ещё раз, и закон в банке расходится с таблицей стопа в каждой пятой строке; коллизию 祠堂 создал и снял именно этот второй проход", + "evidence": "Копия paid-final-project.db, request_log: попытка -1 (stage terminology, ids 12-18, до 19:58:23) и попытка -2 (ids 25-31, 20:00:01–20:01:25; 3 classifier + 4 terminologist, три новых request_hash и один кэш-хит f9fbb1bc38 с cost 0.0). live-journal.md:31: «второй заход стоил $0.033793 … пере-классифицировал 7 термов»; подпись двух термов через mined-delta — между попытками (live-journal.md:28). Диф stop→final в B: 14 из 66 dst, в том числе 宗祖祠堂 «храм предков» → «родовой храм предков» (так и возникла коллизия). В A: stop против shipped-selfcheck-A.json — 11 из 65 найденных, в том числе 宗祖祠堂 «родовой храм предков» → «храм предков-основателей» (так коллизия исчезла).", + "why_it_matters": "Любое правило приёма или проверка коллизий на таблице стопа или на первом проходе терминолога не связывает закон, который реально получает редактор. Это касается и идеи «партия видит уже назначенное через ⟦TM-CANON⟧». Подпись двух строк пере-бросила 14 других передач, и подписывающий видел не тот банк, что ушёл в провод." + }, + { + "title": "Единственный детектор «одно имя на две вещи» ограничен статусом, который по доктрине провод больше не различает", + "evidence": "memory.go:1245 `if r.Status != \"approved\" || strings.TrimSpace(r.Dst) == \"\" { continue }` при memory.go:762-768 «no fork by status at all (D39.104 п.2)… LAW for every role and every row «независимо от статуса строки»». В финальном банке B approved 2 из 66, то есть детектор не видит 64 строки закона.", + "why_it_matters": "Целевое правило «две разные вещи не получают одно имя» опирается на механизм, слепой к 97% банка авто-режима. Расширять его на неподписанные строки можно только вместе с проверкой референта (следующая находка)." + }, + { + "title": "Наблюдённая коллизия dst — законное слияние одного референта: голое равенство dst даст ложные срабатывания", + "evidence": "door-to-file-b/reader/original.zh.txt @1597 и @2141: 宗族祠堂 и 宗祖祠堂 — один зал в одной сцене (выход в коридор, глава закрывает дверь). В полной книге 宗族祠堂 11 раз, 宗祖祠堂 2 раза.", + "why_it_matters": "Если принять в конструкцию запрет «разные src → одна dst» без вопроса «указывают ли src на ОДНУ вещь», он навяжет два имени одному храму, то есть сломает ровно тот критерий референтности, на котором стоит приём в банк." + } + ], + "obstacles": "1) Полных баз прогонов A и B здесь нет (~/tm-coldrun-a, ~/tm-coldrun-b). Финальный банк A виден только через door-to-file-b/checks/shipped-selfcheck-A.json (bank_rows 69), файл сделан сессией B; его происхождение и то, пере-консолидировал ли A после подписи, самостоятельно не проверены. Для A есть лишь journal/run-attempt-2.log: «glossary materialized entries=69». Финальный банк B взят из door-to-file-b/paid-final-project.db, это файл в репозитории книг (открывал копию в scratchpad).\n2) Числа корпуса ряда 330 (162/161/142/13350/0/142) не пере-сняты: TM_CORPUS запрещён. Проверены только код прибора и арифметика.\n3) Демон-логи B (daemon-paid.log 88 строк, daemon-zero.log 174) не несут WARN-строк пайплайна: контроль «glossary materialized» 0 хитов. Отсутствие варнингов в B из логов доказать нельзя; вывод о слепоте InjectivityCollisions сделан по статусам строк.\n4) «Один ли храм» — чтение одной сцены (3 вхождения 祠堂 в срезе), а не формальная кореференция.\n5) Почти-коллизии искались подстрокой и грубым стемом (срез двух последних букв). Синонимические пары (храм/святилище) и супплетивные формы прибор не видит.\n6) Что видит переводчик и редактор, выведено чтением RenderGlossaryBlock и editorLines, без захвата реального провода.\n7) Перепись детекторов сделана грепом по именам функций и чтением. Детектор с неговорящим именем мог ускользнуть: шаблону отвечают 17 деклараций из 722.\n8) Внимание оркестратору. За время моей сессии рядом с оригиналами в books появились или обновились сайдкары: door-to-file-b/paid-final-project.db-wal (14:48:35), -shm (14:52:06), bankstop/project.db-shm (14:49:51). Мои sqlite-открытия шли только по копиям в scratchpad/verify-C; их сайдкары там же, 14:42:56 и 14:50:15. Оригиналы я не открывал. Сейчас файлы не держит ни один процесс (0 из 66). В git они игнорируются (.gitignore:12-13 `*.db-shm`, `*.db-wal`). Вероятно, их открыл параллельный верификатор без копии." + }, + "critic": { + "gaps": [ + { + "title": "Критерию референтности нечем выразиться: ни у терминолога, ни у майнера нет поля смысла (sense)", + "why": "Конструкция спрашивает, указывает ли источник на ОДНУ вещь. Если на две, хранилище выражает это двумя строками с разным sense: migrate.go:203 `UNIQUE (book_id, src, sense, since_ch, until_ch)`, полисемия по D16.1. Но у терминолога ответ из трёх полей: terminologist.md:39 «ровно ТРИ поля» (термин, перевод, уверенность), разбор — func replyColumns в terminology.go (src, dst, conf). У miner.Term поля Sense нет (miner_emit.go:43-60; «sense» в miner_emit.go встречается 0 раз на 425 строк), и DeltaFile его не заполняет, так что у всех добытых строк sense пустой. Остаётся одно действие — отказ, а отказ сегодня оставляет законом передачу из черновика (следующий пункт). Ни одно утверждение этого не проверяло.", + "how_to_check": "Подсадить многозначный источник (青山: фамилия и направление) и провести через ParseReply → DeltaFile → MaterializeBank → RenderEditorConstraintBlock overlay-тестом, по образцу /tmp/claude-1000/-home-ubuntu-projects-textmachine-main/6bf42f99-b840-4396-80ac-ab93384b11dc/scratchpad/verify-completeness/zz_probe_membank_test.go. В самой конструкции решить, как терминолог говорит «это две вещи»: отдельной колонкой sense или отказом." + }, + { + "title": "Третий исход — «нет ответа» — сегодня означает догадку черновика в роли закона; бинарного отказа нет", + "why": "Отказ через ⟦TM-NO-DST⟧, молчание, батч, срезанный бюджетом («remaining terms left unchanged»), и сгоревший батч дают одно и то же: status auto С dst первого прямого предложения черновика. Код: miner_emit.go:251 `Status: \"auto\"`, :268 `st.Dst = props[0].Dst`. Такая строка грузится как Source mined (mining.go:734), и editorLines рендерит её без различия по статусу. Проверено исполнением (go test -overlay по 5dbb5cb, после прогона git status — 0 строк): `src=\"家老\" status=\"auto\" dst=\"старейшина\"` при пустом m.Dst. Контроль: `src=\"古月\" status=\"auto\" dst=\"\"` — у терма нет предложений, dst пуст. В блоке редактора auto-строка выходит как `- 山寨 → «горная крепость»`. У конструкции два исхода (закон или вне банка), а в коде три, и третий — закон из черновика.", + "how_to_check": "Две пробы: scratchpad/verify-completeness/zz_probe_miner_test.go и zz_probe_membank_test.go (overlay.json там же). В конструкции назвать судьбу терминов из срезанного, сгоревшего и промолчавшего батча и резать такой терм на эмиссии, а не на dst." + }, + { + "title": "Триггер spread>=2 не видит терм, который назвал один чанк: spread=1 почти всегда значит одно наблюдение, а не согласие", + "why": "Spread считает различные формы в банкнотах черновиков (terminology.go:665-680), поэтому не превышает числа чанков, предложивших терм. Замер по полю variants («×N») в bank.json: в B из 58 строк со spread=1 у 52 предложение пришло из ОДНОГО чанка, в том числе 族长 (freq 12), 资质 (15), 开窍 (12), 蛊 (12). В A — 51 из 60. У терма, который ни один черновик не назвал банкнотой (家族), spread нет вовсе. «Жирный контекст» по spread>=2 обойдёт большинство трудных термов. S1 и P3 мерили долю spread>=2, но не то, что стоит за spread=1.", + "how_to_check": "python по proposed[].variants обоих bank.json: сумма ×N на строку. На длинном срезе сравнить spread с числом чанков, где src реально встречается." + }, + { + "title": "Жирный контекст опирается на незамеренную посылку, а приём обычных терминов — открытый вопрос владельца", + "why": "D39.47 (05-decisions-log.md:281, 287): «Главный открытый вопрос покрытия — расширение эмиссии на класс term», «kwic-дефолты 3×40 не покрыты замером (мерено на ~8×120)», «Санкция владельца на дизайн расширения — ожидается». Критерий референтности пускает в банк обычные термины, то есть этот вопрос за владельца решает. Польза широкого контекста при размере 3×40 не мерена. Ни одна линза этого не касалась.", + "how_to_check": "Греп реестра 05-decisions-index.md: была ли санкция после D39.47. Если нет — выносить вопрос владельцу с ценой (feed_cap, D39.45) и с замером пользы контекста." + }, + { + "title": "На настоящей книге объём приёма решают срезы, а не критерий", + "why": "Обе двери режутся на 200 строк: эмиссия майнера — emitRankCap=200 (miner_emit.go:33), причём до emissionEligible; обратная секция — mining.go:625 `if cap := miner.EmitRankCap(); len(out) > cap`. Авто-банк переписывается целиком из урезанной дельты, и WARN в mining.go:812 прямо говорит, что терм может выпасть из банка посреди прогона. Значит, «закон на всю книгу» на романе в тысячи глав ограничен порядка 400 строками при любом критерии. На срезе в 3 главы этого не видно. B4 мерил срез top-200 (1670→200), но не последствия для полноты закона. Число ~400 — вывод из двух констант, не замер.", + "how_to_check": "На полной книге снять из логов eligible против emitted для обеих дверей и WARN о выпавших между прогонами термах." + }, + { + "title": "Закон ничем не принуждается: 16 из 89 показанных неподписанных строк редактор не выполнил, а промахов записано 0", + "why": "Копия paid-final-project.db, таблица retrieval_state:\n- n_unverified_shown 19/24/21/25 = 89;\n- n_unverified_followed 13/19/19/22 = 73;\n- n_postcheck_miss = 0 во всех 6 строках из 6.\nКонтроль: счётчики показа ненулевые, прибор писал. Промах засчитывается только для Confirmed (mempostcheck.go:140, 154), а Confirmed — только approved. Выходит, «всегда закон» — свойство провода, а не гейта. Линза B назвала механизм без числа, утверждения этого не спрашивали.", + "how_to_check": "Проверить 16 невыполненных строк по тексту отгруженного перевода: матчер с учётом склонений мог не найти верную форму (ряд 434). Решить, флагирует ли юнит неисполненная неподписанная строка." + }, + { + "title": "Передачи терминолога меняются между проходами: «уже назначенное» — не константа", + "why": "B, стоп против финала: dst изменился у 14 из 66 (общих строк 66, лишних 0). Среди них:\n- 宗祖祠堂 «храм предков» → «родовой храм предков» — так и возникла коллизия;\n- 管家 «домоправитель» → «домоправительница» — сменился род;\n- 牌位 «табличка предков» → «таблички предков» — против правила «единственное число» (terminologist.md:35).\nВторой проход вызвали две подписи. Конструкция опирается на то, что имя, назначенное партией, стабильно и годится соседним партиям как якорь. Цель 6 (детерминизм) для конструкции не проверило ни одно утверждение; C дал это как extra, без связи с P1.", + "how_to_check": "Сравнить bank.json стопа с glossary финала (dst по src). На двух проходах с одинаковым входом сравнить dst: одинаковый хеш даёт тождество только при попадании в кэш." + }, + { + "title": "Бюджет инжекта (glossary_token_budget 800): посылка «всегда закон» на полной книге не мерена", + "why": "Select вытесняет строки сверх бюджета (memory.go:662-667). На B бюджет не кусает: волна правки передала 21/26/23/26 строк, n_evicted 0 в 4 юнитах из 4. Overlay-выборка по всему исходнику B с финальным банком дала injected 64, evicted 0 — и при бюджете 800, и при бюджете 0. На главе полной книги с сотнями строк банка не мерено. Приоритет низкий.", + "how_to_check": "wave_selection.n_evicted и evicted_srcs на полной книге." + } + ], + "contradictions": [ + { + "ids": "A:T4 и extra_findings ↔ B:B2", + "explanation": "B2 пишет: «auto остаётся только строке без dst… Не инжектируются только auto-строки без dst». A пишет, что отклонённый терм держит передачу черновика в auto-строке. Исполнение подтверждает A: DeltaFile даёт `家老 status=\"auto\" dst=\"старейшина\"` (miner_emit.go:268), а блок редактора рендерит auto-строку `- 山寨 → «горная крепость»`. Вердикт B2 REFUTED в целом устоял, но клауза поправки про auto неверна." + }, + { + "ids": "C:R2(а),(б) ↔ B:B3", + "explanation": "C утверждает: «Переводчик: RenderGlossaryBlock → две строки» и «у переводчика тоже две». По B3 черновая волна выбирает по базовому банку без Source:mined (bankmaterialize.go:321), а и авто-банк, и подписанная дельта — mined (mining.go:734). Исполнение:\n- обогащённый банк даёт блок переводчика из 5 строк, 方源 в нём дважды;\n- базовый банк — только 2 строки сида;\n- в финале B все 66 строк Source mined, включая обе approved; в черновой волне wave_selection injected 0 в 6 чанках из 6.\nПро переводчика C прав только для пар, где обе строки из сида (например, 繁/简 в одном glossary_seed: проверка окон сравнивает сырой src, memseed.go:212). На авто-пути переводчик не видит ни одной такой строки. Про редактора C прав." + }, + { + "ids": "код miner_emit.go:251,268 ↔ D39.42 п.1 (§C2-7) и D39.104 п.1", + "explanation": "D39.42 п.1 (05-decisions-log.md:275): «двухрежимная эмиссия §C2-7 (есть dst → draft, нет → auto)». D39.104 п.1 (:359): «Инвариант D39.42 §C2-7 не задет», и при этом банк на проводе — «ЗАКОН… независимо от статуса строки». В коде auto-строка несёт dst черновика и потому едет законом. С кодом расходятся:\n- terminology.go:693 `A declined term emits status:auto (inert) instead of a guess`;\n- miner_emit.go:274 `term with no dst stays auto, inert`;\n- промпт terminologist.md:36-37: «непереведённый термин останется на ручную подпись, а выдуманный попадёт в книгу». На авто-пути подписи по умолчанию нет (B1), так что в книгу попадает догадка черновика.\nНи одна линза не связала этот механизм с ратифицированным инвариантом." + }, + { + "ids": "B:B3 ↔ D39.42 п.3 ↔ mining.go:237", + "explanation": "D39.42 п.3 обещает, что неподписанные строки едут редактору «и черновикам следующих прогонов». Реестр отмечает у D39.42 только одну поправку: «маркер/двухсекционка на проводе → D39.104» (05-decisions-index.md:102). Код исключает mined-строки из черновика на любом прогоне (bankmaterialize.go:321), и комментарий mining.go:237 `and the next run's drafts do too` ложен. Ратифицированный текст и код расходятся, поправки не найдено." + }, + { + "ids": "C:R1/R2 ↔ memseed.go:703,742 ↔ memory.go:905,925", + "explanation": "Комментарий к UnverifiedKeyConflicts («Both rows of such a pair are injected, and a signature changes nothing about what the model is shown») и текст его варнинга («the model is shown two renderings of one surface») противоречат editorLines: неподписанная строка уступает подписанной с тем же СЫРЫМ src (memory.go:905, 925). Исполнение: варнинг сработал на обе пары, но в блоке редактора 方源 одной строкой, а 族長/族长 — двумя. Детектор, на котором ряд 330 держит «0 конфликтов» и «142 из 142», для редактора завышает пары с одинаковым сырым src и точен только для вариантов написания и алиасов." + }, + { + "ids": "конструкция «закрыть ряд 330 формулировкой» ↔ BACKLOG.md:269 ↔ D39.216", + "explanation": "Ряд 330 озаглавлен «РЕШЕНИЕ ВЛАДЕЛЬЦА, И ОНО ПРО ДЕНЬГИ»: исполнитель — владелец, закрывает его «решение владельца по (а) и (б) одним ответом + цена в книгах». Ратификаций ряда 330 в журнале решений и реестре — 0 (контроль: «409» в журнале встречается 12 раз). Ссылка ряда на «слово владельца (строка 267)» ведёт в пустоту: строки `| 267 |` в BACKLOG.md нет (контроль: `| 275 |` и `| 286 |` на месте). Закрыть ряд формулировкой оркестратора — значит подменить того, кто решает. По R2 и сама формулировка неверна." + }, + { + "ids": "конструкция «⟦TM-CANON⟧ несёт назначенное этим прогоном» ↔ terminologist.md:25-28 ↔ 18-bank-ontology.md:31-36 ↔ terminologist.go:325", + "explanation": "Промпт называет блок «УЖЕ ПОДПИСАННЫЕ владельцем термины» и велит НАСЛЕДОВАТЬ перевод вложенного элемента: «если термин… содержит подписанный элемент исходника, перевод ОБЯЗАН нести подписанный перевод этого элемента». Это толкает передачи к совпадению, а не запрещает отдавать занятое имя другой вещи. Код исключает неподписанное нарочно: terminologist.go:325 `an unverified row agreeing with an unverified row is not evidence`. Онтология 18 (ратифицирована D39.158) требует не сливать слово владельца со словом движка. A:P1 опроверг «по построению» через хеши и срез, но упустил, что блок по смыслу толкает в обратную сторону, а на проводе выдаёт неподписанное за подписанное." + }, + { + "ids": "конструкция «приём по референтности, обычные термины в банк» ↔ D39.47", + "explanation": "D39.47 оставляет расширение эмиссии на класс term открытым вопросом и ждёт санкции владельца (05-decisions-log.md:281, 287). Конструкция решает этот вопрос без ратификации." + } + ], + "weakest_verdicts": [ + { + "id": "T6 (A, CONFIRMED)", + "why": "Числа сняты с двух проходов и двух ролей на прогоне с --verify-bank. Второй проход ($0.033793) случился только потому, что владелец подписал 2 строки. В первом проходе $0.024779 — два сгоревших батча классификатора (id 12 и 14, finish length, ok=0). А выдана цифра как цена терминологии книги, то есть как цена дефолтного пути. Сама A признаёт, что doc 25 этих чисел не печатает.", + "recheck_result": "Пере-снял по копии paid-final-project.db (sha 90097e39…, в request_log 35 строк).\n- Арифметика сходится: классификатор $0.045313 + терминолог $0.038026 = 21.0% от $0.396657; вход 28150 + 27445 = 55595 токенов против 22553 у редактора.\n- Первый проход без второго: $0.049546, это 13.7% книги, и половина суммы сгорела.\n- «Самый большой вход» верен и для одного прохода: 28728 и 26867 больше 22553.\nВерный вердикт — PARTIAL: числа верны, приписывать их дефолтному пути нельзя." + }, + { + "id": "B6 (B, CONFIRMED)", + "why": "«Обычный термин» определён LLM-меткой type==term. B7 той же линзы показывает, что метка стохастична: на резюме сменилось 7 меток из 66, между прогонами A и B 6 из 53 общих src перешли границу. Значит, «30 из 66» — подсчёт метки финального прохода, а не класса сущностей.", + "recheck_result": "Число не пере-считывал. Структурную половину («только через банкноту») подтвердил чтением: mining.go:601-603 пускает в обратную секцию только OriginBanknote с контекстами; майнер эмитирует только name|place|title (miner_emit.go:346). Вердикт устоял наполовину." + }, + { + "id": "B7 (B, CONFIRMED)", + "why": "«42 терма из 66 без машинного типа» есть только в live-journal.md, из сырья не пересчитано; линза пишет это сама.", + "recheck_result": "В копии request_log: id 12 и 14 — классификатор, finish length, ok=0; id 13 — stop, ok=1. Два провальных батча подтверждены. Счёт 42 по сырью не восстановить: тела ответов с числом answered не хранятся. По механизму устояло, число — пересказ журнала." + }, + { + "id": "B5 (B, CONFIRMED)", + "why": "Отрицательное утверждение, стоит на грепе.", + "recheck_result": "`grep '.Spread()|.Conventions()'` вне тестов — 1 место: mining.go:463, это проекция bankStopRows. Контроль: вместе с тестами — 6 мест. Устояло." + }, + { + "id": "R2 (C, REFUTED — несущий)", + "why": "Главное утверждение линзы C. До моей проверки стояло на чтении кода и чужих тестах.", + "recheck_result": "Проверено overlay-тестом на membank (5dbb5cb, после прогона git status — 0 строк).\n- 族長 approved «глава клана» и 族长 draft «глава рода», одно окно: в блоке редактора ДВЕ строки закона — `- 族長 → «глава клана»` и `- 族长 → «глава рода»`.\n- 方源 approved и 方源 draft с since_ch 2: у редактора одна строка, подписанная.\n- UnverifiedKeyConflicts предупреждает об обеих парах, InjectivityCollisions возвращает [].\nREFUTED устоял. Поправка к C: для mined-строк утверждения о блоке переводчика неверны (противоречие 2)." + }, + { + "id": "B2 (B, REFUTED — несущий)", + "why": "Несёт посылку «банк всегда закон».", + "recheck_result": "Проверено исполнением. Заголовок блока редактора — «КАНОНИЧЕСКИЕ ПЕРЕВОДЫ… ДОЛЖЕН быть передан именно указанной формой справа»; draft- и auto-строки идут без пометки. Финал B: 64 draft + 2 approved, все Source mined; редактору в 4 юнитах показано по 21–26 строк. REFUTED устоял, но клауза поправки «auto — только строке без dst» опровергнута пробой DeltaFile." + }, + { + "id": "P1 (A, REFUTED — несущий)", + "why": "Несёт часть конструкции про ⟦TM-CANON⟧.", + "recheck_result": "Проверено чтением по 5dbb5cb.\n- Сообщения всех батчей строятся до первого вызова: terminologist.go:931 `msgsPer[i] = m`.\n- Допуск по чекпойнту читает эти сообщения: :975 `r.bankCheckpointExists(st, snapID, ch, msgsPer[i])`.\n- Хеш сворачивает содержимое: render.go:374 `w(m.Role, m.Content, …)`.\n- Срез до 40 молчаливый: terminology.go:900 `picked = picked[:max]`, cap 40 в terminologist.go:648.\nREFUTED устоял. Добавляю довод, которого у A нет: промпт делает блок инструкцией наследовать подписанный элемент, а не запретом на занятое имя (противоречие 7)." + }, + { + "id": "S1 и S3 (C, CONFIRMED)", + "why": "Проверил, та ли популяция.", + "recheck_result": "Распределение spread воспроизвёл по bank.json: B 58/4/3/1, A 60/6/2/1. Устояли. Толкование нужно поправить: spread=1 в основном означает одно наблюдение из одного чанка (52 из 58 в B), а не согласие черновиков (gap 3)." + } + ], + "obstacles": "Все три линзы вернули вердикты; непроверенных (null) линз нет.\n\n1. Полных баз A и B с другой машины здесь нет. Финальный банк и финальные типы A видны только через checks/shipped-selfcheck-A.json, а этот файл сделала сессия B. На нём стоит вывод C:S2 «в финале A 0 коллизий»; происхождение файла я не проверял.\n2. Тела запросов банк-ролей не хранятся нигде. Что реально ушло в ⟦TM-CANON⟧ на резюме B, выведено из кода, а не прочитано с провода.\n3. Мои пробы — overlay-тесты на синтетических строках, файлы в /tmp/claude-1000/-home-ubuntu-projects-textmachine-main/6bf42f99-b840-4396-80ac-ab93384b11dc/scratchpad/verify-completeness/. Судьбу терма из сгоревшего или срезанного бюджетом батча терминолога я вывел из DeltaFile и чтения runBankRoleBatches. Настоящий сгоревший батч не воспроизводил: на B у терминолога таких 0.\n4. «16 из 89 не выполнено» — показания матчера с учётом склонений, который по ряду 434 даёт ложные «не найдено»; по тексту отгруженного перевода не проверял.\n5. Базы открывал только копиями в scratchpad; sha финала совпал (90097e39…). Оригиналы не открывал. Файлы -wal и -shm рядом с оригиналами в books появились до меня (14:48–14:52), их же заметила линза C.\n6. Посылку D39.47 о пользе контекста 3×40 проверить нечем: полигон выведен из скоупа (D39.248).\n7. Оценка gap 5 (порядка 400 строк на книгу) выведена из двух констант, на полной книге не мерена.\n8. Ратификации ряда 330 грепал только в живом журнале и реестре, без архивных слайсов. Слайсы покрывают эры до D39.90, а ряд 330 заведён 06.09, так что содержать его они не могут. Это рассуждение, а не замер." + } +} \ No newline at end of file diff --git a/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/02-design-v1-fable.md b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/02-design-v1-fable.md new file mode 100644 index 00000000..60765940 --- /dev/null +++ b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/02-design-v1-fable.md @@ -0,0 +1,37 @@ +# Проект старшего коллеги (Fable 5), 15.09: целевой банк памяти длинной книги — одна архитектура + +> ⛔ **ОТОЗВАНО 15.09 — АРХИВ-УЛИКА, НЕ ПЛАН.** Проверка `03` нашла в этой редакции шесть блокеров, сверка `05` — +> 12 расхождений итоговой редакции с решённым и замеренным. Порядок стройки, «слово владельца» и прочие инструкции +> ниже НЕ исполнять. Читать только вместе с `README.md` этого каталога. + +> Предмет проверки. Автор — Fable 5 (советчик оркестратора). Утверждения о коде — по дереву 5dbb5cb +> (`/home/ubuntu/tm-verify-1509`). Пометка [мнение] — мнение автора. Текст ниже — дословно из его отчёта. + +### 0. Диагноз одной фразой +Сегодня банк — **пересчёт**: на каждой границе прогона движок заново спрашивает модель обо всём и переписывает файл целиком (`mining.go:766-775`; проход куплен заново на подписи и на каждой покупке — `volume.go:333-352` говорит это сам). Все восемь проблем списка — следствия трёх вещей: решение не записывается как решение, тождество ключа определено сырой строкой, а исход «не закон» не существует. Лечится не заплатками, а сменой природы банка: **банк — журнал решений с окнами, свёрнутый в закон.** + +### 1. Что банк есть + +**(a) Тождество ключа — одно определение, параметризованное данными исходного языка.** Ядро даёт ровно одну функцию `Identity(surface)` = универсальные шаги (NFKC · lower · drop-ignorables · апостроф) + шаги, ОБЪЯВЛЕННЫЕ данными `configs/langpacks//` (таблица свёртки рун, флаг «снять комбинирующие знаки», диапазонные свёртки). Сегодня трад→упрощ. таблица и кана-свёртка зашиты в ядро и применяются к ЛЮБОМУ источнику (`text/norm.go:47-48` `//go:embed data/trad2simp.txt`; `:141-153` — trad2simp и `0x30A1..0x30F6−0x60` безусловно; сам файл называет свой скоуп «zh/ja»: `:28`). Это нарушает §0.1/§0.5 норматива общности и **ломает японский**: 後 «после» и 后 «императрица» — оба живые кандзи — схлопываются в один ключ, ハル (имя) = はる (весна); симметрия свёртки спасает матчинг, но даёт ЛОЖНЫЕ тождества, а майненые строки и промт терминолога получают чужое письмо (`mining.go:82` src = нормализованный текст; `terminology.go:774` печатает его модели). Прецедент выноса есть: письмо источника уже данные (`lang/data/lang-script.txt`: zh/ja/ko/en/ru), `pack.Version()` фолдит байты пакета в снапшот (`langpack.go:204`; §0.1 норматива) — громкий `--resnapshot` сохраняется. Аналоги в других языках — класс универсальный, только таблица своя: ja — старые/новые кандзи (舊/旧), кана и её ширина; ko — ханча↔хангыль, пробелы; de — ß/ss, ä/ae; fr/es/pt — потеря диакритики в скрапах, капитель без акцентов; ru-источник — ё/е, й/и; ar — харакат, варианты алефа إأآا, ة/ه, ي/ى; he — никкуд. NFKC ничего из этого не сворачивает, кроме лигатур и ширины; ё→е сегодня зашито на ЦЕЛЕВОЙ стороне (`norm.go:203-205`) и уже стоит в очереди владельца как «данные» (D39.64 §5, ряд 14). **Все двери сравнивают по Identity** — сид-линт, дельта, загрузчик авто-банка (сегодня сырой кортеж `mining.go:717-733`), майнер, реверс, уступка на проводе (сегодня сырой src `memory.go:905,925`), UNIQUE схемы (`migrate.go:203,389` — по сырому src). Хранимый `src` остаётся авторским — для показа. ⇒ ряд 330 исчезает как класс для любого языка: две строки одного Identity в пересекающихся окнах — одна поверхность; движок такого не производит, рука получает отказ линта или требование `sense`/окна. «Разные написания — китайская проблема?» — нет; китайской была только таблица в ядре. + +**(b) Единица закона** = `(Identity, sense, окно [since, until]) → dst, gender`. Схема это уже держит (UNIQUE `migrate.go:203`; окна `memory.go:681-689`). Меняется роль окна: из спойлер-гейта оно становится ЕДИНСТВЕННЫМ инструментом изменения закона по ходу книги. `sense` — только рукой и без рантайм-дизамбигуации (матчер ключуется только по src: `memseed.go:203-207`) ⇒ полисемия ВНУТРИ окна в банке невыразима — и не должна быть: по принципу 6 такой surface либо не закон, либо закон плюс оговорка области употребления у редактора (D39.104 п.1 её обещал; в `editor.md` её нет — только `:5` идиомы и `:7` «СТРОГО»). Оговорка — обязательная часть архитектуры, а не патч: она и есть механизм «имя против обычного слова» (`方正`). + +**(c) Решение — событие с провенансом, а не пересчёт.** Кто решил (терминолог/владелец), в каком прогоне, на каких уликах (окна источника, варианты черновиков, уверенность, INVENTED), с каким исходом. Банк книги = детерминированная свёртка журналов по окнам: журнал владельца (дельта/rejects, дверь) и журнал движка (авто-банк — из «проекции этого прогона» становится append-журналом). Онтология 18 сохраняется буквально: источники → вид → проекции, у каждого источника один писатель, вид пересобирается целиком на границе; меняется лишь то, что источник движка накопительный, как и все прочие источники. Следствия, которые раньше были заплатками: «заморозка» — нечего пере-решать, решение уже записано; повтор прогона реплеит события, а не модель (принцип 8); терминолог вызывается только для Identity без действующего закона в окне — цена падает с томами, а не растёт (`pipeline-c1.yaml:161-162` называет сегодняшнюю обратную кривую). + +**(d) Приём — закрытый словарь исходов.** Номинация — открытый набор каналов (майнер по источнику, банкнота черновиков, владелец; позже — любой канал данных, напр. частотный по паре); архитектура впуск обычных существительных не закрывает и не открывает — это остаётся решением владельца по замеру (D39.47/ряд 440; сегодня 家族/族 режет срез top-200 ДО типа, `miner_emit.go:126-129`). Решение терминолога — один из: `law(dst, gender, conf)` · `not-a-term` (принцип 6: слово остаётся свободным, закона НЕТ) · `polysemous` (нужен sense/окно; на лист, не закон) · `undecided` (нет улик; не закон; спросить снова, когда появятся новые улики — новый том номинировал повторно). Парсер принимает только словарь + рендеринг в целевом письме; сегодня «не термин» и «90» становятся законом, а ⟦TM-NO-DST⟧ отдаёт закон догадке черновика (`terminology.go:1115-1121` → `miner_emit.go:261-269`). Предохранитель «имя выкинуть нельзя» — не тип (стохастичен, B7), а ДЕТЕРМИНИРОВАННАЯ улика майнера (`Evidence`, `terminology.go:106`; паттерны фамилий/титулов/топонимов — данные пары): при ней `not-a-term` запрещён, отказ превращается в `undecided`. Улики решению — не «первые три вхождения» (`terminology.go:375-396`), а выборка по всей книге и вокруг расхождений черновиков (параметры — данные пары/гейт; тот же вызов, другой вход — позиция 5 владельца). + +**(e) Изменение по ходу книги — преемник.** Событие «с главы N: dst'/gender'» закрывает прежнее окно (`until=N−1`) и открывает новое. Источники: владелец через дверь ОДНИМ глаголом (`succeed`; сегодня два глагола, окно одним решением не правится, decline стирает все окна — `decisions.go:33-34,86-92`) или движок по детектору — по умолчанию ПРЕДЛОЖЕНИЕ на лист, исполнение — ручка. Детекторы — данные пары: местоимения рода по главам (`/pronouns.txt`: 他/她 · he/she · er/sie), расхождение черновиков нового тома по конвенции ≥K кусков. Главы ≤N не трогаются по построению: их строка провода не меняется ⇒ $0-репин (`volume.go:798-840`, `repin.go:305-327`); дверь пишет только дельту (Source:mined, до черновиков не доходит — `decisions.go:50-57`, `bankmaterialize.go:318-333`), сид не трогается никогда ⇒ «пол книги перегенерировать» невозможно без явного заказа пере-прохода (принцип 7). + +**(f) Провод и рычаги.** Редактору — как сегодня, один закон на Identity в окне куска (D39.104) плюс оговорка области употребления; черновик по-прежнему без движковых строк — это правильно: черновик остаётся СВИДЕТЕЛЕМ (варианты), а не потребителем закона, и черновая волна не перекупается никогда. Проекции с названным читателем: `terms` = действующий закон по окнам, `proposed` = события этого прогона (новое, `undecided`, `polysemous`, предложения преемников, споры) — платформа обязана читать обе (сегодня только `terms`, `platform/internal/ingest/bank.go:57-70`); лист подписи = дельта событий; отчёт сборки — по отгрузке. Рычаги человека без обязательного человека: `approve` · `decline` · `succeed`. + +### 2. Как проходит каждая проблема +пере-решение на подписи/покупке → решения — события, терминолог только для новых Identity, резюм — реплей · сущность меняется → преемник (dst и род — поля события), детектор по данным пары, один глагол двери · два закона на поверхность → Identity + окна структурно; написания — таблица `/`; рукописные пары — линт · отказ = догадка законом → словарь исходов; `not-a-term`/`undecided` не порождают закон · тип/род стохастичны → тип закона не несёт; род — поле события с преемником; регенерация классификатора — инженерное · одно наблюдение / INVENTED → улики по всей книге, INVENTED — метка события на лист, повторный вопрос только при новых уликах (`undecided`), не ре-ролл · нет читателя → `proposed` читает платформа, лист = дельта · обычные существительные → номинация открыта, исход `not-a-term` держит принцип 6, решение о расширении — владельца. + +### 3. Трейдоффы +Первое решение живёт до преемника — цена принципа 2; смягчается уликами и N=2-согласием на спорных (центы) [мнение]. Детектор преемника ошибается в сторону ложного разреза ⇒ по умолчанию предложение. Журнал вместо перезаписи — миграция формата авто-банка; кап 200 — на события прогона, не на размер банка; рост банка упирается в бюджет инъекции 800/кусок, вытеснение по-кусковое и логируемое (`memory.go:662-672`). Identity по данным пары: правка таблицы = `--resnapshot` книг пары (как сегодня `NormVersion`, только через `pack.Version()`); zh-книги переживут один пере-снапшот при выносе — в фазе «одна платная книга» это $0 (D39.63). Оговорка в промте редактора фолдится в снапшот — окно пере-снапшота. Терминолог остаётся единственным стохастическим шагом — теперь его выход записывается. + +### 4. Порядок стройки +**Пакет 1 (бэкенд, $0 + центы перекупки банк-ролей):** журнал событий движка (append) + свёртка по окнам + терминолог только по новым Identity + реплей-пины (стоп→подпись→резюм; том 2 не меняет закон тома 1) · словарь исходов в промте (данные) + парсер + защита по улике · `Identity` в ядре с таблицей в `configs/langpacks/zh/`, дедуп/уступка/загрузчик по Identity, UNIQUE по Identity (миграция схемы) · преемник — движковая половина + глагол двери (контрактный минор) · `proposed` с исходами и спорами · счётчик промахов по неподписанным. **Пакет 2:** платформенный читатель `proposed` (зона платформы, ряд 224) · детектор рода по местоимениям и детектор споров (данные пары) как предложения · расширенные улики терминологу · регенерация классификатора. **В окне пере-снапшота (вместе со структурой глав):** оговорка области употребления в промте редактора; ё-фолд цели в данные. **Позже, по слову владельца:** авто-исполнение преемника; расширение номинации на обычные существительные. + +### 5. Слово владельца — три пункта +1. Банк — журнал решений: принятое не пересчитывается, меняется только преемником с главы N (человеком или предложением детектора). 2. Исход «не термин» оставляет слово свободным, а детерминированная улика имени запрещает этот исход — так держится «не обеднять язык» без человека. 3. Автоматические преемники без человека — выключены до статистики первой длинной книги (или «никогда без человека» — тогда детекторы только предлагают). diff --git a/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/03-design-v1-verification.json b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/03-design-v1-verification.json new file mode 100644 index 00000000..91e10fcf --- /dev/null +++ b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/03-design-v1-verification.json @@ -0,0 +1,430 @@ +{ + "L1": { + "verdicts": [ + { + "id": "F1", + "claim": "norm.go:47-48 embed; :141-153 trad2simp и катакана→хирагана безусловно; :28 скоуп «zh/ja»; у NormalizeSourceKey нет параметра языка; число мест вызова; ветки по языку нет", + "verdict": "PARTIAL", + "evidence": "Факты верны, две ссылки на строки неверны. norm.go:47-48 `//go:embed data/trad2simp.txt` / `var trad2simpRaw string`. norm.go:136 `func NormalizeSourceKey(s string) string`: параметра языка нет. :147-152 `if m, ok := trad2simp[r]; ok { r = m }` и `if r >= 0x30A1 && r <= 0x30F6 { r -= 0x60 }` без условий. Строка :28 — это «It is shared substrate: the memory bank matches and post-checks with it, the miner», слов «zh/ja» в ней нет; скоуп «zh/ja» стоит в :32 и :126. Ё-фолд, процитированный как :203-205, на деле в :198-200 (в :203 `return strings.TrimSpace`). Места вызова (python-скан не-тестового Go с вырезанными комментариями): 54 вызова в 12 файлах — decisions.go 17, mining.go 13, terminologist.go 7, banknote.go 4, memseed.go 3, memory.go 2, miner_alias 2, miner_emit 2, по одному в memconsistency, miner_patterns, miner_substrate, bankdecisions. Ещё 2 передачи функцией (terminologist.go:517 в ParseReply, :697 в ParseTypes) и контракт хранимого ключа store/migrate.go:460. Ветки по языку: греп `SourceLang|source_lang|\"ja\"|\"zh\"` по internal/text, membank, miner, terminology дал 0 (контроль: просканировано 23 не-тестовых go-файла).", + "correction": "Скоуп «zh/ja» — norm.go:32 и :126. Ё→е — :198-200. Мест вызова 54 в 12 файлах плюс 2 передачи функцией. Самый крупный потребитель, дверь membank/decisions.go (17 вызовов), чистая функция без пака: mining.go:29-31 прямо говорит, что bank-apply Runner не строит." + }, + { + "id": "F2", + "claim": "Нормализация «ломает японский»: 後→后, 乾→干, 髮→发; ハル=はる; японская книга идёт через тот же NormalizeSourceKey; терминолог получает нормализованный src", + "verdict": "PARTIAL", + "evidence": "Класс верен, примеры неверны. Контроль: в trad2simp.txt 508 пар. 後, 乾, 髮 в таблице ОТСУТСТВУЮТ (python-лукап: «後 -> (absent)», «乾 -> (absent)», «髮 -> (absent)»), шапка таблицы :13-14 прямо исключает «後→后 vs 后→后». Пар, где обе стороны кодируются в JIS X 0208 (shift_jis), — 68. Среди них живые японские кандзи с разным значением: 機→机 (машина/стол), 葉→叶, 準→准, 築→筑, 範→范, 僕→仆, 據→据, 莊→庄. enkan_no_hate_ja.txt (60 127 знаков после NFKC, из них 14 909 Han): переписано 1 798 Han-рун (12,1%), топ — 見→见 217, 葉→叶 118, 誰→谁 116, 機→机 15, 築 10, 準 3; ещё 2 558 знаков катаканы свёрнуты в хирагану. Пример ハル/はる: memory.go:73 `minKeyLenPhonetic = 3`, а по :78-83 ключ из 2 каны не срабатывает никогда. Ключи из 3 и более каны срабатывают, но collisionProneKey (memory.go:88-90) делает их AMBIGUOUS, KeyTrusted=false. Исполнимость пары: в configs/langpacks только ru, zh, zh-ru; в backend/prompts только zh-ru; config/pipeline.go:1038 отказывает: «no prompt for pair %q role %q ... never silently substitute another pair's conventions» (то же пишет books/gu-zhenren/door-to-file/poscontrol-paid-holes/book.yaml:34-40). Ветки по языку нет, поэтому куски любой книги проходят через memory.go:574 и mining.go:82. Вход модели: строки `ctx:` — окна по NSource (terminology.go:375-396, источник mining.go:130 `NSource: c.NSource`), всегда нормализованы. Поле `### src` (terminology.go:773) нормализовано у майненых кандидатов (terminologist.go:1052-1056: «a substring of already-normalized chunk text and therefore equals its own key») и сырое, как написал черновик, у банкнотных (banknote.go:532 `Observed{Key: key, Src: a.src}`). В листе стопа прогона B банкнотных 64 из 66 (origin=banknote 64, both 2).", + "correction": "Ложные тождества и чужое письмо в контекстах для ja реальны; нужные примеры — 機/机, 葉/叶, 築/筑; ハル/はる не срабатывает, а サクラ/さくら срабатывает как AMBIGUOUS. Пары ja в репо нет, поэтому вред перспективный: это ровно вопрос §Цели п.2, а не наблюдаемая поломка." + }, + { + "id": "F3", + "claim": "pack.Version() фолдит байты пакета в снапшот (langpack.go:204); memoryNormVersion хеширует trad2simpRaw; перенос таблицы в langpack сохраняет громкий --resnapshot", + "verdict": "PARTIAL", + "evidence": "langpack.go:204 `func (p *Pack) Version() string { return p.version }`; Load фолдит каждый прочитанный файл (langpack.go:237-238); снапшот получает его в snapshot.go:409/477 `LangpackVersion: r.packVersion()`. norm.go:83 `sha256.Sum256([]byte(memoryNormAlgoVersion + \"\\x00\" + trad2simpRaw))`. НО сегодня NormVersion попадает в снапшот ТОЛЬКО внутри memory_version (membank/memory.go:417 `h.Write([]byte(text.NormVersion() + ...))`); отдельного norm-поля в снапшоте нет (поля snapshot.go: langpack_version :409, embedded_version :418, memory_version :425). repin.go classifySnapshotMove: любой другой изменившийся ключ даёт `moveOther`, а тогда «Nothing is re-pinnable». Итог: правка таблицы сегодня — перемещение только банка, и незатронутые юниты пере-пиниваются за $0 (volume.go rowsResumeFree :798-829). Через pack.Version() та же правка сдвигает langpack_version, это moveOther, и перекупается каждый сохранённый юнит. Кроме того, runner.go:450-456 возвращает `\"\"` при отсутствии пака, а config/book.go:93-98 держит `langpack_root` необязательным: zh-книга без пака осталась бы без таблицы. «Прецедент» lang-script.txt — встроенные Go-данные (lang/embedded.go:22 `//go:embed ... data/lang-script.txt`), их фолдит EmbeddedVersion, а не pack.Version(); по природе это тот же артефакт, что text/data/trad2simp.txt.", + "correction": "Для книг с паком громкость сохраняется, но класс цены хуже: полная перекупка вместо $0-репина незатронутых юнитов. Этого не будет, если хеш таблицы Identity фолдить в memory_version, а не в pack.Version(). Книгам без пака нужна дефолтная Identity или обязательный пак. lang-script.txt не прецедент выноса в langpack." + }, + { + "id": "F4", + "claim": "UNIQUE по сырому src (migrate.go:203,389); матчер ключуется только по src, sense в рантайме не различается (memseed.go:203-207)", + "verdict": "CONFIRMED", + "evidence": "store/migrate.go:203 `UNIQUE (book_id, src, sense, since_ch, until_ch)` (glossary); в :389 тот же кортеж, но у voice_profiles. Алиасы: `UNIQUE (book_id, term_id, alias)`, комментарий «raw; normalized in Go for matching». memseed.go:203-207: «The deterministic matcher keys ONLY on src (it cannot disambiguate sense within a chunk), so BOTH rows fire together». memory.go:357 `b.keyOwners[nk] = append(b.keyOwners[nk], idx)`, memory.go:592 `for _, ei := range b.keyOwners[k]`; Select поле sense не читает. Оговорка: строки движка хранят в src уже нормализованный ключ (mining.go:612 `miner.Term{Src: c.Key, ...}`), сид — сырой.", + "correction": "Строка 389 — это voice_profiles, а не glossary." + }, + { + "id": "F5", + "claim": "Преемник: главы ≤N не перегенерируются — строка провода не меняется ⇒ $0-репин (volume.go:798-840, repin.go:305-327)", + "verdict": "PARTIAL", + "evidence": "repin.go:305-329 repinnable → bankOnlyMove; volume.go:798-829 rowsResumeFree требует `h == cs.ContentHash` и repinnable; хеш — по пере-отрендеренным сообщениям (repin.go:131-160, `MessagesWithInjection(..., injection[st.Role])`). Проба через overlay в internal/membank (дерево не тронуто, git status 0): старая draft-строка [0,0]→[0,4], одобренный преемник [5,0], кусок «古月山寨里,方源说道:好。方源又说。», бюджеты 800 и 8. Главы 1 и 4: editorLines побайтно те же («- 方源 → «Фан Юань»\\n- 古月山寨 → «деревня Гуюэ»»), memory_version сдвинулся. Главы 5 и 8: строка сменилась на «- 方源 → «Старый Фан»», ambiguous→confirmed. Для ≤N−1 меняется только id записи (memory.go:309, в id входит until_ch), а id не рендерится. Сам репин идёт через --resnapshot (volume.go:351). Изъяны: (1) off-by-one в тексте проекта: «с главы N … until=N−1» и тут же «Главы ≤N не трогаются», хотя глава N меняется. (2) СИД-термин (origin given) дельтой не преемствуется. Проба `ApprovedSharedKeyCollisions`: одобренный сид [0,0] + одобренный преемник [5,0] → «firing key \"方源\" is shared by different terms … with overlapping spoiler windows»; этот гард роняет прогон (bankmaterialize.go:146-148), и та же проверка стоит в вердикте двери (decisions.go:913-914). С неподписанным преемником коллизии нет, но в главе 8 editorLines = [«- 方源 → «Фан Юань»»]: уступка по memory.go:925, преемник молча инертен. Закрыть окно сида — это правка сида, а дверь её отклоняет (decisions.go:358-363: «Editing a seed term means editing glossary_seed, which moves the BASE snapshot and re-pays the draft wave») и контракт её исключает (openapi.yaml:2370-2372). (3) Закрыть окно строки ДВИЖКА — значит писать в авто-банк, у которого единственный писатель движок (таблица 18-bank-ontology.md); на проводе это работает только через уступку неподписанной строки подписанной.", + "correction": "Главы ≤N−1 не трогаются, глава N пере-редактируется. $0-репин держится для строк движка и дельты при сдвиге только банка с --resnapshot. Для сид- и given-терминов преемник требует правки сида: базовый снапшот сдвигается, и черновая волна перекупается на кусках ≥N с этим термином. Это противоречит (e) «сид не трогается никогда» и (f) «черновая волна не перекупается никогда»." + }, + { + "id": "F6", + "claim": "Дверь: decisions.go:33-34 два глагола, :50-57 DecisionDepth=edit_wave, род не принимается, окно одним решением не правится (:86-92); контракт BankCorrection с закрытым словарём action; platform/internal/runs/bank.go:90 пробрасывает документ в tmctl bank-apply", + "verdict": "CONFIRMED", + "evidence": "decisions.go:33 «TWO VERBS AND NO THIRD. `approve` … `decline`»; :57 `const DecisionDepth = \"edit_wave\"`; :80-84 про род: «It is still NOT ACCEPTED … correcting one stays a seed edit»; :86-88 «a term's chapter WINDOW cannot be corrected in one decision … declining removes every window of the surface». openapi.yaml:2348-2350 `BankCorrection: type: object, additionalProperties: false`; :2418-2420 `action: type: string, enum: [approve, decline]`; :2375-2377 окно — операция в два вызова. platform/internal/runs/bank.go:88 ApplyBankCorrections, :141 `ingest.EncodeDecisions(in.BookID, in.Decisions)`, :160 `s.Bank.BankApply(ctx, s.Cfg.EngineBinary, book.Workdir, path, in.Preview)`. «Контрактный минор» для нового глагола согласуется с политикой: openapi.yaml:112 «While the version is 0.x, a MINOR bump is the lane for breaking changes».", + "correction": "Запуск verb — runs/bank.go:160 (кодирование — :141), а не :90." + }, + { + "id": "F7", + "claim": "terminology.go:1115-1121 → miner_emit.go:261-269: ⟦TM-NO-DST⟧ отдаёт закон догадке черновика; «не термин» и «90» становятся передачей; Evidence майнера (terminology.go:106) детерминирован — какая доля термов прогона B его несёт", + "verdict": "CONFIRMED", + "evidence": "Проба ParseReply через overlay (internal/terminology, target unicode.Cyrillic): «方正\\tне термин\\t90» → dst=«не термин», bad=0; «方正\\t90» → dst=«90», bad=0; «方正 90» → dst=«90»; «方正\\tне является термином\\t80» → принято; «方正\\t⟦TM-NO-DST⟧\\t40» → dst=\"\". Причины: wellFormedLemma (terminology.go:643-656) пропускает всё от 2 рун без дефиса по краям и скобок; OffLanguage (script.go:31-46) возвращает false, если букв нет («90»). Проба DeltaFile (internal/miner): отклонённый термин с предложением черновика → `dst=\"Фан Чжэн\" status=\"auto\" note=\"dst PROPOSED by the translator (banknote, 1 chunk(s)) — NOT approved…\"` (miner_emit.go:261-266). Проба membank: auto-строка с dst → injected=1, editorLines «- 方源 → «Фан Юань»» (memory.go:315-327 делает строку матчибельной при непустом dst, editorLines рендерит строку любого статуса). Значит комментарий terminology.go:692-693 «A declined term emits status:auto (inert) instead of a guess» ложен. Промт сам просит этот ответ: prompts/zh-ru/terminologist.md:36-37. В оплаченных прогонах: 0 строк NoDst, 0 цифровых передач, 0 передач со словом «термин» (контроль: 129 строк ответов в B и 137 в A; авто-банк 64 в B и 67 в A, все draft) — дефект латентный. Evidence детерминирован (паттерн-канал miner.go:100-121 поверх нормализованных кусков), но в листе стопа B строка `evidence:` есть у 2 из 66 кандидатов: 方正 [surname:方], 沈翠 [surname:沈]. В авто-банке у 62 из 64 заметок тег «banknote-only candidate (the miner did not surface it)» — не паттерн, его дописывает эмиссия (mining.go:607-612).", + "correction": "Код подтверждает проект. Замечание к проекту: детерминированная улика есть у ~3% кандидатов (см. D-d3)." + }, + { + "id": "F8", + "claim": "Улики терминологу — первые три вхождения по порядку (terminology.go:336-400); что нужно, чтобы брать выборку по всей книге без роста цены выше «центов»", + "verdict": "CONFIRMED", + "evidence": "terminology.go:340-352: AttachKWIC сортирует куски по (chapter, chunk_idx); kwicFor (:375-396) набирает вхождения с начала книги до maxPer. Дефолты terminologist.go:75-76: `terminologyDefaultKWICPer = 3`, `terminologyDefaultKWICWidth = 40`; ручки config/pipeline.go:345-346 и terminology.txt пака. Что нужно для выборки: (1) детерминированный стратифицированный селектор в AttachKWIC ($0); (2) позиции по вариантам — у Proposal только счётчик (terminology.go:62 `Chunks int`; banknote.go:504 `cur.Chunks++`), поэтому «вокруг расхождений» требует протащить id кусков через свёртку банкноты → Observed → Variant; (3) стоп читает только уже начерненные куски (volume.go:338-340 «consolidates over the chunks drafted SO FAR»), так что «вся книга» — это чтение не купленного исходника; (4) смена байт запроса или состава батча один раз промахивается мимо чекпойнтов на книгу (комментарий dropBankSettled, terminologist.go:1160-1168). Цена по прогону B: терминолог — 8 вызовов, prompt 27 445 ток. (кэш 5 376), completion 21 394 ток., $0.03803 по $0.44 / $0.014 / $1.32 за M (models.yaml:230); промпт-сторона $0.0097 (25%), completion $0.0282. Классификатор ($0.04531) читает те же батчи. Даже если весь некэшированный промпт считать контекстами, 4× контекстов добавит ≈$0.03 на 66 кандидатов (≈$0.00044 за кандидата) и ≈$0.18 на ~400 кандидатов (два капа по 200) за консолидацию.", + "correction": "«Центы» за консолидацию правдоподобны (оценка, не замер), но нужны протяжка позиций и одна перекупка прохода на книгу; при сегодняшней пере-консолидации на каждой покупке цена множится на число покупок." + }, + { + "id": "A-a2", + "claim": "ё→е зашито на целевой стороне (norm.go:203-205) и стоит в очереди владельца как данные (D39.64 §5, ряд 14)", + "verdict": "PARTIAL", + "evidence": "Ё-фолд в norm.go:198-200 (`if r == 'ё' { r = 'е' }`); в :203 уже `return strings.TrimSpace(b.String())`. BACKLOG.md строка 28, ряд 14: «ё-фолд → target-данные (`char_fold`; … сдвиг `memory_version`)», источник D39.64 — верно.", + "correction": "norm.go:198-200." + }, + { + "id": "A-a3", + "claim": "Загрузчик авто-банка сравнивает сырым кортежем (mining.go:717-733); уступка на проводе — по сырому src (memory.go:905,925)", + "verdict": "CONFIRMED", + "evidence": "mining.go:717-733 `type ukey struct { src, sense string; since, until int }` и `held[ukey{e.Src, e.Sense, e.SinceCh, e.UntilCh}]` (реджекты при этом нормализуются, :726). memory.go:905 `signedSrc[strings.TrimSpace(p.entry.src)] = true`, :925 `if p.entry.status != \"approved\" && signedSrc[src]`.", + "correction": "" + }, + { + "id": "A-a4", + "claim": "«Хранимый src остаётся авторским — для показа»", + "verdict": "REFUTED", + "evidence": "Сегодня строки движка хранят НОРМАЛИЗОВАННЫЙ ключ: mining.go:612 `out = append(out, miner.Term{Src: c.Key, ...})`; terminologist.go:1052-1056 — майненый кандидат приходит с поверхностью майнера, а это подстрока нормализованного текста. Память стопа тоже нормализована: store/migrate.go:460 `surface TEXT NOT NULL, -- text.NormalizeSourceKey form`. Майнер работает только по NSource (mining.go:82), сырую поверхность майненого кандидата не сохраняет вовсе.", + "correction": "«Остаётся» верно только для сида. Чтобы строки движка хранили авторский src, нужен новый путь захвата поверхности; смена Identity перевыключает хранимое состояние (bank_stop_presented, src авто-банка), то есть это миграция данных, а не только --resnapshot." + }, + { + "id": "B-b1", + "claim": "Схема уже держит (Identity, sense, окно): UNIQUE migrate.go:203; окна memory.go:681-689", + "verdict": "CONFIRMED", + "evidence": "store/migrate.go:203 `UNIQUE (book_id, src, sense, since_ch, until_ch)`; memory.go:681-689 spoilerBlocked: `if e.sinceCh > 0 && chapter < e.sinceCh` / `if e.untilCh > 0 && chapter > e.untilCh`. Оговорка: UNIQUE стоит на сыром src, а не на Identity (см. F4).", + "correction": "" + }, + { + "id": "B-b3", + "claim": "Оговорку области употребления обещал D39.104 п.1; в editor.md её нет — только :5 про идиомы и :7 «СТРОГО»", + "verdict": "CONFIRMED", + "evidence": "05-decisions-log.md:359 (D39.104 п.1): «получают узкую оговорку ОБЛАСТИ употребления, действующую на все строки одинаково». Греп «област» в backend/prompts/zh-ru/editor.md — 0 (контроль: 41 строка), по всем 7 файлам prompts/zh-ru/*.md — 0. editor.md:5 — кальки жестов и идиом; :7 «СТРОГО по приведённому глоссарию». Нюанс: D39.104 п.2 откладывает внесение в движок до строки бэклога 134 «ПОСЛЕ отчёта пробы»; в живом BACKLOG.md строки 134 нет (0 из 314 нумерованных), её судьба не прослежена.", + "correction": "" + }, + { + "id": "D-d1", + "claim": "Сегодня 家族/族 режет срез top-200 ДО типа (miner_emit.go:126-129)", + "verdict": "REFUTED", + "evidence": "Кап действительно стоит до фильтра приемлемости (miner_emit.go:126-129 `if len(ranked) > emitRankCap { ranked = ranked[:emitRankCap] }`), но названные термины режутся не им. emissionEligible, miner_emit.go:346 `if !hasAnyType(c.Types, \"name\", \"place\", \"title\") { return false }` и :349 `runeLen(c.Src) < 2`. BACKLOG ряд 440, опровержение 12.09: «`族` отсечён БЕЗУСЛОВНО как ОДНОРУННЫЙ … `家族` отсечён ТИПОМ — у него 2 руны и freq 9 при emitMinFreq 5».", + "correction": "Обычные существительные сегодня закрывает тип-фильтр name|place|title и запрет однорунных, а не срез top-200; подмена механизма уже опровергнута в ряду 440." + }, + { + "id": "D-d3", + "claim": "Предохранитель «имя выкинуть нельзя» — детерминированная улика майнера (Evidence, terminology.go:106): при ней not-a-term запрещён", + "verdict": "REFUTED", + "evidence": "Детерминизм подтверждён (F7), достаточность — нет. Лист стопа прогона B: `evidence:` у 2 из 66 кандидатов (方正, 沈翠 — surname). Авто-банк B: 16 строк name/place, из них 14 без паттерн-улики: 凤雏, 华夏, 卧龙, 古月一族, 古月方源, 宗族祠堂, 宗祖祠堂, 方家, 方老魔, 沈嬷嬷, 熊家寨, 白凝冰(→Бай Нинбин), 白家寨, 青茅山. Поле Evidence двусмысленно: при эмиссии 62 из 64 строк получают в него не-паттерн «banknote-only candidate (the miner did not surface it)» (mining.go:607-612). Гард по непустому Evidence на эмиссии запретил бы not-a-term на всём, гард по входу терминолога защитил бы 2 из 66.", + "correction": "Детерминированная улика имени покрывает ~3% кандидатов; принцип «не обеднять язык без человека» на ней не держится. Нужен другой источник улики (паттерны по банкнотным кандидатам, тип после классификатора) или человек." + }, + { + "id": "E-e3", + "claim": "Дверь пишет только дельту (Source:mined), до черновиков не доходит (decisions.go:50-57, bankmaterialize.go:318-333); сид не трогается никогда ⇒ «пол книги перегенерировать» невозможно", + "verdict": "PARTIAL", + "evidence": "Путь дельты подтверждён: decisions.go:57 `DecisionDepth = \"edit_wave\"`; bankmaterialize.go:318-333 — базовый банк исключает `row.Source == \"mined\"`. Но преемник для сид-термина дельтой невозможен (коллизия или молчаливая инертность, пробы в F5), а правку сида дверь отклоняет (decisions.go:358-363).", + "correction": "Для сид- и given-терминов пункт (e) недостижим без правки сида, а она сдвигает базовый снапшот и перекупает черновую волну на затронутых кусках." + }, + { + "id": "F-f1", + "claim": "Платформа читает только terms (platform/internal/ingest/bank.go:57-70)", + "verdict": "CONFIRMED", + "evidence": "В ingest/bank.go:57-70 `wireBank` содержит только Version, BookID и Terms. Греп `json:\"proposed` по platform — 0 (контроль: 209 go-файлов). Движок секцию публикует: backend/internal/pipeline/bankexport.go:64 `Proposed []BankExportProposal json:\"proposed,omitempty\"`; ряд 224 фиксирует то же.", + "correction": "" + }, + { + "id": "F-f2", + "claim": "Черновик по-прежнему без движковых строк", + "verdict": "CONFIRMED", + "evidence": "bankmaterialize.go:318-333: `if row.Source == \"mined\" { hasMined = true; continue }` → `r.baseMemory = MaterializeBank(baseIn, ...)`; черновая волна выбирает по базовому банку.", + "correction": "" + } + ], + "extra_findings": [ + { + "title": "Механизм преемника не применим к подписанным сид- и given-терминам: получается либо падение прогона, либо молча инертная строка", + "evidence": "Проба через overlay (internal/membank). ApprovedSharedKeyCollisions над одобренным сидом 方源 [0,0] и одобренным преемником [5,0] → «firing key \"方源\" is shared by different terms … with overlapping spoiler windows»; bankmaterialize.go:146-148 роняет на этом прогон, вердикт двери делает ту же проверку (decisions.go:913-914). С неподписанным преемником коллизии нет, но в главе 8 editorLines = [«- 方源 → «Фан Юань»»] (уступка по memory.go:925). Закрыть окно сида дверь не даёт (decisions.go:358-363), контракт тоже (openapi.yaml:2370-2372, origin given).", + "impact": "Центральные имена книги, заданные сидом, не получают «один глагол succeed» без правки сида. Правка сдвигает базовый снапшот и перекупает черновики на кусках ≥N — прямо против (e) и (f). Пакет 1 должен либо разрешить преемнику закрывать сид-окно (новый писатель сида), либо честно исключить given-термины." + }, + { + "title": "Вынос таблицы через pack.Version() меняет класс цены правки таблицы: $0-репин превращается в полную перекупку", + "evidence": "Сегодня NormVersion фолдится только в memory_version (memory.go:417); отдельного поля в снапшоте нет (snapshot.go:409 langpack_version, :425 memory_version). repin.go classifySnapshotMove: любой изменившийся ключ, кроме memory_version, даёт moveOther («Nothing is re-pinnable»). pack.Version() — это langpack_version (snapshot.go:477).", + "impact": "Любая правка таблицы свёртки для пары перекупает все юниты обеих волн у всех книг пары, а не только юниты с изменившимися байтами. В трейдоффах проекта это не названо. Лечится фолдом хеша Identity в memory_version, а не в хеш пака." + }, + { + "title": "В хранилище лежат уже нормализованные ключи: смена Identity — миграция данных, а не только --resnapshot", + "evidence": "store/migrate.go:460 `bank_stop_presented.surface -- text.NormalizeSourceKey form`; mining.go:612 `miner.Term{Src: c.Key}`; terminologist.go:1052-1056 (src майненого кандидата — нормализованная подстрока).", + "impact": "Для zh-simplified вывод не изменится, но для любой пары, где Identity станет отличаться от сегодняшней свёртки, память стопа (стоп на новизне) и src авто-банка перевыключаются — будут ложные «новые» кластеры и повторные стопы. Обещание «хранимый src авторский» требует нового захвата поверхности в майнере." + }, + { + "title": "«Терминолог только для новых Identity» гасит споры, которые сегодня выдаёт ответ роли, а замену проект кладёт позже", + "evidence": "terminologist.go:1127-1134, замер: «439 candidates sit on a surface the seed holds, and in 366 of them at least one draft disagreed … A one-condition filter would have bought a saving by silencing 366 disputes». CanonConflicts (terminology.go:929-932) без consolidated возвращает nil. В проекте терминолог «только по новым Identity» стоит в Пакете 1, а «детектор споров (данные пары)» — в Пакете 2.", + "impact": "Между пакетами лист подписи теряет метки противоречий с банком на ~27% кандидатов корпуса (366 из 1365). Бесплатное сравнение черновик↔закон должно войти в тот же пакет, что и фильтр." + }, + { + "title": "Нить Identity через код дороже заявленного: дверь и сид-линт работают без пака, книги без пака остаются без таблицы", + "evidence": "54 вызова в 12 файлах плюс 2 передачи функцией (F1); membank/decisions.go (17 вызовов) — чистая функция, bank-apply Runner не строит (mining.go:29-31); runner.go:450-456 `packVersion … \"\" when not`; config/book.go:93-98 — langpack_root необязателен.", + "impact": "Пакету 1 нужно протащить пак (или объект Identity) в дверь, сид-линт, майнер, терминолога и материализацию, а для книг без пака определить дефолт. Иначе zh-книга без langpack_root молча теряет trad→simp после одного громкого пере-снапшота." + } + ], + "obstacles": "Не проверено или слепые места: (1) Преемник проверен пробами на уровне membank (Select и editorLines, ApprovedSharedKeyCollisions), а не сквозным прогоном через renderedContentHashes и rowsResumeFree с настоящими шаблонами. То, что content_hash зависит только от отрендеренного текста, выведено из кода repin.go:131-160. (2) Отказывает ли вердикт двери на коллизии, внесённой решением (compare-by-subject), или записывает её — не прослежено; установлено только, что проверка идёт (decisions.go:913-914). (3) «Живой японский кандзи с другим значением» я определял по кодированию в JIS X 0208 (python shift_jis) и собственному знанию значений; списка Jōyō офлайн нет. (4) Цена выборки по всей книге — оценка из разбиения токенов прогона B, не замер; доля контекстов в промпте не выделена, потому что тексты запросов в БД не хранятся (checkpoints хранят только ответы). (5) Ряд 134 (носитель D39.104 п.2) в живом BACKLOG не найден (0 из 314) — в архивных слайсах не искал. (6) Формулировки «одна платная книга» в docs нет; D39.63 п.3 (01.08) говорит «боевых книг в полёте нет». Идут ли сейчас платные книги через платформу, не проверял, поэтому утверждение раздела 3 про «$0» не вердиктовано. (7) Разделы 0, 2, 3, 4 проекта проверены только там, где пересекаются с F1–F8. (8) Кейсы «90» и «не термин» доказаны пробой парсера; в оплаченных прогонах A и B таких ответов 0 (контроль: 129 и 137 строк), так что частота в бою неизвестна. Пробы запускались через go test -overlay из файлов в scratchpad; дерево /home/ubuntu/tm-verify-1509 не менялось (git status --short: 0 до и после)." + }, + "L2": { + "verdicts": [ + { + "id": "R1", + "claim": "The auto-bank goes from 'this run's projection' to an append journal, and the bank becomes a deterministic fold of the owner's and engine's journals. The claim is that ontology 18 survives literally and only the engine source changes, becoming cumulative 'like every other source'.", + "verdict": "PARTIAL", + "evidence": "What survives is real. Each source keeps one writer (18-bank-ontology.md:13-15), the view is still rebuilt whole (:16, :20-22), and a fold of journals is still a full rebuild.\n\nThe framing is wrong. In the ontology the auto-bank is a SOURCE, not a projection: 18:15 says '`.auto-bank.yaml` (слово ДВИЖКА, сидит при базе)', writer 'прогон'. The phrase 'проекция этого прогона' appears nowhere in docs or backend code (0 hits); the control is that the ontology names auto-bank twice, both times as a source or the loop.\n\nFive places need a note:\n(a) 18:17 says 'остановившийся прогон авто-банк не пишет', and the code agrees: mining.go:234-249 `if !stopping { writeAutoBank … seedGlossary }`. The terminologist runs before the stop decision (mining.go:165) and nothing from it is kept as a source on the stop. So the design's 'реплей-пины (стоп→подпись→резюм)' and 'повтор прогона реплеит события, а не модель' require writing events at the stop boundary. That changes the clause.\n(b) The loop, 18:24-29, is guarded by `unsignedEngineSurfaces`. Its contract (mining.go:752-758) is to keep offering the engine's own unsigned rows 'until the owner PROMOTES … or DECLINES'. The design's 'терминолог вызывается только для Identity без действующего закона в окне' turns the engine's past unsigned decisions into durable law that stops re-asking across runs. The ontology does not state that property.\n(c) Successor on an engine term: the door writes only delta and rejects (18:15; decisions.go:33 'TWO VERBS AND NO THIRD'). Closing the engine window (until=N−1) inside the engine journal would need a second writer, so the fold needs a new rule, 'an owner event cuts off engine law'. Today that rule exists only on the editor wire (memory.go:926 'an unsigned rendering yields to the signed canon'). The loader only warns on approved×unsigned (seeding.go:72) and fails on approved×approved (bankmaterialize.go:146).\n(d) Format: mining.go:763 says the auto-bank uses the seed schema 'so `tmctl seed-lint` reads it, and a row can be moved into the owner's delta by copy-paste'. An event journal with outcome and provenance breaks that.\n(e) 'Накопительный, как и все прочие' does not hold. The delta is overwritten, not appended: decisions.go:35 'a decision is REPLACED by the opposite one', and mergeTerm overwrites the row.", + "correction": "Say it plainly: the ontology changes, and it needs a note. Rewrite 18:15-17 so the engine source is a durable journal, written on the stop boundary too. Rewrite the loop paragraph 18:24-29: the loop now carries unsigned engine decisions forward between runs, and `unsignedEngineSurfaces` changes meaning. Add a precedence rule to the view (owner event over engine law, including window truncation) with a pin. Record that the engine file leaves the seed schema, or keep the journal as a separate file next to a seed-compatible view." + }, + { + "id": "R2", + "claim": "The closed outcome vocabulary (law / not-a-term / polysemous / undecided) fits D39.42 §C2-7 (two-mode emission), D39.104 п.1 (law whatever the status, with an area-of-use carve-out) and D39.144 (one OK for the whole bank, stop only on novelty).", + "verdict": "PARTIAL", + "evidence": "D39.42 §C2-7 (research/20-bank-mining.md:604-608) allows only 'status: auto (без dst — инертны)' or 'status: draft', 'в схеме seedTerm … БЕЗ новых полей', with Source class and evidence kept in a separate signature map. D39.42 п.1 (log:275) defines the terminologist's output as 'консолидированное dst на каждый терм'. `law` maps to draft and `undecided` to auto without dst. `not-a-term` and `polysemous` have no form in the status machine (migrate.go:192 auto|draft|approved). They either collapse into auto, indistinguishable from undecided, or need new fields, which breaks 'БЕЗ новых полей'. Either way D39.42 п.1 and §C2-7 need amending.\n\nToday's behaviour sharpens this. miner_emit.go:261-269 copies the banknote proposal into st.Dst, and status becomes draft only when a consolidated dst exists (:276-279). D39.104 makes the wire blind to status (editorLines skips only dst==\"\"). So the §C2-7 promise 'never on a raw per-chunk banknote guess' (miner_emit.go:271-275) holds on status only, and on the wire the guess rides as law. 'Не-закон' for undecided/not-a-term therefore means changing what an auto row may carry.\n\nD39.104: there is no clash on the wire. The carve-out, though, is ratified only as doctrine (log:359). Its sole design was a probe arm 'метаязыковое окно (оговорка области + leakage)' (archive/05-decisions-D39-91-105.md:119). D39.104 itself names the leftover risk 'оговорка как лазейка — под leakage-метрикой пробы'. It is not on the wire (injection.txt editor_header: 'не вводи иных вариантов') and not in editor.md (:7 'СТРОГО'). Its scope is narrow: 'игра слов · разбор знаков · буквальное не-терминное прочтение'. The design makes it 'обязательная часть архитектуры' and the mechanism for name versus ordinary word, without naming the leakage gate. (Search in 13 files: 3 hits, none dropping the clause.)\n\nD39.144 and D39.47: in section 1(f) the `proposed` list is 'новое, undecided, polysemous, предложения преемников, споры', with no `not-a-term`. So an engine decision to throw a term out never reaches what the single OK covers. That goes against D39.47, 'решение о переводе принадлежит ПОДПИСИ владельца', and ontology 18:33-36, 'какие переводы человек действительно одобрил'. Separately, D39.144 п.1 and backlog row 192 say of the post-reading edit cycle 'НЕ проектировать до полигонных итогов', yet the design puts `succeed` plus a contract minor into package 1. I found no conflict with the novelty stop (D39.158 п.1): re-asking about `undecided` goes to the terminologist, not to the presented-memory.", + "correction": "Put the vocabulary through as an amendment to D39.42 п.1/§C2-7: new outcome fields live in the journal and signature map, not the seed schema, and an auto row drops the banknote dst. Add `not-a-term` to `proposed` so the owner sees every engine refusal in the same single OK. Introduce the area-of-use carve-out only after the leakage metric (D39.104). Move `succeed` out of package 1 until row 192 is opened by the owner." + }, + { + "id": "R3", + "claim": "The design names, as the owner's own decision, each item he already settled or deferred: cross-run bank accumulation (row 130), term-class emission expansion (D39.47), the ё-fold into data (D39.64 §5 / row 14), and 'one paid book' (D39.63).", + "verdict": "PARTIAL", + "evidence": "Counted in the design (control: 5 'D39.' mentions in 10,910 characters). '130' 0, 'D39.118' 0, 'D39.50' 0, 'D39.190' 0, '192' 0, 'D39.144' 0.\n\nRow 130: NOT named. BACKLOG.md:70 lists 'накопительный мердж авто-банка … СТОП-решение владельца (двигает банк → memory_version)', gated on 'WARN второго прогона'. The code says so too, mining.go:773: 'The BOUNDARY is deliberate and is the owner's STOP: this reports, it does not accumulate'. The design puts the journal in package 1 as 'бэкенд, $0 + центы'. §5 п.1 does put the substance to the owner, but not as a decision he previously stopped, and without its gate or its cost class (volume.go:333-352 describes the edit-unit re-payment when the auto-bank grows).\n\nD39.47: named ('D39.47/ряд 440', 'Позже, по слову владельца'). Not named: D39.50 п.1, the ratified negative close of emission expansion (archive/05-decisions-D39-20-58.md:325), and D39.102 п.3 'term-класс эмиссии … не заводится'. The proposed 'частотный по паре' nomination channel runs into D39.50 п.2, 'частотного экрана НЕ существует'. The stated cause for 家族, 'режет срез top-200 ДО типа (miner_emit.go:126-129)', contradicts the corrected causality in row 440 (BACKLOG.md:361): 族 is dropped by the one-rune floor and 家族 by the type filter in `emissionEligible`.\n\nё-fold: named as the owner's queue, but §4 slots it into the re-snapshot window as work. Row 14 (BACKLOG.md:28) reads 'владелец | когда-нибудь | отдельное решение'.\n\nD39.63: the phrase 'одна платная книга' is not in D39.63. It lives in BACKLOG:95/218, research/27 and CHAPTER_STRUCTURE_DESIGN:1524; D39.63 п.3 says only 'стендовый корпус ОДНОРАЗОВЫЙ'. The ratified basis for $0 is D39.190 п.4 (log:2121): 'coldrun-v16 закрыт словом владельца «не доводить»'. For the later paid runs A (bk_ROEHZBD46ALFI43E) and B (bk_NH6275ZIRFFTLZHG) there is no such record: 'не доводить' hits only coldrun-v16 across 97 live md files, and experiments 24/25 and NEAR_TERM_PLAN hold no continuation decision. The reversal condition stated in the chapter design (CHAPTER_STRUCTURE_DESIGN:760-767) is not carried over.", + "correction": "In §5, name each item as a prior owner decision or deferral: row 130 (STOP, gate WARN, memory_version move) · D39.50/D39.102 п.3 (expansion closed negatively; a frequency screen does not exist) · row 14 (separate decision, not a window item) · row 192/D39.144 п.1 (post-reading edits not to be designed yet). Take the $0 claim from D39.190 п.4 and add the condition 'if nobody plans to continue runs A/B'. Take the 家族 cause from row 440." + }, + { + "id": "R4", + "claim": "The law unit (Identity, sense, window [since, until]) is already held by the schema, and the window becomes the only tool for changing law mid-book. Successor 'from chapter N' sets until=N−1, and 'главы ≤N не трогаются по построению'. At issue: whether the ordinal-window journal is a mine for the chapter re-cut.", + "verdict": "REFUTED", + "evidence": "The design never mentions chapter identity: 'chapter' 0, 'перекро' 0, 'D39.245' 0. The one mention of 'структура глав' is as a window for the editor carve-out. Meanwhile D39.245 (log:3542) and backlog row 161 move bank windows onto chapter-ID.\n\n(1) The chapter design lets the engine's own files be regenerated: CHAPTER_STRUCTURE_DESIGN:662 'движковые файлы … пере-генерируются, а не мигрируются', with the single durable exception `.mined-delta.yaml`, which 'молча указывает на чужую главу' (:183-187). The engine journal in this design is a second durable carrier holding ordinals. It is missing from the inventory 'ТАБЛИЦ, КОМАНД и ФАЙЛОВ' (:187). `since_ch` 'перекроем никем не переписывается' (:788), so after inserting a chapter before N the successor boundary silently lands on another chapter. 'Главы ≤N не трогаются' holds only until the first re-cut.\n(2) Successor windows are AUTHORED windows. The chapter design measured 'Сегодня авторских окон в дереве НОЛЬ' (:616) and treats their migration as 'проектная страховка, а не работа' (:721). The design makes that class non-empty before the re-cut, using up exactly the window the chapter design calls its opportunity.\n(3) On class `gone`, the rule 'Авторское — ДЕГРАДИРУЕТ В ОТКРЫТОЕ' (:718) turns a successor pair into two rows with the same src, different dst and overlapping windows. parseBankSeed fails loud on that (memseed.go:217 'a term has ONE rendering per chapter'). The engine-written leniency covers only wire-unfit rows (memseed.go:152), so loading the book aborts the run. Two approved rows fail at bankmaterialize.go:146.\n(4) The door verb 'с главы N' as a contract minor would take an ordinal, since BankCorrection windows are ordinals (openapi.yaml:2363 'windows move with a re-cut'). The platform already stores the order boundary as identity (platform/.../00033_order_and_price.sql:72 `ordered_through_chapter_id`).\n(5) The same UNIQUE constraint (migrate.go:203) gets migrated twice: 'UNIQUE по Identity' in package 1, and 'переезжает на chapter-id вместе с колонками' (CHAPTER_STRUCTURE_DESIGN:715). That is two stop-worlds.\n\nThe chapter design already chose ONE window: bank windows go into the re-cut (:807 row 2 '… ДА', :760 'Выбираю ОБЩЕЕ окно'). D39.245 п.1-2 says the mechanics are not ratified and the build starts by running the migration on a database copy.", + "correction": "Order the work: build the engine journal, successor and door verb inside or after the re-cut window, with windows stored as chapter-ID plus a derived ordinal column (CHAPTER_STRUCTURE_DESIGN §4.2 п.3). Or, if it has to come before, store chapter-ID from day one. Either way, add the engine journal to the migration inventory next to mined-delta. Replace 'degrade to open' for successor pairs with a loud per-term decision. Fold 'UNIQUE по Identity' into the single chapter_id UNIQUE migration. Name all this as a dependency on D39.245 and row 161." + }, + { + "id": "R5a", + "claim": "The core has one Identity: universal steps plus fold steps declared as source-language data. Trad→simp and kana folding are hardwired into the core for every source, which 'ломает японский: 後 и 后 схлопываются'. A table edit costs '--resnapshot книг пары (как сегодня NormVersion, только через pack.Version())'.", + "verdict": "PARTIAL", + "evidence": "CONFIRMED: NormalizeSourceKey applies trad2simp and katakana→hiragana with no language check (norm.go:141-153), the comment scopes it 'zh/ja source surfaces' (norm.go:28), and ё→е is on the target side (norm.go:203-205).\n\nREFUTED example: 後 is NOT in the table. trad2simp.txt:13 says 'phrase-level OpenCC (one-to-many, e.g. 後→后 vs 后→后) is deliberately out of scope'; python prints 'absent 後' (control: 500 mappings). The class itself is real in the table: 葉→叶, 準→准, 範→范, 繫→系, 麵→面 are distinct kanji in Japanese.\n\nThe review question ('would it work for a pair not yet in the repo') does not fully pass:\n- A per-rune table plus a 'strip combining marks' flag cannot express 1:N folds (de ß→ss, ä→ae) or reading-dependent ko hanja→hangul, which is not a fold at all. Those need another primitive in Go.\n- A book with no pack loads silently (runner.go:415-420 'a ja book against a zh-only root just runs'), and configs/langpacks holds only ru, zh and zh-ru (16 files). Moving the kana fold into data would silently switch it off for ja books and for the ja→ru golden, which 'injects these with NO langpack' (injection.txt header).\n\nCost claim WRONG: today NormVersion is folded into memory_version (membank/memory.go:417), which counts as a bank-only move and allows a $0 re-pin (repin.go:44-46, :61-90). Through pack.Version() the table lands in `langpack_version` (snapshot.go:409), a separate field of the shared snapshot payload. classifySnapshotMove then returns moveOther: no unit in either wave is re-pinnable. Separately, both Norm and Langpack are in cutInputs (manifest.go:269-282), so the cut tag and unit ids move in both cases.", + "correction": "Keep Identity data in a plane folded into memory_version, not pack.Version(), so a table edit stays a bank-only move (the precedent is D39.118 п.3, which chose a data plane by what it moves). Make the source Identity channel declared and loud when missing, and create `ja/`. Add a string-level (1:N) fold to the primitive, and state that hanja→hangul is not a fold. Swap the example for 葉/叶 or 準/准." + }, + { + "id": "R5b", + "claim": "Successor detectors are pair data, e.g. gender pronouns per chapter in `/pronouns.txt` (他/她 · he/she · er/sie).", + "verdict": "REFUTED", + "evidence": "The file does not exist: configs/langpacks has 16 files, none named pronouns (find shows 0). No Go code counts pronouns: non-test Go has one hit for 他/她, a comment at checks/voice.go:316 (control: 143 non-test .go files).\n\nA word list is not enough. Measured on guzhenren-utf8.txt (control: 7,778,990 characters): 他 occurs 56,100 times as a substring, of which 其他 3,240 + 他们 6,399 + 他人 870 = 10,509 (18.7%) are not singular 'he'; 她们 is 259 of 8,509 她. Dense-script sources therefore need segmentation or an exclusion list. More to the point, a per-TERM detector has to tie each pronoun to an entity (coreference), and that is not a table.\n\nThe only automatic gender producer today is the LLM classifier (decisions.go, gender comment: 'backlog row 210 (the §2 classifier derives it from the source contexts)'). Sources with no gendered third-person pronoun (ja largely drops them, ko, tr, fi, hu, fa) leave the detector inert.", + "correction": "State the detector's parts and which of them are Go versus data: tokenisation mode by script (data via lang-script), an exclusion list (data), and pronoun-to-entity attribution (Go or LLM, not a table). Without attribution, count only proposals from divergence between new-volume drafts, and call the pronoun detector zh-family-only until a generic attribution exists." + }, + { + "id": "R5c", + "claim": "The fuse 'a name cannot be thrown out' is a DETERMINISTIC miner evidence signal (`Evidence`), with surname/title/toponym patterns as pair data. With that evidence present, `not-a-term` is forbidden.", + "verdict": "REFUTED", + "evidence": "The tables are data, but under `/`, not the pair (configs/langpacks/zh/surnames-single.txt, surnames-compound.txt, title-suffix.txt, topo-suffix.txt …). The channels, however, are Go and Han-only.\n- langpack.go:207-208: 'SCOPE (honest): this manifest is the zh-family NAME-MINER's morphology schema … a different source family that wants mining needs new Pack fields + parse + miner channels, not just a dir'.\n- miner_substrate.go:44 `isMinerHan`.\n- miner_patterns.go:20-22: 'several channels (surname-start, Palladius) are zh-shaped'.\n- D39.50 п.8: 'en-детектора НЕ СУЩЕСТВУЕТ (hanRuns — 0 эмиссии на латинице), ja с zh-таблицами активно неверен (0/10)'.\n- A book without a pack runs with the miner inert (runner.go:415-420).\n\nCandidates seen only by drafts (Freq 0, terminology.go:101) carry no Evidence at all. So for any non-zh-family source, and for draft-only names, the fuse does not exist, and the §5 п.2 promise 'не обеднять язык без человека' holds only for zh.", + "correction": "Say explicitly that the evidence fuse is zh-family. For a source with no detector (and for draft-only candidates), define the default: `not-a-term` is forbidden (fall back to `undecided`) or goes to the owner's list. A second source family needs a second detector (D39.50 п.8), not just a directory." + }, + { + "id": "R5d", + "claim": "The outcome vocabulary lives in the prompt as data. The parser accepts only the vocabulary plus 'rendering in the target script'.", + "verdict": "PARTIAL", + "evidence": "The prompt part passes without Go edits: prompts resolve by path convention (12-go-style-notes.md §0.4; prompts/zh-ru/terminologist.md), and the precedent sentinel is an engine-neutral Go constant (terminology.go:694 `NoDst = \"⟦TM-NO-DST⟧\"`) whose instruction text lives in the pair prompt (terminologist.md:36). New outcome tokens are the same class.\n\nThe 'rendering in the target script' guard, however, fails for Latin-script targets: D39.50 п.3 says '`wellFormedLemma` пропускает латиницу', and D39.102 п.3 records 'NoDst-почти-сентинел … остаток — латиница-target'. For zh→en, a reply of 'not a term' passes a script check.", + "correction": "The parser must recognise only closed sentinel tokens (like ⟦TM-NO-DST⟧), never words, and must not rely on script to catch a refusal. State that for Latin-target pairs the script check proves nothing." + } + ], + "extra_findings": [ + { + "title": "Moving the Identity table into pack.Version() raises the cost of any future table edit from a $0 re-pin to full re-payment", + "evidence": "Today the table is folded via NormVersion into memory_version (backend/internal/membank/memory.go:417). repin.go:44-46 says moveBankOnly means 'the ONLY differing component is the memory version', and classifySnapshotMove (repin.go:61-90) returns moveOther on any other field. pack.Version() goes into `langpack_version` (snapshot.go:409, 477), a separate field of the shared payload of both waves.", + "impact": "The design's claim 'как сегодня NormVersion, только через pack.Version()' is wrong about cost class. On any book that is continued, every table edit re-pays both waves with no $0 re-pin, where today it is a bank-only move. The extraction itself also moves the cut tag (manifest.go:269-282), so it belongs in the re-cut window, not package 1." + }, + { + "title": "The terminologist's 'not a term' verdict is invisible to the owner's single OK", + "evidence": "Section 1(f) of the design lists `proposed` as 'новое, `undecided`, `polysemous`, предложения преемников, споры', with no `not-a-term`. D39.47: 'решение о переводе принадлежит ПОДПИСИ владельца на банк КНИГИ'. Ontology 18:33-36: 'какие переводы человек действительно одобрил'.", + "impact": "The engine removes candidates from the bank by a stochastic call without the owner seeing it. That is the exact 'обеднение' the design says it prevents, and for non-zh sources the evidence fuse does not exist (see R5c)." + }, + { + "title": "The design's cause for 家族 not entering the bank contradicts the corrected finding in row 440", + "evidence": "The design: 'сегодня 家族/族 режет срез top-200 ДО типа, `miner_emit.go:126-129`'. BACKLOG.md:361 (correction of 12.09, re-checked by reading the function): '`族` отсечён БЕЗУСЛОВНО как ОДНОРУННЫЙ … `家族` отсечён ТИПОМ', where `emissionEligible` checks `hasAnyType(c.Types, \"name\", \"place\", \"title\")` first.", + "impact": "The claim that the architecture 'впуск обычных существительных не закрывает и не открывает' is false for the deterministic channel: the type filter closes it by construction. A package that 'moves the cap to run events' will not let 家族 in." + } + ], + "obstacles": "Not checked, or only partly:\n- CHAPTER_STRUCTURE_DESIGN.md: read §0, the §2.1-bis inventory, §2.2-bis, all of §4, pins 8-11 of §9 and §11. Not read in full: §5.2-§5.3 (stop-world count), §6, §12.\n- I could not measure whether 家族 is above or below emitRankCap. That needs running the miner on the book, and go test with books access is forbidden here. I took the causality from row 440, not from measurement.\n- Whether paid runs A/B will be continued is recorded nowhere I looked (experiments 24/25, NEAR_TERM_PLAN and a search for 'не доводить' across 97 live md files). The owner's intent cannot be verified here.\n- I did not trace what the probe found about the area-of-use carve-out's leakage. I only established that the carve-out is neither on the wire nor in the prompt, and that no later note drops it (3 hits in 13 files).\n- The list of Japanese false identities (葉/叶, 準/准, 範/范, 繫/系, 麵/面) rests on my knowledge of kanji usage, not a dictionary in the tree.\n- Design claims outside lens 2 were not re-checked: that the bank pass is bought again at signing and at every purchase, pipeline-c1.yaml:161-162, bankmaterialize.go:318-333, and terminologist resume cost.\n- No go test was run; every verdict comes from reading code and docs plus python counts.\n- Uncommitted backend changes by another session in the main checkout (including store/migrate.go and pipeline/*) were deliberately not read. If they land, schema facts and line numbers may shift." + }, + "L3": { + "verdicts": [ + { + "id": "M1", + "claim": "Все двери сравнивают по Identity; UNIQUE схемы (migrate.go:203,389) сегодня по сырому src; Пакет 1 включает «UNIQUE по Identity (миграция схемы)».", + "verdict": "PARTIAL", + "evidence": "ЗАМЕР. Обойдено 178 файлов БД: *.db и *.sqlite в books (find -L) плюс 2 полные базы прогонов A/B. WAL у всех 0 байт, чтение immutable полное. Имён project.db в books только 2, обе с 0 строк glossary, поэтому обход расширен до всех БД.\n- С таблицей glossary 177 файлов, с хотя бы одной строкой 150.\n- Строк glossary 13 632, alias 2 223, voice_profiles 0, address_pairs 0 (таблицы есть, напр. в базе B).\n\nНОРМАЛИЗАЦИЯ. norm.go скопирован дословно в scratch-модуль с golang.org/x/text v0.40.0. NormVersion: memnorm-v3-…+u15.0.0+xtextv0.40.0-a6c1259543b1. Самопроверка: 魯鎮→鲁镇, ハル→はる, Q→q, 渡邊→渡边.\n\nРЕЗУЛЬТАТ ПО БАЗАМ:\n- Уникальных сырых src 229, уникальных Identity 229; src, у которых Identity≠raw: 0.\n- Конфликтов «разный сырой src, один Identity, один (book, sense, since_ch, until_ch)»: 0.\n- Контроль: сырых дублей внутри UNIQUE 0 (как требует схема); строк с ненулевым окном 1 897.\n\nИСТОЧНИКИ, из которых вид пересобирается: 90 YAML (seed, mined-delta, rejects, auto-bank, signature), 2 857 src-записей, 343 уникальные строки. Identity≠raw: 0; конфликтов внутри файлов 0; в составном наборе seed+delta+auto-bank по 10 стенд-книгам 0.\n\nЦИТАТЫ ПРОЕКТА ВЕРНЫ: migrate.go:203 `UNIQUE (book_id, src, sense, since_ch, until_ch)`, :389 то же у voice_profiles.\n\nНО «миграция схемы» — не тот инструмент:\n- migrate.go:13 `var migrations = []string{` — миграции только SQL, а Identity зависит от данных пака и в SQL не вычисляется.\n- migrate.go:358-360: пересборка этого UNIQUE «forbidden by the append-only discipline».\n- glossary.go:146-160: ReplaceBank делает DELETE+INSERT на каждом прогоне, существующих строк после следующего прогона нет.\n- Аддитивный уникальный индекс возможен (прецедент migrate.go:446 events_outbox_once, 1 из 30 CREATE), но только поверх хранимой колонки identity, т.е. «глупое хранилище» (migrate.go:169-172) получит значение, зависящее от языкового пака.\n- Выживший сырой src решает публикуемый id: TermID из сырого src (decisions.go:166-173), платформа хранит ID (platform ingest/bank.go:25-27).\n- Он же решает позицию в ORDER BY, а значит memory_version и порядок строк провода (bankmaterialize.go:25-41).", + "correction": "На существующих данных миграция пустая: 0 конфликтов в 13 632 строках и 2 857 YAML-записях. Но это корпус одной zh-книги без трад./каны/латиницы в ключах.\n\nЕдинство по Identity должно держаться отказом в сборке, а не миграцией схемы: storeOrder (bankmaterialize.go:173-185), MinedDeltaSeedCollisions (:110-113), ukey в loadAutoBank (mining.go:717-733) — переключить их ключ на Identity. Схемный индекс опционален и требует хранимой колонки.\n\nС парой «разный src, один Identity, одно окно» сборка обязана:\n- в источниках владельца (seed, mined-delta) — громкий отказ с именами обеих строк;\n- в авто-банке — сброс поздней строки с ремаркой (прецедент mining.go:730-733).\nАвтослияние недопустимо: выживший сырой src меняет публикуемый id и memory_version." + }, + { + "id": "M2a", + "claim": "Терминолог только по новым Identity: одна перекупка банк-ролей на книгу — центы; Пакет 1 стоит «$0 + центы перекупки банк-ролей». Прогон B: терминология $0.083 из $0.397, второй проход $0.0338.", + "verdict": "PARTIAL", + "evidence": "ЦИФРЫ B ПОДТВЕРЖДЕНЫ. request_log базы B:\n- draft $0.12065, edit $0.19267;\n- terminology: classifier $0.04531 + terminologist $0.03803 = $0.08334 из $0.39666.\n\nТАЙМЛАЙН:\n- Прогон 1 (19:48–19:58): терминология $0.04955, затем стоп; bank_stop_presented = 67.\n- Прогон 2 (hello 19:59:51): черновик реплей за $0 (6 tm_hit).\n- Терминология куплена заново 20:00:01–20:01:25: classifier 3 новых хеша ($0.01556), terminologist 3 новых ($0.01823) и 1 hit f9fbb1bc38 ($0). Итого $0.03379.\n- Снапшот сменился: memory_version a47d11ec8e99→15a142bfc7d3, langpack тот же.\n\nМЕХАНИЗМ:\n- Ключ — RequestHash (render.go:352-367): SnapshotID + все сообщения. Батчи пакуются по рунам, смена состава = промах (terminologist.go:1158-1172).\n- dropBankSettled (terminologist.go:1173-1205) снимает только кандидатов, которых держит НЕ-движковая строка (unsignedEngineSurfaces, mining.go:748-760). Строки авто-банка оплачиваются каждый прогон.\n- Классификатор идёт по тому же paid (terminologist.go:405).\n\nПРИ ФИЛЬТРЕ «ТОЛЬКО НОВЫЕ» меняется состав каждого батча → первая сборка промахивается по всем чекпойнтам обеих банк-ролей → одна пере-консолидация остатка. На пилоте это ≤ ~$0.05 (первый проход B), потолок книги budget_usd 1.00 + classify_budget_usd 1.00 (pipeline-c1.yaml:173,175).\n\nСКАН АВТО-БАНКОВ: 19 файлов, 921 строка, пустой dst 3, мусорных классов dst (не-термин / цифры / маркер / без кириллицы) 0 — импорт в журнал мусора не заморозит.\n\nЧЕГО «$0 + ЦЕНТЫ» НЕ СЧИТАЕТ:\n- Словарь исходов снимает закон со строк, которые старый парсер делал законом (not-a-term, ⟦TM-NO-DST⟧). Обогащённый банк меняется → edit-волна → платная пере-редактура юнитов, где эти термины встречаются. $0-репин только для байт-равных юнитов (stagerun.go:92-113). На B редактор — $0.193 из $0.397.\n- Фильтр без append-журнала рвёт банк: writeAutoBank переписывает файл целиком из дельты (mining.go:776-790). А накопительный мердж — «СТОП-решение владельца (двигает банк → memory_version)» (BACKLOG строка 130).", + "correction": "«Одна перекупка банк-ролей — центы» верно на пилотном масштабе (≤~$0.05 на B), с потолком $2 на книгу.\n\nЦена Пакета 1 — не «$0 + центы банк-ролей». К ней добавляется оплаченная пере-редактура юнитов, где словарь исходов меняет закон. В долларах это ничтожно только в одноразовой стендовой фазе D39.63.\n\nФильтр «только новые Identity» нельзя лендить раньше append-журнала движка и слова владельца по строке 130." + }, + { + "id": "M2b", + "claim": "Identity по данным пары: правка таблицы = --resnapshot книг пары «как сегодня NormVersion, только через pack.Version()».", + "verdict": "REFUTED", + "evidence": "ЭТО ДВА РАЗНЫХ КЛАССА СДВИГА.\n\nСегодня NormVersion фолдится ВНУТРЬ memory_version: memory.go:417 `h.Write([]byte(text.NormVersion() + \"\\x00\" + matchVersion + \"\\x00\"))` в ComputeVersionScopedIn, общем для базы и обогащённого банка.\n\npack.Version() фолдится ОТДЕЛЬНЫМ полем: snapshot.go:477 `LangpackVersion: r.packVersion()`. Версия = packAlgoVersion + sha256 авторских байтов (langpack.go:202-204, :323). Файл таблицы в configs/langpacks/zh её двигает.\n\nclassifySnapshotMove (repin.go:69-90): любое поле кроме memory_version → moveOther. repinnable истинен только при moveBankOnly (repin.go:283, 318).\n\nЦЕПОЧКА ПЕРЕКУПКИ:\n- stagerun.go:54-66 требует --resnapshot.\n- :92-94 доверяет chunk_status только при равном снапшоте или repinnable.\n- Иначе :536-538: `RequestHash(r.attemptRequest(st, model, snapID, …))` + GetCheckpoint; ключ со SnapshotID (render.go:365-367) → промах → платный вызов даже при байт-равном запросе.\n- Банк-роли хешируют snapshot черновика: waverun.go:179 → runBankMiningStop → runTerminologist(ctx, draftSnapshot, …) → runAttempt(…snapID…) (terminologist.go:832).", + "correction": "Через pack.Version() вынос или правка таблицы — moveOther для обеих волн и банк-ролей. Это полная перекупка каждой уже переведённой книги пары, у которой есть langpack (база A $0.419, B $0.397 — целиком).\n\n«Как сегодня NormVersion» — это moveBankOnly: $0-репин всех юнитов с неизменными байтами провода; для zh при переносе таблицы без правки это все юниты.\n\nЧтобы вынос и будущие правки стоили $0 там, где провод не изменился, хеш таблицы тождества должен ехать в memory_version (как NormVersion), а не в LangpackVersion." + }, + { + "id": "M2c", + "claim": "«zh-книги переживут один пере-снапшот при выносе — в фазе «одна платная книга» это $0 (D39.63)».", + "verdict": "PARTIAL", + "evidence": "ПЛАТНЫХ КНИГ. Обойдено 205 файлов БД (books + оба стенда), request_log есть в 204, cost_usd>0 — в 162.\n- Различных book_id с cost_usd>0: 26, все — эксперименты и стенды gu-zhenren.\n- Сумма максимумов по книге ≈ $7.17: guzhenren-probe4 $2.31, bk_ROEHZBD46ALFI43E $0.419, bk_NH6275ZIRFFTLZHG $0.397 и т.д.\n\nD39.63 (05-decisions-log.md:295) п.3: «боевых книг в полёте нет, стендовый корпус ОДНОРАЗОВЫЙ (старые БД остаются читаемым $0-сырьём, перекупать их не для чего) … механика --resnapshot … про эру боевых книг после МАСШТАБА».\n\nФРАЗЫ «одна платная книга» в доках нет: 0 совпадений по md вне prompts/reports (123 файла в каждом дереве, HEAD и main). Более поздней ноты о смене фазы grep «боевых книг|книг в полёте|платной книг» не нашёл: единственный хит — сама D39.63.", + "correction": "$0 здесь значит «одноразовый стенд не перекупаем» — это 26 book_id и ≈$7 исторической траты. Это не «пере-снапшот бесплатен».\n\nПри маршруте через pack.Version первая же боевая книга пары оплачивается заново целиком (см. M2b).\n\nФормулировка «фаза одной платной книги» — пересказ, D39.63 так не говорит." + }, + { + "id": "M3", + "claim": "«Повтор прогона реплеит события, а не модель (принцип 8)»; undecided — «спросить снова, когда появятся новые улики (новый том номинировал повторно)».", + "verdict": "PARTIAL", + "evidence": "КАК СЕГОДНЯ ПЕРСИСТИТСЯ СОБЫТИЕ ТЕРМИНОЛОГА:\n- checkpoints(request_hash, …, response_text, cost_usd) — схема базы B.\n- Ключ RequestHash (render.go:352-367): book, chapter, chunk_idx = порядковый номер батча, attempt, stage, role, model, temperature, reasoning, json, max_tokens, SnapshotID черновика, все сообщения.\n- Поверх — производный auto-bank.yaml, переписываемый целиком (mining.go:776-790), и сайдкары.\n- glossary_revisions (migrate.go:218-233) — журнал только approved-dst, не решений движка.\n\nКЭШ РЕПЛЕИТ ТОЛЬКО ТОЖДЕСТВЕННЫЙ ЗАПРОС. Код сам называет ловушку (terminologist.go:1158-1172): «a run whose composition differs … finds no checkpoint and buys the pass again». На B стоп→подпись→резюм реплеил 1 батч из 7 (f9fbb1bc38), 6 куплены заново.\n\nЧТО ЖУРНАЛ ПО IDENTITY ДАЁТ СВЕРХ КЭША:\n- переживает смену состава батча, сдвиг снапшота черновика и рост улик;\n- хранит не-закон (not-a-term / undecided), которого в кэше нет как факта: сегодня молчание = «не решал» (terminologist.go:341-343).\n\nПРИНЦИП 8: нумерованных принципов владельца в доках нет — 0 хитов «принцип 2/6/7/8» по 123 md каждого дерева (контроль: слово «принцип» в 46 файлах). Сверить текст нельзя.\n\nПРО UNDECIDED. Реплей детерминирован, только если (а) условие «новые улики» — чистая функция записанных входов с отпечатком в событии и (б) перезапрос пишется в журнал. Проект не задаёт ни то, ни другое.\n\nЗаявленный триггер истинен на КАЖДОЙ покупке. Стоп майнит все уже начерно переведённые куски (mining.go:80-98); volume.go:337-339: «consolidates over the chunks drafted SO FAR». Значит undecided — включая навязанный предохранителем имени при устойчивом ответе not-a-term — перезапрашивается за деньги каждой покупкой, без предела.", + "correction": "Сверх кэша чекпойнтов журнал действительно даёт реплей решений, не зависящий от состава батча. Принципу детерминизма это не противоречит при двух условиях:\n1. У события есть отпечаток улик.\n2. Перезапрос undecided стреляет только при смене этого отпечатка (а не при повторной номинации), и есть предел перезапросов на одно Identity.\n\nБез этого пункт (d) воспроизводит обратную кривую цены для подмножества undecided." + }, + { + "id": "M4", + "claim": "Пакет 1 одним паком: журнал+свёртка+терминолог по новым Identity · словарь исходов+парсер+защита · Identity в ядре с таблицей в langpacks/zh, двери по Identity, UNIQUE-миграция · преемник+глагол двери (контрактный минор) · proposed · счётчик промахов.", + "verdict": "REFUTED", + "evidence": "ОБЪЁМ В GO:\n- Не-тестовых файлов с затрагиваемыми функциями (NormalizeSourceKey, load/writeAutoBank, unsignedEngineSurfaces, dropBankSettled, autoBankPath, MinedDeltaSeedCollisions, Apply/DecodeDecisions) — 17 в 6 пакетах (text, membank, miner, terminology, pipeline, store); тест-файлов 24.\n- NormalizeSourceKey: 54 не-тестовых вызова в 12 файлах (decisions.go 17, mining.go 13, terminologist.go 7, banknote.go 4, memseed.go 3, …) и 58 в тестах.\n- Пакет text объявлен «free of language policy: no pair data» (norm.go:7-8). Identity с таблицей пака = протащить пак во все эти места, включая чистую дверь decisions.go (ApplyInput пака не несёт).\n- Сверх того: internal/lang (новый канал — фиксированный srcFiles, langpack.go:206-215), данные langpacks/zh и промт терминолога, bankexport.go (proposed), cmd/tmctl/bankapply.go, store (миграции только SQL, migrate.go:13).\n\nШОВ:\n- Контракт 14 — зона оркестратора: 14-api-contract/README.md:684 «approve/decline, третьего нет».\n- Платформа пинит DecisionsVersion \"tm-bank-decisions-v1\" (platform/internal/ingest/bankdecisions.go:18), движок отвергает чужую версию (decisions.go:143-144).\n- Платформенный API пропускает только approve/decline (platform/internal/httpapi/bank.go:404).\n- Итог: третий глагол — это бамп документа плюс правка платформы. Иначе у двери нет вызывающего — второй ярус класса A (18-bank-ontology.md:65-72).\n\n«СЧЁТЧИК ПРОМАХОВ ПО НЕПОДПИСАННЫМ» УЖЕ ЕСТЬ: retrieval_state.n_unverified_shown / n_unverified_followed (migrate.go v12, ~:330-354; пишутся waverun.go:858, chunkrun.go:172; агрегат quality.go:110-116).\n\nПРОМЕЖУТОЧНЫЙ ВРЕД ПРИ НЕВЕРНОМ ДРОБЛЕНИИ:\n- фильтр без append-журнала выбрасывает строки авто-банка (mining.go:776-790);\n- словарь исходов без журнала делает not-a-term неотличимым от «не спрошен» → перезапрос каждый прогон;\n- журнал до Identity ключуется сырым src → потом его миграция;\n- Identity через pack.Version → moveOther (M2b).", + "correction": "Это 3 пака бэкенда плюс платформенный. Порядок без промежуточного вреда:\n\n1. Identity + отказы сборки по Identity + маршрут версии таблицы в memory_version. Стоит $0; на существующих данных 0 конфликтов.\n2. После слова владельца по строке 130 — строго одним паком: append-журнал движка, свёртка, фильтр «без закона в окне», словарь исходов, парсер, предохранитель и отпечаток улик. Цена: одна перекупка банк-ролей плюс пере-редактура затронутых юнитов.\n3. Преемник + DecisionsVersion v2 + минор контракта (оркестратор) + proposed-проекция. В том же окне — платформенный вызывающий глагола и читатель proposed (строка 224).\n\nСчётчик промахов — доводка существующих колонок, а не новая сущность." + }, + { + "id": "M5", + "claim": "Черновик остаётся свидетелем, черновая волна не перекупается никогда; дверь пишет только дельту (Source:mined, bankmaterialize.go:318-333, decisions.go:50-57), сид не трогается никогда; главы ≤N не трогаются ⇒ $0-репин.", + "verdict": "PARTIAL", + "evidence": "ПОДТВЕРЖДЕНО ДЛЯ APPROVE/DECLINE:\n- База исключает Source:\"mined\" (bankmaterialize.go:318-333).\n- Дельта штампуется mined (bankmaterialize.go:96-98), авто-банк тоже (mining.go:734).\n- DecisionDepth=\"edit_wave\" (decisions.go:51-57); базовый фолд с доменным разделителем (memory.go:425-427,439).\n\nПРЕЕМНИК ДЛЯ СИД-ТЕРМА (подписанное ядро, имена) ЧЕРЕЗ ДЕЛЬТУ НЕВЫРАЗИМ:\n- approve по ключу сида отвергается безусловно (decisions.go:362-365): «Editing a seed term means editing glossary_seed, which moves the BASE snapshot and re-pays the draft wave».\n- Строка дельты [N,0] с другим dst поверх сид-строки [0,0] роняет прогон: ApprovedSharedKeyCollisions (memseed.go:290-304 — разные dst + windowsOverlap), фатально по bankmaterialize.go:146-148.\n- Сам проект объявляет пересечение окон одного Identity отказом линта.\n- Закрыть окно сид-строки = правка glossary_seed = перекупка черновиков глав ≥N с этим термином.\n\nIDENTITY-МИГРАЦИЯ ДВИГАЕТ БАЗОВЫЙ СНАПШОТ КАЖДОЙ КНИГИ: NormVersion фолдится и в base (memory.go:413-427, excludeMined=true). При маршруте через pack.Version это LangpackVersion (snapshot.go:477) → moveOther (repin.go:78-79) → черновая волна перекупается целиком даже при байт-равных запросах (stagerun.go:536-538).\n\nГЛАВЫ ≤N−1 ПРИ ПРЕЕМНИКЕ СТРОКИ ДВИЖКА: окно на провод не выводится (editorLines: `\"- \" + src + \" → «\" + dst + \"»\"`, memory.go ~:925-935), байты не меняются → $0-репин (stagerun.go:95-111). Подтверждено.\n\nПРЕЕМНИК МЕНЯЕТ ID СТАРОЙ СТРОКИ: TermID(src, sense, since, until) (decisions.go:166-173), платформа держит ID стабильным (platform/internal/ingest/bank.go:25-27).", + "correction": "«Дверь пишет только дельту, черновик не перекупается» верно для approve/decline и для преемника строк движка и дельты.\n\nДля сид-терма нужен один из трёх путей:\n- новая семантика «дельта затеняет сид с главы N» (в коде её нет — сегодня это фатальная коллизия);\n- правка сида с перекупкой черновиков глав ≥N;\n- явный отказ преемнику сид-терма.\n\nIdentity-миграция двигает базовый снапшот всех книг; $0 она стоит только при маршруте версии в memory_version." + }, + { + "id": "C1", + "claim": "Проход «куплен заново на подписи и на каждой покупке — volume.go:333-352 говорит это сам».", + "verdict": "PARTIAL", + "evidence": "volume.go:336-352 говорит о другом: каждая покупка растит авто-банк → сдвиг снапшота edit-волны → пере-оплата юнитов, где встречаются новые термины («Expect that run to need --resnapshot and to re-pay the units the new terms actually touch»). О перекупке прохода терминолога и о подписи там нет ни слова.\n\nПерекупка на подписи — факт базы B (6 из 7 батчей, $0.0338) и terminologist.go:1158-1172.", + "correction": "volume.go подтверждает «на каждой покупке» для пере-редактуры затронутых юнитов. Перекупку прохода на подписи подтверждают данные прогона B и terminologist.go:1158-1172, а не volume.go." + }, + { + "id": "C2", + "claim": "pipeline-c1.yaml:161-162 называет сегодняшнюю обратную кривую цены терминологии.", + "verdict": "CONFIRMED", + "evidence": "backend/configs/pipeline-c1.yaml:161-162: «(1) бюджет КНИГО-ШИРОКИЙ и копится через покупки — книга, проданная десятью покупками, платит десять книжных консолидаций против одного бюджета»." + } + ], + "extra_findings": [ + { + "title": "Identity по данным пака молча ломает zh-книги без langpack", + "evidence": "langpack_root опционален: config/book.go:93-98; в pipeline 9 веток r.pack == nil / != nil. У 2 из 10 стенд-книг zh нет langpack_root: bk_LVYOO5M5ZSQEUPIK, bk_SZFCURJUQ752EXMP (у остальных 8 он есть). LangpackVersion фолдится «ONLY when a pack is present» (snapshot.go:402-409). Сегодня таблица трад→упрощ. вшита в ядро и работает для любой книги (norm.go:47-48, 147-149).", + "impact": "После выноса таблицы в configs/langpacks/zh/ у zh-книги без пака Identity теряет свёртку. Ключ 魯鎮 перестаёт матчиться с 鲁镇 — это ровно класс A4 «silently empty» (norm.go:25-27). Громкого сигнала нет: версия нормализации двинется как bank-only сдвиг. Таблицу тождества нужно грузить независимо от майнерского пака, либо сделать пак обязательным для источника, объявившего свёртку." + }, + { + "title": "Глагол succeed переиндексирует строку для платформы — это не аддитивный минор", + "evidence": "TermID = sha256(src, sense, since, until) (membank/decisions.go:166-173); тот же id публикует bankexport.go:200. Платформа держит ID как «Stable across the bank being rebuilt» (platform/internal/ingest/bank.go:25-27). Преемник закрывает окно (until=N−1), и id старой строки меняется.", + "impact": "После succeed решения, заметки и ссылки платформы по старому id перестают разрешаться: decisions.go резолвит решение по id. Нужна либо преемственность id (не от окна), либо явная карта old→new в квитанции двери — это меняет оценку «контрактный минор»." + } + ], + "obstacles": "1. Корпус — одна zh-книга: все 229 src из БД и 343 из YAML не меняются нормализацией. Поэтому «0 конфликтов» ничего не говорит о японских и традиционно-китайских источниках, ради которых вводится Identity. Живых ja-книг и прогонов нет; утверждения о 後/后 и ハル/はる не проверял — это линзы 1/2.\n2. Нормализатор воспроизведён копией norm.go в scratch-модуле (x/text v0.40.0 из кэша модулей). Его NormVersion-хеш с версией из снапшотов движка не сверял; go test не запускал.\n3. Нумерованные принципы владельца (2/6/7/8) в доках не найдены: 0 хитов по 123 md в каждом дереве. Текст принципа 8 сверить нельзя.\n4. Платформенных баз и возможных боевых книг беты не видел — только движковые БД в books и на стендах. Актуальность фазы D39.63 на 15.09 проверена лишь грепом по журналу.\n5. Размер пере-редактуры edit-волны после смены словаря исходов не мерил: нужен платный прогон или симуляция рендера.\n6. Форма хранения журнала (таблица или файл) в проекте не задана, стоимость её миграции не оценена.\n7. Парсер исходов (terminology.go:1115-1121, miner_emit.go:261-269), editor.md и детекторы преемника не читал — вне линзы 3.\n8. Сумма «$7.17» — сумма максимумов request_log по book_id среди копий и бэкапов, не бухгалтерия." + }, + "critic": { + "blockers": [ + { + "title": "Преемник для имён из сида невыразим без правки сида. Центральные имена книги получают либо падение прогона, либо молча мёртвую строку.", + "ids": "F5, E-e3, M5, extra L1 «seed successor»", + "why": "Проект обещает (e) «сид не трогается никогда» и (f) «черновая волна не перекупается никогда». Код даёт три исхода. (1) Одобренный преемник поверх одобренной сид-строки роняет прогон: ApprovedSharedKeyCollisions, bankmaterialize.go:146-148; та же проверка стоит в вердикте двери, decisions.go:913-914. (2) Неподписанный преемник уступает сиду на проводе и молча не действует (memory.go:925). (3) Закрыть окно сида — это правка glossary_seed, а дверь её отклоняет (decisions.go:358-363: «moves the BASE snapshot and re-pays the draft wave»). Моя пере-проба подтвердила: для строк движка и дельты преемник работает, для сида — нет. Чтобы проект стал верен, нужно одно из трёх: новое правило «решение владельца затеняет сид с главы N» (новый писатель закона над сидом), честная перекупка черновиков глав ≥N или явный отказ преемнику для сид-терминов." + }, + { + "title": "Проект строит журнал с окнами-ординалами и авторские окна преемника до перекроя глав. После первой перенарезки граница преемника молча указывает на чужую главу.", + "ids": "R4 (пере-проверен)", + "why": "CHAPTER_STRUCTURE_DESIGN.md:655-663: движковые файлы пере-генерируются, а долговечен только .mined-delta.yaml. Журнал движка из проекта — второй долговечный носитель ординалов, и в инвентаре миграции его нет. §4.2 п.4 (:717-721): «Авторское — ДЕГРАДИРУЕТ В ОТКРЫТОЕ… Сегодня авторских окон ноль… проектная страховка». Преемник делает этот класс непустым. Пара преемника, деградировавшая в открытые окна, — это один src, разные dst и пересекающиеся окна. Такая пара роняет загрузку: memseed.go:210-222 «a term has ONE rendering per chapter». Поблажка для файлов, записанных движком, покрывает только непригодные для провода строки (memseed.go:151-156), а не пересечения. §5.1 ряд 2 и §4.3 (:760-767) уже кладут окна банка в общее окно перекроя, и UNIQUE (migrate.go:203) переезжает на chapter-id. «UNIQUE по Identity» в Пакете 1 означает второй стоп-мир над тем же ключом. D39.245 ратифицировал предмет «глава = идентичность», но не механику. В проекте слов «перекрой» / «D39.245» / «chapter-ID» — 0." + }, + { + "title": "Оговорка области употребления, которую проект объявляет «обязательной частью архитектуры», уже проверена пробой и опровергнута. Строка 134 закрыта без её внесения.", + "ids": "B-b3 (слабый CONFIRMED), R2 (L2: «ни одна поздняя нота её не снимает» — неверно)", + "why": "experiments/18-editor-wire-probe.md:380-392: «критерий 4 «оговорка работает» — НЕ ВЫПОЛНЕН». На репликации N=3 с оговоркой смысловой передачи 0/3, без оговорки 2/3: «Направление обратно гипотезе». archive/PROGRESS-2026-09-04-07-bank-law.md:50-53: «строка 134: рендер снят… Оговорка области НЕ внесена (опровергнута §A.4)»; приёмка экспа 18 — D39.108. На этой оговорке проект держит механизм «имя против обычного слова» (方正) и исход polysemous. Без неё у полисемии внутри окна нет безопасного пути на провод: закон плюс «СТРОГО» ломает не-терминное употребление, not-a-term теряет консистентность имени. Проект обязан либо назвать другой механизм, либо оставить такие поверхности человеку." + }, + { + "title": "Проект включает в Пакет 1 то, что владелец остановил или велел не проектировать, и не называет это его словом.", + "ids": "R3, R2, M2a", + "why": "Накопление авто-банка между прогонами — ряд 130 (BACKLOG.md:70): «СТОП-решение владельца (двигает банк → memory_version)», гейт — WARN второго прогона; mining.go:773: «this reports, it does not accumulate». Глагол succeed — это пост-ридинговая правка, а D39.144 п.1 (05-decisions-log.md:579): «точную механику пост-ридинговых правок… НЕ проектировать до полигонных итогов». Частотный канал номинации упирается в D39.50 п.2 («частотного экрана НЕ существует») и D39.102 п.3. «Одна платная книга» и $0 опираются на D39.63, хотя основание — D39.190 п.4 с условием «если книгу не продолжат», а статус прогонов A/B нигде не записан. §5 проекта задаёт владельцу вопросы так, будто он решает впервые." + }, + { + "title": "Тождество ключа через pack.Version() меняет класс цены: сегодняшний $0-репин превращается в полную перекупку обеих волн. Книги без langpack молча теряют свёртку.", + "ids": "F3, R5a, M2b, M2c, extra L3 «Identity по данным пака»", + "why": "Сегодня NormVersion фолдится внутрь memory_version (memory.go:417), и это moveBankOnly. pack.Version() — это отдельное поле langpack_version (snapshot.go:409,477), то есть moveOther (repin.go:61-90): ни один юнит не пере-пинивается. langpack_root необязателен (config/book.go:93-98), у 2 из 10 стенд-книг его нет. Формулировка проекта «как сегодня NormVersion, только через pack.Version()» ложна именно в деньгах. Исправление: хеш таблицы тождества фолдить в memory_version, а таблицу грузить независимо от майнерского пака." + }, + { + "title": "Пакет 1 одним паком непостроим без промежуточного вреда. Его фильтр «терминолог только по новым Identity» глушит споры, а их замена лежит в Пакете 2.", + "ids": "M4, extra L1 «366 споров», extra L3 «TermID», F-f1", + "why": "NormalizeSourceKey — 54 не-тестовых вызова в 12 файлах; дверь decisions.go — чистая функция без пака. Платформа пинит DecisionsVersion v1 (platform/internal/ingest/bankdecisions.go:18) и пропускает только approve/decline (httpapi/bank.go:404). Контракт 14 — зона оркестратора. TermID зависит от окна (decisions.go:166-173), поэтому succeed меняет id старой строки, а платформа держит id стабильным: это не аддитивный минор. Фильтр без детектора споров снимает метки противоречия с банком у 366 кандидатов корпуса (terminologist.go:1127-1134). Без append-журнала writeAutoBank переписывает файл и выбрасывает строки (mining.go:776-790). Реалистично 3 бэкенд-пака плюс платформенный, в порядке M4." + } + ], + "gaps": [ + { + "title": "Консистентность длинной книги против денег: новый закон задним числом. Проект не выбирает и не спрашивает.", + "why": "Строки, найденные только черновиками (62 из 64 в авто-банке B), эмитятся с SinceCh: 0 (mining.go:612), майненые — с главы первого появления. Новый закон, решённый на покупке 2, ложится на уже отредактированные главы покупки 1. Моя проба (scratchpad/verify-design-completeness/crit_successor_test.go; настоящие ru-тексты, порядок стора, перенос из предыдущего куска): строка 方正 [0,0] меняет провод глав 1 и 4 (wireSame=false). При тесном бюджете она ВЫТЕСНЯЕТ из старого куска уже действующую строку 方源, потому что при равном ранге порядок — байтовый по src (memory.go:649-676, glossary.go:225). volume.go:336-352 сам называет это перекупкой юнитов на каждой покупке. Цифры проекта «цена падает с томами» и «том 2 не меняет закон тома 1» учитывают только терминолога, а редактор в B — $0.193 из $0.397. Выбор нужен явный: пере-редактировать уже прочитанные главы ради одной формы (деньги, читатель видит правку) или закон с границы покупки (ранние главы остаются разнобойными)." + }, + { + "title": "Детерминизм и спойлеры: «улики по всей книге» дают терминологу будущие главы, а закон потом действует с since=0.", + "why": "spoilerBlocked (memory.go:679-689) описан как «a fact the current chapter must not know yet». Режим пола hidden (memory.go:946-947, D19.3) — уже построенный механизм «до раскрытия», то есть частный случай преемника, и проект с ним не связан. Сегодня стоп читает только уже начерненные куски (volume.go:337-339). Выборка по всей книге превращает раскрытие из главы 500 в закон главы 1." + }, + { + "title": "Род в преемнике: дверь род не принимает, производитель рода — классификатор, а не терминолог.", + "why": "decisions.go:84-88: «It is still NOT ACCEPTED… correcting one stays a seed edit». Род на авто-строки ставит классификатор (mining.go:172 attachClassifiedGender), а в словаре исходов проекта род стоит в law(dst, gender, conf) терминолога. Смена роли-производителя, правка промта, приём рода дверью и контракт в Пакете 1 не перечислены." + }, + { + "title": "Детерминизм перезапросов: у undecided нет отпечатка улик и предела, у not-a-term нет пути назад.", + "why": "Триггер «новый том номинировал повторно» истинен на каждой покупке: стоп заново майнит все начерненные куски (mining.go:80-98). Значит перезапросы undecided платные и без предела (M3). not-a-term записывается навсегда, в proposed его нет (дизайн §1(f)), и если слово позже окажется именем, вернуть его некому." + }, + { + "title": "«Без новых стадий» и «деньги видимы»: проект вводит платные и новые проходы без сметы.", + "why": "«N=2-согласие на спорных (центы)» — новый класс платного вызова без замера. Детектор рода по местоимениям — не таблица: нужна кореференция, а 18,7% вхождений 他 — не единственное «он» (R5b). Цена Пакета 1 «$0 + центы» не включает пере-редактуру юнитов, где словарь исходов снимает закон (M2a), перекупку через pack.Version (M2b) и миграцию существующих авто-банков в журнал." + }, + { + "title": "«Язык — данные» держится только для zh.", + "why": "Предохранитель по улике майнера — это zh-каналы на Go (langpack.go:207-208, miner_substrate.go:44 isMinerHan). Детерминированная улика есть у 2 из 66 кандидатов B (D-d3). Таблица «руна→руна» не выражает свёртки 1:N (ß→ss), а ханча→хангыль вообще не свёртка. Если перенести кана-свёртку в данные, она молча выключится у ja-книг без пака. Проверка «рендеринг в целевом письме» ничего не ловит для латинских целей (R5d)." + }, + { + "title": "Проблема «нет читателя» между пакетами усиливается.", + "why": "Пакет 1 делает долговечными решения «не закон», а читатель proposed у платформы — это Пакет 2. Сегодня у секции 0 читателей (ряд 224; json:\"proposed в platform/ — 0 при 209 go-файлах). В промежутке движок принимает необратимые решения, которых никто не видит." + }, + { + "title": "Алиасы и голоса вне модели тождества и преемника.", + "why": "Алиасы — такие же матчащиеся поверхности (memory.go:328-330), в корпусе 2 223 строки. Дверь переносит их при промоушене (decisions.go:78-80), но проект не говорит, что делает с ними Identity, UNIQUE и преемник. voice_profiles несут тот же ключ (src, sense, since, until) (migrate.go:389), а цель продукта — консистентные голоса; в проекте они не упомянуты." + }, + { + "title": "Рост банка упирается в бюджет, который уже недосчитывает строки.", + "why": "Проект называет бюджет 800 предохранителем роста. Ряд 131 (BACKLOG.md:71): бюджет не считает маркер и гендер-ноты, превышение ~40–60%. Вытеснение внутри равного ранга — по байтовому порядку src, то есть случайное для смысла. Сегодня n_evicted = 0 в A и B (контроль: колонка есть, по 6 строк retrieval_state), так что риск перспективный, но для накопительного банка книги в тысячу глав он не посчитан." + } + ], + "owner_questions": [ + "Банк памяти и перенарезка глав трогают одни и те же окна «с главы N». Строить журнал решений и «преемника» после перенарезки (или вместе с ней, с окнами по идентичности главы), чтобы не мигрировать дважды? И собираетесь ли вы продолжать книги прогонов A/B: от этого зависит, бесплатен ли пере-снапшот.", + "Вы остановили накопление авто-банка между прогонами до второго прогона (ряд 130) и просили не проектировать правки после прочтения до итогов полигона (D39.144). Проект строится на обоих. Снимаете ли вы оба запрета сейчас, или журнал и глагол «с главы N» ждут?", + "Если термин решён на второй покупке, а встречался уже в первой: пере-редактировать уже готовые главы ради одной формы на всю книгу (это деньги, и читатель увидит правку в прочитанном) или вводить закон только с границы покупки, оставив ранние главы как есть?", + "Если имя из вашего сида (списка имён, заданного вручную) нужно сменить с главы N: согласны ли вы, что это пере-оплачивает черновики глав от N с этим именем? Или нужно новое правило «правка владельца перекрывает сид с главы N»?", + "Может ли движок сам решить «это не термин» и не показать вам? Защита имени сегодня срабатывает примерно у 3% кандидатов и только для китайского, а проверенная пробой «оговорка области» не сработала. Или каждое «не термин» должно стоять в списке на ваш один ОК?" + ], + "weakest": [ + { + "id": "B-b3 (L1 CONFIRMED)", + "why": "Буквально верно: в editor.md и injection.txt оговорки нет. Но подменён предмет: «обещанное и забытое» на деле проверено и опровергнуто. L2 (R2) ошибся, написав, что ни одна поздняя нота её не снимает.", + "recheck": "Пере-проверил, НЕ устоял как довод проекта. Скан 7 промтов zh-ru и injection.txt: 0 формулировок оговорки (контроль: editor.md 42 строки, injection.txt 14). experiments/18-editor-wire-probe.md:380-392: «критерий 4 «оговорка работает» — НЕ ВЫПОЛНЕН»; N=3: с оговоркой по смыслу 0/3, без неё 2/3. archive/PROGRESS-2026-09-04-07-bank-law.md:53: «Оговорка области НЕ внесена (опровергнута §A.4)». Оговорка: сама проба мала (одно окно, N=3, текст знаком моделям по претрейну), но она принята D39.108 и закрыла строку 134." + }, + { + "id": "F5 (L1 PARTIAL, несущий $0-репин)", + "why": "Проба L1 шла с пустыми InjectionTexts: байты директивы рода не сравнивались. Не было также порядка стора, переноса из предыдущего куска и тесного бюджета.", + "recheck": "Пере-проверил исполнением (go test -overlay, дерево 0 изменений до и после). Условия: настоящие ru-тексты (контроль HasData=true, «муж. — мужские родовые формы»), ORDER BY стора, перенос из предыдущего куска, строка с hidden, бюджеты 800 и 12. Главы 1 и 4: wireSame=true при сдвинутой версии. Главы 5 и 8: провод сменился на «Старый Фан (жен.)». Юниты редактуры не пересекают главы (chunker.go:386-405). УСТОЯЛ для строк движка и дельты. Для сида по-прежнему ломается (блокер 1). Попутно: новый закон с since=0 меняет провод глав 1 и 4 и при бюджете 12 вытесняет строку 方源." + }, + { + "id": "R4 (L2 REFUTED проекта)", + "why": "Несущий аргумент опирался на цитаты дизайна глав, который сам принят без сходимости механики.", + "recheck": "Пере-читал CHAPTER_STRUCTURE_DESIGN.md:655-663, :717-721, :760-767 и тело D39.245. Правило пересечений в memseed.go:210-222 не прикрыто поблажкой engineWritten (она только для непригодных для провода строк, :151-156). УСТОЯЛ. Уточнение: «деградация в открытое» — нератифицированная механика, но какой бы она ни стала, журнал движка с ординалами и авторские окна преемника в её инвентарь обязаны войти." + }, + { + "id": "M1 (L3 PARTIAL, 0 конфликтов миграции)", + "why": "Ноль получен на корпусе, который физически не может дать конфликт.", + "recheck": "Пере-проверил другим прибором: предфильтр классов символов вместо копии нормализатора. Обойдено 178 файлов БД, с glossary 177; строк glossary 13 632, алиасов 2 223, поверхностей стопа 14 884, уникальных строк 229. Строк, которые Identity изменила бы, — 0; конфликтов — 0. Контроль ёмкости: в единственном zh-исходнике guzhenren-utf8.txt 7 778 990 рун (Han 6 205 702), рун-ключей trad2simp 0, катаканы 0 (таблица: 500 пар). ФАКТ УСТОЯЛ, КАК УЛИКА ПУСТ: про японские и традиционные источники, ради которых вводится Identity, ноль ничего не говорит." + }, + { + "id": "F7 (L1 CONFIRMED)", + "why": "Путь в коде доказан пробой парсера, но «сегодня «не термин» и «90» становятся законом» в оплаченных данных не наблюдалось: 0 из 129 строк ответов в B и 0 из 137 в A.", + "recheck": "Не пере-проверял. Дефект латентный, поэтому приоритет «словаря исходов» как лечения наблюдаемой болезни преувеличен." + }, + { + "id": "F8 (L1 CONFIRMED)", + "why": "«Центы» за выборку по всей книге — оценка из разбиения токенов прогона B, не замер. Доля контекстов в промпте не выделена: тексты запросов в БД не хранятся.", + "recheck": "Не пере-проверял; нужен замер до стройки." + } + ], + "verdict_on_design": "Как направление для владельца проект годен: закон как долговечное решение с окнами, закрытый словарь исходов вместо догадки-закона, тождество источника как данные. В нынешнем виде нести его нельзя. До этого проект обязан: встать в очередь относительно перекроя глав (окна по идентичности главы); назвать запреты владельца (ряд 130, D39.144 п.1, D39.50) вопросами; убрать опровергнутую оговорку области как несущий механизм и показывать not-a-term владельцу; вести версию таблицы через memory_version, а не pack.Version; явно решить преемника для сида и новый закон задним числом; разрезать Пакет 1 на три упорядоченных пака плюс платформенный.", + "obstacles": "Все три линзы дали вердикты (null нет). Что не проверил и где слеп:\n- Список «восьми проблем» и нумерация принципов (2/6/7/8, «позиция 5») пришли из промта оркестратора старшему коллеге, в репозитории их нет: 0 хитов «без новых стадий|закон в точке банка|не обеднять язык» при 123 md-файлах. Пробелы я сверял с принципами в формулировке моего задания.\n- Преемника и новый закон проверил на уровне membank (Select + RenderEditorConstraintBlock), а не сквозь renderedContentHashes и rowsResumeFree с настоящими шаблонами. То, что content_hash зависит только от отрендеренных сообщений, выведено чтением repin.go:128-160.\n- Вытеснение бюджетом в накопительном банке — перспективный риск: в A и B n_evicted = 0 при всего 6 строках retrieval_state на книгу.\n- Платформенные базы и возможные боевые книги беты не видел. Будут ли продолжать A/B, нигде не записано.\n- Опровержение оговорки опирается на пробу 18 (одно окно, N=3, текст, знакомый моделям по претрейну). Её вес ограничен, но она ратифицирована приёмкой (D39.108) и закрыла строку 134.\n- Не пере-проверял: японские пары кандзи (F2), счёт местоимений (R5b), денежные цифры и число файлов (M2, M4), парсер отказа (F7).\n- Незакоммиченную работу другой сессии в основном дереве (migrate.go, stagerun.go, quality.go и др.) не читал: после её лендинга номера строк могут сдвинуться.\n- Мои пробы запускались через go test -overlay из scratchpad/verify-design-completeness; git status дерева /home/ubuntu/tm-verify-1509 — 0 до и после." + } +} \ No newline at end of file diff --git a/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/04-design-v2-and-owner-proposal.md b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/04-design-v2-and-owner-proposal.md new file mode 100644 index 00000000..2d1281a4 --- /dev/null +++ b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/04-design-v2-and-owner-proposal.md @@ -0,0 +1,50 @@ +# Предмет сверки: итоговое предложение по банку памяти (15.09) + +> ⛔ **ОТОЗВАНО 15.09 — АРХИВ-УЛИКА, НЕ ПЛАН.** Предложение ниже расходится с 12 пунктами решённого, замеренного и +> собственного плана (`05`, `synthesis.contradictions`). Обращение «Сверщикам» — задание уже исполненной сверки `05`, +> а не заказ. Инструкции ниже НЕ исполнять. Читать только вместе с `README.md` этого каталога. + +> Это то, что оркестратор уже предложил владельцу. Автор архитектуры — Fable 5 (вторая редакция после +> адверсариальной проверки), с двумя поправками оркестратора, которые Fable подтвердил. Сверщикам: найти в +> РЕПОЗИТОРИИ всё, что уже решено, запланировано, построено, исследовано, изобретено или опровергнуто по тем же +> предметам — и что делает предложение лишним, неполным или неверным. + +## А. Предложение владельцу (как отправлено) + +### Что сломано — три корня +1. Банк пересчитывается, а не помнит: на каждой подписи и каждой покупке модель заново решает все термины, не видя своих прошлых решений; часть переводов меняется (12 из 69, 14 из 66), между томами разнобой. +2. «Тот же ли это термин» решается в разных местах по-разному (подбор — по нормализованной форме; загрузка банка и уступка редактору — по сырой строке) → два закона на одно слово (ряд 330). Таблицы вариантов написания (китайская, японская) зашиты в ядро и применяются к любому языку. +3. У решения нет честных исходов: «не могу решить» становится догадкой черновика законом; «не термин» выразить нельзя; сменить перевод или род с главы N одним действием нельзя, имя из списка владельца — нельзя вовсе. + +### Каким становится банк +- Журнал решений: каждое решение записывается один раз (кто, на каких уликах, с каким исходом); при следующей покупке модель спрашивают только про новые термины; принятое не пересчитывается. +- Одно определение «тот же термин» во всём движке; таблицы вариантов написания — данные исходного языка. +- Честные исходы терминолога: закон · не термин · многозначный (решает человек) · не решено (перезапрос только при новых уликах, с пределом). «Не термин» и «не решено» закона не создают, видны и обратимы; имена из списка владельца под «не термин» не попадают. +- Изменение по ходу книги — преемник: перевод или род с главы N; главы до N не трогаются. Автоматически — только предложения. Скрытый пол — только человек. +- Улики — только из уже переведённой части книги. +- Сигналы (споры черновиков с законом, «N глав до закона») видимы: платформа читает раздел предложений. + +### Трейдоффы +Первое решение живёт до правки человеком (INVENTED 17/66 в B) · до журнала сохраняется пере-решение · «имя против обычного слова» (方正) без человека не решается (оговорка в промте опровергнута экспериментом 18) · разовые цены: одна перекупка банковых вызовов на книгу, миграция банков в журнал. + +### Порядок +1. Сейчас, $0: одно определение тождества на СУЩЕСТВУЮЩЕЙ `NormalizeSourceKey` во всех дверях (storeOrder, MinedDeltaSeedCollisions, loadAutoBank, уступка editorLines) → ряд 330 закрыт. +2. Окно перенарезки глав (ряд 161, D39.245): окна банка по chapter-ID; вынос таблиц нормализации в данные языка (двигает `NormVersion` → идентичность глав, поэтому только там); рядом ряды 131 и 14. +3. Журнал решений + честные исходы (сентинелы парсера) + `since` реверса = первое появление + читатель платформы `proposed` — после слова владельца. +4. Преемник «с главы N» + глагол `succeed` двери (decisions v2, TermID без окна, минор контракта). + +### Вопросы владельцу +1. Журнал и преемник — после перенарезки глав? Книги прогонов A/B не продолжаем? +2. Снимает ли владелец прежние стопы: «не копить банк между прогонами» (ряд 130) и «не проектировать правки после прочтения» (D39.144 п.1)? +3. Закон, решённый позже, на уже готовых главах: показывать «N глав до закона» со сметой и переделывать по заказу — или автоматически? +4. Имя из списка владельца с главы N: правка перекрывает сид только для редактора (черновики со старым именем) — или переоплата черновиков глав ≥N? + +## Б. Архитектура (Fable v2, сжатие) +- Identity = универсальные шаги + канал данных исходного языка `configs/langpacks//identity.txt` (1:N свёртки), хеш таблицы в `memory_version` (не `pack.Version()`), громкий отказ при объявленном и отсутствующем канале; хранимые ключи движка пере-выводятся миграцией. +- Окна по chapter-ID; журнал движка — в инвентарь миграции перекроя. +- Журнал движка `.bank-journal.yaml` (append; Identity, sense, окно, исход, dst, gender, провенанс, отпечаток улик, прогон); `auto-bank.yaml` — выведенный вид; нота к онтологии 18 (источник движка долговечен; правило старшинства «событие владельца > закон движка»); терминолог только для Identity без закона в окне. +- Исходы: сентинелы; исход без dst → строка без dst (инертна, §C2-7); `not-a-term` виден в `proposed`, обратим; допустим только при типе `term` и без детерминированной улики имени, иначе `undecided`; `undecided` с отпечатком улик и пределом перезапросов; род производит классификатор; $0-сверка «черновики против закона» тем же паком, что фильтр. +- Преемник: старая `until=N−1`, новая `since=N`; TermID = hash(Identity, sense)+revision; для сид-терма — «событие владельца затеняет сид с главы N в обогащённом виде», черновики ≥N со старым именем, редактор приводит. +- Закон задним числом: `since` = первое появление в начерненной границе; «юниты до закона» — числом и сметой, ре-мейк только пере-проходом. +- Провод как D39.104, без оговорки; полисемия — человеку. +- Сняты как механизмы: оговорка области употребления (эксп. 18), N=2-согласие, детектор местоимений в ядре (нужна кореференция), `hidden` от классификатора. diff --git a/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/05-prior-art-map.json b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/05-prior-art-map.json new file mode 100644 index 00000000..283739d0 --- /dev/null +++ b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/05-prior-art-map.json @@ -0,0 +1,1702 @@ +{ + "S1": { + "findings": [ + { + "element": "E1", + "source": "docs/archive/architecture/05-decisions-D1-D38.md:116 (D5)", + "kind": "RATIFIED_DECISION", + "relation": "DUPLICATES", + "quote": "approved-глоссарий/series-bible наследуются read-only, новые термины append, approved не ревизуются молча (research/07); разрешение gender=hidden-твиста — ручное событие.", + "summary": "Решение «принятое не пересчитывается, новые термины дописываются» уже ратифицировано в D5 (04.07) для подписанного слоя. Предложение повторяет его для слоя движка и на D5 не ссылается." + }, + { + "element": "E1", + "source": "docs/BACKLOG.md:187 ряд 221 п.(4); код backend/internal/store/glossary.go:180 и :271 (HEAD tm-verify-1509 5dbb5cb)", + "kind": "BUILT_DORMANT", + "relation": "MISSED_RELEVANT", + "quote": "`glossary_revisions` построен наполовину — читатель вызывается только из тестов, графа `reason` заполняется литералом `seed-replace`, а ревизия пишется лишь для ОСТАВШИХСЯ строк, то есть журнал слеп к отклонениям", + "summary": "В хранилище уже есть append-only журнал редакционного времени B1 (src, sense, old_dst, new_dst, editorial_ts, reason). В коде: писатель есть, читатель `GlossaryRevisionsForBook` вне тестов не вызывается. Предложение заводит новый `.bank-journal.yaml` и этот носитель не упоминает; надо решить, заменять его или достраивать." + }, + { + "element": "E1", + "source": "docs/architecture/06-memory-risk-registry.md:44 (риск B1, статус ❌)", + "kind": "RESEARCHED_IDEA", + "relation": "REFUTES_PART", + "quote": "первый (наименее информированный) перевод имени лочится на 1000 глав.", + "summary": "Реестр рисков называет «первое решение живёт вечно» (first-translation-wins по DelTA) источником устаревших записей. Его смягчение — журнал ревизий плюс LLM- или человеческое подтверждение плюс точечный пере-перевод по ключу, а не заморозка. Трейдофф предложения «первое решение живёт до правки человеком» — ровно этот риск." + }, + { + "element": "E1", + "source": "docs/research/14-adaptive-memory.md:165 (M2); docs/BACKLOG.md:66 ряд 47; D39.42 (05-decisions-log.md:299); PACK20_BANK_DESIGN §9 Д2", + "kind": "PLANNED_ROW", + "relation": "MISSED_RELEVANT", + "quote": "для auto/ambiguous БЕЗ approved — first-seen/majority-vote кэш рендеринга (детерминированное расширение банка); adaptive выбор КАКИЕ серо-зонные записи инъектить (risk-sensitive precision-gate, abstention first-class).", + "summary": "Механизм M2 — «кэш предлагает → пост-проверка гейтит → человек повышает статус». D39.42 отложил его как «доктрина Д2 — кандидат на отдельную ратификацию», это живой ряд 47, не ратифицирован ни разу. По существу это тот же журнал решений движка, но предложение на ряд 47 и доктрину Д2 не ссылается." + }, + { + "element": "Q2", + "source": "docs/BACKLOG.md:70 ряд 130; docs/NEAR_TERM_PLAN.md:53 п.10", + "kind": "OWNER_DEFERRED", + "relation": "CONTRADICTS", + "quote": "остаток = накопительный мердж авто-банка / освобождение слотов seed-rejects — СТОП-решение владельца (двигает банк → memory_version); материал для решения даст WARN со ВТОРОГО прогона", + "summary": "Ряд 130 — не прежний запрет владельца «не копить», а открытое СТОП-решение, то есть вопрос о деньгах к владельцу. План п.10 держит его как «ждёт слова владельца «копить ли решения банка между прогонами»». Формулировка Q2 «снимает ли прежний стоп» искажает статус." + }, + { + "element": "E1", + "source": "docs/BACKLOG.md:271 ряд 339; D39.45 (слайс D39-20-58:297); backend/prompts/zh-ru/terminologist.md:25", + "kind": "PLANNED_ROW", + "relation": "BETTER_ALTERNATIVE", + "quote": "`terminology.go:873` и `:941`: обе проверки пропускают пару с РАВНЫМИ источниками; проверочная половина закрыта паком 06.09, якорная — нет. ⚠ Лечение МЕНЯЕТ ЗАПРОС к модели ⇒ деньги и снапшот", + "summary": "Корень 1 («модель не видит своих прошлых решений») уже заведён как якорная половина канон-проверок: показать роли существующую форму поверхности. Якорь ⟦TM-CANON⟧ и детектор CanonConflicts (D39.45) уже защищают подписанные строки от переписывания терминологом. Расширить якорь на строки движка — альтернатива журналу, у которой уже есть носитель." + }, + { + "element": "E1", + "source": "docs/BACKLOG.md:360 ряд 439; эррата 12.09-а в шапке 05-decisions-log.md", + "kind": "PLANNED_ROW", + "relation": "MISSED_RELEVANT", + "quote": "состав банка воспроизводим при повторе прогона ЛИБО названо и ратифицировано, что банк стохастичен, и тогда числа консистентности сравниваются только ВНУТРИ прогона", + "summary": "Банк недетерминирован уже на уровне предложений черновика (Жаккар 0.63). Расходится и ГРАНУЛЯРНОСТЬ ключа: 丙等资质 против 丙等 + 资质. Журнал по Identity закрывает пере-решение терминолога, но не смену состава и дробления ключей между прогонами. Решение, которого требует ряд 439, в предложении не названо." + }, + { + "element": "E1", + "source": "05-decisions-log.md шапка, эррата 11.09-и (к D39.251 п.7)", + "kind": "RATIFIED_DECISION", + "relation": "REFUTES_PART", + "quote": "второй заход **ИЗМЕНИЛ передачу у 12 термов из 69**, и в отгруженном тексте стоят именно НОВЫЕ формы", + "summary": "Та же эррата называет «12 из 69» ценой пере-майнинга после ЧЕЛОВЕЧЕСКОЙ подписи. Результат доехал до читателя, а «хороши ли эти 12 замен — вопрос КАЧЕСТВА», и он не судился. Предложение подаёт 12 из 69 как дефект, хотя ратифицированная запись это качество не оценивала." + }, + { + "element": "E1", + "source": "05-decisions-log.md:319 (D39.69); слайс D39-59-90:115 (D39.65 п.1–2)", + "kind": "REFUTED", + "relation": "MISSED_RELEVANT", + "quote": "**First-occurrence-тест ($0, исполнен): гипотеза первенства ОПРОВЕРГНУТА** — роль не первовхожденческий и не частотный выбиратель, ре-решает контекстом (позитивное подтверждение D39.65).", + "summary": "Нестабильность терминолога уже замерена (43.3%, ряд 21 закрыт). Пере-решение по KWIC ратифицировано как фактический консолидатор: финал отличается от топа §C2-3 в 50 из 75 случаев. Заморозка первого решения отключает механизм, который D39.46/65 признали главным рычагом. Это напряжение в предложении не названо." + }, + { + "element": "E1", + "source": "слайс D39-59-90:109 (D39.59 п.2); D39.77 п.4", + "kind": "RATIFIED_DECISION", + "relation": "EXTENDS", + "quote": "(2) БАНК — КУРС НА АВТОНОМНОСТЬ: подпись владельца ОПЦИОНАЛЬНА (авто-режим уже дефолт D39.44), премиса «решение о переводе = подпись» (D39.42/47) амендирована — банк обязан приходить с максимально качественными АВТОНОМНЫМИ переводами", + "summary": "Курс «автономного качества» ратифицирован. Трейдофф «первое решение живёт до правки человеком» опирается на человека, которого по умолчанию нет (подпись опциональна). Нужен довод, почему закрепление автономного первого решения согласуется с D39.59." + }, + { + "element": "E2", + "source": "05-decisions-log.md:2160 (D39.193 п.3)", + "kind": "RATIFIED_DECISION", + "relation": "EXTENDS", + "quote": "ключ уникальности банка — `(src, sense, since, until)`, значит одна поверхность ЗАКОННО несёт несколько ПОДПИСАННЫХ канонов (фамилия и направление у одного написания), и дедуп по голому `src` ронял подпись МОЛЧА", + "summary": "Правило «уступки редактору» уже ратифицировано: уступает только неподписанная строка, подписанная не роняется никогда. Ключ включает sense и окно. Единое определение тождества обязано сохранить это правило и полисемию двух подписанных канонов. D39.222 п.3(а) дополнительно запинил идемпотентность `NormalizeSourceKey`." + }, + { + "element": "E2", + "source": "слайс D39-20-58:331 (D39.51 п.2)", + "kind": "RATIFIED_DECISION", + "relation": "BETTER_ALTERNATIVE", + "quote": "(2) **кавычки — в свёртке (Q1), не в парсере/NormalizeSourceKey** (Q2/Q3 платят волной за косметику; Q1 $0 и ретроактивен; NormVersion не двигается — тест-страж)", + "summary": "Прецедент: нормализацию тождества сознательно сделали в свёртке, а не в `NormalizeSourceKey`, потому что правка нормализатора двигает `NormVersion` и стоит волны. Шаг 1 предложения («$0, одно определение во всех дверях») должен доказать, что содержимое инъекции не меняется. Иначе это не $0." + }, + { + "element": "E2", + "source": "docs/BACKLOG.md:28 ряд 14", + "kind": "OWNER_DEFERRED", + "relation": "EXTENDS", + "quote": "ё-фолд → target-данные (`char_fold`; смена сигнатуры core-примитива через вердикт-несущий банк, сдвиг `memory_version`)", + "summary": "Вынос таблиц свёрток в данные языка уже стоит в очереди владельца («владелец / когда-нибудь / отдельное решение»), с рекомендованным дизайном для целевой стороны. Предложение ставит его рядом с рядом 14, не упоминая, что это решение владельца, а не инженерное." + }, + { + "element": "E2", + "source": "слайс D39-106-123:159 (D39.118 п.3)", + "kind": "BUILT_ACTIVE", + "relation": "BETTER_ALTERNATIVE", + "quote": "**bankdata-плоскость** — отдельный `//go:embed` вне волнового фолда со своей `BankDataVersion` (вместо колонки `script-series.txt` — та фолдится в `EmbeddedVersion` и перекупила бы драфт-волну без права $0-репина", + "summary": "Для «хеша таблицы не в `pack.Version()`» уже есть ратифицированный шов: отдельная плоскость банковых данных со своей `BankDataVersion`. Канал `identity.txt` разумно класть туда, а не заводить новый путь в `memory_version`. Отдельно: D39.16 Ш-2 и D39.19 R1-FL-C требуют вплетать `unicode.Version` и версию x/text в нормализационные версии." + }, + { + "element": "E2", + "source": "docs/BACKLOG.md:127 ряд 228", + "kind": "PLANNED_ROW", + "relation": "MISSED_RELEVANT", + "quote": "фильтр авто-банка ключуется только по собственному `src` строки (`backend/internal/pipeline/mining.go:179`=`NormalizeSourceKey(m.Src)`). ⚠ **Правильная форма — снять АЛИАС со строки, а не снести строку:**", + "summary": "Тождество термина — это не только нормализованный src, но и граф алиасов: отклонённая поверхность возвращается алиасом уцелевшей строки. Ряд 228 также показывает, что фильтр авто-банка уже нормализует ключ, то есть часть «дверей» из предложения по сырой строке не работает. Нужна сверка с кодом." + }, + { + "element": "E2", + "source": "docs/BACKLOG.md:269 ряд 330", + "kind": "OWNER_DEFERRED", + "relation": "CONTRADICTS", + "quote": "**обошёл 162 файла БД, 161 с таблицей глоссария, 142 книги с непустым банком, прочитано 13 350 строк; книг с ЛЮБЫМ конфликтом — 0**", + "summary": "Ряд 330 сформулирован как денежный вопрос владельцу: (а) стоп роняет оплаченный прогон, (б) отказ схлопывания двигает `memory_version` и ведёт к перекупке. Корпусный замер: конфликтов 0, двери роняют дубли по полному ключу. «Шаг 1, $0 → ряд 330 закрыт» не отвечает ни на (а), ни на (б)." + }, + { + "element": "E3", + "source": "слайс D39-20-58:325 (D39.50 п.1); 05-decisions-log.md:369 (D39.102 п.2); docs/research/24-bank-arbitration.md:217", + "kind": "REFUTED", + "relation": "REFUTES_PART", + "quote": "роль ВЫДУМЫВАЕТ dst 77–82% стабильно (сентинел ⟦TM-NO-DST⟧ различает «переводимо», не «терм», и нестабилен даже там — размах 0.375)", + "summary": "Исход-сентинел терминолога уже мерили и закрыли классом (D39.102). Он различает «переводимо», а не «терм», разброс 0.375, на 7 пассах четырёх семейств ⟦TM-NO-DST⟧ дал 0 срабатываний. «Честные исходы через сентинелы парсера» (не термин / не решено) повторяют опровергнутый канал; нужен довод, чем новые сентинелы лучше." + }, + { + "element": "E3", + "source": "backend/prompts/zh-ru/terminologist.md:36 (HEAD tm-verify-1509 5dbb5cb); backend/internal/terminology/terminology.go:694", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "Если по данным контекстам ты не можешь выбрать перевод уверенно — верни ⟦TM-NO-DST⟧. Это нормальный", + "summary": "Исход «не решено» уже построен и включён: `const NoDst`, инструкция в боевом промпте терминолога, «непереведённый термин останется на ручную подпись». Предложение описывает его как новый механизм." + }, + { + "element": "E3", + "source": "слайс D39-arch-reset:22 (D39.19 R1-FL-B); D39.158 п.4–5; D39.161 п.3", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "**reject-set** (`Book.MinedRejects` yaml, не в BriefHash → не снапшот-двигающ; `MineBank(rejects)` дропает отклонённый терм С кластером", + "summary": "Исход «не термин» на уровне владельца построен: файл mined-rejects, глагол `decline` двери `bank/corrections`. Он же лечил зацикливание, когда отклонённый терм переспрашивался каждый прогон. «Не термин» движка должен лечь в тот же источник или явно от него отличаться, иначе у носителя будет два писателя (онтология 18)." + }, + { + "element": "E3", + "source": "docs/archive/architecture/05-decisions-D1-D38.md:198 (D16 п.1); ряд 320(а)", + "kind": "RATIFIED_DECISION", + "relation": "DUPLICATES", + "quote": "Фикс: fail-loud на пересекающихся окнах разных sense в `loadGlossarySeed` ИЛИ даунгрейд обоих совпадений в AMBIGUOUS.", + "summary": "«Многозначный — решает человек» уже ратифицировано как громкий отказ при полисемии одного src (D16). Ряд 320(а): совет движка «пометь один статусом auto» гард не исполняет. Исход «многозначный» надо сверить с этим гардом и советом." + }, + { + "element": "E3", + "source": "docs/BACKLOG.md:187 ряд 221 п.(3); эррата 11.09-в; D39.249 п.8; ряд 407", + "kind": "RATIFIED_DECISION", + "relation": "CONTRADICTS", + "quote": "⚠ Колонка `undecided` обязана ехать с тем же НЕ-гейтовым контрактом, что `SignatureState`, иначе пер-термная модель вернётся через новую проекцию.", + "summary": "По D39.144 и эррате 11.09-в пер-термной подписи в продукте нет, подписан либо весь банк, либо он неконсистентен. Исходы «многозначный (решает человек)», «скрытый пол — только человек» и видимое `undecided` возвращают пер-термный узел. Их можно пустить только через опциональную дверь правок, без гейта; предложение этого ограничения не называет." + }, + { + "element": "E3", + "source": "05-decisions-log.md:777 (D39.155 п.7); D39.42 п.1 §C2-7", + "kind": "RATIFIED_DECISION", + "relation": "EXTENDS", + "quote": "терм БЕЗ `dst` промотить нельзя вовсе — approved с пустым `dst` роняет загрузку сида и срывает прогон, для WHICH-only термов единственный очищающий глагол это ОТКАЗ", + "summary": "«Исход без dst → строка без dst, инертна по §C2-7» ложится на ратифицированную двухрежимную эмиссию. Но строка без dst не может стать approved, и на двери её снимает только отказ. Событие владельца «закон» на такой строке обязано нести dst." + }, + { + "element": "E4", + "source": "docs/architecture/13-tech-debt-anchors.md:87-91 (кандидат 73, БЕЗ СТРОКИ ТРЕКЕРА); docs/research/15-voice-and-state.md:201", + "kind": "RESEARCHED_IDEA", + "relation": "DUPLICATES", + "quote": "Источник кандидата — research/15-voice-and-state.md:200: одна команда ставит until_ch=N старой записи и since_ch=N новой. При этом СУБСТРАТ построен целиком", + "summary": "«Преемник с главы N» уже спроектирован как `tmctl` «замена термина с главы N» (паттерн NovelCrafter progressions). Субстрат построен: UNIQUE по окнам, $0-пере-пин. Скоуп — тонкая CLI-обёртка. У кандидата нет строки трекера: ряд 73 исчез, держатель — только ячейка справочника техдолга." + }, + { + "element": "E4", + "source": "docs/BACKLOG.md:144 ряд 49; 13-tech-debt-anchors.md:146-150 п.(7)", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "операторский протокол-документ релиза гендер-твиста (D5.1): сам механизм УЖЕ построен — until_ch-правка → точечный re-edit со сметой и $0-пере-пином", + "summary": "Смена рода с главы N уже исполняется: правка `until_ch` → сдвиг только `memory_version` → точечная ре-редактура `repin`/`rebill` со сметой. Не хватает только операторского протокола из ряда 49. Глагол `succeed` в двери должен стать обёрткой над этим, а не новой механикой." + }, + { + "element": "E4", + "source": "docs/archive/architecture/05-decisions-D1-D38.md:119 (D5.1); backend/prompts/zh-ru/classifier.md:10 (HEAD)", + "kind": "RATIFIED_DECISION", + "relation": "CONTRADICTS", + "quote": "когда Analyst в **загруженных** главах видит намеренную неоднозначность (омофонное ta / pro-drop без дизамбигуации), ставить `gender=hidden`", + "summary": "D5.1 ратифицировал проактивную автоматическую установку `hidden`. Предложение («скрытый пол — только человек», снять `hidden` от классификатора) отменяет живую ноту без ратификации. При этом код уже исключил `hidden` из словаря классификатора: «в словарь НЕ входит намеренно». Расхождение D5.1 с кодом надо назвать." + }, + { + "element": "E4", + "source": "docs/archive/architecture/05-decisions-D1-D38.md:140 (D7 правка 1); D39.55 п.(2); 05-decisions-log.md:3633 (D39.248 п.1); ряд 410", + "kind": "RATIFIED_DECISION", + "relation": "MISSED_RELEVANT", + "quote": "ты/вы в series-bible-lite — **журнал событий переходов**, а не статичная матрица пар (переход ты↔вы — сюжетное событие, `12-ru-target §2`)", + "summary": "Изменение по ходу книги как ЖУРНАЛ СОБЫТИЙ уже ратифицировано для обращений (D7, D21 п.2). С 11.09 голос входит в приоритет №1 (D39.248), и форму голоса проектирует Fable 5. Предложение по «журналу и преемнику» голос, обращения и профили не охватывает." + }, + { + "element": "E4", + "source": "docs/archive/reports/PACK20_BANK_DESIGN_2026-07-26.md:510-511 (§10 P1, по ссылке D39.41)", + "kind": "RESEARCHED_IDEA", + "relation": "EXTENDS", + "quote": "строка с `since_ch > c` байт-неспособна изменить инъекцию главы `c`, потому что `matchTrust`", + "summary": "Теорема прямой инвариантности доказана разбором восьми путей и выдержала атаку. Преемник с since=N не двигает хеши оплаченных глав .bank-journal.yaml`", + "source": "/home/ubuntu/tm-verify-1509/backend/internal/store/glossary.go:178-182; /home/ubuntu/tm-verify-1509/backend/internal/store/migrate.go:223; /home/ubuntu/projects/textmachine-main/docs/experiments/25-door-to-file-b.md:85", + "kind": "BUILT_DORMANT", + "relation": "MISSED_RELEVANT", + "quote": "// B1: a term that existed with a non-empty dst and now renders differently", + "summary": "Журнал ревизий B1 ПОСТРОЕН таблицей `glossary_revisions (book_id, src, sense, old_dst, new_dst, reason)`. Пишет его только ветка `reason=\"seed-replace\"`. Пере-решения авто-банка движком туда не попадают: эксп-25 печатает «`glossary_revisions` 0 строк». Контроль: 2 не-тестовых вхождения (INSERT и SELECT) на 381 .go-файл. Предложение заводит второй носитель рядом со спящим первым; надо либо использовать этот, либо снять его явно." + }, + { + "element": "E1 память решений для неподписанных строк", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/14-adaptive-memory.md:165; /home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-log.md:299 (D39.42)", + "kind": "OWNER_DEFERRED", + "relation": "DUPLICATES", + "quote": "для auto/ambiguous БЕЗ approved — first-seen/majority-vote кэш рендеринга (детерминированное расширение банка); adaptive выбор КАКИЕ серо-зонные записи инъектить (risk-sensitive precision-gate, abstention first-class)", + "summary": "M2 «консистентность-кэш» из research/14 — та же идея для неподписанных строк: кэш предлагает, пост-чек гейтит, человек или судья промоутит. D39.42 (решения владельца по паку-20): «НЕ строить в фазе 2: … M2-кэш (доктрина Д2 остаётся кандидатом на отдельную ратификацию)». Предложение переоткрывает M2, не называя его." + }, + { + "element": "E1 «принятое не пересчитывается, спрашивать только про новые»", + "source": "/home/ubuntu/projects/textmachine-main/docs/archive/architecture/05-decisions-D1-D38.md:116 (D5)", + "kind": "RATIFIED_DECISION", + "relation": "DUPLICATES", + "quote": "approved-глоссарий/series-bible наследуются read-only, новые термины append, approved не ревизуются молча (research/07); разрешение gender=hidden-твиста — ручное событие.", + "summary": "Для approved-строк принцип журнала ратифицирован D5 ещё в Ф1. Новое в предложении — распространение на неподписанные решения движка: это 92% строк по research/34. Но с D39.144 пер-термного approved в продукте нет, подписывается весь банк, так что граница «принятого» теперь проходит иначе, чем в D5." + }, + { + "element": "E1/E4 ретроспективные решения «с тома N»", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/07-translation-methodology.md:101", + "kind": "RESEARCHED_IDEA", + "relation": "DUPLICATES", + "quote": "Плюс механизм **ретроспективных решений**: если термин пересмотрен, фиксировать «с тома N — так», а не молча менять.", + "summary": "Профессиональная практика, на которую опираются и журнал, и преемник, записана в research/07 (04.07). Там же: «устоявшиеся имена и термины не пересматриваются без крайней нужды — консистентность ценнее локального улучшения». Шапка дока предупреждает, что сигнал слабый и проверять надо по предмету." + }, + { + "element": "E1/E3 поля записи журнала (провенанс, окно, исход, улики)", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/17-external-critique.md:51,104 (D25 — частичная приёмка)", + "kind": "RESEARCHED_IDEA", + "relation": "DUPLICATES", + "quote": "В каждую запись входят `valid_from`, `valid_to/unknown`, `confidence`, `status` (`candidate/approved/rejected`), `source_span_ids`, `created_by`, версия схемы.", + "summary": "Canon ledger из внешней критики почти совпадает с полями журнала. §A4 там же добавляет: «неизвестность хранится явно, а не заполняется наиболее вероятным значением» (это исход «не решено») и «правка канона создаёт impact set зависимых сегментов». Схемой не ратифицировано." + }, + { + "element": "E1 единое правило принятия для всех термов", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/17-external-critique.md:193", + "kind": "RESEARCHED_IDEA", + "relation": "EXTENDS", + "quote": "**PLAUSIBLE.** Ошибка memory write имеет больший expected loss, чем ошибка одного сегмента; пороги принятия должны зависеть от fan-out.", + "summary": "Предложение замораживает первое решение одинаково для редкого и частого терма. Порог принятия должен зависеть от числа вхождений: research/24:263 замерил, что неверная строка-закон принимается 6 из 6 и вытесняет верную в 5 из 6 окон, то есть заражает почти все чанки терма. Владелец в V1-п.1 предлагал именно счёт упоминаний имён." + }, + { + "element": "E1 цена трейдоффа «первое решение живёт»", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/24-bank-arbitration.md:164 (+ таблица §B3 :172-195)", + "kind": "RESEARCHED_IDEA", + "relation": "EXTENDS", + "quote": "~четверть строк — вкусовой регистр владельца, автономно недостижимый по построению (D39.47).", + "summary": "Автономное решение совпадает с подписью владельца лишь в 18–25 из 45 голд-термов: прод-терминолог 18/45, соло deepseek 20/45, лучший одиночка glm 25/45. Около четверти строк недостижимы автономно в принципе. Трейдофф предложения, INVENTED 17/66, не показывает главного: примерно половина замороженных первых решений расходится с тем, что выбрал бы владелец." + }, + { + "element": "E1/E11 замер до стройки журнала", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/31-harness-independent-critique.md:54 (ФАКТУРА)", + "kind": "RESEARCHED_IDEA", + "relation": "EXTENDS", + "quote": "Проверка роста 10 → 50 → 200 глав против обработки того же текста сразу должна считать удержанные решения, новые ошибки и общую цену.", + "summary": "Независимая критика 06.09 уже нашла, что банковые батчи при новых свидетельствах меняют запрос и перекупаются (terminologist.go:775, :849), и дала дизайн замера. В порядке работ предложения нет пре-замера «удержано / новые ошибки / цена». Нет и активного нуля «без банка», которого требуют research/34 §3 и research/30 §3.3." + }, + { + "element": "E1/E11 числа предложения и деньги", + "source": "/home/ubuntu/projects/textmachine-main/docs/experiments/25-door-to-file-b.md:88; /home/ubuntu/projects/textmachine-main/docs/experiments/24-door-to-file.md:241", + "kind": "RESEARCHED_IDEA", + "relation": "DUPLICATES", + "quote": "заход терминологии ИЗМЕНИЛ передачу у **12 термов из 69**, и **11 из 12 уехали читателю именно в", + "summary": "Отсюда числа предложения. Сам эксперимент квалифицирует их как «цену пере-майнинга банка после человеческой подписи», а не выброшенную покупку. Денежная база для окупаемости журнала (эксп-24): контур банка стоил 15.6% книги, второй заход — $0.028742, это 6.9%. Research/24 §B5: терминолог соло стоит $0.20–0.60 на книгу. Сравнивать «одну перекупку на книгу» надо с этим." + }, + { + "element": "E1/E10 гранулярность и состав банка", + "source": "/home/ubuntu/projects/textmachine-main/docs/experiments/25-door-to-file-b.md:902", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "**Жаккар по книге = 0.63.** ⇒ **банк книги — функция ЧЕРНОВИКА, а черновик есть стохастический выход", + "summary": "Между прогонами расходятся и состав банка, и гранулярность ключей: A предлагает `丙等资质`/`舅父舅母`, B — их составляющие; `舅父舅母` (14 вхождений) есть только в A. Журнал по Identity закрепляет решения, но не сводит «составной ключ против частей». D39.50 уже 26.07 мерил невоспроизводимость банкноты: Жаккар 0.077–0.40." + }, + { + "element": "весь предмет предложения", + "source": "/home/ubuntu/projects/textmachine-main/docs/NEAR_TERM_PLAN.md:53 (пункт 10); /home/ubuntu/projects/textmachine-main/docs/BACKEND_WHAT_THE_BANK_IS_MADE_OF_SESSION_PROMPT.md:5,44", + "kind": "PLANNED_ROW", + "relation": "DUPLICATES", + "quote": "| 10 | **бэкенд** | ⛔ **БАНК: РЕШЁННОЕ ОСТАЁТСЯ РЕШЁННЫМ** — предмет пере-определён проверкой 15.09.", + "summary": "Предложение наполняет уже заведённый пункт 10 плана (ряды 130·330·438·440), который ждёт слова владельца «копить». Снятый баннером пак-предшественник предупреждает (стр. 44–45): «Запереть предложение = отменить майнинг» (D39.144). Журнал должен закреплять решения по термам, но не популяцию предложений." + }, + { + "element": "E2 «два закона на одно слово (ряд 330)», шаг 1 порядка", + "source": "/home/ubuntu/projects/textmachine-main/docs/BACKLOG.md:269 (ряд 330)", + "kind": "PLANNED_ROW", + "relation": "REFUTES_PART", + "quote": "обошёл 162 файла БД, 161 с таблицей глоссария, 142 книги с непустым банком, прочитано 13 350 строк; книг с ЛЮБЫМ конфликтом — 0", + "summary": "Ряд 330 — про противоречие approved×неподписанная и про деньги. Его корпусный прибор дал 0 книг с конфликтом при контроле: подсаженная строка ловится в 142 книгах из 142. Прибор сверяет дубли по полному сырому ключу (src,sense,since,until). Покрывает ли он класс «нормализованный против сырого» из предложения, ряд не устанавливает. Шаг 1 чинит класс без наблюдённых случаев либо требует своего замера; ссылка на 330 как на пример «двух законов» неточна." + }, + { + "element": "E2 одно определение тождества, таблицы вариантов", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/13-memory-bank-validation.md:117; /home/ubuntu/projects/textmachine-main/docs/architecture/06-memory-risk-registry.md:35 (A4 ✅ построено)", + "kind": "RESEARCHED_IDEA", + "relation": "DUPLICATES", + "quote": "- **Молчаливо-пустой матч из-за орфографии** (упрощ./трад., полу/полноширина, кана, ruby) — **самый вероятный баг «тихо пусто»**: обязательный слой нормализации (NFKC + OpenCC + kana-folding + ruby-захват) симметрично к ключам и тексту.", + "summary": "Нормализация, симметричная для ключей и текста, — исходное требование A4, построенное в `internal/text` плюс данные пары. Шаг 1 предложения по сути доводит слово «симметрично» до всех дверей: загрузка, уступка, свод. Идея не новая, это закрытие долга A4." + }, + { + "element": "E2 таблицы вариантов написания как данные языка", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/14-adaptive-memory.md:191", + "kind": "RESEARCHED_IDEA", + "relation": "EXTENDS", + "quote": "Точный матч на trad/alias формах: recall **0.00 → +норм 0.50 → +alias 0.75**. Живой баг: неполная trad-карта (爺→爷) молча промахнула 赵太爷 → **A4 подтверждён: нормализацию покрыть и тестировать бит-в-бит** (OpenCC, не мини-карта).", + "summary": "Рычаг замерен: recall растёт с 0 до 0.50 от нормализации и до 0.75 с алиасами. Там же живой баг неполной мини-карты. Для выноса таблиц в `identity.txt` это требование полноты: OpenCC-уровень плюс побитовый тест, иначе снова «тихо пусто»." + }, + { + "element": "E2 канал `configs/langpacks//identity.txt`", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/33-backend-debt.md:343,357-359 (разобрано в строки 344–350, D39.224)", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "⚠ **Крупнее и точечной правкой не закрывается:** категории каналов зашиты в китайскую форму — пара, которой нужна СВОЯ транслитерация, выразить её не может. Носителя в бэклоге нет.", + "summary": "Каналы langpack — закрытый список в Go (`langpack.go:108-114`: source-morphology, transliteration), манифест без каналов отказывается жёстко. Новый канал identity — это правка этого закрытого списка, а «громкий отказ при объявленном и отсутствующем канале» ложится на уже названный долг Д7. Предложение этот долг не упоминает." + }, + { + "element": "E2 идентичность для ja-источника", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/24-bank-arbitration.md:348-349", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "поймал важнее: **батч 0 вернул термы упрощённым китайским** (魔術→魔术) — off-language класс на не-родной паре", + "summary": "На ja-паре модель возвращает ключи упрощённым китайским. Если таблица вариантов молча сворачивает 術 и 术 в «тот же термин», экран OffLanguage перестаёт отбивать чужой ответ. Кандзи, кана и ромадзи (鈴木/すずき/スズキ) — отдельная ось research/13 A4. Таблицы обязаны быть пер-языковыми, не общими «CJK»." + }, + { + "element": "E2/E9 алиасы в определении тождества", + "source": "/home/ubuntu/projects/textmachine-main/docs/experiments/23-editor-tier.md:7609 (ряд 407; дешёвая половина оставлена ОТКРЫТОЙ актом D39.249 п.7)", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "⇒ **Дрейф ВНУТРИ составного имени не наблюдаем ни пост-чеком движка, ни `presence`-метрикой.** Дёшево чинится: проверять алиас-ключ на собственную канонную форму, а не только dst записи-хозяина.", + "summary": "Алиас полного имени `古月方源` (при записи `方源`) плюс длиннейший матч прячут «Гу Юэ» при каноне «Гуюэ». Единое тождество по нормализованной форме этого не лечит: нужна сверка алиас-ключа с собственной канонной формой. В предложении алиасы не упомянуты." + }, + { + "element": "E3 исход «многозначный (решает человек)»", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/32-harness-architecture-alternatives.md:46 (ФАКТУРА); /home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-log.md:2160 (D39.193 п.3)", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "Полисемия: D16.1 → запрет совпадающего `src` с разными смыслами → D39.193 п.3 от 04.09 признаёт два подписанных канона законными → рендер изменён, входные ограничения остались", + "summary": "Решению человека о многозначности сегодня некуда войти. Загрузчик, свод и дверь отказывают одному src с разными sense в пересекающихся окнах (`memseed.go:201–228`, `decisions.go:914`), а рендер после D39.193 п.3 принимает два подписанных канона. Codex воспроизвёл это пробой (`31-harness-audit/polysemy_contract_probe_test.go.txt`). Исход «многозначный» упрётся в это расхождение контрактов." + }, + { + "element": "E3 обнаружение многозначных", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/20-bank-mining.md:513 (research/20 ACCEPT, D39.6; не построено)", + "kind": "RESEARCHED_IDEA", + "relation": "EXTENDS", + "quote": "$0-симптом: спред dst НЕ падает после лемматизации И KWIC-контексты расслаиваются на кластеры → `sense_split_candidate`; сам сплит кодом не решается (матчер keys-only-src, D16.1)", + "summary": "Детектор кандидатов на многозначность был спроектирован за $0: `sense_split_candidate`, затем LLM-адъюдикация по двум KWIC-пулам, затем человек. В предложении «многозначный» зависит от того, признается ли терминолог сам, а сентинел не используется ни разу (см. research/24:217)." + }, + { + "element": "E6/E9 стабильно-неверное содержание банка", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/20-bank-mining.md:512; /home/ubuntu/projects/textmachine-main/docs/experiments/25-door-to-file-b.md:773", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "**Z1 стабильно-неверный перевод** (蛊→«гусеницы»: высокий термхуд, НУЛЕВОЙ спред, dst — обычное слово) | $0-эвристика: high-score кандидат + spread≈0 + dst не-Палладий/не-заглавный → класс `suspicious_stable`", + "summary": "Сигналы предложения — споры черновиков, INVENTED, «N глав до закона» — не видят терм, стабильно отданный неверно. Прогон B (эксп-25:773): «Содержание банка не судит ничто» (`方家`→«род Фан», хотя «род» занят кланом). Research/20 спроектировал $0-эвристику `suspicious_stable` плюс дешёвого кросс-семейного судью; не построено." + }, + { + "element": "E3/E9 вопросы, на которые можно надёжно ответить", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/30-arhitektura-otvet.md:238-240 (ФАКТУРА)", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "**exact-match точность терминов τ 0.195**, хуже COMET (0.322) и много хуже LLM-судьи (0.514). И сам вопрос «термин верен» ненадёжен даже у экспертов (**κ 0.58–0.61**), тогда как «термин не переведён» надёжен (**κ 0.94–1.0**).", + "summary": "Исходы «закон» и «многозначный» — это суждение «верен ли», и даже эксперты согласны в нём с κ около 0.6. Надёжно отвечаются только «пропущен / не переведён». Это касается и замысла «человек решает спорное», и $0-сверки «черновики против закона»: ставить надо надёжный вопрос." + }, + { + "element": "E4 преемник «с главы N»", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/15-voice-and-state.md:201 (research/15 принят D21; гипотеза 🧪)", + "kind": "RESEARCHED_IDEA", + "relation": "DUPLICATES", + "quote": "3. 🧪 **Операция «замена термина с главы N»** (NovelCrafter progressions): одна команда ставит `until_ch=N` старой записи и `since_ch=N` новой — закрывает дыру «оба варианта активны». Слот: тулинг банка (tmctl), не пайплайн.", + "summary": "Глагол `succeed` предложения (старая запись until=N−1, новая since=N) — это гипотеза 09.07 с внешним прецедентом NovelCrafter Codex Progressions (research/15:187). Предложение её не цитирует." + }, + { + "element": "E4/E7 механика преемника", + "source": "/home/ubuntu/projects/textmachine-main/docs/archive/reports/BANK_QUALITY_DESIGN_2026-08-01.md:203; /home/ubuntu/projects/textmachine-main/docs/BACKLOG.md:144 (ряд 49)", + "kind": "BUILT_DORMANT", + "relation": "DUPLICATES", + "quote": "**tmctl «замена термина с главы N»:** механизм ПОСТРОЕН (`repin.go`+`rebill.go`, D39.42 п.5; команд `translate|report|status|export|redrive|seed-lint` `main.go:72-87`, замены нет).", + "summary": "Правка until_ch запускает точечную пере-редактуру со сметой и $0-пере-пином, и это построено. Не хватает только тонкой команды оператора и протокола. Ряд 49 несёт «операторский протокол-документ релиза гендер-твиста (D5.1): сам механизм УЖЕ построен». Шаг 4 предложения стоит сузить до глагола над repin/rebill плюс смена TermID." + }, + { + "element": "E4/Q1 TermID и окна по chapter-ID", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/33-backend-debt.md:369,381 (разложено D39.224 в пак 161); код: /home/ubuntu/tm-verify-1509/backend/internal/membank/decisions.go:166-173", + "kind": "RESEARCHED_IDEA", + "relation": "DUPLICATES", + "quote": "ключ банка — `TermID(src, sense, since, until)` хеширует `strconv.Itoa(since)` (`decisions.go:166-173`).", + "summary": "Сцепка окна с тождеством уже замерена: на реальном артефакте 142 терма, у 128 since_ch=0, окно у 14; у владельца в сидах около 8 чисел. Вердикт «окна банка на chapter-ID внутри дизайн-пака 161». Порядок предложения (журнал и преемник после перенарезки, TermID без окна) с этим совпадает; на HEAD `TermID` хеширует since и until." + }, + { + "element": "E4 смена рода с главы N, скрытый пол", + "source": "/home/ubuntu/projects/textmachine-main/docs/archive/architecture/05-decisions-D1-D38.md:119 (D5.1); /home/ubuntu/projects/textmachine-main/docs/architecture/06-memory-risk-registry.md:56 (C2 🔶)", + "kind": "RATIFIED_DECISION", + "relation": "DUPLICATES", + "quote": "Плюс ретро-патч-протокол «с тома N — так» с показом стоимости пере-перевода вмороженных глав, которые твист фальсифицировал.", + "summary": "Смена рода «с тома/главы N» с показом стоимости ратифицирована с D5.1 (`gender=hidden(until_ch)`, реестр C2). «Скрытый пол — только человек» — это D5: «разрешение gender=hidden-твиста — ручное событие»." + }, + { + "element": "E4 производитель рода", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/20-bank-mining.md:594; D39.193 (реестр /home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-index.md:254)", + "kind": "RATIFIED_DECISION", + "relation": "DUPLICATES", + "quote": "4. **Пол:** счётчики 他/她/контекст-гоноративов по кластеру → evidence-поле; gender проставляется только владельцем (класс hidden — D19.3 — из текста невыводим).", + "summary": "«Род производит классификатор, hidden — не от классификатора» уже ратифицировано: D39.193 (производитель — классификатор, замок по совпадению ключа `KeyTrusted`) и D19.3 (hidden из текста не выводится). Непостроенным осталось предложение research/20: счётчики 他/她 как улики для человека." + }, + { + "element": "E4/E5 род по книжной памяти", + "source": "/home/ubuntu/projects/textmachine-main/docs/experiments/23-editor-tier.md:4351", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "⇒ **Пайплайн, который видит только главу, по построению слеп примерно в четверти случаев.** Он не «ошибается» — ему нечем узнать. Узнать может ТОЛЬКО книжная память", + "summary": "В 2 окнах из 8 пол рассказчика-от-первого-лица по окну не устанавливается (интервал Уилсона [0.07; 0.59]); его раскрывают другие окна. При правиле «улики только из переведённой части» ранние главы получат пол лишь задним числом, то есть закон на готовых главах (E7) станет нормальным путём для рода, а не исключением." + }, + { + "element": "E5 «улики — только из уже переведённой части книги»", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/19-chunking-cohesion.md:542 (research/19 принят D39.1)", + "kind": "RESEARCHED_IDEA", + "relation": "CONTRADICTS", + "quote": "**Source-side контекст параллелизм НЕ ограничивает:** исходник статичен и известен целиком до первого вызова → src-carryover (хвост предыдущего чанка-источника), lookahead (катафора — даже ЛУЧШЕ, чем в последовательном конвейере: вперёд смотреть можно всегда)", + "summary": "Исходник известен целиком до первого вызова, и улики вперёд по нему бесплатны. Спойлеры по канону проекта держат окна (research/15, D21), а не запрет смотреть. У владельца два слова: V0-п.33 «знать контекст вперед и назад» и V4-п.3 «проход наперед … не очень удачливой»; в реестре требований ПТ-29 помечен ❌ без D-ноты. Предложение ограничение не обосновывает." + }, + { + "element": "E5 выборка улик", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/24-bank-arbitration.md:132", + "kind": "RESEARCHED_IDEA", + "relation": "EXTENDS", + "quote": "**A6. KWIC: первые N вхождений в порядке глав** (`terminology.go:308-329`) — сэмплинг смещён к началу книги; ось «первые-N против стратифицированных» не мерена", + "summary": "Контексты для терминолога берутся первыми N вхождениями по порядку глав. При правиле журнала «перезапрос только при новых уликах» свежие вхождения из поздних глав могут вообще не попасть в выборку. Проба «первые-N против стратифицированных» (~$0.02, research/24 §D п.5) не исполнялась." + }, + { + "element": "E5 «перезапрос только при новых уликах»", + "source": "/home/ubuntu/projects/textmachine-main/docs/archive/architecture/05-decisions-D39-20-58.md:325 (D39.50 п.4)", + "kind": "RATIFIED_DECISION", + "relation": "MISSED_RELEVANT", + "quote": "**kwic-дефолт 3×40 ДОСТАТОЧЕН** (ни одна точка сетки не отличима, 0×0 — лучшая; развилка «подача×контекст» неразличима)", + "summary": "Сетка объёма контекста неразличима, даже 0×0 оказался лучшим; нота сама называет напряжение с D39.46 «контексты — главный рычаг». Правило с отпечатком улик предполагает, что новые улики сдвигают решение, а это не установлено: «не решено» рискует доходить до предела перезапросов без перемен." + }, + { + "element": "E6 показ сигналов (споры, «N глав до закона», proposed)", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/16-reader-ide-alignment.md:82-83 (research/16 принят D29)", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "Подсветка **ЯКОРИТ усилие**: подсвеченные места правят в 2–4.6× чаще, подсвеченные редакторы правят >2× независимо от точности подсветки", + "summary": "Там же (:83): QE должна достичь >80% F1, прежде чем подсветка вообще помогает. Наши сигналы имеют замеренные ложные тревоги: вердикт `split` по `方源` (58 вхождений в 4 падежах, ряд 436), 26 термов из 69 без найденной передачи (ряд 434). Видимость без порога точности будет вредить." + }, + { + "element": "E3/E6 исходы, решаемые человеком", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/34-memory-bank-quality-audit.md:102; /home/ubuntu/projects/textmachine-main/docs/architecture/06-memory-risk-registry.md:92 (G2 ❌)", + "kind": "OPEN_QUESTION", + "relation": "MISSED_RELEVANT", + "quote": "**Ёмкость человека.** Весь механизм консистентности упирается в вашу подпись, а сколько предложений на главу выдаст майнер на полной книге и сколько это минут — не смоделировано никем", + "summary": "Предложение добавляет исходы только для человека: многозначный, скрытый пол, имя владельца с главы N, заказ переделки. Модели ёмкости нет: реестр рисков G2 «flag-rate × throughput» стоит ❌ с 04.07, research/17 подтвердил дыру. На 2283 главах это непроверенная петля." + }, + { + "element": "E3 человек решает по-термно", + "source": "/home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-log.md:599 (D39.144 п.1)", + "kind": "RATIFIED_DECISION", + "relation": "CONTRADICTS", + "quote": "банк на книгу может быть огромным, пер-термная подпись = сотни кликов — НЕ модель продукта; подписывается банк ЦЕЛИКОМ («условный ок»), перевод уходит в доработку.", + "summary": "Исходы «многозначный — решает человек» и «скрытый пол — только человек» возвращают пер-термные решения. Владелец 16.08 назвал пер-термную подпись не моделью продукта. Нужна форма, совместимая с «одним ОК»: например, очередь по уверенности с дефолтом «авто», а не вопрос на каждый терм." + }, + { + "element": "E6 «платформа читает раздел предложений»", + "source": "/home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-log.md:3108 (D39.225 п.4); /home/ubuntu/projects/textmachine-main/docs/architecture/18-bank-ontology.md", + "kind": "RATIFIED_DECISION", + "relation": "DUPLICATES", + "quote": "**4. Класс A заведён СОЗНАТЕЛЬНО и записан у своего предмета.** У новой секции сегодня НОЛЬ читателей.", + "summary": "Раздел `proposed` публикуется движком с 07.09. Читатель на платформе — уже ратифицированная платформенная половина ряда 224 (класс A онтологии 18); полнота консолидации — половина ряда 253. Пункт предложения дублирует открытые ряды, а не вводит механизм." + }, + { + "element": "Q3 закон на готовых главах: по заказу или автоматически", + "source": "/home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-log.md:295 (D39.42 п.5); :1166 (D39.165 п.3)", + "kind": "RATIFIED_DECISION", + "relation": "DUPLICATES", + "quote": "(5) **Смена банка после оплаты** (поздняя подпись и любая правка) = пере-редактура ТОЛЬКО затронутых юнитов через `--resnapshot`-семантику (пере-пин $0 неизменных байт), со сметой «N юнитов, ~$X» ДО согласия", + "summary": "Для редакторской волны Q3 уже решён: смета до согласия (D39.42 п.5), а D39.165 п.3 — «под порогом согласия — свой у книги, иначе `min($0.50, 5% × книги)` — продолжает сам, без флагов (`rebill.go`)». Открыт только доезд до черновиков. Q3 стоит сузить до этого остатка." + }, + { + "element": "Q2/Q4 стоп D39.144 п.1 и доезд правки до черновиков", + "source": "/home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-log.md:1174 (D39.165 п.3); :599 (D39.144 п.1); /home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-index.md:309 (D39.248)", + "kind": "RATIFIED_DECISION", + "relation": "CONTRADICTS", + "quote": "**Владелец снял это 28.08:** открыть дверь к уже построенному движковому механизму — НЕ то же самое, что проектировать продуктовый цикл пост-ридинга.", + "summary": "D39.144 п.1 уже сужен (D39.165 п.3). Под гейтом остался «доезд правки до ЧЕРНОВИКА через сид», то есть ровно Q4. Условие гейта «до полигонных итогов» невыполнимо: D39.248 вывел полигон из скоупа целиком. У владельца надо просить замену условия гейта, а не «снятие стопа»." + }, + { + "element": "E7 since = первое появление", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/20-bank-mining.md:596; код: /home/ubuntu/tm-verify-1509/backend/internal/miner/miner_emit.go:210,389-399; /home/ubuntu/tm-verify-1509/backend/internal/pipeline/mining.go:612", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "5. **Спойлер-окна:** since_ch = первая глава вхождения кластера (автоматически, по source); until_ch — только человек.", + "summary": "Построено в майнере: `SinceCh: entitySinceCh(...)` — минимальная глава по src и алиасам. Дыра: кандидаты, пришедшие из банкноты, получают `SinceCh: 0` (mining.go:612); на артефакте research/33 окно стоит у 14 термов из 142. Предложению надо назвать, какой путь ставит since черновиковым термам." + }, + { + "element": "E7 ретроактивность подписи", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/34-memory-bank-quality-audit.md:105 (ФАКТУРА)", + "kind": "OPEN_QUESTION", + "relation": "DUPLICATES", + "quote": "5. **Ретроактивность подписи.** Два прогона ОДНОЙ книги разошлись в самом каноне — 元石 «первокамень» против «первобытный камень», 真元 «истинная энергия» против «истинная ци», обе записи подписаны.", + "summary": "Аудит 11.09 поставил вопрос E7 первым. Нюанс, который предложение не покрывает: там разошлись два ПОДПИСАННЫХ канона между прогонами, а журнал движка подписанный дрейф не ловит." + }, + { + "element": "E4/E7 преемник и закон задним числом", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/32-harness-architecture-alternatives.md:74,86,88 (ФАКТУРА, полной ревью-шапки нет)", + "kind": "RESEARCHED_IDEA", + "relation": "BETTER_ALTERNATIVE", + "quote": "Но там сначала принимают термин, затем приводят текст к нему. Здесь **результат применения к тексту участвует в выборе самого термина**, а принятие относится ко всему связанному изменению.", + "summary": "Гипотеза 1 Codex: единица принятия — `revision = base_revision + bank_delta + affected_units + candidate_hashes + decision`. Смена закона принимается одной группой вместе с её пере-редактурами, книга не остаётся «наполовину на новом каноне». Это прямо отвечает на трейдофф «первое решение живёт до правки человеком». Не построено и не ратифицировано." + }, + { + "element": "E9 консистентность по отгруженному тексту", + "source": "/home/ubuntu/projects/textmachine-main/docs/architecture/05-decisions-log.md:3685 (D39.249); /home/ubuntu/projects/textmachine-main/docs/experiments/25-door-to-file-b.md:699", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "Теперь есть счёт по ОТГРУЖЕННОМУ тексту с двумя инвариантами (одна форма на термин по книге · где у банка есть форма, отгружена она), с печатаемыми знаменателями и секцией `BOOK CONSISTENCY` в отчёте сборки.", + "summary": "Research/34 §2(1) исполнен: I1 и I2 построены. Известные дефекты: вердикт `split` утверждает больше, чем меряет предикат («это одно имя в четырёх падежах, а не две передачи», ряд 436); прибор A сверялся не с той версией банка (~20%, эксп-25 §8.1). $0-сверка предложения «черновики против закона» унаследует их, если не будет склонительной; decl-форм у майнера нет (ряд 423)." + }, + { + "element": "E8/E9 «черновики ≥N со старым именем, редактор приводит»", + "source": "/home/ubuntu/projects/textmachine-main/docs/experiments/24-door-to-file.md:336-337; /home/ubuntu/projects/textmachine-main/docs/experiments/22-tenant-panel.md:1078", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "**`高脚吊楼` — случай, где закон банка на проводе (`D39.104`: банк есть закон для ВСЕХ строк независимо от статуса) в тексте не виден.** Банк нёс «дом на сваях», файл несёт «свайный дом» четырежды.", + "summary": "На прогоне A из 9 разошедшихся термов 4 отданы банковской формой, 4 — одной, но не банковской, 1 — двумя (ряд 417). В панели эксп-22 покрытие канона у боевого редактора хуже, чем у черновика: 0.882 против 0.909. Черновая волна вообще без добытого банка (research/34 §2(4)). Опора «редактор приведёт» замерено протекает." + }, + { + "element": "E9 принуждение закона флагом и точечным ремонтом", + "source": "/home/ubuntu/projects/textmachine-main/docs/experiments/21-role-topology.md:110 (принят D39.117)", + "kind": "REFUTED", + "relation": "EXTENDS", + "quote": "C2 vs A_law −3.75 [−4.81, −2.56] Holm 0.0006 ✔ ремонт значимо хуже переписывания", + "summary": "Нога «канон-фиксер по флагам» замерена и провалилась против переписывания. Это поддерживает выбор предложения «ре-мейк только пере-проходом» и предостерегает направление D39.205 «glossary_miss как актуатор ремонта»." + }, + { + "element": "E4/E9 рецидив старой формы после смены закона", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/24-bank-arbitration.md:298", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "8. Негативный слой (TBX forbidden): $0-счёт рецидивов отвергнутых форм на coldrun-финалах → при ненулевом потоке дешёвый линт в пост-чеке.", + "summary": "Преемник и исход «не термин» порождают отвергнутые формы. Слой запрещённых форм (TBX forbidden) ловил бы старую передачу после главы N за $0. Не построен: 16 не-тестовых хитов `forbidden` на 381 .go-файл, и все про другое — NG-лексика голоса, леджер, wirefence. Естественная пара к `succeed`." + }, + { + "element": "E9/E10 «одна форма на книгу»", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/29-harness-topology-survey.md:2490-2491; :2484", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "**(4) Сама посылка «одинаково = хорошо» измеренно неверна.** Lei и др. 2024 разметили **30 667** пар повторов zh→en: **13 375 (43.6%) — «false consistency»**, где разнобой был бы допустим.", + "summary": "Там же: в WMT25 «Худшая по терминам система согласованнее лучшей», и организаторы рекомендуют мерить term accuracy. Расширение закона на обычные слова (`家族`/`族`) без отбора рискует навязать одну форму там, где разнобой уместен." + }, + { + "element": "E10 номинация: обычные существительные", + "source": "/home/ubuntu/projects/textmachine-main/docs/experiments/25-door-to-file-b.md:876-879; /home/ubuntu/projects/textmachine-main/docs/BACKLOG.md:361 (ряд 440)", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "⇒ **шесть из восьми термов читателя отсечены потому, что они ОБЫЧНЫЕ КИТАЙСКИЕ СЛОВА.** Контраст спрашивает «характерно ли слово для ЭТОГО текста на фоне китайского вообще»; продукт спрашивает «нужна ли слову ОДНА закреплённая русская передача на всю книгу».", + "summary": "Крупнейшая находка приоритета №1 (род↔клан, `家族`/`族`) исключена контрастом по построению (ряд 440). Журнал и тождество этого не касаются, номинации в порядке работ предложения нет. Внешний A/B (research/30:228): разбавление глоссария «верными, но нерелевантными записями» роняет точность нужных термов до 50.1." + }, + { + "element": "E10 расширение эмиссии", + "source": "/home/ubuntu/projects/textmachine-main/docs/archive/architecture/05-decisions-D39-20-58.md:325 (D39.50 пп.1–2)", + "kind": "RATIFIED_DECISION", + "relation": "MISSED_RELEVANT", + "quote": "**частотного экрана НЕ существует** (§5.1: 少年 1149 против 光阴之河 15 — порога нет; полигон сам снял свою рекомендацию)", + "summary": "26.07 ратифицировано: эмиссия не расширяется («закрыта отрицательно — механизмом»), банкнота невоспроизводима (Жаккар 0.077–0.40), частотой обычное слово от термина не отделить. Любой ход по E10 переоткрывает D39.50; research/24 A8: 8 из 53 подписанных термов банк не видит вовсе." + }, + { + "element": "E9 что видит проверка консистентности", + "source": "/home/ubuntu/projects/textmachine-main/docs/experiments/09-pilot-protocol.md:116", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "3. **Ключевое: M3 consistency (0.467) ≈ M0 (0.567)** — по консистентности M3 выглядит как baseline, вред НЕВИДЕН. Его ловит ТОЛЬКО ось верности → почему её реализация (D13.5) была решающей, а старый харнесс давал ложный «вред меньше».", + "summary": "С неверным глоссарием (рука M3) консистентность выглядит как без глоссария, а вред виден только по оси верности. Сверка «черновики против закона» и I1/I2 не отличат неверный закон, исполненный единообразно. Нужна ось верности или детектор `suspicious_stable`." + }, + { + "element": "E1/E4 необратимость раннего решения", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/12-common-failures.md:211", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "Термин в начале книги переводится так, что позднее его смысл уже невозможно корректно раскрыть.", + "summary": "Таксономия провалов называет класс, который журнал с замороженным первым решением делает системным. Предложение ставит преемник только на ручной триггер и не называет автоматического сигнала для такого терма." + }, + { + "element": "E1 замок решения против глобальной пере-консолидации", + "source": "/home/ubuntu/projects/textmachine-main/docs/research/20-bank-mining.md:255; ср. /home/ubuntu/projects/textmachine-main/docs/research/19-chunking-cohesion.md:558", + "kind": "OPEN_QUESTION", + "relation": "MISSED_RELEVANT", + "quote": "- **First-wins работает онлайн, пост-хок реконсиляция не проверена:** DelTA (см. A3) фиксирует первый перевод имени и этим ПОДНИМАЕТ и консистентность, и COMET — но цену неверного первого выбора не мерил никто, и глобальный пост-хок пересбор не тестировался.", + "summary": "Research/19:558 объявлял глобальную пост-хок консолидацию «КАЧЕСТВЕННО лучше онлайн-замка», research/20 это ограничил, research/32 назвал перенос чрезмерным. Журнал выбирает замок, а сравнение «замок против пересбора» на нашем стеке не мерил никто." + }, + { + "element": "E1 планка точности банка (идея владельца)", + "source": "/home/ubuntu/projects/textmachine-main/START_PROMT.MD:80; реестр ПТ-8 ✅ (/home/ubuntu/projects/textmachine-main/docs/product-requirements.md:23)", + "kind": "OWNER_IDEA", + "relation": "EXTENDS", + "quote": "так вот решение вокруг \"банка памяти\" должно быть крайне точным, так как даже 1 ошибка в переводе текста может быть для читателя фатальной чтоб закрыть перевод перевод книги и сочти решение не зрелым", + "summary": "Мерило владельца — точность, одна ошибка фатальна. Трейдофф «первое решение живёт до правки человеком» при автономной точности около 50% (research/24) с этой планкой расходится, если путь пересмотра не реален. Разобрано в реестр как ПТ-8 ✅." + }, + { + "element": "E1/E5 решение с обоснованием и контекстом первого появления (V6-2)", + "source": "/home/ubuntu/projects/textmachine-main/START_PROMT.MD:100; реестр ПТ-39 ⭕, ПТ-40 🔶 (/home/ubuntu/projects/textmachine-main/docs/product-requirements.md:89-90)", + "kind": "OWNER_IDEA", + "relation": "EXTENDS", + "quote": "2) Перевод банка памяти в хорошую модель. Просить принять хорошую модель взять на себе редакторскую роль ПРИНЯТИЯ РЕШЕНИЯ С ОБОСНОВАНИЕМ. Хорошо приложить контекст термина, например первого появления термина.", + "summary": "Запись журнала «кто, на каких уликах» — это половина V6-2. По реестру ПТ-39 обоснования нет ни в промпте, ни в парсере; поле `Note` в схеме сида есть, нет производителя. Разделение правил по классам (ПТ-40) сделано наполовину. Журнал стоит связать с ПТ-39." + }, + { + "element": "E5/E3 откуда брать новые улики (V4-4, V0-16)", + "source": "/home/ubuntu/projects/textmachine-main/START_PROMT.MD:89 (и :24); реестр ПТ-9 ✅, ПТ-10 ⭕; D39.42 п.2 (веб-фетч не в v1)", + "kind": "OWNER_IDEA", + "relation": "EXTENDS", + "quote": "нужно записывать контекст в котором эти слова чаще всего встречаются, плюс передавать жанр книги наверное. И самое важно некоторые запросы перевода в глоссарий мне кажется надо юзать модель с вебфетчем", + "summary": "Единственный канал новых улик, который задумывал владелец, — веб-фетч. Он отложен D39.42 п.2 и стоит ⭕ в ПТ-10. V0-п.16 предупреждает о многозначности слов. Для «не решено — перезапрос при новых уликах» других источников улик, кроме новых глав, в репозитории нет." + }, + { + "element": "E5 контекст вперёд (V0-33 против V4-3)", + "source": "/home/ubuntu/projects/textmachine-main/START_PROMT.MD:88 (и :44); реестр ПТ-29 ❌ (/home/ubuntu/projects/textmachine-main/docs/product-requirements.md:75)", + "kind": "OWNER_IDEA", + "relation": "EXTENDS", + "quote": "3) Проход книг наперед тоже считаю идеей изначальной не очень удачливой. Что именно и как нам это может дать?", + "summary": "Ограничение «улики только из переведённой части» опирается на V4-п.3, но реестр пишет «вопросительная форма, отдельной ратификации в D-логе нет». В V0-п.33 владелец хотел обратного. Если предложение опирается на V4-3, это надо сказать явно." + }, + { + "element": "E6 сигналы как банк замечаний (V6-4)", + "source": "/home/ubuntu/projects/textmachine-main/START_PROMT.MD:102; реестр ПТ-41 ⭕ (/home/ubuntu/projects/textmachine-main/docs/product-requirements.md:91)", + "kind": "OWNER_IDEA", + "relation": "EXTENDS", + "quote": "МАЙНИНГ ЗАМЕЧАНИЙ (новый банк памяти считай замечаний). Просим критика выделить сцену, проблемное место, уверенность в проблемном месте, что пошло не так.", + "summary": "Форма владельца для видимости сигналов — отдельный банк замечаний со сценой, уверенностью и классом проблемы. Раздел `proposed` предложения уже этого. ПТ-41 ⭕: полигон замерил, что критик не видит удалённого абзаца, поэтому полноту должен ловить детерминированный гейт." + }, + { + "element": "E10 неологизмы и составные слова (V1-6)", + "source": "/home/ubuntu/projects/textmachine-main/START_PROMT.MD:59; реестр ПТ-5 🔶", + "kind": "OWNER_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "Но самое интересное как они переведут какое-нибудь вообще новое выдуманное или составленное слово самим автором? Или соединенное из разных других слов?", + "summary": "Прямо про гранулярность ключей (`舅父舅母` против частей, корни семей) — ось, которую эксп-25 Д1 показал недетерминированной. Журнал по Identity её не решает. В реестре ПТ-5 🔶: замер на тексте вне претрейна не сделан." + }, + { + "element": "E1 порог принятия по частоте (V1-1)", + "source": "/home/ubuntu/projects/textmachine-main/START_PROMT.MD:54; реестр ПТ-27 ✅", + "kind": "OWNER_IDEA", + "relation": "EXTENDS", + "quote": "Можем посчитать количество повторяемых слов например сколько упоминается раз то или иное имя. Могут ли нам помочь эти данные в переводе (банк памяти)?", + "summary": "Счёт упоминаний построен (майнер, ПТ-27 ✅), но в правилах принятия решений не используется. Вместе с research/17:193 это готовая мера fan-out для порога заморозки первого решения." + }, + { + "element": "E6/E3 вопросы на согласование глоссария (V0-23)", + "source": "/home/ubuntu/projects/textmachine-main/START_PROMT.MD:34; реестр ПТ-24 🔶 (модель одного ОК, D39.144)", + "kind": "OWNER_IDEA", + "relation": "EXTENDS", + "quote": "загрузил на фронт книгу, агенты поехали ее разбирать, разобрали, потом задали вопрос на согласование глоссария (если фронтом будут пользоваться проффесиональные переводчики/редактора)", + "summary": "Исходная идея владельца — вопросы профпереводчику о глоссарии. Позже он заменил её «одним ОК» (D39.144), и в реестре ПТ-24 записан этот цикл. Человеческие исходы предложения ближе к исходной V0-23, чем к ратифицированной модели; какую из двух держать, решает владелец." + } + ], + "coverage": "Отбор — по предмету: банк, память, терминолог, майнинг, консистентность, подпись, окна, род, голос, полисемия, первое решение, журнал. Счёт вхождений ключевых слов python-скриптом, затем чтение отобранных частей.\n\n(а) docs/research: в каталоге 44 .md и 2 .txt. Отобрано и прочитано 26 файлов (05, 07, 11-gap-3/4/5, 12-common-failures, 13, 14, 15, 16, 17, 18, 18-chatgpt, 19, 20, 22, 24, 26, 28, 29, 29-codex, 30, 31, 32, 33, 34).\n- Целиком или почти целиком: 34, 26, 32, 24 (504 строки).\n- Разделами: 13 (125 строк), 15 (95), 14 (50), 17 (90), 30 (200), 20 (120 + 23), 33 (50), 29 (80), 28 (25), 19 (35), 16 (17).\n- По грепу: 05, 07, 11-*, 12, 18, 18-chatgpt, 22, 29-codex, 31, 03 — 20–88 строк на файл.\nВетка полигона: все 39 research и 23 experiments сверены через cmp. Расходятся 11 файлов; во всех случаях main новее (шапки и эрраты). Отчётов 31–34 и экспериментов 24–25 на ветке нет. Уникальных отчётов на ветке — 0.\n\n(б) docs/experiments: в каталоге 26 файлов; прочитано 12 отчётов плюс README (карта в README не содержит строк 24 и 25).\n- 25: пре-рег, §8, Д1–Д3 (~170 строк + греп 114).\n- 24: шапка + греп 116.\n- 23: Д32.10, Д38.3, Д50 (~170 строк + греп 36).\n- 16, 18, 21, 22, 14b, 09: шапки и грепы.\n- 12, 13, 15: только греп.\nАрхивные отчёты банка — целиком: BANK_QUALITY_DESIGN (251 строка), POLYGON_BANK_RAWMATERIAL (217), POLYGON_BANK_PROBES (78). PROGRESS bank-law — греп, 28 хитов.\neval: README bank_autonomy, door_to_file и cold_run_b целиком; головы spread.py, dreif.py, bank.py; dovodka/requirements.md, KONSILIUM-30-08, SESSION-30-08 — греп. Контроль: 294 .py в eval; имена consistency-скриптов — 61 файл.\n\n(в) START_PROMT.MD прочитан целиком (103 строки, V0–V6). Сверено 9 идей владельца с реестром docs/product-requirements.md (45 строк ПТ): ПТ-5, 8, 9, 10, 24, 27, 29, 39, 40, 41.\n\nЖурнал решений:\n- Реестр — 314 строк; фильтром по темам банка отобрано и прочитано 159.\n- Тела 16 нот: D5, D7, D16, D21, D39.42, D39.50–52 (головы), D39.55, D39.71, D39.104, D39.144, D39.165, D39.193 п.3, D39.225 пп.3–10, D39.248 (голова), D39.249, D39.252.\n- BACKLOG: 31 ряд (5, 14, 36б, 49, 80, 124, 130, 131, 161, 224, 253, 286, 330, 406–410, 413–418, 423, 434–438, 440).\n- Также NEAR_TERM_PLAN (греп, 29 хитов), архитектурные доки 06 (целиком) и 18 (греп, 24 хита), снятый баннером пак BACKEND_WHAT_THE_BANK (строки 1–60).\n\nКод HEAD /home/ubuntu/tm-verify-1509 (381 .go-файл), точечный греп по 17 механизмам:\n- `NormalizeSourceKey`: 70 не-тестовых хитов.\n- `not-a-term|notATerm|NotATerm`: 0 (контроль — строка выше).\n- `TM-NO-DST`: 2.\n- `glossary_revisions`: 2 (INSERT и SELECT).\n- `forbidden`: 16, все про другое.\n- `ConsolidationConflicts`: 6.\n- `InjectVoice`: 7.\nПрочитаны: промпт терминолога (стр. 20–60), NoDst/isNoDst, писатель журнала ревизий (glossary.go:160–195), entitySinceCh, TermID. Git только на чтение: `git log` по файлу промпта.", + "obstacles": "1. Построчно целиком НЕ прочитаны research/28 (1670 строк), 29 (2672), 29-codex (732) и experiments/23 (8454): только грепом и названными разделами. Находка про банк в их непрочитанной части возможна.\n2. Не открывались, по отбору ключевыми словами или как не относящиеся к предмету:\n - research 01–04, 06, 08, 10, 11-gap-2, 12-* кроме common-failures, 21, 23, 25, 27, папка 31-harness-audit (файл пробы только упомянут);\n - experiments 00–08, 10, 11, 19, 20 (содержание — только через README и D-ноты).\n3. research/32 не имеет полной ревью-шапки, это долг оркестратора. research/31 и research/34 — фактура, не ратифицированы. Их гипотезы в выводах помечены как нератифицированные.\n4. Не установлено кодом:\n - покрывает ли корпусный прибор ряда 330 столкновения вариантов нормализации (ряд говорит только про полный сырой ключ);\n - сколько отказов ⟦TM-NO-DST⟧ было на прогоне A: в отчёте 24 слово declined не встречается ни разу. Есть только число прогона B: declined=0 при 66 консолидированных термах.\n5. Сырьё прогонов в books/ не открывалось (правило «книги — только улики по ссылке»). WARN о выпавших строках со второго прогона, названный рядом 130 материалом для решения, не искался.\n6. Среда:\n - обёртка grep не видит gitignored-файлы — использован `command grep`;\n - кириллические диапазоны разобраны python;\n - файл тел D-нот превысил лимит чтения и прочитан порциями.\n Состояние git не менялось, в репозитории ничего не записано; временные файлы лежат в scratchpad/prior-art-research/." + }, + "S3": { + "findings": [ + { + "element": "E1", + "source": "backend/internal/pipeline/terminologist.go:1124-1145, 1233-1250 (tm-verify-1509 @5dbb5cb)", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "dropBankSettled removes, BEFORE any money moves, the candidates the bank has already settled: the role and the classifier were being paid for surfaces whose renderings the emission then threw away.", + "summary": "A partial «не пересчитывать» is already built and on (terminology gate on in c1 and both arms). But it skips only a banknote-only candidate on a SEED surface where every draft agreed with the bank. The engine's own earlier decisions (unsigned auto-bank rows, excluded via unsignedEngineSurfaces) are never «settled», so they are asked again every run: that is root 1. The journal can be built as a wider «settled» predicate on this path instead of a new mechanism. The comment names two constraints that carry over: the filter must be unconditional, or batch composition changes on resume and gets bought again; and a narrow filter silences disputes (366 of 439 seed-surface candidates had a draft that disagreed)." + }, + { + "element": "E1, E11", + "source": "backend/internal/terminology/terminology.go:1200-1205; backend/internal/pipeline/terminologist.go:1170-1172", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "the consumer addresses batch i as ChunkIdx i (terminologist.go), which folds into the request hash, so a batch's POSITION is part of its address. If a later run's frequencies reorder the batches their ordinals shift and the affected batches re-pay", + "summary": "This is how re-deciding and re-buying actually happen. Bank-role checkpoints are keyed by batch bytes plus batch position. Batches are packed greedily and ordered by frequency, and freq and KWIC are counted over the chunks. So any purchase that changes the candidates reshuffles the batches: fresh calls, fresh decisions. The code names the unbuilt fix and leaves it to a separate decision: «a checkpoint identity that survives a change of batch composition … belongs in its own decision». The proposal does not mention this coupling. A journal only stops the re-buying if «ask only about new terms» also drives how batches are built." + }, + { + "element": "E1", + "source": "backend/docs/MONEY_HONESTY_REPORT.md:228-230 (§5.1)", + "kind": "RESEARCHED_IDEA", + "relation": "DUPLICATES", + "quote": "⇒ **ось пере-покупки — БАЙТЫ БАТЧА.** Батчи пере-собираются, когда растёт множество кандидатов, а оно растёт от каждой новой дочерновленной главы. `buildBankCandidates` не исключает уже консолидированные термы — консолидируется всё, каждый раз.", + "summary": "Root 1 is already diagnosed on the live ledger. Purchase 2 bought the whole terminologist and classifier contour again while the draft snapshot was byte-identical; purchase 3 paid $0. The jobs table shows the terminology snapshot never moved. This refuted the axis written in backlog row 194 (snapshot move), and DISCLOSURE_LAW_DESIGN A10 repeats the refutation. The report names two separate levers: A9 (which candidates go into batches, and how Batch packs them) and A2 (the budget comparison). The proposal restates the diagnosis without citing it." + }, + { + "element": "E1, Q1, Q2 (trade-off «первое решение живёт до правки»)", + "source": "backend/docs/MONEY_HONESTY_REPORT.md:265-268 (§5.3 п.2)", + "kind": "OPEN_QUESTION", + "relation": "DUPLICATES", + "quote": "терм, консолидированный по трём главам, при десяти главах может быть отрендерен лучше. Пропускать уже консолидированные термы — значит фиксировать ранний рендер. Это решение владельца, не сессии", + "summary": "The quality fork behind the proposal's trade-off «первое решение живёт до правки человеком (INVENTED 17/66)» was already put on the table as an owner decision. The code was deliberately not written for that reason. The proposal's question 2 should cite this fork next to the stops of row 130 and D39.144." + }, + { + "element": "E1", + "source": "backend/internal/store/migrate.go:218-233; backend/internal/store/glossary.go:120-122, 178-186, 271", + "kind": "BUILT_DORMANT", + "relation": "MISSED_RELEVANT", + "quote": "-- B1 editorial-time axis, ORTHOGONAL to the spoiler window (since_ch/until_ch is the STORY timeline; this is the EDITORIAL timeline). Append-only journal of approved-dst changes so a stale first-translation-wins rendering is DETECTABLE", + "summary": "An append-only journal table already exists. It is WRITTEN inside ReplaceBank on every seeding, for any row (src, sense, window) whose non-empty dst changed, auto rows included, with reason «seed-replace». Nobody reads it: GlossaryRevisionsForBook has no caller outside tests (grep: only the definition at store/glossary.go:271; control: 381 .go files scanned). It records old_dst/new_dst and a timestamp, with no evidence, outcome, run or author. The proposed .bank-journal.yaml would be a second journal next to this dormant one, so the choice is to extend it or retire it." + }, + { + "element": "E1, E2", + "source": "backend/internal/store/stopmemory.go:6-8; backend/internal/store/migrate.go:448-460; backend/internal/pipeline/mining.go:300-313", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "The set only GROWS. There is no delete on purpose: trimming it re-arms the stop on terms the owner has already been shown, which is the exact re-stop the memory exists to end.", + "summary": "A durable, never-trimmed per-book memory already exists: bank_stop_presented (v16), keyed by NormalizeSourceKey over the whole cluster. The stop compares by intersection over the cluster, so a change of representative does not trigger a new stop. It is precedent for «записано один раз», but it remembers the owner's attention, not renderings. The unified identity definition (E2) must cover this key as well." + }, + { + "element": "E1, Q2 (стоп ряда 130)", + "source": "backend/internal/pipeline/mining.go:766-775, 810-815", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "The BOUNDARY is deliberate and is the owner's STOP: this reports, it does not accumulate. Merging the old file into the new one would change what the bank CONTAINS, which moves memory_version and re-prices the edit wave — a decision, not a hygiene fix.", + "summary": "This is where the row-130 stop from Q2 lives in code. The auto-bank is rewritten whole every run from a delta capped at top-200. A diff WARN only names the terms that fell out («a term the book still uses can drop out of the bank mid-run»). Lifting the stop means changing writeAutoBank and accepting memory_version moves. Terms dropping out of the bank is one more source of drift that the proposal's three roots do not name." + }, + { + "element": "E2 (корень 2)", + "source": "backend/internal/text/norm.go:6-7, 32-36, 46-47; backend/internal/pipeline/manifest.go:282", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "free of language policy: no pair data, no book canon, no configuration … NormalizeSourceKey — zh/ja source surfaces (glossary keys/aliases AND chunk text): NFKC (…) → trad→simp (per-char, the embedded table) → katakana→hiragana fold → Unicode lower.", + "summary": "Root 2 is confirmed. There is one source normalizer for every language, embedding the zh traditional→simplified table (data/trad2simp.txt, 563 lines) and the ja kana fold, while the package header claims it holds no language policy. Its version (algorithm tag plus table hash) is folded into memory_version and into the manifest's cut inputs (manifest.go:282 Norm: text.NormVersion()). Moving the tables into language data therefore moves chapter ids, as the proposal says." + }, + { + "element": "E2, Порядок п.1 ($0-унификация тождества в storeOrder, MinedDeltaSeedCollisions, loadAutoBank)", + "source": "backend/internal/membank/memseed.go:874-877; backend/internal/pipeline/bankmaterialize.go:33-43; backend/internal/store/migrate.go:198-203", + "kind": "BUILT_ACTIVE", + "relation": "REFUTES_PART", + "quote": "Compared RAW, because the store's UNIQUE key is raw: 族長 and 族长 with one sense and window are two accepted rows, not one (migrate.go). Folding them here would skip a pair that really does coexist.", + "summary": "Step 1 is not a pure $0 fix. The store key UNIQUE(book_id, src, sense, since_ch, until_ch) is raw, and storeOrder reproduces that raw key and order byte for byte so the read-only projection equals the paid run (pinned by bankmaterialize_identity_test.go). Moving storeOrder, loadAutoBank or MinedDeltaSeedCollisions to NormalizeSourceKey without migrating that UNIQUE key (or merging traditional/simplified twins first) breaks that equality, or lets ReplaceBank crash on the insert. Any merge or drop of rows also changes bank content, which moves memory_version: units whose injection changed are re-edited through the consent gate. Only the code edit costs $0." + }, + { + "element": "E2", + "source": "backend/internal/text/enclosure.go:15-17; backend/internal/membank/decisions.go:755-763 vs 781-800; backend/internal/membank/memory.go:900-906; backend/internal/pipeline/banknote.go:486-488", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "NOT part of the normalization artifact (norm.go / NormVersion): it is applied by one consumer to one class of string (a surface a model wrote), and folding it into NormalizeSourceKey would re-verdict every match the bank ever made.", + "summary": "There are more places that define «the same term» than the four doors in step 1. TrimEnclosure is a deliberate second fold, applied only to banknote proposals. In bank-apply, findTerm matches raw TrimSpace src, while dropTerms, addReject, aliasOwner and rejectsHoldSurface use NormalizeSourceKey: decline is surface-scoped, approve is keyed on the raw tuple. The yield rule in editorLines uses a raw signedSrc, and ConsolidationKeyConflicts compares raw on purpose. One definition means listing all of these." + }, + { + "element": "E2 (ряд 330)", + "source": "backend/internal/membank/memseed.go:699-713; backend/internal/pipeline/seeding.go (S14 warn)", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "UnverifiedKeyConflicts reports every pair of bank rows that share a firing surface, render it differently and have overlapping spoiler windows, except approved×approved — that pair belongs to ApprovedSharedKeyCollisions' fail-loud", + "summary": "«Two laws on one word» is already caught at load, on the matcher's identity (entryFiringKeys → NormalizeSourceKey). It is a WARN when at least one row is unsigned, and a fail-loud error when both are approved (ApprovedSharedKeyCollisions). InjectivityCollisions warns on two sources sharing one dst. After step 1 these detectors are a ready $0 check: the WARN count on the A/B banks should drop to zero." + }, + { + "element": "E2", + "source": "backend/internal/lang/bankdata.go:14-24; backend/docs/CHAPTER_STRUCTURE_DESIGN.md:436-437, 484", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "WHY A PLANE OF ITS OWN, and why it is NOT in data/ beside script-series.txt. Both existing data planes fold into the WAVE snapshot: the embedded one through EmbeddedVersion, the pack one through Pack.Version().", + "summary": "The engine already has three language-data planes, each with its own version and money axis. Embedded data goes into EmbeddedVersion, which is inside the manifest cut. The pair pack goes into Pack.Version(). Bank-assembly data goes into BankDataVersion, which is not snapshot-folded and is keyed by SCRIPT. The chapter-structure design sorts every data file onto an axis (провод · вердикт · банк · крой) and plans to split the planes inside the re-cut window. The proposal's `configs/langpacks//identity.txt`, with its own hash in memory_version, is a fourth plane. It belongs in that taxonomy: identity is wire plus cut, like NormVersion." + }, + { + "element": "E2 (хеш таблицы в memory_version)", + "source": "backend/docs/D15.2-content-addressed-resume-spec.md:277, 289-290 (§6)", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "значит `memory_version` можно убрать из ключа вызова целиком. … ⚠ **`memoryNormVersion` двусторонний:** SOURCE-нормализация ключей матчера — wire (→ `memoryInjectVersion` → `content_hash`), но post-check ищет dst-формы в ВЫВОДЕ по TARGET-нормализации", + "summary": "The content-addressed resume spec plans to split memory_version into an inject part (wire → content_hash) and a postcheck part (verdict), and to drop memory_version from the call key entirely. CHAPTER_STRUCTURE_DESIGN §2.3 treats that bump as already ordered. The proposal puts the identity-table hash «в memory_version», a field this spec dissolves. The source-identity hash belongs on the inject (source) side." + }, + { + "element": "E2, E10 (пара, которой ещё нет)", + "source": "backend/docs/SEAM_PACK_FINDINGS.md:178-187; backend/internal/membank/memseed.go:378-431", + "kind": "BUILT_DORMANT", + "relation": "MISSED_RELEVANT", + "quote": "**`rubyToCandidates` мёртв в проде — пере-проверено 02.09.** `grep -rn \"rubyToCandidates\" --include=*.go .` → 4 хита: определение, два комментария и ЕДИНСТВЕННЫЙ вызов — из теста", + "summary": "The ja nomination channel is built but disconnected: ruby readings become auto candidates with a name/gloss/ambiguous class and since_ch = first chapter. Re-checked: 0 non-test callers (control: defined at memseed.go:386). Only AttachRubyAliasesToManual runs, which adds kana aliases to seed terms and skips contested homophones. It is relevant to identity and nomination for a non-zh source." + }, + { + "element": "E3 (исход «не решено»)", + "source": "backend/internal/terminology/terminology.go:690-694, 1178-1189; backend/prompts/zh-ru/terminologist.md:≈36-37", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "NoDst is the engine sentinel the terminologist returns for a term it cannot render confidently. A bracketed engine token (the ⟦TM-BANK-v1⟧/⟦TM-NOCHANGE⟧ idiom) rather than a natural-language phrase", + "summary": "One honest outcome is already built as a sentinel. ⟦TM-NO-DST⟧ is parsed tolerantly (isNoDst) and counted as Declined, separately from Unanswered and from a budget cut (bankexport Consolidation reports these separately). The zh-ru prompt tells the model to use it: «это нормальный ответ: непереведённый термин останется на ручную подпись». The proposal's new sentinels (не термин, многозначный) fit the same pattern: token in Go, wording in the pair prompt." + }, + { + "element": "E3 (корень 3: «не могу решить» → догадка черновика законом)", + "source": "backend/internal/miner/miner_emit.go:224-227 vs 261-269; backend/internal/membank/memory.go:326-331, 762-768; backend/internal/pipeline/terminologist.go:33-35", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "Every term stays status:auto — that is the load-bearing line. Attaching a dst delivers EVIDENCE, not trust: an auto term is outside the CONFIRMED-only injection (D39.2 trust gate), so nothing the model proposed reaches the book until the owner signs it.", + "summary": "The code confirms root 3, and the guarantee it describes is stale. DeltaFile attaches the top DIRECT banknote proposal as dst to a status:auto row even when the terminologist declined. MaterializeBank makes every row with a dst matchable. RenderGlossaryBlock and editorLines have «no fork by status at all (D39.104 п.2)». So a declined term reaches the editor's law block carrying a draft's guess. This comment and terminologist.go:33-35 («A term it declines emits `auto`, inert») are false today. The fix for E3 includes not attaching a banknote dst to declined or undecided outcomes, and correcting both comments." + }, + { + "element": "E3 (исход «не термин»)", + "source": "backend/internal/membank/decisions.go:33-36; backend/internal/pipeline/mining.go:679-681, 949-951; backend/internal/miner/miner_emit.go:182-190", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "TWO VERBS AND NO THIRD. `approve` promotes a term into the mined delta with an explicit `status: approved`; `decline` puts its surface on the reject list so the bank-mining stop stops re-proposing it.", + "summary": "The OWNER can already record a visible, reversible «не термин». mined_rejects filters the miner's emission (the whole cluster), the auto-bank on load and the delta; approving the term removes the reject (dropReject). The proposal adds a `not-a-term` outcome for the engine but does not say how it relates to this list. Otherwise there will be two «не термин» registries with different identity scopes: the reject list keys on the normalized surface, the journal on Identity plus sense plus window." + }, + { + "element": "E3 (многозначный), Б (полисемия — человеку)", + "source": "backend/internal/membank/memseed.go:229-232", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "the deterministic matcher keys only on src and cannot pick a sense, so both inject as authoritative and the post-check is guaranteed to miss one (give them non-overlapping windows, merge the senses into one rendering, or drop one; a status will not separate them", + "summary": "The bank cannot hold two senses of one firing surface with overlapping windows: the load fails (D16.1), and the alias variants are caught by ApprovedSharedKeyCollisions and UnverifiedKeyConflicts. `sense` is in the schema and in TermID, but the matcher never uses it. A «многозначный» outcome can only be resolved by a person choosing one rendering or separate windows, which matches the proposal." + }, + { + "element": "E4 (род производит классификатор; hidden только человек)", + "source": "backend/internal/terminology/classify.go:40-51; backend/prompts/zh-ru/classifier.md:8-10; backend/internal/membank/decisions.go:84-88", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "⚠ `hidden` (пол скрыт до раскрытия) в словарь НЕ входит намеренно — это решение о сюжете и о спойлерной политике книги, а не наблюдение по контекстам; оно остаётся ручным, в сиде.", + "summary": "Already built (row 210): the §2 classifier's third column produces gender (male|female|neuter|none). It runs only when classify_types is on (true in c1 and both arms, absent in c2). The value is stamped on auto rows. bank-apply carries it forward on promotion but never ACCEPTS it («correcting one stays a seed edit»). The proposal's «род производит классификатор», «скрытый пол — только человек» and «hidden от классификатора снят» all repeat built behaviour." + }, + { + "element": "E4, E8 (преемник: until=N−1 / since=N)", + "source": "backend/internal/store/migrate.go:198-203; backend/internal/membank/memseed.go:209-219", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "A term whose approved rendering changes across a spoiler boundary is two rows with different windows (legitimately distinct), not a collision.", + "summary": "The data model for a successor already exists. The window is part of the UNIQUE key, the seed loader rejects only OVERLAPPING windows with different dst, and spoilerBlocked selects by chapter. For a seed term the owner can already write a successor by hand in glossary_seed (this moves the base snapshot, so drafts are paid again). What is missing is the write path (the bank-apply door and the engine's own writes), not the model." + }, + { + "element": "E4 (глагол succeed, Порядок п.4)", + "source": "backend/internal/membank/decisions.go:90-92", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "⚠ ONE NARROWNESS OF v1, named rather than hidden: a term's chapter WINDOW cannot be corrected in one decision. Approving the new tuple adds a second row and leaves the old one standing, and declining removes every window of the surface. Widening or moving a window is a two-call operation for now.", + "summary": "The code itself names the gap that the proposal's `succeed` verb fills. Caution: the «two-call operation» claim looks unreachable. decline is surface-scoped (dropTerms removes every row whose normalized surface matches, decisions.go:781-800), and a new overlapping tuple with a different dst is refused as term-window-overlap. So there seems to be no two-call path to move a window today. This needs an adversarial check before anyone relies on it." + }, + { + "element": "Q4, E8 (правка перекрывает сид только для редактора)", + "source": "backend/internal/membank/decisions.go:51-57; backend/internal/pipeline/bankmaterialize.go:313-333", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "it reaches the EDITOR and does not re-form the draft. Making the draft itself carry a corrected term means moving glossary_seed, which shifts the base snapshot and re-pays the whole draft wave; that is a different door and it is not designed yet (backlog row 192).", + "summary": "Option 1 of Q4 is already the depth of EVERY owner decision. mined-delta rows are Source:\"mined\" and excluded from the base bank the drafts select over, and the bank-apply report publishes `depth: edit_wave`. Option 2 (paying for drafts again) is backlog row 192, not designed. Q4 can be put as: keep the existing depth, or open row 192." + }, + { + "element": "E4 (смена по ходу книги — голос/обращение)", + "source": "backend/internal/pipeline/bankmaterialize.go:295-298; backend/internal/seed/seed.go:44-47; backend/internal/membank/memory.go:374-376", + "kind": "BUILT_DORMANT", + "relation": "MISSED_RELEVANT", + "quote": "InjectVoice is FALSE and has no config knob: pack-19 builds the schema and the flagger, and D21 п.2 holds the injection conditional until the polygon experiment.", + "summary": "A character's voice profile and the ты/вы address pairs are windowed on the same chapter axis («a register change is a new row with a non-overlapping window … the switch is a story event»), so succession of register and self-reference is already modelled. Their injection is compiled off (InjectVoice is false with no config key). The voice flagger key `gates.voice` is absent in all 4 configs (0 of 4, so off; control: gates: = 1 in each). Bank.Voices()/Pairs() have no caller. The proposal's E4 covers only the rendering and gender." + }, + { + "element": "E4 (TermID без окна, минор контракта — Порядок п.4)", + "source": "backend/docs/CHAPTER_STRUCTURE_DESIGN.md:679-693 (§4.2 п.3); backend/internal/membank/decisions.go:155-173, 321-325", + "kind": "RESEARCHED_IDEA", + "relation": "CONTRADICTS", + "quote": "новый `id` при неизменном `(src, sense, since, until)` бьётся о `bank_terms_key` на ещё живой старой строке, `on conflict (id)` этого не ловит, транзакция откатывается — и так на КАЖДОМ следующем экспорте.", + "summary": "Step 4 («TermID = hash(Identity, sense)+revision, без окна») re-mints every exported id. The chapter-structure design found in its third rebuttal round that the platform upserts bank rows by id, keeps a second unique key on (book, src, sense, since, until), and writes before deleting. So any re-minted id breaks every following bank-export ingest. Its decision was «не двигать id». bank-apply also resolves decision ids from store rows. The contract says «the id is derived from the chapter window». Step 4 needs a coordinated platform migration, not a «contract minor»." + }, + { + "element": "E4, E7 (since = первое появление; окна преемника)", + "source": "backend/docs/CHAPTER_STRUCTURE_DESIGN.md:601-618, 651-663 (§4.1)", + "kind": "RESEARCHED_IDEA", + "relation": "EXTENDS", + "quote": "Все ненулевые окна — это `since_ch`, и все они означают ОДНО: главу первого появления термина. … **Сегодня авторских окон в дереве НОЛЬ**", + "summary": "Measured: 3 non-zero windows in the live seed and 14 in the mined auto-bank, all of them since_ch = first appearance; until_ch is zero everywhere. The design separates DERIVED windows (re-derived on a re-cut) from AUTHORED ones (moved by the shift map; if the chapter is `gone`, the window degrades to open, loudly). It names `.mined-delta.yaml` as a durable carrier of ordinal windows written by bank-apply. Successor windows from an owner event would be the first authored windows and fall under that migration rule." + }, + { + "element": "E4, E9 (черновики ≥N со старым именем)", + "source": "backend/internal/membank/mempostcheck.go:284-301; backend/internal/pipeline/voicerun.go:57-65", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "SpoilerLeaks checks the chunk's REJECTED records against the model output: the row's key fired here, the window said the chapter must not know this rendering yet, and the rendering is in the output all the same.", + "summary": "An always-on $0 check with no gate (n_spoiler_leaks, visible in the quality report). Once a successor closes the old row with until_ch=N−1, any chapter ≥N whose shipped text still carries the old rendering on a fired key is reported as a leak. That is a ready detector for «черновики ≥N со старым именем», so that half of the successor needs no new check." + }, + { + "element": "E5 (отпечаток улик)", + "source": "backend/internal/terminology/terminology.go:771-799; backend/internal/lang/langpack.go:92-95, 297; backend/internal/pipeline/terminologist.go:645-648", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "fmt.Fprintf(&b, \"key: %s\\ntype: %s\\norigin: %s\\nfreq: %d\\nsince_ch: %d\\n\", c.Key, typeOr(c.Type), c.Origin, c.Freq, c.SinceCh)", + "summary": "The evidence is already a structured, deterministic block per candidate: key, type, origin, freq, since_ch, aliases, related, evidence, drafts (with chunk counts and Via), and ctx KWIC. KWIC size comes from the pair's terminology.txt, or 3×40 by default. Each batch also carries a ⟦TM-CANON⟧ anchor of at most 40 signed rows. An «отпечаток улик» can simply be the hash of this block. But freq and since_ch are on the wire, so the fingerprint changes on every purchase or re-cut unless those fields are excluded." + }, + { + "element": "E5 (улики только из переведённой части)", + "source": "backend/internal/pipeline/waverun.go:144, 179, 238, 288; backend/internal/pipeline/bookrun.go:182; backend/internal/pipeline/mining.go:22-25, 80-83", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "the miner scores WHICH-candidates over the draft wave source (the detector is offline — it reads the SOURCE, not the drafts; drafts only mark that a chapter was reached)", + "summary": "Today runBankMiningStop(ctx, chunks, …) gets the chunks of the WHOLE ingested book (SplitChunksWithChapters over every chapter). The volume scope filters only the waves: scope.allows is called at 3 places (waverun.go:144/238/288), none of them in mining.go. So the miner's candidates, freq, KWIC contexts and since_ch come from chapters not yet bought or translated. The proposal's «улики — только из переведённой части» is a behaviour change: it would also change batch bytes and spoiler exposure. Not checked: whether the platform gives the engine a truncated source." + }, + { + "element": "E5, E1 («спрашивать только про новые термины»)", + "source": "backend/internal/lang/bankdata/family-morphology.txt:2-4; backend/internal/terminology/series.go:8-13; backend/internal/terminology/terminology.go:841-856 (CanonFor)", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "Measured: the same model rendered the 古月-family one way in batch 0 and another way in batch 2 — a chimera that correlates with the batch boundary perfectly, on a family DetectSeries cannot co-batch", + "summary": "Consistency between related terms is kept by putting a series (甲等/乙等) or a family (shared root, one term contained in another) into a single call; the rules are script data. A journal that asks only about NEW terms would split a family across time: old members fixed, a new member asked alone, which is the same chimera. The rule needs to work per unit: either ask the whole unit again, or pass the decided members as an anchor. CanonFor already picks related rows by containment and shared runes, but only signed ones." + }, + { + "element": "E3, E6 (сортировка/пороги уверенности)", + "source": "backend/internal/terminology/terminology.go:1156-1159", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "it orders the review list «least sure first» — an ordinal INSIDE one model's reply — and nothing more. It is not a weight, not a threshold, not comparable between models, and never decides which rendering wins", + "summary": "The ban on using confidence as a threshold, as recorded in code under D39.102, forbids deriving `undecided` or `not-a-term` from low confidence. They must come from explicit sentinels, which fits the proposal. Confidence already orders the stop table and the `proposed` section (−1 when the reply carried none)." + }, + { + "element": "E3, E5 (сняты: N=2-согласие)", + "source": "backend/internal/terminology/terminology.go:430-438; backend/prompts/zh-ru/terminologist.md:≈22-24", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "Plain majority is explicitly not the rule (§C2-3: «побеждает вариант, а НЕ первое вхождение»; D39.42: «формула §C2 п.3, не мажоритарность») — frequency is one factor among four.", + "summary": "Majority is already rejected in both code and prompt. Frequency is bounded to 2× and can be outweighed by transliteration conformance and agreement with signed siblings. The prompt says «варианты черновиков — это свидетельства, а не голосование». Dropping «N=2-согласие» as a mechanism is consistent with this built line." + }, + { + "element": "E6 (платформа читает раздел предложений)", + "source": "backend/internal/pipeline/bankexport.go:51-64, 108-120; backend/cmd/tmctl/invocation.go:141", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "Proposed is what a signature STOP is putting in front of the owner: rows this run mined and consolidated that are NOT in the bank yet. … Empty at every boundary that is not a stop.", + "summary": "The `proposed` section of the bank export exists (src, dst, kind, channel, freq, spread, conventions, conf, invented, contradicts, bank_holds, variants), next to `consolidation` completeness. But it is filled only at a --verify-bank stop, and the flag defaults to false. On the default auto-continue path the rows go straight into `terms` as auto. Signals like «N глав до закона», or an engine `not-a-term` placed in `proposed`, would be invisible on the default path unless the section is published at every boundary." + }, + { + "element": "E6 (читатель платформы `proposed`)", + "source": "platform/internal/ingest/bank.go:61-73, 104-113 (tm-verify-1509); backend/docs/DISCLOSURE_LAW_DESIGN.md:90", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "func termStatus(engine string) (string, bool) {\n\tswitch engine {\n\tcase \"auto\":\n\t\treturn TermProposed, true", + "summary": "The platform decodes only bank_version, book_id and terms from the bank export; its wireBank struct has no proposed or consolidation field. So a platform reader of the engine's `proposed` section really is unbuilt. The contract word «proposed» already names unsigned auto rows inside `terms` (draft maps to in_progress). The proposal's «not-a-term виден в proposed» is ambiguous against that word. DISCLOSURE_LAW_DESIGN §3.1 also finds unsigned_bank_terms decoded but with no production reader." + }, + { + "element": "E6 (споры черновиков с законом)", + "source": "backend/internal/pipeline/mining.go:398-401, 540-561; backend/internal/pipeline/terminologist.go:558-600", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "Contradicts names THIS RUN's other consolidations the rendering breaks (§G2). BankHolds names rows the bank ALREADY carries for the same firing surface with a different rendering.", + "summary": "Dispute signals are already computed at $0 on every consolidation. They are: CanonConflicts (against signed rows), ConsolidationConflicts (inside one run; 18 of 149 on a live bank), ConsolidationKeyConflicts (against any bank row), INVENTED, spread/conventions and NOT ASKED. They go to the stop table sidecar, the `proposed` section and WARN logs. What is not built is keeping them across runs and a platform reader." + }, + { + "element": "E9 (консистентность по отгруженному тексту)", + "source": "backend/internal/pipeline/bookconsistency.go:11-26; backend/internal/pipeline/quality.go:256-271, 437; backend/internal/membank/memconsistency.go:28-35", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "the book-wide consistency answer (backlog row 406) — the first measure in this engine that asks the owner's priority-#1 question of the text a READER actually gets.", + "summary": "Consistency over the shipped text is built. `tmctl report` always computes it when a bank exists: per-term fired and shipped counts over the whole book in manifest order, absent/split verdicts with chapter lists, three matching columns, MaskCandidates (the report's own bias), SuppressedSilent (row 407) and a NeverFired control. So the E9 measurement is an existing report, not new construction. Its limit: it cannot name the competing rendering («Closing that needs the variants channel»)." + }, + { + "element": "E9 (принуждение закона: пост-чек-гейт)", + "source": "backend/internal/config/pipeline.go:481-491; backend/internal/pipeline/waverun.go:617-624, 750-756; backend/configs/pipeline-{c1,c2,arm-glm,arm-mistral}.yaml", + "kind": "BUILT_DORMANT", + "relation": "MISSED_RELEVANT", + "quote": "PostcheckGate promotes a miss from a mere record to a DISPOSITION flag (the chunk is flagged, downstream stages skip): opt-in (default false = flagger), flipped on only AFTER the owner validates the false-flag rate on real chapters (E1)", + "summary": "Enforcement by flag is built: gates.glossary.postcheck_gate flags glossary_miss and withholds the text from export. The key is absent from all four shipping configs (glossary: = 0 and postcheck_gate = 0 in each; control: gates: = 1 in each), so it is OFF. It counts only Confirmed misses, i.e. approved rows fired on a trusted key. On the default unsigned auto-bank it could not fire: the 11.09 run reported 0 misses beside 18 deviations (bookconsistency.go:36-42). Turning it on moves the snapshot (snapshot.go:431, 480) and first needs the false-flag measurement." + }, + { + "element": "E9 (регенерация по промаху закона)", + "source": "backend/internal/membank/mempostcheck.go:28-30; backend/internal/pipeline/stagerun.go:215-217; backend/internal/checks/repair.go:40-46", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "It is a post-CHECK, never a blind post-REPLACE (E2): forcing a dictionary form into an oblique Russian case breaks agreement (46% of constrained-model errors in en-cs are agreement, 2106.12398), so v1 only FLAGS.", + "summary": "There is no regenerate or escalate path for a glossary miss. regenerate_before_escalate covers only retryable flags raised inside the stage loop. The glossary gate is evaluated after the stage sequence (waverun.go:617, 752) and can only flag and withhold. gates.repair has no glossary class (only dc1_time_units, dc1_fractional, latin_residue, broken_word) and is absent from all four configs. Regenerating on a missed law would be new construction, and the ban on blind post-replace is a recorded design rule." + }, + { + "element": "E9, E3 (статусы исходов vs подпись банка целиком)", + "source": "backend/internal/pipeline/bookconsistency.go:36-42", + "kind": "OPEN_QUESTION", + "relation": "MISSED_RELEVANT", + "quote": "⚠ THE ENGINE DOES NOT AGREE WITH THAT MODEL, and the disagreement is worth more than this file: glossary rows carry a per-term machine `auto|draft|approved` (store/migrate.go:192), dispositionFor promotes only `approved` to Confirmed", + "summary": "The code records a mismatch that nobody has ordered fixed: the product signs the bank as a whole (D39.144), while the engine trusts row by row and the post-check counts only Confirmed misses («Not this pack's to change — it needs its own order»). The proposal's outcomes (закон / не термин / многозначный / не решено) are a new per-term state machine. It should say how they relate to auto|draft|approved and to the Confirmed-only post-check, or it inherits this mismatch." + }, + { + "element": "E9, Б (снят «детектор местоимений в ядре»)", + "source": "backend/internal/pipeline/waverun.go:712-716; backend/internal/membank/memory.go:123-126", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "sticky_prev is nil, and that is a LOSS, not a degenerate case: assignEditUnits closes a unit INSIDE a chapter … while the sticky window resets only at a CHAPTER boundary …, so every unit after the first in a chapter is selected with no memory of the rows its predecessors carried.", + "summary": "A mechanism for pronoun-only chunks without coreference is already built: scene inertia carries recent matches forward (StickyDepth=2, reset per chapter, disposition inherited). It works in the draft wave. The editor wave loses it for multi-unit chapters (1962 of 2283 on the stand book, row 321; drift not measured). The proposal drops the pronoun detector as needing coreference but does not name this mechanism or its hole on the editor side." + }, + { + "element": "E9, E2 (закон вложенного термина съедается)", + "source": "backend/internal/pipeline/bookconsistency.go:117-122; backend/internal/membank/memory.go:1098-1111", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "It counts rows whose key fired but was eaten by a longer key of equal-or-higher trust AND whose own rendering did not reach the shipped text. The bank suppresses the shorter match on purpose and says nothing about it", + "summary": "Which term fires is also decided by containment. A nested term (古月 inside 古月方源) is suppressed by the longer key when the longer key's trust is equal or higher, so its law is neither injected nor post-checked there (row 407, second root). A lower-trust longer key is refused as a suppressor (TrustGateEvent). Changing outcomes or statuses (E3) changes trustRank, and with it which laws get eaten." + }, + { + "element": "E9 ($0-сверка «черновики против закона» тем же паком)", + "source": "backend/internal/membank/memconsistency.go:21-26, 119-147; backend/internal/lang/data/target-ru.txt:187-193", + "kind": "BUILT_ACTIVE", + "relation": "BETTER_ALTERNATIVE", + "quote": "It reuses the bank's own machinery rather than standing a second matcher beside it — the source side runs the SAME automaton and the SAME two suppressions Select runs (a private matcher of our own would re-earn their bugs", + "summary": "The proposed $0 drafts-against-law check can reuse what exists. ScanShipping(source, text, chapter) already counts, per row, how often the key fired and how often the rendering came out. It stems with target data (decl_suffix, 40 rows in target-ru.txt) and guards sentence boundaries. Running it over drafts instead of shipped text is a new call site, not a second matcher." + }, + { + "element": "E10 (номинация: типы, срезы)", + "source": "backend/internal/miner/miner_emit.go:126-130, 343-356; backend/internal/pipeline/mining.go:583-629", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "// emissionEligible applies the build_precision30 filters: type ∈ {name,place,title}, freq ≥ 5, src not subsumed, len ≥ 2 rune, not a boundary fragment.", + "summary": "The nomination limits are Go constants. The miner emits only name/place/title with freq ≥ 5 and at least 2 runes, after a top-200 cap applied BEFORE the filters, so seed and declined terms use up slots. Common nouns (`term`) reach the bank only through the banknote reverse section, which runs only with the terminology gate on and has the same 200 cap. The E10 levers are already in these few places, as commit 6dd26f6 describes." + }, + { + "element": "E10 (однорунные термины)", + "source": "backend/internal/membank/memory.go:63-74, 164-168; backend/internal/membank/mempostcheck.go:163-168", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "allowShort is the author's explicit override of the single-key ban AND the collision-prone disposition downgrade (full trust in a short key).", + "summary": "A one-rune term (蛊 → гу) can enter the bank today only by hand: `allow_short: true` in the seed lets a key below the minimum fire, and the post-check demotes a confirmed miss on a single-Han key to Unverified. The miner never emits one-rune terms and no engine outcome can set allow_short. E10 should name this existing switch." + }, + { + "element": "E10 (номинация черновиками)", + "source": "backend/prompts/zh-ru/translator-banknote.md:17-25; backend/internal/pipeline/banknote.go:236-256", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "Тип — одно из: name, place, title, term, nickname.\nНе более 20 строк.", + "summary": "The draft channel nominates common nouns and nicknames too: at most 20 per chunk, only terms missing from the injected glossary, and only if the surface occurs in the book source (bankSrcAttested). This is the only automatic path for `term`/`nickname`. So E10 has two levers: miner eligibility (Go constants) and this pair prompt (data)." + }, + { + "element": "E11 (деньги банк-ролей)", + "source": "backend/internal/pipeline/terminologist.go:947-1004, 486-501; backend/configs/pipeline-c1.yaml:173-175", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "⛔ THE PLAN IS CUT TO WHAT FITS **BEFORE THE FIRST CALL**, not discovered halfway through it.", + "summary": "Money controls for the bank roles exist. Each role has a book-wide budget accumulated across every purchase (budget_usd 1.00 and classify_budget_usd 1.00 in c1 and the arms; MONEY_HONESTY §5.2). The estimate is logged before any call, batches are admitted one by one, already-paid batches are free, and BatchesDropped is published. With re-deciding on every purchase, repeats eat the lifetime budget. The proposal's «одна перекупка банковых вызовов на книгу» already has a warning carrier, logKeyReconsolidated, for a one-time change in batch composition." + }, + { + "element": "E11, Порядок п.2 (окно перенарезки)", + "source": "backend/docs/CHAPTER_STRUCTURE_DESIGN.md:256-258, 300-303 (§2.2-бис)", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "⇒ **чистая перенумерация меняет пользовательское сообщение КАЖДОГО банк-батча ⇒ банк-проход покупается заново.** Цена замерена проектом и лежит в коде: банк-роли — **$0.04980482 из $0.43610966, 11.4 % холодного прогона**", + "summary": "The re-cut design, the same window step 2 of the proposal joins, has already shown that since_ch rides the bank-role wire (terminology.go:775) and that bank batches are bought again on a re-cut. The share of that price caused by since_ch alone lies between zero and the whole pass. That number is unmeasured and was sent to the backlog as a measurement. A journal that stores `since` and an evidence fingerprint must decide whether since_ch stays in the candidate block." + }, + { + "element": "E11, корень 1 («на каждой покупке»)", + "source": "backend/internal/pipeline/volume.go:351", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "a VOLUME ceiling on a book that MINES its bank: each purchase drafts more, so the bank-mining stop writes a larger auto-bank, and the next purchase moves the edit-wave snapshot the previous purchase's edit jobs are pinned to.", + "summary": "The engine already warns that the bank grows with each purchase, moving the edit-wave snapshot, so touched units need a re-snapshot and re-payment (bounded by consent). The money side of root 1 at purchase level is known and reported at runtime. A journal reduces it only if the auto-bank stops being re-derived on every purchase." + }, + { + "element": "E7, Q3 (закон задним числом: смета и переделка)", + "source": "backend/internal/pipeline/repin.go:28-35; backend/internal/pipeline/rebill.go:40-50", + "kind": "BUILT_ACTIVE", + "relation": "DUPLICATES", + "quote": "bank-only snapshot move + unchanged content hash ⇒ the request this run would issue is byte-identical to the one already paid for … the unit is RE-PINNED for $0 instead of re-bought. A unit whose injected bytes DID change is the one where the term actually occurs — and that one is re-translated", + "summary": "An automatic path for applying a law to finished chapters already exists. When only the bank changed, just the units whose editor injection changed are edited again (edit wave only, drafts untouched). projectRebill prices this with the same predicate, and the consent gate applies above min($0.50, 5% of the projected book) (`--accept-rebill[=usd]`, or rebill_consent_usd in book.yaml). So Q3's «смета+по заказу против автоматически» is today «automatic under the threshold, consent above». Missing: drafts where the key fired before `since` (not a bank-only move), and a per-term «N глав до закона» number." + }, + { + "element": "E8, E6 (событие владельца во время прогона)", + "source": "backend/docs/SEAM_PACK_FINDINGS.md:130, 195-196", + "kind": "RESEARCHED_IDEA", + "relation": "MISSED_RELEVANT", + "quote": "4. **Проекция берёт тот же лок**, что и применение ⇒ «поправить термин при живом прогоне» даёт 12 даже на ПРЕВЬЮ, на всю длину прогона. Платформенный пак обязан это спроектировать, а не обнаружить.", + "summary": "While a run holds the project lock, an owner event (a name change from chapter N, a successor) cannot be applied or even previewed: it gets exit class 12. The same report notes the platform has 0 callers of bank-apply (line 130). The proposal's precedence rule («событие владельца > закон движка») and the `succeed` verb inherit this lock behaviour." + }, + { + "element": "E6, Порядок п.2 (что входит в окно перенарезки)", + "source": "backend/internal/lang/data/injection.txt:6; backend/internal/lang/embedded.go:389-395; backend/docs/CHAPTER_STRUCTURE_DESIGN.md:812 (§5.1 п.7, ряд 320б)", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "ru\tglossary_header\tГЛОССАРИЙ (используй эти утверждённые переводы имён и терминов последовательно; строки с пометкой ⟨проверить⟩ — неподтверждённые кандидаты):", + "summary": "The live draft header still tells the translator that ⟨проверить⟩ marks unconfirmed candidates, but that marker has left the wire (D39.104 п.2). embedded.go explains the retired rows stay because injection.txt is folded into EmbeddedVersion and therefore into unit ids («Both leave together at the next touch of the embedded plane, in a window that already re-cuts»). The design puts the injection.txt edit (row 320б) into the re-cut window, the same window as the proposal's step 2, next to rows 131 and 14. Worth bundling." + }, + { + "element": "E6, E9 (дошёл ли закон до промта редактора)", + "source": "backend/internal/store/migrate.go:464-474; backend/internal/pipeline/waveselection.go:24-45", + "kind": "BUILT_ACTIVE", + "relation": "MISSED_RELEVANT", + "quote": "v17 (row 417): WHAT EACH WAVE WAS SHOWN — the axis retrieval_state does not have.", + "summary": "A per-wave record of which source surfaces were injected and which were evicted, for draft and edit separately, already exists and is recomputed at $0 every run. It answers «did the law reach the editor's prompt for unit X». It is a base for «N глав до закона» and for telling a term evicted by glossary_token_budget (800 in every config) from one the model ignored." + }, + { + "element": "E2 (канал данных исходного языка identity.txt)", + "source": "backend/internal/lang/langpack.go:212-218, 297", + "kind": "BUILT_ACTIVE", + "relation": "EXTENDS", + "quote": "\"surnames-single.txt\", \"surnames-compound.txt\", \"title-suffix.txt\", \"ordinal-title.txt\",\n\t\"rank-word.txt\", \"topo-suffix.txt\", \"grade-prefix.txt\", \"numeral.txt\", \"alias-particle.txt\",\n\t\"title-formant.txt\", \"sentence-terminator.txt\",", + "summary": "Source-language bank data already lives in configs/langpacks/zh/: 11 miner pattern files (surnames, title suffixes, alias particles…). Pair data lives in zh-ru/: the Palladius conformance tables that feed §C2-3 ranking, plus the optional terminology.txt. The proposal's configs/langpacks//identity.txt fits this directory convention. But this pack folds into Pack.Version() (the wave snapshot), which is why the proposal wants its own hash; that has to be squared with the data-plane taxonomy." + } + ], + "coverage": "Subject: the code on HEAD /home/ubuntu/tm-verify-1509 at 5dbb5cb. main HEAD 9241934 is 3 commits ahead, and git log --stat shows only docs changed in them, so backend and platform are identical to main. The uncommitted backend changes in the main worktree were not reviewed.\n(a) Code. Non-test .go files in backend/internal and backend/cmd: 143 (control count). About 40 bank identifiers were grepped across all 143 with hit counts: postcheck, sticky, InjectVoice, arbitrat, cluster, consolidat, collision, reject, wave_selection, retrieval_state, bankapply, hidden, gender, alias, window, sense, since/until, auto-bank, succeed, NormalizeSourceKey, NormVersion, memory_version, proposed.\nRead in full (19 files): membank/{memory, memseed, decisions, mempostcheck, memconsistency}.go, pipeline/{bankmaterialize, mining, terminologist, bankexport, bookconsistency, quality, seeding, voicerun}.go, terminology/terminology.go, miner/miner_emit.go, seed/seed.go, lang/bankdata.go, store/stopmemory.go, cmd/tmctl/bankapply.go.\nRead partly (about 18 files): config/pipeline.go:280-519, stagerun.go:100-275, waverun.go:100-190 and 580-790, banknote.go:120-540, text/norm.go, text/enclosure.go, series.go, classify.go, driftbasis.go, memvoice.go, checks/voice.go, repin.go, rebill.go, bankdecisions.go, store/glossary.go:120-215, migrate.go:170-262 and 436-505, bookrun.go:165-250, embedded.go:380-402.\nPipeline configs: all 4 pipeline-*.yaml read in full (504 lines), plus a mechanical key count per file (gates / banknote / terminology / glossary / postcheck_gate / voice / repair / classify_types / contrast_path).\n(b) backend/docs (12 documents). CHAPTER_STRUCTURE_DESIGN: grep (306 hits) plus §0, §2.2-бис and §4 read. DISCLOSURE_LAW_DESIGN: grep plus §3.1 and A10. MONEY_HONESTY_REPORT: §5 read (39 hits). SEAM_PACK_FINDINGS: lines 125-200 read (98 hits). MONEYSTOP_REPORT: grep (38 hits). D15.2 spec: grep (14 hits). The remaining 6 were counted only (1–6 hits each).\n(c) Prompts: read 4 of the 7 zh-ru prompts in full (terminologist, classifier, translator-banknote, editor). Not read: translator, editor-mono, judge-selector.\nLangpacks and language data: 16 langpack files listed. Read in full: zh/alias-particle, zh/title-suffix, lang/bankdata/family-morphology, script-series, injection.txt. From target-ru.txt only the decl_suffix section.\nPlatform: 88 non-test .go files grepped for verify-bank, proposed, bank_export and unsigned_bank_terms; ingest/bank.go read (lines 1-140).\nSelection criterion: the elements of E1–E11 and the lens list from the brief. Output: 50 findings.", + "obstacles": "1. Decision-log notes were NOT checked. D-numbers (D39.104, D39.144, D39.102, D21 п.2, D39.42) are quoted only as the code comments cite them, so ratification status and superseded banners were not verified; that belongs to the other checkers.\n2. mining-contrast.zh.txt is missing from backend/configs in the verify tree (ls: No such file). Config load refuses the bank contour without it, so nothing could be checked by running it.\n3. Not checked: whether the platform hands the engine a source truncated to the ordered chapters. The finding «майнер читает всю книгу» is about the engine's own path only.\n4. The claim in decisions.go:90-92 that a window can be moved in «two calls» looks unreachable to me (decline removes every row of the surface), but I only reasoned about it; nothing was executed.\n5. eval/ and the books were not read (outside the code lens). Some prompt line numbers are approximate and marked ≈.\n6. The `grep` wrapper was not needed: all searches were on backend and platform code, not on the gitignored books." + }, + "synthesis": { + "per_element": [ + { + "element": "E1 журнал решений / не пересчитывать банк", + "existing": "РЕШЕНО: D5 (docs/archive/architecture/05-decisions-D1-D38.md:116, в реестре ЖИВОЕ): «approved-глоссарий/series-bible наследуются read-only, новые термины append, approved не ревизуются молча». Тот же принцип, но для подписанного слоя.\nРИСК: B1 ❌ (docs/architecture/06-memory-risk-registry.md:44): «первый (наименее информированный) перевод имени лочится на 1000 глав.»\nОПРОВЕРГНУТО:\n- D39.69 (05-decisions-log.md:319): «гипотеза первенства ОПРОВЕРГНУТА»;\n- research/24:279: «DelTA: «первый перевод фиксируется» — у нас опровергнуто».\nОТЛОЖЕНО: M2 (research/14:165): «first-seen/majority-vote кэш рендеринга». По D39.42 (log:299) «доктрина Д2» — кандидат на отдельную ратификацию, ряд 47.\nПОСТРОЕНО, НО СПИТ: таблица glossary_revisions, backend/internal/store/migrate.go:218-233: «Append-only journal of approved-dst changes so a stale first-translation-wins rendering is DETECTABLE». Пишет только glossary.go:182 (reason seed-replace). Читатель GlossaryRevisionsForBook вне тестов не вызывается (контроль: 4 хита вместе с тестами, определение glossary.go:271).\nПОСТРОЕНО И РАБОТАЕТ: dropBankSettled, backend/internal/pipeline/terminologist.go:1124: «removes, BEFORE any money moves, the candidates the bank has already settled». Отсеивает только сид-поверхности.\nНАСТОЯЩАЯ ПРИЧИНА ПЕРЕКУПКИ:\n- terminology.go:1203: «so a batch's POSITION is part of its address» (ряды 38 и 233);\n- backend/docs/MONEY_HONESTY_REPORT.md:229: «`buildBankCandidates` не исключает уже консолидированные термы — консолидируется всё, каждый раз.»\nВЛАДЕЛЬЦУ РАЗВИЛКА УЖЕ ПОСТАВЛЕНА: там же §5.3 п.2: «Пропускать уже консолидированные термы — значит фиксировать ранний рендер. Это решение владельца, не сессии».\nЭРРАТА 11.09-и (log:124-134): «ПЕРЕ-МАЙНИНГА БАНКА ПОСЛЕ ЧЕЛОВЕЧЕСКОЙ ПОДПИСИ», «Хороши ли эти 12 замен — вопрос КАЧЕСТВА».\nМАРШРУТИЗАЦИЯ: research/24:234: «любой роутинг (какому арбитру отдать строку) обязан быть кластерным».\nСТОХАСТИКА СОСТАВА: ряд 439; эксп-25:902: «**Жаккар по книге = 0.63.**»\nПЛАН: NEAR_TERM_PLAN:53 п.10: «**БАНК: РЕШЁННОЕ ОСТАЁТСЯ РЕШЁННЫМ**».", + "verdict": "ДУБЛИРУЕТ D5, B1, M2 и п.10 плана. ПРОПУСТИЛО ЛУЧШЕЕ: готовый фильтр dropBankSettled, спящий журнал glossary_revisions и порядковый адрес батча — настоящую причину перекупки. Трейдофф «первое решение живёт» идёт против опровергнутого первенства (D39.69); развилку владельцу уже ставили (MONEY_HONESTY §5.3 п.2). НОВОЕ одно: запись исхода и улик для неподписанных строк движка." + }, + { + "element": "E2 одно определение тождества; таблицы вариантов написания как данные языка", + "existing": "ПОСТРОЕНО: backend/internal/text/norm.go:7 заявляет «free of language policy», но зашивает таблицу trad→simp и свёртку каны. NormVersion входит в memory_version и в разрез манифеста.\nСЫРОЙ КЛЮЧ — НАМЕРЕННО, в нескольких дверях:\n- storeOrder, bankmaterialize.go:34: «carries UNIQUE (book_id, src, sense, since_ch, until_ch) (store/migrate.go)». Порядок воспроизводится байт в байт, пин — bankmaterialize_identity_test.go.\n- MinedDeltaSeedCollisions, memseed.go:939-945: «It keys on the FULL uniqueness tuple (not the firing surface». Это страж от падения INSERT.\n- memseed.go:874, ConsolidationKeyConflicts: «Compared RAW, because the store's UNIQUE key is raw».\n- memory.go:925, editorLines: «continue // an unsigned rendering yields to the signed canon of the same surface». Сравнение по сырому signedSrc.\n- enclosure.go:16: вторая свёртка намеренно вне NormalizeSourceKey.\nПО ТОЖДЕСТВУ МАТЧЕРА уже работает UnverifiedKeyConflicts (memseed.go:699).\nПРЕЦЕДЕНТ: D39.51 п.2 (слайс 20-58:331): «кавычки — в свёртке (Q1), не в парсере/NormalizeSourceKey».\nШОВ ДАННЫХ: D39.118 п.3 (слайс 106-123:159): «bankdata-плоскость** — отдельный `//go:embed` вне волнового фолда со своей `BankDataVersion`».\nОЧЕРЕДЬ ВЛАДЕЛЬЦА: ряд 14: «ё-фолд → target-данные».\nРЯД 330 — денежный вопрос: «Два выхода требуют слова владельца, потому что оба стоят денег». Замер по полному ключу: «книг с ЛЮБЫМ конфликтом — 0».\nD39.193 п.3: ключ `(src, sense, since, until)`; два подписанных канона законны.\nИССЛЕДОВАНО:\n- research/13:117: «самый вероятный баг «тихо пусто»»;\n- research/14:191: «recall **0.00 → +норм 0.50 → +alias 0.75**»;\n- research/33:358: «категории каналов зашиты в китайскую форму»;\n- research/24:348, пара ja: «батч 0 вернул термы упрощённым китайским»;\n- спека D15.2:178: «`memoryNormVersion` двусторонний».\nАЛИАСЫ: ряды 228 и 407.", + "verdict": "РАСШИРЯЕТ: закрывает долг A4 и ряд 14. ПРОТИВОРЕЧИТ шаг 1 «$0 → ряд 330 закрыт»: сырой ключ хранилища стоит намеренно, а нормализация в storeOrder, MinedDeltaSeedCollisions и editorLines меняет вставку, порядок и байты инъекции. Ряд 330 — денежное решение владельца, а не баг тождества. ПРОПУСТИЛО: список каналов langpack закрыт в Go; таблицы должны быть отдельными на каждый язык (ja); алиасы тоже часть тождества." + }, + { + "element": "E3 честные исходы терминолога", + "existing": "ПОСТРОЕНО И ВКЛЮЧЕНО:\n- ⟦TM-NO-DST⟧ — backend/prompts/zh-ru/terminologist.md:36: «Если по данным контекстам ты не можешь выбрать перевод уверенно — верни ⟦TM-NO-DST⟧. Это нормальный»; парсер terminology.go:690.\n- «Не термин» у владельца: decisions.go:33: «TWO VERBS AND NO THIRD.»; mined_rejects (D39.19 R1-FL-B).\n- Полисемия — громкий отказ (D16, слайс D1-D38:198); memseed.go:231: «the deterministic matcher keys only on src and cannot pick a sense».\n- Уверенность — ранг, не порог: terminology.go:1154: «It is not a weight, not a threshold, not comparable between models». research/24:211: «AUC ds 0.770 (CI90 0.656–0.879) · glm 0.851».\nОПРОВЕРГНУТО И ЗАКРЫТО КЛАССОМ:\n- D39.50 п.1 (слайс 20-58:325): «сентинел ⟦TM-NO-DST⟧ различает «переводимо», не «терм», и нестабилен даже там — размах 0.375»;\n- D39.102 п.2 (log:369) закрывает «отказ-сигнал ⟦TM-NO-DST⟧»;\n- research/24:217: «⟦TM-NO-DST⟧ = 0 на всех 7 пассах четырёх семейств».\nКОРЕНЬ 3 ПОДТВЕРЖДЁН КОДОМ:\n- miner_emit.go:262-268 кладёт dst банкноты (`st.Dst = props[0].Dst`) в строку status:auto и тогда, когда терминолог отказал;\n- memory.go:762: «no fork by status at all (D39.104 п.2, backlog row 134)»;\n- значит, устарели комментарии miner_emit.go:225 («an auto term is outside the CONFIRMED-only injection (D39.2 trust gate)») и terminologist.go:33 («A term it declines emits `auto`, inert.»).\nОГРАНИЧЕНИЯ:\n- D39.144 п.1: «пер-термная подпись = сотни кликов — НЕ модель продукта»;\n- ряд 221 п.3: «Колонка `undecided` обязана ехать с тем же НЕ-гейтовым контрактом, что `SignatureState`»;\n- D39.155 п.7: «терм БЕЗ `dst` промотить нельзя вовсе»;\n- ряд 223: «отклонение всех 117 не подняло ни одного».\nНЕ ПОСТРОЕНО: sense_split_candidate (research/20:513).", + "verdict": "ДУБЛИРУЕТ: исход «не решено» построен, «не термин» у владельца есть. ПРОТИВОРЕЧИТ D39.50 и D39.102: канал сентинела закрыт как поведенчески пустой, а новые сентинелы предлагаются без замера. НОВОЕ: разделить «не термин» и «многозначный», предел перезапросов. Настоящая правка корня 3 — не прикреплять dst банкноты при отказе — в предложении не названа." + }, + { + "element": "E4 изменение по ходу книги: окна, преемник, смена рода и имени", + "existing": "СПРОЕКТИРОВАНО:\n- research/15:201: «Операция «замена термина с главы N»** (NovelCrafter progressions)»;\n- docs/architecture/13-tech-debt-anchors.md:89: «При этом СУБСТРАТ построен целиком»;\n- ряд 49: «сам механизм УЖЕ построен».\nДАННЫЕ: окно входит в UNIQUE. Загрузчик отбивает только пересекающиеся окна с разным dst (memseed.go:216, term-window-overlap).\nДВЕРЬ: decisions.go:90: «ONE NARROWNESS OF v1, named rather than hidden» и «Widening or moving a window is a two-call operation for now.» approve снимает отказ (decisions.go:635), поэтому decline→approve, по-видимому, окно двигает. Сверщик S3 считал путь недостижимым; не исполнено никем.\nИНВАРИАНТНОСТЬ: PACK20_BANK_DESIGN:510: «строка с `since_ch > c` байт-неспособна изменить инъекцию главы `c`».\nДЕТЕКТОР: mempostcheck.go:284: «SpoilerLeaks checks the chunk's REJECTED records against the model output».\nРОД:\n- D5.1 (слайс D1-D38:119, ЖИВОЕ) велит ставить hidden автоматически: «когда Analyst в **загруженных** главах видит намеренную неоднозначность»;\n- в коде иначе: classifier.md:10: «в словарь НЕ входит намеренно»;\n- D39.193: род производит классификатор.\nГОЛОС И ОБРАЩЕНИЯ:\n- D7 (слайс:140): «ты/вы в series-bible-lite — **журнал событий переходов**, а не статичная матрица пар»;\n- bankmaterialize.go:295: «InjectVoice is FALSE and has no config knob»;\n- D39.248: голос входит в приоритет №1.\nTermID: backend/docs/CHAPTER_STRUCTURE_DESIGN.md:678-694 (дизайн принят актом D39.245): «бьётся о `bank_terms_key` на ещё живой старой строке» → «**Решение — не координировать зоны, а не двигать id:**».\nЦЕНА ОКОН: ряд 421, не замерена.", + "verdict": "ДУБЛИРУЕТ: субстрат, данные, детектор утечки, род от классификатора и ручной hidden уже построены. ПРОТИВОРЕЧИТ дизайну, принятому актом D39.245 (TermID без окна ломает каждую загрузку банка на платформе), и живому тексту D5.1 (без поправочной ноты). ПРОПУСТИЛО голос и обращения. НОВОЕ: только глагол succeed в двери и протокол оператора." + }, + { + "element": "E5 улики для решения (контексты, выборка)", + "existing": "РАТИФИЦИРОВАНО: D39.42 (05-decisions-log.md:293), слова владельца 26.07: «мы намайнить в банк можем весь контекст». Тот же довод в коде: terminologist.go:26-29.\nПОСТРОЕНО: waverun.go:179, `r.runBankMiningStop(ctx, chunks, draftSnapshot, editWave)`, получает главы всей загруженной книги. Фильтр объёма scope.allows стоит только в waverun.go:144, 238 и 288, в mining.go его нет.\nРЫЧАГ КАЧЕСТВА:\n- D39.46 п.1: «контексты — главный рычаг качества терминолога»;\n- D39.50 п.4: «kwic-дефолт 3×40 ДОСТАТОЧЕН».\nИССЛЕДОВАНО:\n- research/19:542: «Source-side контекст параллелизм НЕ ограничивает»;\n- research/24:132: «KWIC: первые N вхождений в порядке глав» — выборка смещена к началу книги, стратифицированная проба (~$0.02) не исполнена;\n- эксп-23:4351: «Пайплайн, который видит только главу, по построению слеп примерно в четверти случаев.»\nТРЕБОВАНИЯ: ПТ-29 ❌ (product-requirements:75): «отклонено брифом V4-п.3 (вопросительная форма, отдельной ратификации в D-логе нет)».\nПРОВОД: KWIC-блок (terminology.go:771-799) несёт freq и since_ch, поэтому отпечаток улик меняется с каждой покупкой и перекроем.", + "verdict": "ПРОТИВОРЕЧИТ ратифицированному D39.42 и построенному коду, довод (спойлеры или деньги) не приведён. У отпечатка улик ПРОПУЩЕНО, что freq и since_ch входят в блок, а KWIC смещён к началу книги." + }, + { + "element": "E6 видимость сигналов: споры, proposed, читатель на платформе, подпись", + "existing": "ПОСТРОЕНО:\n- раздел proposed — bankexport.go:62: «Empty at every boundary that is not a stop.»; стоп на подпись по умолчанию выключен (research/34:77 → invocation.go:141);\n- споры — mining.go:397: «BankHolds names rows the bank ALREADY carries for the same firing surface with a different rendering.»; D39.225 п.9, D39.226.\nЧИТАТЕЛЯ НЕТ:\n- D39.225 п.4 (log:3108): «У новой секции сегодня НОЛЬ читателей.»;\n- ряд 224: «ОСТАЁТСЯ ПЛАТФОРМЕННАЯ»;\n- platform/internal/ingest/bank.go:111, `func termStatus(engine string) (string, bool) {`: auto становится proposed внутри terms, а отдельного поля proposed в wireBank нет.\nСПИТ: таблица bank_decisions (ряд 214), platform/internal/pgstore/readmodel.go:343: «Nothing writes that table today».\nРАТИФИЦИРОВАНО: D39.48: «ось G7 переформулирована: «что банкуется без подписи ≠ что кладётся на подпись»».\nИССЛЕДОВАНО: research/16:82: «Подсветка **ЯКОРИТ усилие**» — помогает только при F1 выше 80%.\nИДЕЯ ВЛАДЕЛЬЦА: V6-4, банк замечаний (ПТ-41 ⭕).", + "verdict": "ДУБЛИРУЕТ: раздел и споры построены, читатель — открытый ряд 224. ПРОПУСТИЛО: на дефолтном пути раздел пуст; у сигналов нет порога точности; слово proposed на платформе уже означает другое." + }, + { + "element": "E7 закон задним числом на готовых главах", + "existing": "РАТИФИЦИРОВАНО И ПОСТРОЕНО:\n- D39.42 п.5 (log:295): «пере-редактура ТОЛЬКО затронутых юнитов», смета ДО согласия;\n- D39.165 п.3 (log:1166): «`min($0.50, 5% × книги)` — **продолжает сам, без флагов**»;\n- repin.go:30: «the unit is RE-PINNED for $0 instead of re-bought»;\n- D39.170: смета доступна в status до покупки, жёсткий гейт `chapter < since_ch`.\nSINCE: research/20:596: «since_ch = первая глава вхождения кластера (автоматически, по source)», в майнере построено. По S2, у кандидатов банкноты SinceCh 0 (mining.go:612); мной не перепроверено.\nДЫРЫ:\n- ряд 241: «пользователь правит банк, получает квитанцию об успехе — и правка не доезжает ни до одной строки никогда»;\n- ряд 322: «прежний текст остаётся в чекпойнтах, но без адреса».\nИССЛЕДОВАНО:\n- research/34:105: подписанные каноны разошлись между прогонами;\n- research/32:88 (ФАКТУРА): «результат применения к тексту участвует в выборе самого термина».", + "verdict": "ДУБЛИРУЕТ для редакторской волны: построено и под порогом работает автоматически. РАСШИРЯЕТ: черновики глав до since и счёт «N глав до закона» по термину. ПРОПУСТИЛО ряды 241 и 322: без указателя принятой редакции пере-проход может отнять хороший текст." + }, + { + "element": "E8 смена имени из сида", + "existing": "ПОСТРОЕНО: decisions.go:54: «it reaches the EDITOR and does not re-form the draft.» Отчёт двери печатает depth: edit_wave. Доезд до черновиков — ряд 192, не спроектирован.\nЭРРАТА 27.08-в (log:36): «правка СИД-терма дверью отклоняется по имени».\n«РЕДАКТОР ПРИВЕДЁТ» ПРОТЕКАЕТ, это замерено:\n- эксп-24:336: «случай, где закон банка на проводе», а в тексте его не видно;\n- ряд 409: «с подключённым банком боевой редактор держит ХУДШЕЕ покрытие канона в панели — 0.882 против 0.909».\nЛОК: SEAM_PACK_FINDINGS.md:195: «Проекция берёт тот же лок» — пока идёт прогон, событие владельца не применить и даже не посмотреть.\nВРУЧНУЮ: сид уже может держать преемника двумя непересекающимися окнами (memseed.go:216).", + "verdict": "ДУБЛИРУЕТ: глубина edit_wave построена, переоплата черновиков — это ряд 192. ПРОПУСТИЛО: замер, что редактор старое имя не приводит, и лок проекта." + }, + { + "element": "E9 консистентность по отгруженному тексту и принуждение закона", + "existing": "ПОСТРОЕНО:\n- D39.249 (log:3685): «Теперь есть счёт по ОТГРУЖЕННОМУ тексту с двумя инвариантами»; bookconsistency.go:11;\n- memconsistency.go:21: «It reuses the bank's own machinery rather than standing a second matcher beside it».\nПРИБОР НЕ БАЗОВАЯ ЛИНИЯ: D39.252 п.3 (log:3758): «числа консистентности этого прогона БАЗОВОЙ ЛИНИЕЙ НЕ ЯВЛЯЮТСЯ до починки прибора.» (ряды 434, 436).\nПОСТРОЕНО, НО ВЫКЛЮЧЕНО:\n- config/pipeline.go:475: «PostcheckGate promotes a miss from a mere record to a DISPOSITION flag»;\n- ключа нет в 4 из 4 конфигов (контроль: `gates:` — по одному в каждом);\n- D39.205 п.4: «Гейт глоссария (`gates.glossary.postcheck_gate`) НЕ ВКЛЮЧАЕТСЯ.»;\n- гейт считает только Confirmed: bookconsistency.go:36: «THE ENGINE DOES NOT AGREE WITH THAT MODEL».\nНАПРАВЛЕНИЕ ВЛАДЕЛЬЦА: D39.205 п.5: «или флагать, или ПЕРЕГЕНЕРИРОВАТЬ проблемный участок».\nОГРАНИЧЕНИЯ:\n- mempostcheck.go:28: «It is a post-CHECK, never a blind post-REPLACE»;\n- эксп-21:110: «ремонт значимо хуже переписывания».\nСЛЕПОТА:\n- D39.215 п.4: «Исполненная неверная строка присутствует в выводе ⇒ промах не пишется»;\n- эксп-09:116: «M3 consistency (0.467) ≈ M0 (0.567)».\nРЕДАКТОР ТЕРЯЕТ ЛИПКОСТЬ: waverun.go:712: «sticky_prev is nil, and that is a LOSS, not a degenerate case».\nПОСЫЛКА: research/29:2490: «Сама посылка «одинаково = хорошо» измеренно неверна.»", + "verdict": "ПРОПУСТИЛО: предложение не говорит, что закон делает при нарушении. Гейт выключен словом владельца до замера ложных срабатываний, ремонт хуже переписывания, прибор не базовая линия, неверный закон, исполненный моделью, невидим. $0-сверка «черновики против закона» ДУБЛИРУЕТ ScanShipping." + }, + { + "element": "E10 номинация: какие слова попадают в банк", + "existing": "ПОСТРОЕНО:\n- miner_emit.go:343: «emissionEligible applies the build_precision30 filters» — только name, place, title; freq ≥ 5; не короче 2 рун; потолок 200 срабатывает ДО фильтров (ряд 223);\n- обычные слова идут только банкнотой: translator-banknote.md:24: «Тип — одно из: name, place, title, term, nickname.»;\n- однорунный термин — только вручную: memory.go:166: «allowShort is the author's explicit override of the single-key ban».\nОТКРЫТЫЙ ВОПРОС ВЛАДЕЛЬЦУ: ряд 440: «имеет ли право обычное существительное входить в банк детерминированным каналом». Причинность ряда опровергнута 12.09: «**`族` отсечён БЕЗУСЛОВНО как ОДНОРУННЫЙ**, к контрасту это отношения не имеет».\nРАТИФИЦИРОВАНО ОТРИЦАТЕЛЬНО:\n- D39.50 п.1: «расширение `emitRankCap`/фильтра типа НЕ строится»;\n- D39.50 п.2: «частотного экрана НЕ существует»;\n- D39.48: ось G7.\nСМЕЖНОЕ: ряд 284 (заголовки через банк), ряд 423 (что банк обязан отдавать).", + "verdict": "ПРОПУСТИЛО: номинации нет в порядке работ, открытого вопроса владельцу (ряд 440) нет среди Q1–Q4. «Имя против обычного слова» решает не терминолог, а фильтр типа и запрет однорунных; их расширение ратифицированно закрыто D39.50." + }, + { + "element": "E11 деньги и перекупки банка", + "existing": "РАТИФИЦИРОВАНО: D39.42 п.3: «**ВСЕ строки банка фолдятся в версию памяти** ⇒ тихой пере-оплаты не существует как класса».\nЗАМЕРЕНО:\n- ряд 323: «проход терминолога перекупается НА КАЖДУЮ ПОДПИСЬ»;\n- ряд 38: «адрес чекпойнта батча = ординал при частотной сортировке»; terminology.go:1203; MONEY_HONESTY §5.1;\n- CHAPTER_STRUCTURE_DESIGN.md:256: «чистая перенумерация меняет пользовательское сообщение КАЖДОГО банк-батча»; банк-роли — $0.04980482 из $0.43610966 (11.4%);\n- эррата 11.09-и: второй заход стоил $0.028742, 6.9% книги.\nПОСТРОЕНО:\n- terminologist.go:947: «THE PLAN IS CUT TO WHAT FITS **BEFORE THE FIRST CALL**» (budget_usd 1.00 на всю книгу);\n- volume.go:351: «a VOLUME ceiling on a book that MINES its bank».\nРАТИФИЦИРОВАНО:\n- D39.224 п.5: «Цена «заплатить дважды» УСЛОВНА; жёсткое ограничение — время.»;\n- ряд 182: копить сдвиги memory_version в одно окно.", + "verdict": "РАСШИРЯЕТ. «Одна перекупка на книгу» не доказана, пока адрес батча — порядковый номер (ряды 38 и 233). Четыре шага, каждый из которых двигает версию, расходятся с рядом 182 (одно окно)." + }, + { + "element": "Q1 журнал и преемник после перенарезки; книги A/B не продолжаем", + "existing": "- D39.224 п.5: цена двойной оплаты условна, пока продолжаемых книг нет.\n- NEAR_TERM_PLAN:149: открытые вопросы В-2…В-5 по перекрою («что происходит с уже переведёнными книгами при перекрое»).\n- CHAPTER_STRUCTURE_DESIGN §4.1: окна делятся на выведенные и авторские.\n- Собственный план оркестратора, NEAR_TERM_PLAN:53 п.10: «Предложен порядок: РАНЬШЕ 5(в) — перекрой глав без якоря пере-решил бы банк платной книги».", + "verdict": "ПРОТИВОРЕЧИТ собственному плану п.10: там якорь банка стоит ДО перекроя, в Q1 — после, и довод разворота не приведён. РАСШИРЯЕТ: вопрос стоит подать вместе с В-2…В-5." + }, + { + "element": "Q2 снимает ли владелец стопы ряда 130 и D39.144 п.1", + "existing": "РЯД 130 (BACKLOG:70) — не запрет, а отложенное решение владельца: «СТОП-решение владельца (двигает банк → memory_version); материал для решения даст WARN со ВТОРОГО прогона». Срок: «когда-нибудь (гейт: WARN второго прогона)».\nПЛАН п.10: «⏳ ждёт слова владельца «копить ли решения банка между прогонами»».\nПРЕЖНЕЕ «НЕТ» — ИНЖЕНЕРНОЕ: D39.71: «Q1/Q4 «не строить»», по BANK_QUALITY_DESIGN:233: «строить ли автономный канон-пин родового слова МЕЖДУ прогонами». Развилка качества — MONEY_HONESTY §5.3 п.2.\nD39.144 п.1 («НЕ проектировать до полигонных итогов») УЖЕ СУЖЕН: D39.165 п.3: «**Владелец снял это 28.08:** открыть дверь к уже построенному движковому механизму». Под гейтом осталось: «доезд правки до ЧЕРНОВИКА через сид».\nУСЛОВИЕ ГЕЙТА НЕДОСТИЖИМО: D39.248: «полигон выведен из скоупа целиком»; ряд 192: «триггер: итоги фазы Д».", + "verdict": "ПРОТИВОРЕЧИТ статусам: оба «стопа» описаны неверно. Спрашивать надо иначе: (1) «вот WARN прогонов A и B о выпавших строках — копим?»; (2) «условие ‘итоги полигона’ недостижимо — чем его заменить для доезда правки до черновиков?»." + }, + { + "element": "Q3 закон на готовых главах: по заказу или автоматически", + "existing": "- D39.42 п.5 и D39.165 п.3: редакторская волна уже переделывается сама под порогом min($0.50, 5% книги), выше порога — с согласием (rebill.go).\n- D39.205 п.5, направление владельца: «ПЕРЕГЕНЕРИРОВАТЬ» (ряд 296).\n- эксп-21:110: ремонт хуже переписывания.\n- Ряды 241 и 322.", + "verdict": "ДУБЛИРУЕТ решённое для редакторской волны. Сузить до черновиков глав до since и до точечной перегенерации, которую владелец уже называл." + }, + { + "element": "Q4 имя из сида с главы N: только редактор или переоплата черновиков", + "existing": "- decisions.go:54: глубина edit_wave у каждого решения двери.\n- Эррата 27.08-в: правка сид-терма дверью отклоняется.\n- Ряд 192: доезд до черновиков не спроектирован.\n- Ряд 230 (по S1): decline сид-терма отвечает «уже применено».\n- Эксп-24:336 и ряд 409: редактор старое имя не приводит.", + "verdict": "ДУБЛИРУЕТ: первый вариант — уже построенная глубина, второй — ряд 192. Спросить надо «оставить построенное или открыть ряд 192», с ценой черновой волны и замером протечки." + } + ], + "missed_smart": [ + { + "idea": "Расширить построенный фильтр «не спрашивать решённое» с сид-поверхностей на неподписанные решения движка, вместо нового файла журнала и выведенного вида", + "source": "backend/internal/pipeline/terminologist.go:1124 (dropBankSettled, BUILT_ACTIVE): «removes, BEFORE any money moves, the candidates the bank has already settled»", + "how_it_changes": "E1 строится как более широкий предикат на существующем пути. Комментарий там же требует безусловности фильтра, иначе состав батчей меняется на резюме. Цена: код и одна перекупка банк-ролей (около 11.4% холодного прогона на замеренной книге)." + }, + { + "idea": "Адрес чекпойнта банк-батча по содержимому, а не по номеру позиции", + "source": "terminology.go:1203: «so a batch's POSITION is part of its address»; ряды 38 и 233; MONEY_HONESTY §5.1", + "how_it_changes": "Без этого «спрашивать только про новые» перекупку не остановит: частоты пере-сортировывают батчи на каждой покупке. Это надо вписать в шаг 3 как предусловие. Цена: код, одна перекупка." + }, + { + "idea": "Спящий журнал редакционного времени B1 вместо второго носителя", + "source": "backend/internal/store/migrate.go:218-233 и glossary.go:182 (BUILT_DORMANT; читателей вне тестов 0)", + "how_it_changes": "Выбор носителя: достроить glossary_revisions (исход, улики, прогон, автор) или явно снять. Иначе у знания «что решено» будет три писателя вместе с bank_decisions на платформе. Цена: $0 и миграция схемы." + }, + { + "idea": "Единица перезапроса — семья или серия терминов, а решённые члены идут якорем", + "source": "research/24:234 («любой роутинг … обязан быть кластерным»); family-morphology.txt («a chimera that correlates with the batch boundary perfectly»); ряд 339 (якорная половина не закрыта)", + "how_it_changes": "Правило «терминолог только для Identity без закона» надо заменить на «для семьи, где у кого-то нет закона, решённые члены передаются якорем, как ⟦TM-CANON⟧». Иначе возвращаются химеры 古月. Цена: правка запроса, пере-снапшот банк-ролей на центы." + }, + { + "idea": "Колонка уверенности (построена, AUC 0.77–0.85) упорядочивает очередь человека вместо новых сентинелов", + "source": "research/24:211; terminology.go:1154 (не порог, только ранг); сентинел не использовался ни разу (research/24:217)", + "how_it_changes": "Исходы «не решено» и «многозначный» сортируются по уверенности. Строить новые сентинелы можно только после пробы, берёт ли их модель вообще. Цена: $0 и проба на центы." + }, + { + "idea": "Починить корень 3 там, где он живёт: не прикреплять dst банкноты к термину, от которого отказался терминолог, и исправить два устаревших комментария", + "source": "miner_emit.go:262-268 (`st.Dst = props[0].Dst` при status auto); memory.go:762 (нет развилки по статусу, D39.104 п.2); terminologist.go:33 («A term it declines emits `auto`, inert.»)", + "how_it_changes": "Малая правка, независимая от журнала, может идти первой. Меняет содержимое банка на затронутых книгах, значит memory_version и пере-редактуру с согласием; цену надо назвать." + }, + { + "idea": "SpoilerLeaks как готовый бесплатный детектор старого имени после преемника", + "source": "mempostcheck.go:284 (BUILT_ACTIVE, работает всегда)", + "how_it_changes": "Для преемника и смены имени из сида не нужна новая проверка: until_ch=N−1 сам делает старую форму в главах ≥N утечкой в отчёте качества." + }, + { + "idea": "ScanShipping для $0-сверки «черновики против закона»", + "source": "memconsistency.go:21 (BUILT_ACTIVE; стемминг по данным target-ru decl_suffix)", + "how_it_changes": "Не нужен второй матчер и отдельный фильтр пака: достаточно нового места вызова по черновикам." + }, + { + "idea": "Детекторы стабильно-неверного закона и полисемии за $0", + "source": "research/20:512 (`suspicious_stable`) и :513 (`sense_split_candidate`), не построены; D39.215 п.4 (исполненная ложь невидима)", + "how_it_changes": "Сигналы предложения (споры, INVENTED) не видят неверный закон, исполненный единообразно. Без детектора верности журнал делает такую ошибку вечной. Цена: $0-эвристика плюс дешёвый судья по желанию." + }, + { + "idea": "Слой запрещённых форм (TBX forbidden)", + "source": "research/24:298 («$0-счёт рецидивов отвергнутых форм»), не построен", + "how_it_changes": "Естественная пара к преемнику и к исходу «не термин»: бесплатный линт отвергнутой формы в пост-проверке." + }, + { + "idea": "Принимать банковое изменение одной группой вместе с его пере-редактурами и указателем принятой редакции", + "source": "research/32:84-88 (ФАКТУРА, не ратифицировано); ряд 322", + "how_it_changes": "Отвечает на трейдофф «первое решение живёт» и на риск, что пере-проход снесёт хорошую редактуру. Меняет E7: «ре-мейк только пере-проходом» без указателя опасен." + }, + { + "idea": "Порог принятия решения зависит от числа вхождений термина", + "source": "research/17:193 («пороги принятия должны зависеть от fan-out»); счёт упоминаний построен в майнере (идея владельца V1-п.1, ПТ-27 ✅)", + "how_it_changes": "Вместо заморозки любого первого решения: редкие термины фиксировать, частые перезапрашивать при заметном росте улик. Смягчает опровергнутое первенство. Цена: $0." + }, + { + "idea": "Замер до стройки: рост 10 → 50 → 200 глав против той же книги целиком", + "source": "research/31:54; research/24:313 («тёплый» банк «не мерено никем»)", + "how_it_changes": "Перед шагом 3 появляется замер: сколько решений удержано, сколько новых ошибок, какая цена. Вся эмпирика терминолога холодная, а журнал делает каждую покупку тёплой. Цена: платный прогон, центы или единицы долларов." + }, + { + "idea": "Голос и обращения на той же оси глав: схема построена, инъекция выключена", + "source": "seed.go:44-47, bankmaterialize.go:295 (InjectVoice FALSE), D7 (журнал переходов ты/вы), D39.248 (голос в приоритете №1)", + "how_it_changes": "Преемник и журнал надо распространить на смену регистра и самоназвания; иначе приоритет №1 закрыт наполовину." + }, + { + "idea": "Стратифицированная выборка контекстов вместо первых N по порядку глав", + "source": "research/24:132 (проба ~$0.02 не исполнена)", + "how_it_changes": "«Перезапрос при новых уликах» бесполезен, если новые вхождения из поздних глав в выборку не попадают." + }, + { + "idea": "Реальный объём выноса таблиц в данные языка", + "source": "research/33:358 (категории каналов langpack зашиты в Go, «Носителя в бэклоге нет»); research/24:348 (ja-ключи уходят в упрощённый китайский); research/14:191 (нужна полнота уровня OpenCC и побитовый тест); спека D15.2:178 (memory_version растворяется, хеш источника — на стороне инъекции)", + "how_it_changes": "Шаг 2 включает открытие списка каналов, отдельные таблицы на каждый язык и побитовый тест. Хеш таблицы кладётся на сторону инъекции, а не в поле, которое спека D15.2 упраздняет." + } + ], + "contradictions": [ + { + "what": "E5 «улики только из уже переведённой части книги» против ратифицированной архитектуры терминолога (владелец 26.07: весь контекст книги) и построенного кода: runBankMiningStop получает главы всей книги, фильтра объёма в mining.go нет.", + "source": "docs/architecture/05-decisions-log.md:293 (D39.42) «мы намайнить в банк можем весь контекст»; backend/internal/pipeline/terminologist.go:26-29; waverun.go:179; D39.46 п.1 «контексты — главный рычаг качества терминолога»" + }, + { + "what": "Трейдофф E1 «первое решение живёт до правки человеком» возвращает опровергнутое первенство первого перевода; риск B1 записан как нерешённый; ратифицирован курс на автономное качество без обязательной подписи.", + "source": "05-decisions-log.md:319 (D39.69) «гипотеза первенства ОПРОВЕРГНУТА»; research/24:279; 06-memory-risk-registry.md:44 (B1 ❌); слайс D39-59-90:109 (D39.59 п.2)" + }, + { + "what": "E3 «честные исходы через сентинелы парсера» повторяет канал, закрытый по замеру: сентинел отказа кодирует «переводимо», а не «термин», нестабилен и на 7 пассах четырёх семейств не использовался ни разу.", + "source": "слайс D39-20-58:325 (D39.50 п.1) «размах 0.375»; 05-decisions-log.md:369 (D39.102 п.2) «отказ-сигнал ⟦TM-NO-DST⟧»; research/24:217" + }, + { + "what": "Порядок п.1 «$0 … → ряд 330 закрыт». Ряд 330 — денежное решение владельца о том, что ДЕЛАТЬ с противоречием; замер по полному ключу дал 0 книг с конфликтом. Сырой ключ в дверях намеренный: storeOrder воспроизводит UNIQUE хранилища байт в байт, MinedDeltaSeedCollisions сторожит падение INSERT, editorLines сравнивает по сырому signedSrc, и нормализация меняет байты инъекции.", + "source": "docs/BACKLOG.md:269 (ряд 330) «Два выхода требуют слова владельца, потому что оба стоят денег»; backend/internal/pipeline/bankmaterialize.go:34; backend/internal/membank/memseed.go:939-945, :874; memory.go:925" + }, + { + "what": "Порядок п.4 «TermID = hash(Identity, sense)+revision, минор контракта» против решения дизайна, принятого актом D39.245: перечеканка id ломает каждую загрузку банк-экспорта на платформе, поэтому решено id не двигать.", + "source": "backend/docs/CHAPTER_STRUCTURE_DESIGN.md:678-694 «бьётся о `bank_terms_key` на ещё живой старой строке», «**Решение — не координировать зоны, а не двигать id:**»; 05-decisions-log.md:3562 (D39.245)" + }, + { + "what": "«Оговорка в промте опровергнута экспериментом 18» и «провод как D39.104, без оговорки». Эксперимент 18 оговорку НЕ опроверг, а не подтвердил на N=3+1. D39.104 п.1 по-прежнему ратифицирует узкую оговорку области употребления; поправочной ноты нет (контроль: 10 файлов журнала, слайсов, реестра, бэклога и плана, 6191 строка).", + "source": "docs/experiments/18-editor-wire-probe.md:621 «**Не подтверждено:** оговорка области §B (обратное направление на N=3+1). В движок не вносить.»; 05-decisions-log.md:379 «получают узкую оговорку ОБЛАСТИ употребления, действующую на все строки одинаково»" + }, + { + "what": "Q2 называет ряд 130 прежним стопом «не копить банк». Это открытое решение владельца, у которого названы гейт и материал (WARN второго прогона). Инженерное «не строить» — это D39.71 Q1.", + "source": "docs/BACKLOG.md:70 (ряд 130); NEAR_TERM_PLAN.md:53 «ждёт слова владельца «копить ли решения банка между прогонами»»; слайс D39-59-90:123 (D39.71) «Q1/Q4 «не строить»»" + }, + { + "what": "Q2 просит «снять» стоп D39.144 п.1. Владелец сузил его 28.08; под гейтом остался только доезд до черновика, а условие гейта (итоги полигона) стало недостижимым после выведения полигона из скоупа.", + "source": "05-decisions-log.md:1174 (D39.165 п.3) «**Владелец снял это 28.08:**»; 05-decisions-index.md (D39.248) «полигон выведен из скоупа целиком»; BACKLOG.md:114 (ряд 192) «триггер: итоги фазы Д»" + }, + { + "what": "Исходы, которые решает только человек («многозначный», «скрытый пол», видимое undecided), возвращают пер-термное решение, которое владелец назвал не моделью продукта; колонка undecided обязана быть не-гейтовой.", + "source": "05-decisions-log.md:599 (D39.144 п.1) «пер-термная подпись = сотни кликов — НЕ модель продукта»; BACKLOG.md:187 (ряд 221 п.3)" + }, + { + "what": "«Скрытый пол — только человек; hidden от классификатора снят». Живой D5.1 велит ставить hidden автоматически, код его уже из словаря исключил, а расхождение D5.1 с кодом не ратифицировано.", + "source": "слайс D1-D38:119 (D5.1) «когда Analyst в **загруженных** главах видит намеренную неоднозначность»; backend/prompts/zh-ru/classifier.md:10 «в словарь НЕ входит намеренно»" + }, + { + "what": "Корень 1 подаёт «12 из 69» как дефект памяти. Ратифицированная эррата называет это ценой пере-майнинга после подписи; качество этих замен никто не судил.", + "source": "05-decisions-log.md:124-134 (эррата 11.09-и) «ПЕРЕ-МАЙНИНГА БАНКА ПОСЛЕ ЧЕЛОВЕЧЕСКОЙ ПОДПИСИ», «Хороши ли эти 12 замен — вопрос КАЧЕСТВА»" + }, + { + "what": "Q1 ставит журнал ПОСЛЕ перенарезки глав, а план того же оркестратора ставит якорь банка ДО перекроя; довод разворота не приведён. План не ратифицирован, но это собственный документ.", + "source": "docs/NEAR_TERM_PLAN.md:53 «Предложен порядок: РАНЬШЕ 5(в) — перекрой глав без якоря пере-решил бы банк платной книги»" + } + ], + "must_change": [ + "Q2 переписать: ряд 130 — открытое решение владельца, а не его запрет. Предъявить WARN о выпавших строках из прогонов A и B (это и есть названный материал) и сослаться на инженерное «не строить» D39.71 Q1 и развилку MONEY_HONESTY §5.3 п.2. Про D39.144 п.1 сказать, что он сужен 28.08 (D39.165 п.3), а условие гейта недостижимо после D39.248; просить замену условия для доезда до черновиков, а не «снятие стопа».", + "Шаг 1: убрать «$0» и «ряд 330 закрыт». Ряд 330 — денежный вопрос (а)/(б). Сырой ключ UNIQUE хранилища держат storeOrder, MinedDeltaSeedCollisions и ReplaceBank, а editorLines по сырому signedSrc формирует байты инъекции. Нужны: сначала $0-замер нормализованных двойников по корпусу (прибор ряда 330 мерил сырой полный ключ), миграция ключа и полный список дверей, включая findTerm, ConsolidationKeyConflicts и TrimEnclosure.", + "E5 «улики только из переведённой части» снять или вынести отдельным вопросом владельцу с доводом: это меняет ратифицированный D39.42 и построенный код и режет «главный рычаг» D39.46.", + "E3 опереть на построенный ⟦TM-NO-DST⟧ и назвать замер: 0 использований на 7 пассах, размах 0.375, закрыт D39.102. Новые сентинелы — только после пробы. Корень 3 чинить в miner_emit.go (не прикреплять dst банкноты при отказе) и исправить устаревшие комментарии miner_emit.go:225 и terminologist.go:33. Очередь человека сортировать колонкой уверенности (ранг, не порог).", + "Исход «не термин» движка либо писать в тот же mined_rejects, что и отказ владельца, либо явно развести носители. Все человеческие исходы — только опциональная не-гейтовая дверь (D39.144, ряд 221 п.3).", + "E1: назвать носитель. Достроить спящий glossary_revisions или снять его. «Не пересчитывать» строить как расширение dropBankSettled вместе с адресом батча по содержимому (ряды 38, 233), иначе перекупка останется. Единица перезапроса — семья или серия с якорем решённых членов (research/24:234, ряд 339).", + "Трейдофф «первое решение живёт» переписать честно: первенство опровергнуто (D39.69), риск B1 открыт, автономный терминолог совпадает с подписью владельца на 18–25 из 45 (research/24:164). Предложить путь пересмотра: порог по числу вхождений (research/17:193), перезапрос частых терминов при росте улик.", + "Числа: «12 из 69» — цена пере-майнинга, качество замен не судилось (эррата 11.09-и). «14 из 66» и «INVENTED 17/66» не найдены ни в эксп-25, ни в эксп-24, ни в журнале, ни в бэклоге — дать источник или убрать.", + "Оговорку области не называть «опровергнутой»: эксп-18 — «не подтверждено, в движок не вносить», а D39.104 п.1 её по-прежнему ратифицирует. Для «провода без оговорки» нужна ратифицирующая нота.", + "Шаг 4 TermID: либо сохранить id (решение CHAPTER_STRUCTURE_DESIGN §4.2 п.3, принятое актом D39.245), либо назвать скоординированную миграцию платформы. Это не «минор контракта».", + "E4: назвать расхождение D5.1 (автоматический hidden) с кодом и research/20 и вынести его на ноту. Распространить преемник на голос и обращения: схема окон построена, InjectVoice выключен, голос входит в приоритет №1 по D39.248. Проверить исполнением, двигает ли окно decline→approve (decisions.go:90 и :635).", + "E9: сказать, что закон делает при нарушении. Гейт построен, но выключен словом владельца до замера ложных срабатываний (D39.205 п.4). Перегенерацию владелец называл (п.5), но ремонт замерено хуже (эксп-21), а слепая замена запрещена. Прибор консистентности не базовая линия (D39.252 п.3). Неверный исполненный закон невидим (D39.215 п.4), нужен детектор верности.", + "E10 и вопросы: добавить ряд 440 (обычные существительные; причинность опровергнута 12.09, сечёт фильтр типа и запрет однорунных), research/34 §4 п.1 (стоп или флаг) и п.5 (остановка на подпись как свойство продукта). Упомянуть потолок до фильтров (ряд 223).", + "Q1: объяснить разворот порядка против собственного плана п.10 (якорь банка до перекроя 5(в)) и подать вопрос вместе с В-2…В-5 перекроя.", + "Q3 сузить до черновиков глав до since и счёта по термину: для редакторской волны автоматика под порогом уже построена (D39.42 п.5, D39.165 п.3). Приложить ряды 241 и 322: правка на дочитанной книге не доезжает, у принятой редакции нет указателя.", + "Q4 переформулировать: «оставить построенную глубину edit_wave или открыть ряд 192», с ценой черновой волны и замером, что редактор старое имя не приводит (эксп-24:336, ряд 409).", + "E6: раздел proposed пуст на дефолтном пути (bankexport.go:62), поэтому публиковать его на каждой границе или признать сигналы невидимыми. Показ сигнала — только при замеренной точности (research/16:82). Слово proposed на платформе уже означает неподписанные строки.", + "Перед шагом 3 заказать замер роста 10 → 50 → 200 глав против книги целиком (research/31:54) и тёплого банка (research/24:313). Шаги, двигающие memory_version, свести в одно окно (ряд 182)." + ], + "sync_honest": "Синк слабый. Диагноз из трёх корней совпадает с планом п.10 и с кодом, корень 3 я подтвердил чтением miner_emit.go:262-268 и memory.go:762. Но опора предложения — около десятой доли того, что относится к делу.\\n\\nНОТЫ ЖУРНАЛА. В реестре 300 D-строк, у 72 тема «банк», 106 проходят по ключевым словам (мой python). Сверщики нашли 57 относящихся родительских нот. Предложение опирается на 5: явно D39.245, D39.144, D39.104; неявно D39.42 (через §C2-7) и D39.158 (через онтологию 18). Это около 9%.\\n\\nБЭКЛОГ. 323 ряда, 107 по банковым словам, относящихся 58. Предложение называет 5 (14, 130, 131, 161, 330), около 9%. Из четырёх рядов собственного плана п.10 (130, 330, 438, 440) взяты два; открытый вопрос владельцу 440 выпал.\\n\\nОТЧЁТЫ, РЕСЁРЧИ, ДИЗАЙН-ДОКИ. Относящихся 40, названо 5: явно эксп-18 и онтология 18, неявно эксп-24/25 и CHAPTER_STRUCTURE_DESIGN через ряд 161. Около 12%.\\n\\nПОСТРОЕННЫЕ МЕХАНИЗМЫ. Относящихся 44, названо 4 (NormalizeSourceKey, storeOrder, раздел proposed, сентинелы в общем виде). Около 9%. Из пяти спящих ровно по предмету (glossary_revisions, postcheck_gate, InjectVoice, rubyToCandidates, bank_decisions) не назван ни один.\\n\\nРАСХОЖДЕНИЯ. Я подтвердил 12 расхождений с ратифицированным, замеренным или собственным планом; в предложении названо 0.\\n\\nЧИСЛА ПРЕДЛОЖЕНИЯ. «12 из 69» есть в эксп-25:88. «14 из 66» — только в собственном плане п.10. «INVENTED 17/66» не найдено (контроль: эксп-25 972 строки, эксп-24 962, журнал 3776, бэклог 362).\\n\\nМЕТОД. Знаменатели — объединение источников трёх сверщиков плюс мои подсчёты по реестру и бэклогу. Отбор делали сверщики и читали не всё, поэтому знаменатель — оценка снизу.", + "owner_summary": "1. Диагноз верный, и код его подтверждает: банк на каждой покупке решается заново, а «не могу решить» у терминолога превращается в догадку черновика, которая идёт редактору как закон.\\n2. Почти всё, что предложение подаёт как новое, в репозитории уже есть. Работает: ответ «не могу решить», ваш отказ «не термин», переделка только затронутых кусков со сметой, проверка консистентности готового текста. Построено, но выключено: журнал правок переводов, флаг «термин разъехался», голос по главам. Опирается предложение примерно на десятую часть относящегося.\\n3. Пять мест расходятся с решённым или замеренным:\\n - «улики только из переведённой части» — вы 26.07 решили, что терминолог видит всю книгу, так и построено;\\n - «первое решение живёт» — «первый перевод побеждает» у нас опровергнут замером;\\n - сигнал «не могу решить» уже мерили: модели его не используют;\\n - смена id терминов сломает загрузку банка на платформе, дизайн глав это отверг;\\n - «оговорка опровергнута экспериментом 18» — эксперимент написал «не подтверждено».\\n4. Вопросы 2–4 поставлены неточно. «Копить ли банк» — не ваш запрет, а ваше отложенное решение, и материал (логи двух прогонов) уже есть. Запрет на правки после прочтения вы сузили 28.08, а его условие («итоги полигона») стало недостижимым. Готовые главы редактор уже переделывает автоматически под порогом цены.\\n5. Не заданы три ваших вопроса: стоп или флаг при разъехавшемся термине; пускать ли в банк обычные слова («род/клан»); останавливаться ли на подпись по умолчанию.\\n6. Самое умное из пропущенного: фильтр «не спрашивать решённое» уже есть в коде, но только для терминов вашего списка. Его можно расширить на решения движка, если пачки перестанут адресоваться порядковым номером, и спрашивать семьями терминов, а не по одному.\\n7. Рекомендация: не утверждать как есть. Попросить переписать на опоре на построенное, исправить пять расхождений и перед стройкой сделать дешёвый замер «книга растёт 10→50→200 глав против всей сразу».", + "obstacles": "СВЕРЩИКИ. Все три вернули результат, пустых нет.\\n\\nПРОВЕРКА ЦИТАТ. Python-скрипт в scratchpad/prior-art-synth/verify.py проверил 180 цитат: 170 как дословные подстроки (точно или с нормализацией пробелов) и 10 повторно, после снятия маркеров комментариев. Дословными оказались 178. Не найдена одна: цитата S3 из memseed.go «A term whose approved rendering changes across a spoiler boundary…» (файл есть, «spoiler boundary» даёт 0). У двух цитат неверна атрибуция:\\n- цитата S1 про D39.248 п.4 живёт в BACKLOG:114 (ряд 192), а не в теле ноты;\\n- цитата S3 «Compared RAW» (memseed.go:874) стоит в ConsolidationKeyConflicts, а не в MinedDeltaSeedCollisions. Та тоже сравнивает сырой UNIQUE-кортеж (memseed.go:939-945), так что вывод S3 стоит.\\n\\nОШИБКИ СВЕРЩИКОВ.\\n- S1 и S2 цитируют ряд 440, не упоминая, что его причинность опровергнута 12.09 (BACKLOG:361: сечёт фильтр типа и запрет однорунных, а не контраст).\\n- Вывод S3 «окно двухходовкой не сдвинуть» не подтверждаю: approve снимает отказ (decisions.go:635), значит decline→approve, по-видимому, двигает окно. Не исполнено.\\n\\nНЕ ИСПОЛНЕНО. Путь «dst банкноты на отказанном термине доходит до редактора» подтверждён чтением (miner_emit.go:262-268, memory.go:320-331 и :762), прогона не было. mining.go:612 (SinceCh 0 у банкноты, по S2) не перепроверял. Не проверено, отдаёт ли платформа движку усечённый исходник.\\n\\nЧИСЛА. «14 из 66» и «INVENTED 17/66» не найдены ни в эксп-25, ни в эксп-24, ни в журнале, ни в бэклоге. Возможна другая формулировка; помечено как непроверенное, а не опровергнутое.\\n\\nОГОВОРКА ОБЛАСТИ. Поправочную ноту к D39.104 искал по 10 файлам (6191 строка): «оговорк» даёт 27 хитов в журнале, но вместе со словом «област» — только сам D39.104 п.1. Упоминания эксп-18 в нотах есть только как санкция пробы (D39.103).\\n\\nКОД. Проверен на /home/ubuntu/tm-verify-1509 (5dbb5cb). По S3, в main (9241934) сверху только правки доков. Незакоммиченные бэкенд-правки main-дерева (quality.go, stagerun.go, migrate.go, chunkstatus.go и др.) не смотрел, якоря строк могут сдвинуться.\\n\\nНЕ ЧИТАЛОСЬ.\\n- Мной: книги, eval и docs/PROGRESS.md (его правит другая сессия).\\n- Сверщиками целиком: research/28, 29, 29-codex и эксп-23.\\n- START_PROMT: только проверил наличие четырёх цитат (4 из 4, контроль 103 строки), никуда не копировал.\\n\\nЗНАМЕНАТЕЛИ. Отбор относящегося делали сверщики, поэтому знаменатели sync — оценка снизу." + } +} \ No newline at end of file diff --git a/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/06-owner-words-and-freeze-answers.md b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/06-owner-words-and-freeze-answers.md new file mode 100644 index 00000000..b4d13cfd --- /dev/null +++ b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/06-owner-words-and-freeze-answers.md @@ -0,0 +1,273 @@ +# Слова владельца и ответы оркестратора о заморозке банка — выписка из транскрипта, 15.09 + +> ⚠ **АРХИВ-УЛИКА, НЕ ЗАКАЗ.** Выписка сделана скриптом из транскрипта сессии оркестратора +> `/home/ubuntu/.claude/projects/-home-ubuntu-projects-textmachine-main/6bf42f99-b840-4396-80ac-ab93384b11dc.jsonl` +> (строки файла нумеруются с 1). Транскрипт лежит вне репозитория и умрёт с машиной; пока он жив, первоисточник — +> он. Тексты ниже перенесены без правок; граница реплики владельца во вставке §2 — первая пустая строка после «❯». +> +> **Что отобрано.** §1 — сообщения владельца 15.09, где речь о банке памяти или о решениях по нему, включая одно, +> пришедшее из очереди (`queue-operation`, строка 1456). Вне отбора, как не о банке: строка 17 до вставки (роль +> оркестратора, git, план), строка 183 из очереди («Тебе от меня нужно что то? С прошлой машины?»), строка 202 +> (сессия b1 пуста, копии прогонов). §3 — ответы оркестратора о заморозке. +> +> ⛔ **Ответы оркестратора в §3 — предложение, ОТОЗВАННОЕ 15.09** (`04`, README каталога). Не держатся или не установлены: +> - «Ломается он между прогонами, примерно на каждом пятом термине» (строка 870) — выведено из 12 из 69 и 14 из 66, +> снятых ПОСЛЕ человеческой подписи; на покупках глав живьём не наблюдалось; качество замен не судилось (эррата 11.09-и). +> - Случайность модели как причина пере-решения — не установлена. Строка 870: «пере-решение — просто бросок кубика»; +> строка 840: «…«пере-решить позже» — это бросить кубик ещё раз»; строка 1038: «Модель случайна, поэтому часть +> переводов меняется». Второй проход шёл после подписи двух термов, и вход терминолога менялся: общих +> `request_hash` между проходами у A 0 (7 и 6 вызовов), у B 1 из 7 (замер опровергателя 16.09). +> - ⚠ **Про окна верно обратное тому, что сказано в строке 920.** Утверждение строки 896 «Сегодня на авто-пути у строки +> нет окна «с главы N»» ДЕРЖИТСЯ. Неверна поправка в начале строки 920 (в выписку не вошла): «У движковых строк +> окно есть: оно начинается с главы первого появления термина». +> - Замер 16.09 по базам A/B: `since_ch` > 0 только у 2 строк на книгу (`方正` = 2, `沈翠` = 3); у 67 из 69 и 64 из 66 +> строк он 0; `until_ch` = 0 у всех. +> - Нижнюю границу по первому появлению ставит только детерминированный канал майнера +> (`backend/internal/miner/miner_emit.go:210`, `:387-399`); кандидаты только из банкноты идут с `SinceCh: 0` +> (`backend/internal/pipeline/mining.go:612`). +> - По замеру опровергателя 16.09, из строк с нулевой границей 30 (A) и 22 (B) впервые встречаются в главах 2–3. +> - «Скрытый в первом томе пол персонажа замёрзнет как «без рода»» (строка 1038) — сказано без D5 п.1, где +> ратифицированы проактивный `gender=hidden` и ретро-патч «с тома N — так». +> - Прочие утверждения о коде в §3 этой сменой не пере-проверялись — сверяй по дереву `5dbb5cb`. + +## 1. Слова владельца 15.09 о банке — сообщения целиком + +### строка 731 · 2026-09-15T14:12:26.839Z + +```text +1. Ну да, так так и должно быть? Это ведь обычный механизм останова который должен отрбатать, и далее просто можно возобновить прогон пополнив или подняв траты. Разве это проблема? 2. Выдай ему, да. 3. ТЫ имеешь ввиду решение когда у нас сам банк памяти уже неконсистентен и мы из-за того что отправляем батчами это не замечаем? А точно это так решается? Я просто не понимаю о чем речь, что то похитрее мы тут придумать не можем? 4. Еще раз о чем речь? Опиши нормально что решаем и какие альтернативы +``` + +### строка 867 · 2026-09-15T14:37:18.772Z + +```text +НУ так по 3 и 4 что фабл предлагает? Я чет не понимаю, вы досоветовались конкретно по проблеме то, +``` + +### строка 878 · 2026-09-15T14:40:49.693Z + +```text +3. Ну вариант где замораживаем звучит логично, так а что тут не так пойти может? Форма как то перевода поменяться или что? 4. Ну да, звучит логично, глава клана должен сохраниться как перевод, другое выкинуться, только я спрашивал скорее какой алгоритмический фикс и какие трейдоффы тут могут произойти +``` + +### строка 993 · 2026-09-15T16:22:51.559Z + +```text +1. Не очень понял как это так получается? 2. Как это работать то продуктово будет? НЕ очень понял, ты прежде чем ко мне идти ты обсудил с фаблом? 3. Что такое перекрывающее окно? +``` + +### строка 1035 · 2026-09-15T16:33:18.109Z + +```text +Так, еще раз. В чем проблемы заключаются без воды, ваше решение которые вы предлагаете, возможные трейдоффы решения +``` + +### строка 1042 · 2026-09-15T17:08:02.429Z + +```text +1. Меня вот интересует как банк памяти решает проблему которая по идее должна быть общей, например у нас перосонаж был мужским первые 10 глав, затем поменял пол, вот на докупке новых 10 глав, как с этим банк памяти справляется? И то же самое вопрос в целом абстрактный, есть ли еще подобные кейсы? То что как то замораживать банк памяти и каждый раз не переводить его это понятно, представь если там что то изменится на перевод это же пол книги может перегенерировать. 2. Так, при чем тут фронт? Что за спор? У нас диалог был про окно какое то покрывающее. 3. А как это работает? Я что то не очень понял, ну типо у нас контекста стало больше из-за новых глав и поэтому терминолог начинает спорить что это термин по другому переводится? 4. 族长 и 族長 это точно одинаковый термин? Я китайский не знаю, но выглядит это как разные слова, просто я думал что мы все время говорим как бы об одном слове которое не схлопывается, поэтому тут вообще вопрос а о том ли мы говорим с тобой. 5. Так а что значит глава оплачена но не доделана? А я понял, мы же батчами засылаем, ну тогда да, надо начинать с того что мы уже перевели, зачем ее сначало то мусолить, это вообще странно что сразу так сделано не было +``` + +### строка 1094 · 2026-09-15T17:22:01.525Z + +```text +1. Ты тут не упарываешься в конкретное решение на моих замечаниях? Нам бы придумать что то качественное вместо каких то заплаток. Обсудил бы что ли окончательное решение грамотное с фаблом и его предложение, только потом ко мне идти надо. 2. Да, но как? Я так и не понял, ты как хочешь определеять что термины разных написаний? Это чисто китайская проблема? Или еще других языков? У нас не получается антипаттерн заплатка под конкретный язык? Опять же вопрос как сделать универсально. 3. Я все еще не понял что ты хочешь? Кому биллинг записывать в чей счет? Юзера или наш? Или как? Или это чисто вопрос метадаты которая возвращается? Ты меня прям запутал с этим всем +``` + +### строка 1296 · 2026-09-15T18:29:05.141Z + +```text +Тут еще вопрос насколько ты в синке с тем что мы запланировали по банку памяти и насколько ты в синке с тем что мы исследовали и ресерчили и изобретали алгоритмы по банку памяти в репозитории, а то может быть мы уже запланировали в бэклог что то умное что решает нашу проблему +``` + +### строка 1362 · 2026-09-15T19:53:35.856Z + +```text +Поднял, передавай дела сессии, пусть наследуется от тебя. И еще скажи ей что на протяжении всей работы это скорее не прям ресерч а ресерч консилуум где идет совет о том как строить между разными агентами (разрешаю 1-2 фабла по необходимости для этой сессии) +``` + +### строка 1456 · 2026-09-15T20:05:01.662Z · из очереди + +```text +Не отвлекайся пока от банка памяти, работай по нему +``` + +## 2. Реплики владельца из вставки разговора с прежним оркестратором (строка 17; метки «Saturday» — 12.09) + +### реплика 1 + +```text +Ну да, у нас вроде бы вот ты говоришь имена места и титулы? Где то в документации я уже обсжудал добавить майнинг обычного term. Тут то есть проблема в том что какой нибудь название меча тоже не войдет в банк? Или еще какой нибудь термин. Ты в целом имеешь ввиду что черновику не дали задание найти слова которые могут попасть в банк памяти а только четко месте титулы имена? Просто тут в чем проблема, конечно какой нибудь клан переводить надо консистенотно, но тут проблема если мы начнем майнить такие термины то это взорвет кардинальность банка памяти, то есть тут я не знаю даже как поступить, не можем мы ведь предсказать что такой тремин как клан может быть переведен еще и как род? Хотя тут вот сложно как то в общем говоря, может просить модель черновую складывать в банк памяти все термины которые она прям 50\50 может переводить? Ну знаешь вот я слышал что есть алгоритм сейчас который водные метки в тексте ставит что это ии генерейтед текст и там он работает на основе что модели без ранзицы какое слово ставить если оно по эмбедингам близко. А знает ли модель на момент перевода что она может это слово несколькими значениями перевести? Или это чисто от текста зависит вокруг? +``` + +### реплика 2 + +```text +Да, ты прав, модель не стоит загружать вопросом про стохастичность выбора перевода слова. Подправь тогда промт на стройку майнинга термина в банк по spread: но тут же как, опять надо продумать алгоритм, дай задание сессии. Потому что как думаешь может ли эта стройка обернуться чем то против нас? Ну за что придется платить чем то (я имею ввиду переносном что могут побочные эффекты начаться и так же кардинальность сильна вырастет) +``` + +### реплика 3 + +```text +Кстати тут ведь знаешь еще как, такой банк памяти по spread может обеднять очень сильно язык. Потому что термин который можно перевести по-разному это вообще то нормальная составляющая художественного перевода. И вот где мы тут можем заплатить проблемами новыми, у нас начнут переводиться все слова в книге одинаково которые вовсе не обязаны переводится одинаково и даже плохо что они переводятся одинаково. Что думаешь? +``` + +### реплика 4 + +```text +Только вот тут проблема в том что у нас есть алгоритм в бэкенде который скипает подпись банка, и дловек не контролирует перевод. Поэтому надеяться что это отловит человек довольно ненадежно. А тыговоришь что мы можем точно определить такие вот слова алгоритмом по spread? Или мы отказываемся от этой идеи в целом? +``` + +### реплика 5 + +```text +Так это может решить не просто редактор, а банк памяти. у нас ведь хорошая модель переводит банк памяти, мы можем сделать эту штуку чуть посообразительнее чем она есть сейчас. Потому что запросы перевода намайненого банка памяти очень дешевые относительно всей книги, мы можем на них не экономить, ведь там очень мало текста и аутпута. Но вот как это нормально реализовать не очень понятно конечно говоря. К слову тут еще примешиваются мои идеи из start promt которые v6 давать и назначать еще ролей черновику и банку памяти как майнинговым сессиям в бэкенде, что там можно намайнить не только термины, ну вот главы размечать тоже моя идея была, у нас ведь это сейчас построено? +``` + +### реплика 6 + +```text +Нет, не нужно их сводить. Пусть они останутся идеями, потому что самая оптимальная штука которая есть сейчас по цене качеству это черновик -> банк памяти -> редактор переписыватель полный. Если мы будем сюда внедрять всяких критиков то это уже начнет сильно дорожать перевод, нам это в этом плане не нужно. Нам бы вот на текущей архитектуре разрулить проблему эту. Так что тут принимаются идеи светлые +``` + +### реплика 7 + +```text +1. Честно говоря я не понял о чем ты говоришь, можешь подраскрыть мысль? И она вообще нормальная как идея? Или это хак? 2. Да, наверное можно, и даже мне кажется лучшее решение, но тут к сожалению надо разграничить, возможно модель терминолог захочет выкинуть термин который выкидывать точно нельзя. 3. В целом да, можно, но опять же у нас это стабильно по черновику будет, а редактору дано задание более живой язык предоставить, если не гейтануть его терминами, то он может переписать их часть просто под горячую руку попав. 4. Ну вот я не знаю, так как модель стохастическая то с чего ты взял что редакторы будут все время принимать одно и то же решение? Грубо говоря + если ты скажешь им вот этот термин из банка он spread >= 2 но мы не знаем художественный перевод эедактор может принять так же не консистентное решение. В общем я тут думаю механизм какой то нужен именно в точке консистентности и закона и там же принимать решение -- в точке банка памяти, возможно нужно сейчас нынешний контекст под термином хорошенько расширить, или делать на такие вот термины запросы с контекстом пожирнее где они встертились и тп, надо подумать +``` + +### реплика 8 + +```text +1. А, да. Это действительно так и есть, но это баг, который мы вроде как пытались закрыть чем то? Или закрыли? Я уже честно говоря не помню, но мне кажется что мы о проблеме в курсе, где то это написано и какой то услоный подход к решению мы уже делали, или записали в бэклог что это надо пофиксить так-то и так то. 2. Ну опять же это ничего не улучшает, ты редактору подсовываешь термин который должен быть консистентным а может быть и художественным, у редактора нет знаний о том что с этим термином сделают другие редакторы, поэтому так оставлять его опасно, поэтому я и говорю что тут банк памяти сразу должен идти законом. Пак переписывай да, только я не понимаю подо что ты его переписывать собрался то, какое целевое решение правильное то которое работать будет а не стрелять ты определился? И ты уверен в своем решении? +``` + +### реплика 9 + +```text +Можешь луп свой снять? И касательно ряда 330 -- поясни о чем вообще речь и какое предложение от тебя? +``` + +## 3. Ответы оркестратора о заморозке банка (отозваны — см. баннер) + +### строка 840 · 2026-09-15T14:20:34.080Z + +```text +Поправляю свою склонность из прошлого сообщения: вариант Б — «пере-решать до отгрузки с бо́льшим контекстом» — снимаю. Старший коллега (Fable) его опроверг, и я проверил довод по коду: цепочка идёт от `TranslateBook` до стопа банка. Контексты для терминолога собираются из исходника ВСЕЙ книги уже при первом решении, включая неоплаченные главы. Следующий том новой информации о термине не приносит. Значит, «пере-решить позже» — это бросить кубик ещё раз: перевод меняется, а лучше не становится. + +**Рекомендация по вопросу 3 — А: заморозить принятое, плюс бесплатная сверка.** +- **Что делаем.** Однажды принятый перевод больше не пересматривается, при следующих покупках добавляются только новые термины. Модель спрашивают лишь про новое, поэтому выходит дешевле, чем сейчас. +- **Сверка.** Если черновики новых глав переводят замороженный термин иначе, это попадает тебе в карту подписи вместе с ценой переделки уже отгруженных глав. Молча ничего не меняется. +- **Минус.** Неудачный первый перевод живёт, пока его не поправит человек. Правка уже построена: смета и точечная переделка глав, где встречается термин. +- **Где настоящая хитрость.** Не в том, чтобы пере-решать, а в том, чтобы лучше решать первый раз. Сейчас терминолог видит по каждому термину 3 фрагмента по ±40 знаков. Трудным терминам можно дать больше. Помогает ли это качеству, не измерено: два старых замера противоречат друг другу. Поэтому это отдельный маленький платный замер потом, а не условие. + +**По вопросу 4** рекомендация прежняя: вариант «в», считать разные написания одного термина одним термином, ряд закрыть. + +Если согласен с «А + сверка» и с «в», пишу пак про банк. Выдам его, когда пак b1 закроется актом: слот бэкенда один. От `textmachine-main-b1` жду эхо. +``` + +### строка 870 · 2026-09-15T14:38:21.268Z + +```text +## 3. Банк пере-решает сам себя + +**Проблема на примере.** В первую покупку банк решил: `舅母` → «жена дяди по матери». Главы 1–3 ушли читателю с этим переводом. При следующей покупке терминолог переводит весь банк заново, своих прошлых решений не видит и на этот раз выдаёт «тётя по матери». Главы 4+ редактируются уже так, а главы 1–3 остаются как были. Это не батчи и не «банк внутри неконсистентен»: внутри одного прогона банк ровный. Ломается он между прогонами, примерно на каждом пятом термине. + +**Что предлагаем — «решённое остаётся решённым».** +1. **Заморозка.** Перевод, который уже ушёл в отгруженные главы, замораживается. При следующих покупках модель про него больше не спрашивают, а спрашивают только про новые термины. +2. **Сверка на каждой покупке, бесплатная.** Если черновики новых глав упорно переводят замороженный термин иначе, ничего не меняется молча. Тебе в карту подписи приходит: «`舅母`: в банке “жена дяди по матери”, черновики пишут “тётя по матери”; переделать главы 1–3 под новый вариант — $X». +3. **Менять замороженное может только человек** — через уже построенную правку банка, со сметой и переделкой только тех глав, где термин встретился. + +**Что это стоит.** +- *Дешевле, чем сейчас.* Банковые вызовы идут только по новым терминам. В прогоне B повторная прогонка того же банка стоила 8.5% цены книги, и эта часть уходит. +- *Минус.* Неудачный первый перевод живёт, пока его не поправит человек. +- *Разово.* На первом прогоне каждой книги после лендинга банковые вызовы перекупятся один раз — это центы. + +**Что отвергли и почему.** +- **«Пере-решать позже, с бо́льшим контекстом»** — к нему я склонялся, и это была моя ошибка. Модель уже при первом решении видит фрагменты из всей книги, так что второй том новой информации не даёт, и пере-решение — просто бросок кубика. +- **«Разрешить модели передумывать с причиной»** — это либо тот же разнобой, либо платная переделка прочитанных глав. + +**Оговорка.** Разнобой между томами выведен из кода, живьём на многотомной книге мы его не видели. Поэтому первое, что сделает пак, — бесплатный тест: подписать один термин и возобновить прогон; переводы остальных терминов обязаны не измениться. +``` + +### строка 896 · 2026-09-15T14:44:07.914Z + +```text +## 3. Что может пойти не так при заморозке + +**Форма перевода не поменяется.** Банк хранит словарную форму («жена дяди по матери»), а склоняет её редактор по месту, как сейчас. Заморозка фиксирует только словарную форму. Единственный побочный эффект с формами — возможный шум в сверке: если черновик назовёт термин в косвенном падеже, сверка может принять это за расхождение. + +Настоящие риски, от серьёзных к мелким: +1. **Неудачный первый перевод живёт.** В прогоне B переводы 17 терминов из 66 терминолог придумал сам, ни один черновик их не предлагал. Сверка покажет расхождение с черновиками, но на пути без человека перевод останется, пока его не поправят. +2. **Термин законно меняется по ходу книги.** Героя повысили в титуле, секту переименовали, прозвище сменилось; или одни иероглифы в разных местах значат разное (фамилия и обычное слово). Сегодня на авто-пути у строки нет окна «с главы N», так что замороженный перевод потащит старый вариант дальше. Сверка это заметит, но исправить может только человек. +3. **Составной термин против составляющей.** Если заморожен «дядя и тётя по матери» (`舅父舅母`), а позже отдельно решается «тётя по матери» (`舅母`), они могут разойтись. Лечится тем, что замороженные строки подаются терминологу опорой — так же, как сегодня подписанные. +4. **Поздно замеченный термин.** Черновики назвали термин только во втором томе, а в отгруженных главах 1–3 он уже встречался и был переведён свободно. Заморозка это задним числом не исправит. Сверка может показать это с ценой переделки. +5. **Банк растёт.** Сегодня банк каждый раз переписывается из топ-200, и термины молча выпадают посреди книги — заморозка это как раз лечит. Обратная сторона: на длинной книге строк больше, и в кусках, где срабатывает много терминов, наименее важные вытесняются из промта редактора. Это логируется, но на полной книге не мерено. +6. **Доплаты не исчезают совсем.** Каждая покупка добавляет новые термины, значит главы, где сработал новый термин, переделываются за деньги. Их станет заметно меньше, чем сейчас, но не ноль. + +По сумме рекомендация прежняя: заморозка лучше того, что есть. Пункты 1–4 закрываются сверкой и правкой человеком, пункт 3 — отдельной мерой в паке. Fable сейчас опровергает этот список рисков; если найдёт существенное, донесу. Оба решения — заморозку со сверкой и фикс ряда 330 — могу вписывать в пак? +``` + +### строка 920 · 2026-09-15T14:47:52.249Z + +```text +## Заморозка: три риска, которых у меня не было + +1. **Поздний род.** + - *Риск.* Если в первом томе пол персонажа не виден или скрыт до раскрытия, классификатор честно ставит «нет рода», и заморозка закрепит это на всю книгу. Редактор так и не получит подсказку по согласованию. + - *Лечение.* Замораживать только перевод, а пустые поля вроде рода разрешить дополнять позже: «пусто → значение» — это не пере-решение. + - *Цена.* Когда род дополнится, главы, где встречался персонаж, переделываются за деньги. + +2. **Многозначность станет вечной.** + - *Риск.* Для имён и названий это терпимо. Но если когда-нибудь пустим в банк обычные слова вроде «род/клан», закон ударит по каждому их употреблению. + - *Лечение.* Добавить оговорку в промт редактора. + - *Цена.* Такая правка сдвигает снапшоты всех книг, поэтому её место — в окне большой перенарезки, в паке структуры глав, а не в паке про банк. Называю зависимость. + +3. **Первое решение часто стоит на одном примере.** + - *Риск.* В прогоне B у 52 из 58 терминов с одним вариантом этот вариант пришёл из одного куска. Такой перевод замёрзнет. + - *Лечение.* Закрывается только сверкой в карте подписи. + +## Уточнения формы — рекомендацию не меняют + +- **Что замораживать.** Не «термин, дошедший до конкретной главы», а все движковые строки банка того прогона, который отгрузил хотя бы одну главу. Так проще, не зависит от номеров глав, которые перекрой изменит, и ошибается в безопасную сторону: заморозит лишнее, но не разморозит прочитанное. +- **Составной термин и составляющая.** Замороженные строки становятся опорой терминолога так же, как сегодня подписанные. Это закрывает риск, что они разойдутся. +- **Рост банка ограничен.** Детерминированный канал на длинной книге и сегодня даёт не больше 200 терминов за всю книгу, черновики — не больше 200 новых за прогон. Мой прежний риск «банк растёт» был раздут. + +**Рекомендация прежняя:** заморозка, бесплатная сверка в карту подписи, менять замороженное — только человеку. По ряду 330 — фикс с правилом покрывающего окна. Вписываю оба решения в пак про банк? +``` + +### строка 1038 · 2026-09-15T16:34:22.651Z + +```text +## 1. Банк пере-решается между покупками + +**Проблема.** При подписи и, по коду, при каждой следующей покупке глав терминолог заново переводит весь банк и своих прошлых решений не видит. Модель случайна, поэтому часть переводов меняется: после подписи замерено 12 из 69 и 14 из 66. Новые главы идут с новым переводом, отгруженные остаются со старым — между томами получается разнобой, и ни одна проверка его не ловит. + +**Решение.** +- **Заморозка.** Всё, что было законом для отгруженных глав, заморожено. Модель решает только новые термины, а старые видит как закон. +- **Бесплатный детектор споров.** Если черновики новых глав упорно переводят замороженный термин иначе, записывается «спор»: как в банке, как пишут черновики, сколько глав задето. Молча ничего не меняется. +- **Правка.** Менять замороженное может только человек, через правку банка. + +**Трейдоффы.** +- **Неудачный первый перевод живёт до правки человеком**, а на пути без подписи — навсегда. В прогоне B 17 переводов из 66 модель придумала сама. +- **Законная смена термина по ходу книги** (повышение, переименование) на пути без подписи не отработает: останется старый перевод. +- **Скрытый в первом томе пол персонажа замёрзнет как «без рода».** Нужно разрешить дописывать пустые поля, но это платная переделка глав с этим персонажем. +- **Плюс: дешевле, чем сейчас.** Модель спрашивают только про новое. Разовая цена — одна перекупка банка на книгу после лендинга, это центы. +``` + +### строка 1038 · 2026-09-15T16:34:22.651Z + +```text +## 3. Автосмена перевода «с главы N» без человека + +**Проблема.** На пути без подписи решать должен банк, а не человек — твоя позиция. + +**Решение.** Механизм «модель дважды подтверждает спор → новый перевод действует только в новых главах» пока не включаем. + +**Трейдоффы.** +- Пока выключено, законная смена термина на пути без подписи не лечится. +- Включить раньше опасно: ошибочный разрез нельзя откатить, отклонение в двери правки стирает термин целиком. Сама ошибка тоже создаст разнобой. +- Условия включения: в двери правки появилось действие «сменить перевод с главы N», и есть статистика детектора на длинной книге. +``` + diff --git a/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/README.md b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/README.md new file mode 100644 index 00000000..c2a501b6 --- /dev/null +++ b/docs/archive/reports/BANK_CONSILIUM_INPUTS_2026-09-15/README.md @@ -0,0 +1,126 @@ +# Входы консилиума по банку памяти — доказательная база смены 15.09 + +> ⚠ **АРХИВ-УЛИКА. НЕ РЕШЕНИЯ И НЕ ЗАКАЗ.** Здесь собрано то, что оркестратор №23 (продолжение, сессия +> `textmachine-main-75`) и его советчик Fable 5 выяснили, спроектировали и опровергли 15.09, прежде чем передать +> предмет консилиуму. Инструкции отсюда НЕ исполняются. Заказ — `docs/BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md`, +> итог консилиума — `docs/research/35-bank-memory-consilium.md`. +> Код, по которому всё снято, — `5dbb5cb` (рабочее дерево `/home/ubuntu/tm-verify-1509`); `backend/` и `platform/` +> закоммиченного `9241934` те же. Незакоммиченные правки бэкенд-сессии в главном дереве сверщики не смотрели. Базы +> прогонов и транскрипт сессии лежат вне репозитория и умрут вместе с машиной. + +## Файлы + +| файл | что это | кто сделал | статус | +|---|---|---|---| +| `01-premises-verification.json` | Проверка посылок прежнего оркестратора: приём в банк по разнобою черновиков, отказ терминолога, закрытие ряда 330. Три линзы (`A`, `B`, `C`) и критик, код `5dbb5cb`, улики прогонов A/B | воркфлоу оркестратора (Opus) | ОПРОВЕРГНУТЫ: `T4` (отказ у терминолога есть) · `T7` (оба числа провалов — классификатора) · `P1` (подмешать решения в партии терминолога без перекупки нельзя: сообщения собраны заранее) · `B2` (неподписанная строка с передачей едет редактору законом) · `B3` (петли «банк → черновик» нет) · `P2` (смена приёма двигает `memory_version`) · `R2` · `R3` | +| `02-design-v1-fable.md` | Проект «банк — журнал решений с окнами», первая редакция | Fable 5 | ⛔ отозван; проверен в `03`, шесть блокеров | +| `03-design-v1-verification.json` | Адверсариальная проверка v1: факты кода (`L1`) · ратифицированное и перекрой глав (`L2`) · миграция, деньги, детерминизм (`L3`) · критик | воркфлоу (Opus) | критик: «Как направление для владельца проект годен… В нынешнем виде нести его нельзя» | +| `04-design-v2-and-owner-proposal.md` | Вторая редакция Fable и предложение, ушедшее владельцу | Fable 5 + оркестратор | ⛔ **ОТОЗВАНО 15.09**: 12 расхождений с решённым, замеренным и собственным планом (`05`) | +| `05-prior-art-map.json` | **Главный вход.** Сплошная сверка репозитория по банку. Сверщики: `S1` решения и планы (60 находок) · `S2` исследования, эксперименты, бриф владельца (69) · `S3` код, построенное и выключенное (52). Сводчик `synthesis`: `per_element` · `missed_smart` · `contradictions` · `must_change` · `sync_honest` · `owner_summary` · `obstacles` | воркфлоу (Opus) | 180 цитат проверены скриптом: 178 дословных, но у 2 из них неверная атрибуция; 1 не найдена; 1 сводчиком не учтена (`synthesis.obstacles`). ⚠ Сверщики читали не всё, знаменатели — оценка снизу. D5 п.1 сверка нашла (`S1` и `S2`, элемент E4; в `synthesis` 6 упоминаний), а оба проекта его не использовали | +| `06-owner-words-and-freeze-answers.md` | Выписка скриптом из транскрипта: сообщения владельца 15.09 о банке целиком (одно — из очереди), его реплики из вставки разговора 12.09 и ответы оркестратора о заморозке банка (строки 840, 870, 896, 920, 1038) | скрипт оркестратора | ⛔ ответы оркестратора — отозванное предложение; неподтвердившиеся утверждения перечислены в баннере файла | + +## Замеры оркестратора 15.09 + +Прибор: `python3`, `sqlite3.connect('file:<база>?mode=ro&immutable=1', uri=True)`. +Базы: `~/tm-coldrun-a/stand/books/bk_ROEHZBD46ALFI43E/project.db` (A) и +`~/tm-coldrun-b/stand/books/bk_NH6275ZIRFFTLZHG/project.db` (B). +Сайдкары стопа банка: `books/gu-zhenren/door-to-file/bankstop-paid/` (A) и `books/gu-zhenren/door-to-file-b/bankstop/` (B). +⚠ `books` — симлинк на `/home/ubuntu/projects/textmachine/books`, и `find` без `-L` в него не заходит — даёт ложный ноль. +Все числа ниже независимо пере-сняты опровергателем промта тем же прибором и сошлись. + +- **Пере-решение между стопом и финалом.** Сравнивались `proposed[].dst` из `project.db.bank.json` стопа и `glossary.dst` + полной базы, ключ — `src`. + - A: все 69 предложенных есть в финале, передача сменилась у 12. + - B: все 66 есть в финале, сменилась у 14. + - Все сменившиеся строки в финале со статусом `draft`. + - ⚠ В обоих прогонах между стопом и финалом был второй проход терминолога после ЧЕЛОВЕЧЕСКОЙ подписи двух термов. + - Подпись лежит в `mined-delta.yaml` стендов: по два `status: approved` (`方源`, `古月山寨`). + - `docs/experiments/25-door-to-file-b.md:88`: «заход терминологии ИЗМЕНИЛ передачу у **12 термов из 69**». + - Эррата 11.09-и (греп `Эррата 11.09-и` в `docs/architecture/05-decisions-log.md`) называет это ценой + пере-майнинга после подписи: «Хороши ли эти 12 замен — вопрос КАЧЕСТВА». + - Пере-решение на следующей ПОКУПКЕ глав выведено из кода, живьём на многотомной книге не наблюдалось: + - предупреждение `a VOLUME ceiling on a book that MINES its bank` (`backend/internal/pipeline/volume.go:351`); + - порядок «новые юниты раньше пере-делки» (`:410-427`, `DELIVERY BEFORE REWORK`). +- **Разнобой черновиков.** Термов со `spread ≥ 2` на стопе: A — 9, все 9 в финальном glossary; B — 8, все 8 в финале. +- **INVENTED** (строки `INVENTED(no draft proposed it)` в `project.db.bank-stop.txt`): A — 11 из 69, B — 17 из 66. +- **Одна передача у разных `src`.** `宗族祠堂` и `宗祖祠堂` → «родовой храм предков»: в финале у B, на стопе у A. В финале + A и на стопе B совпадений нет. По контекстам `bank-stop.txt` это один зал в одной сцене. +- **Подписанные строки финала** — по 2: `方源` → «Фан Юань» в обоих; `古月山寨` → «горная крепость Гуюэ» (A) и + «крепость Гу Юэ» (B). +- **Деньги.** Суммы `request_log.cost_usd` и `checkpoints.cost_usd` совпадают в обеих базах. + + | | весь прогон | терминология | classifier | terminologist | 1-й проход | 2-й проход | + |---|---|---|---|---|---|---| + | A | $0.419423 (33 вызова) | $0.065297 = 15.6% | $0.035803 (6) | $0.029494 (7) | $0.036554 (id 10–16) | $0.028742 (id 23–28) | + | B | $0.396657 (35 вызовов) | $0.083339 = 21.0% | $0.045313 (6) | $0.038026 (8) | $0.049546 (id 12–18) | $0.033793 (id 25–31) | + + Проходы разделены вызовами черновой стадии: id 17–22 в A и 19–24 в B. У классификатора B 2 из 6 вызовов закончились + `finish_reason = length`, у классификатора A — 0 из 6. +- **Размышление модели не видно.** `request_log.reasoning_tokens` = 0 у всех ролей обеих баз. `ReasoningTokens` в + `checkpoints.usage_json` равно 0 или отсутствует (у части вызовов черновой стадии). + +## Что снято в эту смену — не повторять + +- «Приём в банк по разнобою черновиков» вакуумен: термы со `spread ≥ 2` уже в банке. +- «Партия терминолога увидит решения предыдущих партий» даром не получается: сообщения всех партий собраны до первого + вызова, и хеш каждой следующей зависел бы от ответов предыдущих (`01`, `P1`). +- «У терминолога нет отказа» — есть: ⟦TM-NO-DST⟧ или молчание. Но строка сохраняет передачу из черновика + (`backend/internal/miner/miner_emit.go:261-268`). Как механизм сигнал отказа закрыт D39.102 п.2. +- «Петля банк → черновик следующих глав» — нет: черновая волна идёт по базовому банку без `Source:mined`-строк + (`01`, `B3`; ряд 409). +- «Ряд 330 исполнен по построению» — нет (`01`, `R2`). Хранилище сравнивает сырую строку намеренно: «族長 and 族长 with + one sense and window are two accepted rows, not one» (`backend/internal/membank/memseed.go:874-876`). И «одно + определение тождества за $0» тоже нет: нормализация меняет байты инъекции (`05`, `must_change`). +- «Первое решение живёт до правки человеком» — против риска B1 (`docs/architecture/06-memory-risk-registry.md:44`: + «первый (наименее информированный) перевод имени лочится на 1000 глав»). И против D39.69: «гипотеза первенства + ОПРОВЕРГНУТА — роль не первовхожденческий и не частотный выбиратель, ре-решает контекстом». + - Это же посылка предложения «заморозка + сверка + менять замороженное только человеку» (`06`, строка 870). + - Владелец назвал его логичным и спросил, что при нём ломается. Ответы оркестратора — в `06`, с оговорками баннера. +- «Улики только из переведённой части книги» — против D39.42: банк майнится по черновикам всей книги сразу. +- «Оговорка области употребления опровергнута экспериментом 18» — неточно. `docs/experiments/18-editor-wire-probe.md:621`: + «Не подтверждено: оговорка области §B … В движок не вносить.» А D39.104 п.1 её ратифицирует. +- «`hidden` — исход классификатора» — нет: `backend/prompts/zh-ru/classifier.md:10-11` держит его ручным полем сида. + ⚠ **Но у смены пола уже есть ратифицированный ответ: сверка `05` его нашла, а оба проекта не использовали.** + - D5 п.1: проактивная эвристика `gender=hidden` и ретро-патч «с тома N — так» со стоимостью пере-перевода. + - D7 правка 1: `gender` — «с проактивной установкой `hidden` Analyst-ом на неоднозначности (D5.1)»; ты/вы — журнал + событий переходов. + - D19 п.3(в): `白凝冰` этой же книги — «хрестоматийный кейс механизма D5.1». + - Построена ручная половина: у этой книги `hidden` выставлен в сиде (греп `сид финализирован (白凝冰` в журнале + решений). Проактивной установки нет, и это расхождение ратифицированного с построенным не снято. +- Вынос свёрток написания из ядра в данные языка двигает `NormVersion`, а он входит в тег нарезки и в ключ манифеста + (`backend/internal/pipeline/manifest.go:282`, `:384`). Это событие класса перекроя глав. +- `bankTermID` не двигать: D39.245 п.7 (перечеканка экспортных id уронила бы каждый банк-экспорт платформы) и + `backend/docs/CHAPTER_STRUCTURE_DESIGN.md:693` (§4.2). Акт D39.245 ратифицирует предмет структуры глав, а не механику. +- Ряд 130 — открытое СТОП-решение владельца, материалом для которого станет WARN второго прогона; «запретом» он не + является. Запрет D39.144 п.1 касается проектирования продуктового цикла пост-ридинговых правок. D39.165 его сужает, + греп `ОБЛАСТЬ D39.144 п.1 СУЖЕНА ЯВНО`. +- Откуда числа предложения. Сверка `05` (`sync_honest`): «14 из 66» на момент сверки было только в собственном плане + (`docs/NEAR_TERM_PLAN.md`, п.10), внесённом этой же сменой (`4200036`), а «INVENTED 17/66» не найдено ни в эксп-24 и эксп-25, ни в журнале, ни в бэклоге. + Оба — замеры оркестратора 15.09; «14 из 66» линза `B` в `01` сняла и сама. Выше оба пере-сняты. + +## Проверено по коду в эту смену (якоря по `5dbb5cb`; сомневаешься — пере-сними) + +- Движок по умолчанию не останавливается на подпись: `backend/cmd/tmctl/invocation.go:141` (`--verify-bank`, + «Default: never stop»). В коде это записано и так: `backend/internal/pipeline/bookconsistency.go:31`. У платформы + `stop_for_signing` обязателен: `platform/internal/httpapi/v0.go:655`. +- Платформа декодирует из банк-экспорта только `terms`: `platform/internal/ingest/bank.go:58-70`. Секция `proposed` + отбрасывается. +- У двери правки банка два глагола, `approve` и `decline` (`backend/internal/membank/decisions.go:61-62`). Род + решением не принимается (`:84-88`). Окно одним решением не правится, а `decline` снимает все окна поверхности + (`:90-92`). +- Окон у движковых строк почти нет (замер 16.09, базы A/B): `since_ch` > 0 только у 2 строк на книгу (`方正` = 2, + `沈翠` = 3), у 67 из 69 и 64 из 66 строк он 0; `until_ch` = 0 у всех. Нижнюю границу по первому появлению ставит только + детерминированный канал майнера (`backend/internal/miner/miner_emit.go:210`, `:387-399`); кандидаты только из + банкноты идут с `SinceCh: 0` (`backend/internal/pipeline/mining.go:612`). +- Свёртки написания исходника зашиты в ядро: таблица трад.→упрощ. встроена `backend/internal/text/norm.go:47` + (`data/trad2simp.txt`). Подбор строк нормализует и ключи, и текст куска: `backend/internal/membank/memory.go:333`, + `:574`. +- Контексты терминолога собирает `AttachKWIC` (`backend/internal/terminology/terminology.go:340`), вызов — + `backend/internal/pipeline/terminologist.go:280`. Куски упорядочены по (глава, кусок), то есть берутся ПЕРВЫЕ + вхождения по книге (`terminology.go:344-349`). Число и ширина берутся из конфига, затем из данных пар-пака + (`kwic_per_term`, `kwic_width`; `backend/internal/lang/langpack.go:744`), иначе действуют умолчания 3 и 40 + (`terminologist.go:75-76`, `:232-247`). В `configs/pipeline-c1.yaml` и `configs/langpacks/zh*` ключей `kwic` нет, + так что сегодня это три первых вхождения ±40. +- Редактору велено: «Род и форму имён и терминов сверяй по глоссарию» (`backend/prompts/zh-ru/editor.md:10`). Банкнота + черновика несёт три поля — термин, перевод, тип — и рода не несёт (`backend/prompts/zh-ru/translator-banknote.md:20`). +- `wave_selection` — только наблюдение: `backend/internal/pipeline/waveselection.go:22`. diff --git a/docs/orchestrator-norms-scratchpad.md b/docs/orchestrator-norms-scratchpad.md index 683b041c..b43d619c 100644 --- a/docs/orchestrator-norms-scratchpad.md +++ b/docs/orchestrator-norms-scratchpad.md @@ -58,10 +58,11 @@ | Зона | Промт | Сессия | Состояние | |---|---|---|---| -| бэкенд | `BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md` | ~~textmachine-b1~~ → свежая | ⛔ **СЕССИЯ b1 ПОТЕРЯНА 15.09** при переезде окружения (`textmachine-main-b1` — пустая сессия владельца, НЕ b1). Пак не завершён: круги не сошлись, нет «Чисел», таблицы мутаций, строки завершения. Сдача — в индексе main (sha `git diff --cached --binary` = `166997963c95…`), бэкап `~/tm-b1-orphan-index.patch`, копия только для чтения `~/tm-b1-orphan`; гейт на копии зелёный (19 ok · 0 FAIL · lint 0 · 9 скипов · 23/23). Передача — разделом ред. 5 того же промта; опровергатель к нему сошёлся за три круга (21 → 3 мажора → 0 мажоров, шесть миноров последнего внесены); выдан 15.09 сессии `textmachine-main-b1` словом владельца «выдай ему», confirm по слову 11.09 получен (эррата 15.09-а); жду эхо | +| бэкенд | `BACKEND_BOUGHT_MEANS_DELIVERED_SESSION_PROMPT.md` | ~~textmachine-b1~~ → свежая | ⛔ **СЕССИЯ b1 ПОТЕРЯНА 15.09** при переезде окружения (`textmachine-main-b1` — пустая сессия владельца, НЕ b1). Пак не завершён: круги не сошлись, нет «Чисел», таблицы мутаций, строки завершения. Сдача — в индексе main (sha `git diff --cached --binary` = `166997963c95…`), бэкап `~/tm-b1-orphan-index.patch`, копия только для чтения `~/tm-b1-orphan`; гейт на копии зелёный (19 ok · 0 FAIL · lint 0 · 9 скипов · 23/23). Передача — разделом ред. 5 того же промта; опровергатель к нему сошёлся за три круга (21 → 3 мажора → 0 мажоров, шесть миноров последнего внесены); выдан 15.09 сессии `textmachine-main-b1` словом владельца «выдай ему», confirm по слову 11.09 получен (эррата 15.09-а); эхо ✅. ⏸ **СДАН 15.09 ПО ПРАВИЛУ ОСТАНОВКИ П4** — круги не сошлись, остаток в таблице; со слов сессии: 29 путей, сырьё каталога вне репо в `/home/ubuntu/tm-mut-logs-final-1509`, числа мною не пере-сняты. **Приёмка отложена словом владельца** «Не отвлекайся пока от банка памяти, работай по нему» | | платформа | — | — | 🟢 **СЛОТ СВОБОДЕН** — пак принят актом `D39.250`, минор 0.15.0 | | полигон | — | — | ⛔ **ЗАКАЗ СНЯТ ВЛАДЕЛЬЦЕМ 11.09** («полигон не надо выдавать»); промт готов и лежит, пере-выдача — только его словом | | сквозной (вне кодовых зон) | — | — | ✅ **ЗАКРЫТ актом `D39.252`** 11.09; промт в архиве с баннером. Стенд поднят до конца приёмки, гасить по pid | +| консилиум банка (вне кодовых зон) | `BANK_MEMORY_CONSILIUM_SESSION_PROMPT.md` | textmachine-main-1e | ⏳ выдан 16.09 словом владельца 15.09 «передавай дела сессии, пусть наследуется от тебя»; совет агентов, Fable 1–2, $0 по моделям проекта; пишет только `research/35`; жду эхо | | фронт | заморожен | — | разморозка по критерию `NEAR_TERM_PLAN.md` | **Резерв израсходован: `textmachine-61` получила пак о падениях 11.09, как только слот освободился актом `D39.249`.** @@ -104,7 +105,8 @@ UNKNOWN 1 — её, дошёл один раз до правок; десять | 8 | бэкенд | за одну единицу платим дважды | textmachine-61 | ✅ своими словами, 4 возражения — и первое ПЕРЕВЕРНУЛО посылку пака | ✅ закрыт актом `D39.251` с дофиксом | | 9 | бэкенд | купленное доставлено (ряд 291 + приложение 379) | textmachine-b1 | — | ⛔ сессия ПОТЕРЯНА 15.09 при переезде окружения, пак не завершён → строка 11 | | 10 | сквозной | ХОЛОДНЫЙ ПРОГОН B, платный, с вычиткой всего текста | textmachine-82 | ✅ своими словами, 5 опасностей — три исправили промт | ✅ **ПРИНЯТ актом `D39.252`**, факт $0.396657 | -| 11 | бэкенд | ДОВОДКА пака 9 после потери сессии — раздел ПЕРЕДАЧИ ред. 5 того же промта | textmachine-main-b1 | ✅ своими словами, хеш индекса сверен, +5 недоделок сверх семи (две протухшие строки отчёта · цвет пинов снят не на HEAD · противоречие счёта читателей · §4.5(а) без исполнения · редрайв без катчера) — исходы отправлены | выдан 15.09 после трёх кругов опровергателя (21 → 3 мажора → 0) и confirm владельца | +| 11 | бэкенд | ДОВОДКА пака 9 после потери сессии — раздел ПЕРЕДАЧИ ред. 5 того же промта | textmachine-main-b1 | ✅ своими словами, хеш индекса сверен, +5 недоделок сверх семи (две протухшие строки отчёта · цвет пинов снят не на HEAD · противоречие счёта читателей · §4.5(а) без исполнения · редрайв без катчера) — исходы отправлены | выдан 15.09 после трёх кругов опровергателя (21 → 3 мажора → 0) и confirm владельца · ⏸ **СДАН 15.09 по правилу остановки П4**, приёмка отложена словом владельца «Не отвлекайся пока от банка памяти, работай по нему» | +| 12 | — (вне кодовых зон) | КОНСИЛИУМ «банк памяти длинной книги — как строить»: наследует банковую работу смены после отзыва проекта оркестратора; совет агентов, Fable 1–2 | textmachine-main-1e | ⏳ жду | выдан 16.09 после механической сверки 13 блоков и ЧЕТЫРЁХ кругов опровергателя: 4 мажора + 15 миноров → 1 + 7 → 1 + 2 → 0 + 2, миноры последнего внесены. ⭐ Опровергатель нашёл то, мимо чего прошли оба отозванных проекта: ратифицированный ответ на заглавный кейс владельца (D5 п.1, D7 правка 1) и что у движковых строк банка окон почти нет (`since_ch` > 0 у 2 строк на книгу, `until_ch` = 0 у всех). ⚠ Дважды мажор родила МОЯ правка: цитата о заморозке без её предмета · баннер выписки, объявивший опровергнутым верное утверждение | ⛔ **ПОЛИГОН СНЯТ ВЛАДЕЛЬЦЕМ 11.09.** Я предлагал пак трижды — `ed`, `5c` (обе отработавшие, отказались ПО НОРМЕ и были правы) и свежей `37`, — после чего владелец сказал «полигон не надо выдавать». Выдача `37` ОТОЗВАНА тем же часом. ⚠ Урок не про полигон: **я трижды искал адресата для заказа, приоритет которого не подтверждал у владельца.** Слот зоны свободен ≠ работу зоны надо заказывать.