Land softsign decl study and both decisions as D39.76: seed stopgap for two names, finding closed outside the core, engine anchor rule gated behind a cross-pair measure

This commit is contained in:
Claude (backend session) 2026-08-01 18:43:47 +03:00
parent 78b7b3480b
commit f4c4d458d6
7 changed files with 630 additions and 7 deletions

View file

@ -1,8 +1,8 @@
# Журнал прогресса # Журнал прогресса
> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-02, голова D39.75). **Источник истины по РЕШЕНИЯМ — `architecture/05-decisions-log.md` (D1D39.75); этот файл — ЖУРНАЛ.** > **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-02, голова D39.76). **Источник истины по РЕШЕНИЯМ — `architecture/05-decisions-log.md` (D1D39.76); этот файл — ЖУРНАЛ.**
> - **Сделано (сводно; детали — D-лог и архив-слайсы):** Ф0 ✅ · Ф1-инфра ✅ · арх-ресет D39 (7 слоёв, паки 1116) ✅ · паки 17 «канал B» · 18 «долги» · 19 «голос/состояние» · 20 «банк+терминолог» ✅ (D39.2628/31/4156) · мини-прогон (D39.37) и ХОЛОДНЫЙ прогон (D39.58: recall банка 0.918/0.980, банк приходит переведённым) приняты · полигон-пакеты 58, ToS-речек (D39.57), Р6+P4 (D39.61) закрыты · **карта языковой привязки движка (D39.60): 149 сайтов/45 файлов, книго-ось чиста (4), ja→ru безопасно без правки Go, en→ru — нет** · Р1Р4 закрыты целиком (D39.63: Р2 = ЗНАЧЕНИЕ, Р4 = норма потолка recall) · **ФАЗА 2 ОБЩНОСТИ ✅ (D39.64: П0 эмбед-хеш · П1 цель-шов · П2 скрипт-шов, ko-баг закрыт · П3 нарезка · П4 манифест-по-каналам; голден вердикт-нейтрален 0/172, майнер-парити EXACT)** · жанровый словарь отменён как класс (D39.47) · петля ремонта построена и НЕ включена (D39.38). > - **Сделано (сводно; детали — D-лог и архив-слайсы):** Ф0 ✅ · Ф1-инфра ✅ · арх-ресет D39 (7 слоёв, паки 1116) ✅ · паки 17 «канал B» · 18 «долги» · 19 «голос/состояние» · 20 «банк+терминолог» ✅ (D39.2628/31/4156) · мини-прогон (D39.37) и ХОЛОДНЫЙ прогон (D39.58: recall банка 0.918/0.980, банк приходит переведённым) приняты · полигон-пакеты 58, ToS-речек (D39.57), Р6+P4 (D39.61) закрыты · **карта языковой привязки движка (D39.60): 149 сайтов/45 файлов, книго-ось чиста (4), ja→ru безопасно без правки Go, en→ru — нет** · Р1Р4 закрыты целиком (D39.63: Р2 = ЗНАЧЕНИЕ, Р4 = норма потолка recall) · **ФАЗА 2 ОБЩНОСТИ ✅ (D39.64: П0 эмбед-хеш · П1 цель-шов · П2 скрипт-шов, ko-баг закрыт · П3 нарезка · П4 манифест-по-каналам; голден вердикт-нейтрален 0/172, майнер-парити EXACT)** · жанровый словарь отменён как класс (D39.47) · петля ремонта построена и НЕ включена (D39.38).
> - **Курс (D39.5975): ОБЩНОСТЬ ✅ → КАЧЕСТВО БАНКА ✅ (ядро D39.69 + фикс-пак D39.75).** **Текущее: очередь за ПАКЕТОМ-ЧЕКЕРОВ (промт `BACKEND_CHECKER_PACKAGE_SESSION_PROMPT.md` выдан, теперь можно запускать — фикс-пак заленден) + строка 91 у владельца (Decl мягкознаковых имён: forms[] vs anchor-gated).** ⚠ **DeepSeek-V4-Flash-0731: платные прогоны СТОП до ре-пробы (строка 74; там же 6/6-порог классификатора и слоты Q2/Q7). Перекупок нет (D39.63).** > - **Курс (D39.5975): ОБЩНОСТЬ ✅ → КАЧЕСТВО БАНКА ✅ (ядро D39.69 + фикс-пак D39.75).** **Текущее: очередь за ПАКЕТОМ-ЧЕКЕРОВ (промт `BACKEND_CHECKER_PACKAGE_SESSION_PROMPT.md` выдан, теперь можно запускать — фикс-пак заленден) + строка 91: решения приняты, стопгэп A в работе (D39.76).** ⚠ **DeepSeek-V4-Flash-0731: платные прогоны СТОП до ре-пробы (строка 74; там же 6/6-порог классификатора и слоты Q2/Q7). Перекупок нет (D39.63).**
> - **Горизонт (D39.62/67):** пакет-чекеров (строка 25) + фикс-лист банка (87) → ре-проба flash (74; + платный порог 6/6 классификатора + пробы 36б-замера Q2/эмиссии Q7 по слову) → **ДОБОР ИДЕАЛА** (первым прогоном: оси голоса 24 · авто-режим · итерация №2 редакторов 65 · цена 16 · веса K1K12 13а · вне-претрейн чекпоинт 55) → ВТОРАЯ ПАРА живьём (ja→ru; преп 81) → МАСШТАБ → пилот Ф2.5 (гейт резюме-строки 80; строки 6268, 85) → Ф3 ридер-IDE (6971). **Стоячие:** ToS-триггер 25.10 · Ш-2 до go1.27 · строка 74 перед любым платным прогоном. > - **Горизонт (D39.62/67):** пакет-чекеров (строка 25) + фикс-лист банка (87) → ре-проба flash (74; + платный порог 6/6 классификатора + пробы 36б-замера Q2/эмиссии Q7 по слову) → **ДОБОР ИДЕАЛА** (первым прогоном: оси голоса 24 · авто-режим · итерация №2 редакторов 65 · цена 16 · веса K1K12 13а · вне-претрейн чекпоинт 55) → ВТОРАЯ ПАРА живьём (ja→ru; преп 81) → МАСШТАБ → пилот Ф2.5 (гейт резюме-строки 80; строки 6268, 85) → Ф3 ридер-IDE (6971). **Стоячие:** ToS-триггер 25.10 · Ш-2 до go1.27 · строка 74 перед любым платным прогоном.
> - **Стек:** draft deepseek-v4-flash thinking-ON (+банкнота) **⚠0731** → терминолог (та же модель, батчи, экран `target_script`) → editor deepseek-v4-pro БИЛИНГВ ИНТЕРИМ (вендором НЕ тронут; glm-5 резерв) → судья gemini (Ф2, полигон); канал B Mistral+grok; ~$0.85/ранобэ (D30.4) — пере-калибровка после развилки 74. > - **Стек:** draft deepseek-v4-flash thinking-ON (+банкнота) **⚠0731** → терминолог (та же модель, батчи, экран `target_script`) → editor deepseek-v4-pro БИЛИНГВ ИНТЕРИМ (вендором НЕ тронут; glm-5 резерв) → судья gemini (Ф2, полигон); канал B Mistral+grok; ~$0.85/ранобэ (D30.4) — пере-калибровка после развилки 74.
> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). > - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор).
@ -30,7 +30,7 @@
| 13б | `speech-cue.txt` zh НЕ шипить до замера голос-флаггера на холодном прогоне (данные для недоказанного детектора = инерция; вывод обсуждения 31.07): оси пустые → файл не нужен, оси ловят → решение владельца о шипе (байты двигают `LangpackVersion`) | владелец | отложено-до-замера | первый прогон добора идеала (оси голоса, строка 24) → отдельное решение | D39.56, PACK19_BUILD §7.2, чат 31.07 | | 13б | `speech-cue.txt` zh НЕ шипить до замера голос-флаггера на холодном прогоне (данные для недоказанного детектора = инерция; вывод обсуждения 31.07): оси пустые → файл не нужен, оси ловят → решение владельца о шипе (байты двигают `LangpackVersion`) | владелец | отложено-до-замера | первый прогон добора идеала (оси голоса, строка 24) → отдельное решение | D39.56, PACK19_BUILD §7.2, чат 31.07 |
| 14 | Четыре data-инженерных флага фазы-2 общности, каждый с рекомендованным дизайном (§5 отчёта): ё-фолд → target-данные (`char_fold`; смена сигнатуры core-примитива через вердикт-несущий банк, сдвиг `memory_version`) · segmentation-фолбэк громким (ломает контракт corridor-фолбэка `pipeline.go:839-848` + голден-фикстура на нём; лечение — объявить блок в голден-yaml) · `Fertility` per-script map (калибровка ждёт боевого токенизатора) · `source-encoding.txt` + Go-реестр декодеров | владелец | когда-нибудь (следующий пак общности) | отдельное решение | D39.64, GENERALITY_PHASE2 §5.15.4 | | 14 | Четыре data-инженерных флага фазы-2 общности, каждый с рекомендованным дизайном (§5 отчёта): ё-фолд → target-данные (`char_fold`; смена сигнатуры core-примитива через вердикт-несущий банк, сдвиг `memory_version`) · segmentation-фолбэк громким (ломает контракт corridor-фолбэка `pipeline.go:839-848` + голден-фикстура на нём; лечение — объявить блок в голден-yaml) · `Fertility` per-script map (калибровка ждёт боевого токенизатора) · `source-encoding.txt` + Go-реестр декодеров | владелец | когда-нибудь (следующий пак общности) | отдельное решение | D39.64, GENERALITY_PHASE2 §5.15.4 |
| 86 | Мелкие открытые решения одним списком (свип D39.66): echo-семантика дропнутого c-lite-члена (D39.18 — оставить pre-c-lite?) · magnitude-кап тяжёлой CJK-утечки (D38.3 п.4в; сейчас strip+flag) | владелец | когда-нибудь | отдельные решения | D39.66, D39.69(feed_cap закрыт §1) | | 86 | Мелкие открытые решения одним списком (свип D39.66): echo-семантика дропнутого c-lite-члена (D39.18 — оставить pre-c-lite?) · magnitude-кап тяжёлой CJK-утечки (D38.3 п.4в; сейчас strip+flag) | владелец | когда-нибудь | отдельные решения | D39.66, D39.69(feed_cap закрыт §1) |
| 91 | Decl-приёмка МЯГКОЗНАКОВЫХ имён (finding-1 фикс-пака, D39.75): стеммером НЕВОЗМОЖНА — «ь» неотличим от коллизии «Синь»↔«синий» (доказано контрфактикой, регресс-гвозди стоят); выбор: (а) сид/терминолог перечисляет `decl.forms[]` для -нь/-ль имён (ложится на Decl-эмиссию) · (б) anchor-gated матч; при решении добавить прямой тест-гвоздь на «Фан Юаню» и заменить инертную пару Линь/линию→Линь/линий | владелец → бэкенд | скоро (малый дизайн) | отдельное решение | D39.75, BANK_FIXPACK §а | | 91 | Finding-1 (мягкознаковый decl): замер ПРИНЯТ, решения ПРИНЯТЫ (D39.76: A1 отвергнут глобально · anchor-gated СЛОМАН — переносит коллизию, транслит-везение · промах ~47/25 глав, почти весь «Винный червь») — **СТОПГЭП A В РАБОТЕ**: сид-формы «Винный червь»+«Фан Юань» (пишет сессия, подпись владельца) + гвоздь Линь/линий + прямой тест «Фан Юаню»; закрытие строки по лендингу стопгэпа; C = загейченный триггер (реопен = вторая пара, кросс-парный замер-гейт) | бэкенд → владелец (подпись сида) | в работе (мини-касание) | стопгэп → лендинг → закрытие | D39.75, D39.76 |
| **— ХВОСТЫ ХОЛОДНОГО ПРОГОНА (исполнен достаточно, D39.58; Р7 владельца) —** | | | | | | | **— ХВОСТЫ ХОЛОДНОГО ПРОГОНА (исполнен достаточно, D39.58; Р7 владельца) —** | | | | | |
| 16 | Полная цена холодного старта: edit-волна не гонялась (Р7); измерено всё ДО редактуры (драфт+банкнота $0.0247/волна · терминолог $0.0060.013/проход) | бэкенд | когда-нибудь (первый прогон добора идеала) | добор идеала | D39.58 | | 16 | Полная цена холодного старта: edit-волна не гонялась (Р7); измерено всё ДО редактуры (драфт+банкнота $0.0247/волна · терминолог $0.0060.013/проход) | бэкенд | когда-нибудь (первый прогон добора идеала) | добор идеала | D39.58 |
| 18 | Эмиссия головы 蛊: сид-половина = чек-лист (определяющий терм книги сидится `allow_short`, D39.50); эмиссия-КАНАЛ демотирован до ИЗМЕР-ГЕЙТА (Q7): полигон-замер «меняет ли эмиссия головы рендер композитов» — строить ТОЛЬКО по эффекту и ПОСЛЕ #10 (однознаковый пост-чек чинится чекер-паком); перед стройкой резолвить K-гейт и KWIC-грязь одиночной головы | полигон → бэкенд | скоро (санкция Q7 D39.70 — после #10, очередью с ре-пробой) | полигон-замер → решение | D39.58, D39.60, D39.69 | | 18 | Эмиссия головы 蛊: сид-половина = чек-лист (определяющий терм книги сидится `allow_short`, D39.50); эмиссия-КАНАЛ демотирован до ИЗМЕР-ГЕЙТА (Q7): полигон-замер «меняет ли эмиссия головы рендер композитов» — строить ТОЛЬКО по эффекту и ПОСЛЕ #10 (однознаковый пост-чек чинится чекер-паком); перед стройкой резолвить K-гейт и KWIC-грязь одиночной головы | полигон → бэкенд | скоро (санкция Q7 D39.70 — после #10, очередью с ре-пробой) | полигон-замер → решение | D39.58, D39.60, D39.69 |
@ -104,6 +104,10 @@
| 69 | Gemini API «под-18» обязательство на конечный продукт (независимо от лейблов) | владелец | когда-нибудь | Ф3 / отдельное решение | D39.32, D39.34(7) | | 69 | Gemini API «под-18» обязательство на конечный продукт (независимо от лейблов) | владелец | когда-нибудь | Ф3 / отдельное решение | D39.32, D39.34(7) |
| 70 | Action-security gate перед выдачей tools/webfetch (D25 п.5) | бэкенд | когда-нибудь | Ф3 | D39.34(7) | | 70 | Action-security gate перед выдачей tools/webfetch (D25 п.5) | бэкенд | когда-нибудь | Ф3 | D39.34(7) |
| 71 | Планы research/22: epub-tag-rewrite · Q7-леджер ; + F3-brief из D29.3 (chat-edit · Not-useful-петля · cost-of-fix) + Ф3-скоуп 02-mvp-plan (TMX/TBX · Bertalign · дистилляция 714B) | бэкенд | когда-нибудь | Ф3 | D39.34(7) | | 71 | Планы research/22: epub-tag-rewrite · Q7-леджер ; + F3-brief из D29.3 (chat-edit · Not-useful-петля · cost-of-fix) + Ф3-скоуп 02-mvp-plan (TMX/TBX · Bertalign · дистилляция 714B) | бэкенд | когда-нибудь | Ф3 | D39.34(7) |
## Оркестратор №9 + бэкенд + владелец — SOFTSIGN-DECL: ЗАМЕР ПРИНЯТ, РЕШЕНИЯ ПРИНЯТЫ (D39.76), 02.08
Отчёт: [`archive/reports/SOFTSIGN_DECL_FINDING1_2026-08-02.md`](archive/reports/SOFTSIGN_DECL_FINDING1_2026-08-02.md) (ревью-шапка с решениями; харнесс `eval/softsign-decl/` заленден). «Замер до стройки» отработал: наивное «ь» похоронено глобально, anchor-gated сломан адверсариалом самой сессии (перенос коллизии; чистота книги — транслит-везение), промах мал и локализован. Решено: стопгэп A (сид-формы «Винный червь»+«Фан Юань», формы пишет сессия, подпись владельца) + гвоздь Линь/линий + прямой тест «Фан Юаню»; finding-1 закрывается на A; движковый C — загейченный триггер до второй пары. В ядро — ничего.
## Оркестратор №9 + бэкенд — ФИКС-ПАК БАНКА ПРИНЯТ И ЗАЛЕНДЕН (D39.75), 02.08 ## Оркестратор №9 + бэкенд — ФИКС-ПАК БАНКА ПРИНЯТ И ЗАЛЕНДЕН (D39.75), 02.08
Отчёт: [`archive/reports/BANK_FIXPACK_2026-08-02.md`](archive/reports/BANK_FIXPACK_2026-08-02.md) (ревью-шапка). 9/9 пунктов отработаны: 6 сделано (head-finality в данных · правдивый Batch-коммент+WARN · classify fail-loud+тесты · мутационные neuter-тесты · фикстура 4-серий · TokenizeLetters-консолидация, побочно закрывшая combmark-щель), 2 «не делать» с контрактом (voice×стеммер; Q5 уже в промптах с D39.45), 1 ОТКАЧЕН правильно — «ь» ловил бы коллизию Синь/синий (мандат самопроверки сработал: адверсариальный ревьюер сессии поймал до лендинга). Верификация: батарея зелёная, голден маскированно ПУСТ, 14/15 CONFIRMED. Строка 87 закрыта; finding-1 → строка 91 (владелец); плотность-граница → дописка 79. Очередь: ПАКЕТ-ЧЕКЕРОВ можно запускать. Отчёт: [`archive/reports/BANK_FIXPACK_2026-08-02.md`](archive/reports/BANK_FIXPACK_2026-08-02.md) (ревью-шапка). 9/9 пунктов отработаны: 6 сделано (head-finality в данных · правдивый Batch-коммент+WARN · classify fail-loud+тесты · мутационные neuter-тесты · фикстура 4-серий · TokenizeLetters-консолидация, побочно закрывшая combmark-щель), 2 «не делать» с контрактом (voice×стеммер; Q5 уже в промптах с D39.45), 1 ОТКАЧЕН правильно — «ь» ловил бы коллизию Синь/синий (мандат самопроверки сработал: адверсариальный ревьюер сессии поймал до лендинга). Верификация: батарея зелёная, голден маскированно ПУСТ, 14/15 CONFIRMED. Строка 87 закрыта; finding-1 → строка 91 (владелец); плотность-граница → дописка 79. Очередь: ПАКЕТ-ЧЕКЕРОВ можно запускать.
@ -180,6 +184,8 @@ Q1 = П1 цель-шов санкционирован («главное бэке
## Бэкенд ## Бэкенд
**finding-1 (строка 91, Decl мягкознаковых имён) — ЗАМЕР ПРОВЕДЁН (02.08, бэкенд-сессия по указанию владельца в eval-конвенции, $0); РЕШЕНИЕ — владелец+оркестратор.** Отчёт: [archive/reports/SOFTSIGN_DECL_FINDING1_2026-08-02.md](archive/reports/SOFTSIGN_DECL_FINDING1_2026-08-02.md); харнесс `eval/softsign-decl/` (пин-модуль, боевой стеммер), сырьё+2 адверсариал-прогона durable в `~/books/gu-zhenren/softsign-decl/`. ИТОГ: разрыв реален но МАЛ (~47 ложных промахов/25 глав на реальном размере чанка, почти весь — ОДИН термин «Винный червь»; «Фан Юань»→0 per-chunk; occurrence-level 259 — код-верифицирован). Вариант **(б) anchor-gated** НЕ закрывает коллизию «Синь/Линь» — ПЕРЕНОСИТ на форму `[титул]+[ь-фамилия]` + не защищает числовой класс («пятого/шестого ранга» ×23); чистота на gu-zhenren = транслит-везение, доказательство **пара-зависимо**, safety НЕ измерена (M4=3 пары/1 книга). Рекомендация: **(а) сид-перечень 12 ВИДИМЫХ мягких канон-имён** — данные `decl.forms`, матч generic `containsWholeWord`, **вне ядра Go**, ноль коллизии (честно: ручной труд — майнер морфологию НЕ майнит, declForms руко-писаны); движок (б) — только на КРОСС-ПАРНОМ гейт-замере (≥2 пары), не на одном. Строку 91 и CURRENT-STATE НЕ трогал. Открытые решения — в §«Что решить» отчёта.
**Фикс-пак банка (строка 87 + Q5) исполнен (02.08, бэкенд-сессия по `BACKEND_BANK_FIXPACK_SESSION_PROMPT`, D39.71, $0 — только фейк-провайдер в тестах, НЕ закоммичено).** Отчёт: [archive/reports/BANK_FIXPACK_2026-08-02.md](archive/reports/BANK_FIXPACK_2026-08-02.md). СДЕЛАНО: **(б)** head_final → данные (`script-series.txt`+`SeriesHeadFinal`, zh/ja/ko байт-идентичны, тест «плотный не-head-final заводится данными») · **(в)** лживый коммент `Batch` переписан (ChunkIdx фолдится в request-hash) + `BatchRunes`-WARN на оверсайз-серию (не резать — убьёт со-батч §1) · **(г)** classify_types при выкл.гейте = fail-loud + 5 config-тестов · **(д)** мутационный neuter-фолд (mined-scope) · **(ж)** дистилл-фикстура `BANK-FULL` пинит ровно 4 серии (转/等/等资质/阶) · **(и)** `lang.TokenizeWords``text.TokenizeLetters` (общий шов, чинит combmark-щель). НЕ ДЕЛАТЬ с обоснованием: **(е)** стеммер НЕ в voice (accept-bias не единонаправлен; контракт в код) · **(з)** Q5-реалии УЖЕ в `terminologist.md`/`classifier.md` (пинг: `PromptSHA256` не двинулся). **(а) ОТКАЧЕНО — предложенный «ь» ФЛАВЕД: адверсариальное ревью (author≠reviewer, подтверждено white-box) поймало коллизию «Синь/Линь»→«син/лин»=«синий/линия» → ложный `SpoilerLeaks` (шум); «юань»→«юан» неотличим по форме — min-stem не разделяет.** Откат + регресс-гвоздь; finding 1 (палладий) открыт в safe-направлении, нужен сид-decl-перечень или anchor-gated матч — **РЕШЕНИЕ владельца (пинг §а)**. Приёмка: `build`/`vet`/`test -race ./...` зелёные · майнер-парити EXACT · голден пере-захвачен, маскированный дифф ПУСТ (двинулся только `embedded_version`; `memory_version`/`prompt_sha256`/`content_hash`/вердикты — на месте) · греп-общность чист. **СТОП — приёмка оркестратора.** **Фикс-пак банка (строка 87 + Q5) исполнен (02.08, бэкенд-сессия по `BACKEND_BANK_FIXPACK_SESSION_PROMPT`, D39.71, $0 — только фейк-провайдер в тестах, НЕ закоммичено).** Отчёт: [archive/reports/BANK_FIXPACK_2026-08-02.md](archive/reports/BANK_FIXPACK_2026-08-02.md). СДЕЛАНО: **(б)** head_final → данные (`script-series.txt`+`SeriesHeadFinal`, zh/ja/ko байт-идентичны, тест «плотный не-head-final заводится данными») · **(в)** лживый коммент `Batch` переписан (ChunkIdx фолдится в request-hash) + `BatchRunes`-WARN на оверсайз-серию (не резать — убьёт со-батч §1) · **(г)** classify_types при выкл.гейте = fail-loud + 5 config-тестов · **(д)** мутационный neuter-фолд (mined-scope) · **(ж)** дистилл-фикстура `BANK-FULL` пинит ровно 4 серии (转/等/等资质/阶) · **(и)** `lang.TokenizeWords``text.TokenizeLetters` (общий шов, чинит combmark-щель). НЕ ДЕЛАТЬ с обоснованием: **(е)** стеммер НЕ в voice (accept-bias не единонаправлен; контракт в код) · **(з)** Q5-реалии УЖЕ в `terminologist.md`/`classifier.md` (пинг: `PromptSHA256` не двинулся). **(а) ОТКАЧЕНО — предложенный «ь» ФЛАВЕД: адверсариальное ревью (author≠reviewer, подтверждено white-box) поймало коллизию «Синь/Линь»→«син/лин»=«синий/линия» → ложный `SpoilerLeaks` (шум); «юань»→«юан» неотличим по форме — min-stem не разделяет.** Откат + регресс-гвоздь; finding 1 (палладий) открыт в safe-направлении, нужен сид-decl-перечень или anchor-gated матч — **РЕШЕНИЕ владельца (пинг §а)**. Приёмка: `build`/`vet`/`test -race ./...` зелёные · майнер-парити EXACT · голден пере-захвачен, маскированный дифф ПУСТ (двинулся только `embedded_version`; `memory_version`/`prompt_sha256`/`content_hash`/вердикты — на месте) · греп-общность чист. **СТОП — приёмка оркестратора.**
**Качество банка — этап 1 (дизайн) исполнен (01.08, бэкенд-сессия по `BACKEND_BANK_QUALITY_SESSION_PROMPT`, $0, read-only, НЕ закоммичено).** Отчёт: [archive/reports/BANK_QUALITY_DESIGN_2026-08-01.md](archive/reports/BANK_QUALITY_DESIGN_2026-08-01.md). 6 пунктов свипа сведены в **3 переиспользуемых примитива** (A head-aware кластер-по-морфеме: §1 серия-батчинг + §6 голова 蛊 · B ре-порядок `terminology.Batch`: §1 + feed_cap · C стеммер целевого письма: §3 Decl-шов + omission-бэкстоп чекеров) + дата-правки (тип — ОТДЕЛЬНЫМ классификатором первичным; род neuter enum+seed-lint, ось `RenderFormatVersion`). **Самопроверка — 3 рубежа (грунтинг + анкор-верификация всех 8 tech-debt-якорей CONFIRMED + 5-агентная адверсариальная дизайн-критика): §1 серия-дефиниция «равная длина/1 позиция» и §2 инлайн-тип были BROKEN — переработаны (§1 → head-aware, пере-верифицировано на `BANK-FULL.tsv`: наивное = 19 кластеров вкл. блоб с §2-harm+протагонист, head-aware = 4 годных серии; §2 → классификатор первичным, DO-роль ДО RenderBatch; $0-экран честно пере-скоупнут — провабельно пропускал юаньши/Юаньхай); §5/§6/§7-эмбеддинг WEAKENED вправлены.** §4 (36б второе мнение) и §7-эмбеддинг ЗАКРЫТЫ по нужности; §5 (резюме-слой 80) → пилот-Ф2.5-гейт (проза-суммарайзер закрыт; «дата-состояние свободно от D1» опровергнуто — source-anchored reveal без верификатора); §6-эмиссия головы → полигон-замер + после #10 (seed-половина строится). **First-occurrence-тест ИСПОЛНЕН** ($0, `eval/bank_autonomy/m_firstocc.py`): гипотеза первенства ОПРОВЕРГНУТА (финал==первое 7 == финал==частота 7, большинство — ни то ни другое) ⇒ роль = контекстный ре-решатель, усиливает §1 (со-батч — единственный рычаг). **7 вопросов владельцу** (§9: канон-пин между прогонами · замер 36б · диспозиция резюме · hard-инъективность · вкус авто-транслита реалий юаньци/цзин-ци-шэнь · короткая форма 27 · замер эмиссии головы). **СТОП — ратификация оркестратора/владельца; этап 2 (стройка) — по релею после лендинга пакета-чекеров.** → **РАТИФИЦИРОВАНО ВЛАДЕЛЬЦЕМ, ЭТАП 2 (СТРОЙКА) ИСПОЛНЕН (01.08, та же сессия, $0 — только фейк-провайдер в тестах, НЕ закоммичено, resnapshot НЕ запускался).** **Качество банка — этап 1 (дизайн) исполнен (01.08, бэкенд-сессия по `BACKEND_BANK_QUALITY_SESSION_PROMPT`, $0, read-only, НЕ закоммичено).** Отчёт: [archive/reports/BANK_QUALITY_DESIGN_2026-08-01.md](archive/reports/BANK_QUALITY_DESIGN_2026-08-01.md). 6 пунктов свипа сведены в **3 переиспользуемых примитива** (A head-aware кластер-по-морфеме: §1 серия-батчинг + §6 голова 蛊 · B ре-порядок `terminology.Batch`: §1 + feed_cap · C стеммер целевого письма: §3 Decl-шов + omission-бэкстоп чекеров) + дата-правки (тип — ОТДЕЛЬНЫМ классификатором первичным; род neuter enum+seed-lint, ось `RenderFormatVersion`). **Самопроверка — 3 рубежа (грунтинг + анкор-верификация всех 8 tech-debt-якорей CONFIRMED + 5-агентная адверсариальная дизайн-критика): §1 серия-дефиниция «равная длина/1 позиция» и §2 инлайн-тип были BROKEN — переработаны (§1 → head-aware, пере-верифицировано на `BANK-FULL.tsv`: наивное = 19 кластеров вкл. блоб с §2-harm+протагонист, head-aware = 4 годных серии; §2 → классификатор первичным, DO-роль ДО RenderBatch; $0-экран честно пере-скоупнут — провабельно пропускал юаньши/Юаньхай); §5/§6/§7-эмбеддинг WEAKENED вправлены.** §4 (36б второе мнение) и §7-эмбеддинг ЗАКРЫТЫ по нужности; §5 (резюме-слой 80) → пилот-Ф2.5-гейт (проза-суммарайзер закрыт; «дата-состояние свободно от D1» опровергнуто — source-anchored reveal без верификатора); §6-эмиссия головы → полигон-замер + после #10 (seed-половина строится). **First-occurrence-тест ИСПОЛНЕН** ($0, `eval/bank_autonomy/m_firstocc.py`): гипотеза первенства ОПРОВЕРГНУТА (финал==первое 7 == финал==частота 7, большинство — ни то ни другое) ⇒ роль = контекстный ре-решатель, усиливает §1 (со-батч — единственный рычаг). **7 вопросов владельцу** (§9: канон-пин между прогонами · замер 36б · диспозиция резюме · hard-инъективность · вкус авто-транслита реалий юаньци/цзин-ци-шэнь · короткая форма 27 · замер эмиссии головы). **СТОП — ратификация оркестратора/владельца; этап 2 (стройка) — по релею после лендинга пакета-чекеров.** → **РАТИФИЦИРОВАНО ВЛАДЕЛЬЦЕМ, ЭТАП 2 (СТРОЙКА) ИСПОЛНЕН (01.08, та же сессия, $0 — только фейк-провайдер в тестах, НЕ закоммичено, resnapshot НЕ запускался).**

View file

@ -11,7 +11,7 @@
## Структура ## Структура
- `architecture/` — синтез. **Источник истины по решениям — [`05-decisions-log.md`](architecture/05-decisions-log.md) (D1D39.75); при конфликте с любым доком он выше.** - `architecture/` — синтез. **Источник истины по решениям — [`05-decisions-log.md`](architecture/05-decisions-log.md) (D1D39.76); при конфликте с любым доком он выше.**
- `01-decisions.md` — принципы Р1Р10; `02-mvp-plan.md` — фазы и приёмка (v3, 09.07); `03-implementation-notes.md` — контракты Фазы 0; `04-unhappy-paths.md` — ~70 режимов отказа → механизм; `06-memory-risk-registry.md` — реестр рисков банка памяти; **[`09-target-architecture.md`](architecture/09-target-architecture.md) — целевая 7-слойная архитектура (D39; статус стройки — шапка-таблица; инвариант общности §0.1)** · [`10-prompt-architecture.md`](architecture/10-prompt-architecture.md) — консолидированная промпт-заметка (концерн 4) · [`12-go-style-notes.md`](architecture/12-go-style-notes.md) — норматив общности §0 + Go-ответы · [`13-tech-debt-anchors.md`](architecture/13-tech-debt-anchors.md) — якоря техдолга (справочник к бэклогу, НЕ трекер). **Исполненные (архив 25.07, санкция владельца, → `archive/architecture/`):** [`07-strategic-review.md`](archive/architecture/07-strategic-review.md) (стратаудит 09.07 — курс исполнен) · [`08-sync-audit-ledger.md`](archive/architecture/08-sync-audit-ledger.md) (ледджер синк-аудита — отработан) · [`11-implementation-plan.md`](archive/architecture/11-implementation-plan.md) (план пака-11 — исполнен целиком); `components.puml`/`pipeline.puml` — диаграммы (перерисованы 25.07 под пост-пак-16 реальность: волновой исполнитель, пакетный сплит пака-15, repair-петля за `enabled:false`, generic content-labels D39.25; владелец смотрит PlantUML-расширением VS Code; вручную НЕ рендерить). - `01-decisions.md` — принципы Р1Р10; `02-mvp-plan.md` — фазы и приёмка (v3, 09.07); `03-implementation-notes.md` — контракты Фазы 0; `04-unhappy-paths.md` — ~70 режимов отказа → механизм; `06-memory-risk-registry.md` — реестр рисков банка памяти; **[`09-target-architecture.md`](architecture/09-target-architecture.md) — целевая 7-слойная архитектура (D39; статус стройки — шапка-таблица; инвариант общности §0.1)** · [`10-prompt-architecture.md`](architecture/10-prompt-architecture.md) — консолидированная промпт-заметка (концерн 4) · [`12-go-style-notes.md`](architecture/12-go-style-notes.md) — норматив общности §0 + Go-ответы · [`13-tech-debt-anchors.md`](architecture/13-tech-debt-anchors.md) — якоря техдолга (справочник к бэклогу, НЕ трекер). **Исполненные (архив 25.07, санкция владельца, → `archive/architecture/`):** [`07-strategic-review.md`](archive/architecture/07-strategic-review.md) (стратаудит 09.07 — курс исполнен) · [`08-sync-audit-ledger.md`](archive/architecture/08-sync-audit-ledger.md) (ледджер синк-аудита — отработан) · [`11-implementation-plan.md`](archive/architecture/11-implementation-plan.md) (план пака-11 — исполнен целиком); `components.puml`/`pipeline.puml` — диаграммы (перерисованы 25.07 под пост-пак-16 реальность: волновой исполнитель, пакетный сплит пака-15, repair-петля за `enabled:false`, generic content-labels D39.25; владелец смотрит PlantUML-расширением VS Code; вручную НЕ рендерить).
- `experiments/` — эмпирика «Полигона»: `00-provider-quirks` (читать перед любым вызовом провайдера), `01-token-calibration`, `02-refusal-benchmark`, `03-local-stand`, `04-editor-quality`, `06-local-extraction`, `07-coverage-precision`, `08-cost-model-v2` (актуальная денежная модель), `09-pilot-protocol` (пилот Ф2.5 + поправки D13), `10-explicit-benchmark` (18+ violence-рука канала B), `11-erotica-benchmark` (erotica по трём парам/регистрам — закрытие D14.4, D22), `12-quality-diagnosis`/`13-translator-bakeoff`/`14-quality-empirics`/`14b-meaning-battery` (дуга качества «мерить→строить», закрыты → D30/D32/D37/D38), `15-segmentation-empirics` (exp15: когезия под floor-шумом, фертильность — закрыт → D39.7/D39.8), `16-bank-mining` (exp16: WHICH/WHAT банк-майнинга — закрыт → D39.10). - `experiments/` — эмпирика «Полигона»: `00-provider-quirks` (читать перед любым вызовом провайдера), `01-token-calibration`, `02-refusal-benchmark`, `03-local-stand`, `04-editor-quality`, `06-local-extraction`, `07-coverage-precision`, `08-cost-model-v2` (актуальная денежная модель), `09-pilot-protocol` (пилот Ф2.5 + поправки D13), `10-explicit-benchmark` (18+ violence-рука канала B), `11-erotica-benchmark` (erotica по трём парам/регистрам — закрытие D14.4, D22), `12-quality-diagnosis`/`13-translator-bakeoff`/`14-quality-empirics`/`14b-meaning-battery` (дуга качества «мерить→строить», закрыты → D30/D32/D37/D38), `15-segmentation-empirics` (exp15: когезия под floor-шумом, фертильность — закрыт → D39.7/D39.8), `16-bank-mining` (exp16: WHICH/WHAT банк-майнинга — закрыт → D39.10).
- `research/` — фактура исследований 0405.07: `0110` базовые, `11-gap-*` добор критиком, `12-*` режимы отказа/отзывы/таксономии (+ два внешних материала с провенанс-шапками), `13` валидация памяти, `14` адаптивная память, `15` голос и состояние (принят, D21), **`16` ридер-IDE (принят с ревью-шапкой, D29)**, **`17` внешняя критика GPT-5.6 (принят с ревью-шапкой, D25)** — у 16/17 читать шапку прежде тела. **`18` рычаги качества (два отчёта, D36)** · **`19` нарезка+когезия+контракт t/e (D39.1)** · **`20` банк-майнинг W1.5 (D39.6)** · **`21` обзор LLM-транспорта чужих харнессов (23.07: наш транспорт опережает/вровень со всеми 11)** · **`22` доменные харнессы перевода (24.07: калибрующий — ядро подтверждено, впереди COGS/18+/общность/измеренность, позади Q4-выпуск и gate+repair-петля; сиквел `02`/`05`)** — у всех ревью-шапки. ⚠ Часть под superseded-баннерами (01/02/03/04/05/09 и gap-1/2/5) — **читай баннер прежде содержимого**. - `research/` — фактура исследований 0405.07: `0110` базовые, `11-gap-*` добор критиком, `12-*` режимы отказа/отзывы/таксономии (+ два внешних материала с провенанс-шапками), `13` валидация памяти, `14` адаптивная память, `15` голос и состояние (принят, D21), **`16` ридер-IDE (принят с ревью-шапкой, D29)**, **`17` внешняя критика GPT-5.6 (принят с ревью-шапкой, D25)** — у 16/17 читать шапку прежде тела. **`18` рычаги качества (два отчёта, D36)** · **`19` нарезка+когезия+контракт t/e (D39.1)** · **`20` банк-майнинг W1.5 (D39.6)** · **`21` обзор LLM-транспорта чужих харнессов (23.07: наш транспорт опережает/вровень со всеми 11)** · **`22` доменные харнессы перевода (24.07: калибрующий — ядро подтверждено, впереди COGS/18+/общность/измеренность, позади Q4-выпуск и gate+repair-петля; сиквел `02`/`05`)** — у всех ревью-шапки. ⚠ Часть под superseded-баннерами (01/02/03/04/05/09 и gap-1/2/5) — **читай баннер прежде содержимого**.
@ -19,9 +19,9 @@
- **Активные хендофф-промты (01.08; всё остальное — в `archive/prompts/` с баннерами-исходами):** [`ORCHESTRATOR_SESSION_PROMPT.md`](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояние НЕ дублирует) · [`BACKEND_CHECKER_PACKAGE_SESSION_PROMPT.md`](BACKEND_CHECKER_PACKAGE_SESSION_PROMPT.md) (**ТЕКУЩИЙ бэкендный**: пакет-чекеров против labels + чистка ведра D — фикс-пак заленден, МОЖНО ЗАПУСКАТЬ) · [`POLYGON_PACKAGE4_SESSION_PROMPT.md`](POLYGON_PACKAGE4_SESSION_PROMPT.md) (residual-трекер пилота/18+/echo, отложен; P4-хвост из него закрыт D39.61). Закрытые 30.0701.08 (промты в `archive/prompts/`, отчёты с ревью-шапками в `archive/reports/`): пак-19 «голос/состояние» (D39.5456) · холодный мини-прогон (D39.58) · ToS-речек (D39.57) · ресёрч общности фаза 1 (D39.60) · полигон Р6+P4 (D39.61) · **фаза 2 общности (D39.64)** · **полигон «сырьё арки банка»+пробы (D39.65)** · **качество банка, оба этапа (D39.69)** · **фикс-пак банка (D39.75)**. - **Активные хендофф-промты (01.08; всё остальное — в `archive/prompts/` с баннерами-исходами):** [`ORCHESTRATOR_SESSION_PROMPT.md`](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояние НЕ дублирует) · [`BACKEND_CHECKER_PACKAGE_SESSION_PROMPT.md`](BACKEND_CHECKER_PACKAGE_SESSION_PROMPT.md) (**ТЕКУЩИЙ бэкендный**: пакет-чекеров против labels + чистка ведра D — фикс-пак заленден, МОЖНО ЗАПУСКАТЬ) · [`POLYGON_PACKAGE4_SESSION_PROMPT.md`](POLYGON_PACKAGE4_SESSION_PROMPT.md) (residual-трекер пилота/18+/echo, отложен; P4-хвост из него закрыт D39.61). Закрытые 30.0701.08 (промты в `archive/prompts/`, отчёты с ревью-шапками в `archive/reports/`): пак-19 «голос/состояние» (D39.5456) · холодный мини-прогон (D39.58) · ToS-речек (D39.57) · ресёрч общности фаза 1 (D39.60) · полигон Р6+P4 (D39.61) · **фаза 2 общности (D39.64)** · **полигон «сырьё арки банка»+пробы (D39.65)** · **качество банка, оба этапа (D39.69)** · **фикс-пак банка (D39.75)**.
- `archive/``prompts/`: закрытые сессионные промты (только история, инструкции оттуда не исполнять) · `reports/`: отчёты паков/ресёрч-сессий с ревью-шапками (живая фактура приёмок — на них ссылаются D-лог и активные промты) · `architecture/`: исполненные арх-доки (07 стратревью · 08 синк-ледджер · 11 план пака-11) · четыре слайса хроники `PROGRESS-2026-07-{04-10,10-13,13-25,25-31}.md`. - `archive/``prompts/`: закрытые сессионные промты (только история, инструкции оттуда не исполнять) · `reports/`: отчёты паков/ресёрч-сессий с ревью-шапками (живая фактура приёмок — на них ссылаются D-лог и активные промты) · `architecture/`: исполненные арх-доки (07 стратревью · 08 синк-ледджер · 11 план пака-11) · четыре слайса хроники `PROGRESS-2026-07-{04-10,10-13,13-25,25-31}.md`.
## Статус (2026-08-01, голова D39.75 — эра «общность → качество банка») ## Статус (2026-08-01, голова D39.76 — эра «общность → качество банка»)
Полная карта состояния НЕ здесь: фазы/курс/очередь/горизонт — в шапке [`PROGRESS.md`](PROGRESS.md) (CURRENT-STATE + единый бэклог), решения — в [`architecture/05-decisions-log.md`](architecture/05-decisions-log.md) (карта актуальности; свежая голова — с хвоста файла). Коротко: Ф0/Ф1 ✅ · арх-ресет D39 (паки 1116) ✅ · паки 1720 ✅ · мини-прогон и холодный прогон приняты (D39.37/58) · карта языковой привязки движка снята (D39.60: книго-ось чиста; ja→ru безопасна без правки Go, en→ru — нет) · Р1Р4 закрыты (D39.63) · пак-21 растворён (D39.62) · **фаза 2 общности принята (D39.64: цель/скрипт-швы по данным, эмбед-хеш, манифест-по-каналам; голден вердикт-нейтрален)**. Полигон-ветка закрыта D39.65 (строки 21/22, фиксы 36а/36в проверены живьём). Банк готов целиком (D39.69 ядро + D39.75 фикс-пак; вопросы §9 закрыты D39.70). Текущее: пакет-чекеров — можно запускать; строка 91 у владельца. Свип полноты исполнен и пост-сверен кодом (D39.66: 951 обязательство, потери возвращены; якоря — architecture/13). ⚠ DeepSeek-0731 сменил веса под слагом — платные прогоны СТОП до ре-пробы (бэклог-строка 74). Дальше: стройка банка ∥ пакет-чекеров → ре-проба flash → ДОБОР ИДЕАЛА (мини-прогон и свип гипотез влиты, D39.67) → вторая пара (ja→ru) → МАСШТАБ → пилот Ф2.5 → Ф3 ридер-IDE. Полная карта состояния НЕ здесь: фазы/курс/очередь/горизонт — в шапке [`PROGRESS.md`](PROGRESS.md) (CURRENT-STATE + единый бэклог), решения — в [`architecture/05-decisions-log.md`](architecture/05-decisions-log.md) (карта актуальности; свежая голова — с хвоста файла). Коротко: Ф0/Ф1 ✅ · арх-ресет D39 (паки 1116) ✅ · паки 1720 ✅ · мини-прогон и холодный прогон приняты (D39.37/58) · карта языковой привязки движка снята (D39.60: книго-ось чиста; ja→ru безопасна без правки Go, en→ru — нет) · Р1Р4 закрыты (D39.63) · пак-21 растворён (D39.62) · **фаза 2 общности принята (D39.64: цель/скрипт-швы по данным, эмбед-хеш, манифест-по-каналам; голден вердикт-нейтрален)**. Полигон-ветка закрыта D39.65 (строки 21/22, фиксы 36а/36в проверены живьём). Банк готов целиком (D39.69 ядро + D39.75 фикс-пак; вопросы §9 закрыты D39.70). Текущее: пакет-чекеров — можно запускать; строка 91 — стопгэп A в работе (D39.76). Свип полноты исполнен и пост-сверен кодом (D39.66: 951 обязательство, потери возвращены; якоря — architecture/13). ⚠ DeepSeek-0731 сменил веса под слагом — платные прогоны СТОП до ре-пробы (бэклог-строка 74). Дальше: стройка банка ∥ пакет-чекеров → ре-проба flash → ДОБОР ИДЕАЛА (мини-прогон и свип гипотез влиты, D39.67) → вторая пара (ja→ru) → МАСШТАБ → пилот Ф2.5 → Ф3 ридер-IDE.
## Доступные ключи от моделей ## Доступные ключи от моделей
DEEPSEEK_API_KEY, ZAI_API_KEY, KIMI_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY, MISTRAL_API_KEY DEEPSEEK_API_KEY, ZAI_API_KEY, KIMI_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY, MISTRAL_API_KEY

View file

@ -1,4 +1,4 @@
# Журнал решений оркестратора — контракт D1D39.75 (развязки 04.07 · пакеты 0910.07 · приёмка/качество-первым/пивот/эмпирика 1112.07 · арх-ресет+стройка пере-прогонного стека 1319.07) # Журнал решений оркестратора — контракт D1D39.76 (развязки 04.07 · пакеты 0910.07 · приёмка/качество-первым/пивот/эмпирика 1112.07 · арх-ресет+стройка пере-прогонного стека 1319.07)
> **КАРТА АКТУАЛЬНОСТИ (ревизия D31, продлена до D38.2 [12.07]; исторические записи ниже НЕ переписываются — дисциплина D23.3).** Читая контракт целиком, держи под рукой, что чем перекрыто: > **КАРТА АКТУАЛЬНОСТИ (ревизия D31, продлена до D38.2 [12.07]; исторические записи ниже НЕ переписываются — дисциплина D23.3).** Читая контракт целиком, держи под рукой, что чем перекрыто:
> ⚠ **Навигация (актуализация 01.08):** карта ниже детально покрывает D1D39.28; решения D39.2963 живут хронологически в теле файла, **свежая голова — С ХВОСТА** (новые ноты аппендятся вниз). Сводка текущей головы и очередь — CURRENT-STATE в `../PROGRESS.md`. > ⚠ **Навигация (актуализация 01.08):** карта ниже детально покрывает D1D39.28; решения D39.2963 живут хронологически в теле файла, **свежая голова — С ХВОСТА** (новые ноты аппендятся вниз). Сводка текущей головы и очередь — CURRENT-STATE в `../PROGRESS.md`.
@ -1227,3 +1227,5 @@ API-529-долг закрыт: 8-осевой refute-by-default воркфлоу
## D39.74 — АУДИТ РЕСЁРЧЕЙ СОСЕДНИХ ХАРНЕССОВ (research/21 транспорт · research/22 домен; вопрос владельца 02.08 «есть ли утерянное из /home/ubuntu/projects/tmp?»): **утерянного НЕТ** — из 15 клонов оба ресёрча покрыли корпус, взятое ПОСТРОЕНО (research/21: 9 транспорт-пунктов паками 12/13 — quota-429/Retry-After/keepalive/джиттер/xAI-гард/GLM-finish/retryable-пин/billed-decode-кап/models-валидация + CostSource и луп-гард; вердикт «наш транспорт опережает/вровень со всеми 11, не трогаем» ратифицирован; research/22: разрыв Q6 gating+repair закрыт паком-16 по прецеденту AiNiee ProofreadTask, Problem-классы №5 → строка 25, планы → строка 71), отклонённое отклонено ЗАПИСЬЮ, кандидаты Q7-квирков ждут вендор-сверки по правилу 10.07 (не абсорбированы — так и задумано). Два хвоста, уроненные МОИМ триажем внутри пучковых находок (класс D39.73), добиты: **(1) Mistral-strip гейт message-builder** (research/21 §1.1: extra_forbidden на reasoning-поля; ЛАТЕНТЕН — наш wire single-shot без reasoning-полей; станет несущим при multi-turn/continuation или прод-пути mistral в канале B) → дописка в строку 59 (транспорт-гигиена); **(2) halve-chunk-on-retry** (research/22 §2 №7) → ОТКЛОНЁН ЯВНО: волновая архитектура с чекпойнтами + флор max_tokens + ре-ген-ручка 77 делают полу-чанк малоценным; реопен — при живых max_tokens-упорах (строка 45, дописка) (02.08, оркестратор №9). ✅ ## D39.74 — АУДИТ РЕСЁРЧЕЙ СОСЕДНИХ ХАРНЕССОВ (research/21 транспорт · research/22 домен; вопрос владельца 02.08 «есть ли утерянное из /home/ubuntu/projects/tmp?»): **утерянного НЕТ** — из 15 клонов оба ресёрча покрыли корпус, взятое ПОСТРОЕНО (research/21: 9 транспорт-пунктов паками 12/13 — quota-429/Retry-After/keepalive/джиттер/xAI-гард/GLM-finish/retryable-пин/billed-decode-кап/models-валидация + CostSource и луп-гард; вердикт «наш транспорт опережает/вровень со всеми 11, не трогаем» ратифицирован; research/22: разрыв Q6 gating+repair закрыт паком-16 по прецеденту AiNiee ProofreadTask, Problem-классы №5 → строка 25, планы → строка 71), отклонённое отклонено ЗАПИСЬЮ, кандидаты Q7-квирков ждут вендор-сверки по правилу 10.07 (не абсорбированы — так и задумано). Два хвоста, уроненные МОИМ триажем внутри пучковых находок (класс D39.73), добиты: **(1) Mistral-strip гейт message-builder** (research/21 §1.1: extra_forbidden на reasoning-поля; ЛАТЕНТЕН — наш wire single-shot без reasoning-полей; станет несущим при multi-turn/continuation или прод-пути mistral в канале B) → дописка в строку 59 (транспорт-гигиена); **(2) halve-chunk-on-retry** (research/22 §2 №7) → ОТКЛОНЁН ЯВНО: волновая архитектура с чекпойнтами + флор max_tokens + ре-ген-ручка 77 делают полу-чанк малоценным; реопен — при живых max_tokens-упорах (строка 45, дописка) (02.08, оркестратор №9). ✅
## D39.75 — ФИКС-ПАК БАНКА ПРИНЯТ И ЗАЛЕНДЕН (все 9 пунктов строки 87 отработаны; приёмка исполнением + 3-агентное адверсариальное ревью: 14/15 CONFIRMED · 1 PARTIAL · 0 REFUTED; голден независимо: маскированный дифф ПУСТ, двинулся только `embedded_version`): **СДЕЛАНО** — (б) head-finality В ДАННЫХ (`script-series.txt` + `SeriesHeadFinal`; zh/ja/ko функционально идентичны — пин-тест; синтетический head-initial скрипт заводится данными) · (в) лживый комментарий Batch переписан на правду (ChunkIdx фолдится в RequestHash) + `BatchRunes`-WARN на оверсайз-серию (НЕ режет — резка убила бы со-батч) · (г) `classify_types` при выключенном гейте = fail-loud + 5 config-тестов · (д) мутационные тесты neuter-фолда (версия двигается; mined-scope: BASE байт-идентичен — draft-волна не перепокупает) · (ж) дистилл-фикстура BANK-FULL (150 поверхностей побайтно = боевому TSV; тест требует ТОЧНОГО членства 4 серий и id=0 для 方源/元石/元海) · (и) `TokenizeWords``text.TokenizeLetters` — консолидация чистая (слои однонаправленны) И ПОБОЧНО ЗАКРЫЛА РЕАЛЬНУЮ ЩЕЛЬ: старый токенизатор рвал слово на mid-word U+0301 («сло́во»→[сло во] — воспроизведено на копии старого кода), decl-пост-чек промахивался на ударениях. **НЕ ДЕЛАТЬ с контрактом в код** — (е) стеммер НЕ заводится в voice (направления несимметричны: SelfRef-стемминг безопасен, NG-стемминг = шум; контракт-блок voice.go:368-378, фактура сверена) · (з) Q5-инструкция реалий УЖЕ в `terminologist.md`/`classifier.md` — причём с D39.45 (мисатрибуция отчёта «D39.58» только усиливает клейм), PromptSHA256 не двигался. **(а) ОТКАЧЕН — МАНДАТ САМОПРОВЕРКИ СРАБОТАЛ ПО НАЗНАЧЕНИЮ:** «ь» в `decl_suffix` закрыл бы «Фан Юаню», но неотличим по форме от коллизии мягкознаковых имён с лексикой («Синь»↔«синий/синим» — контрфактика воспроизведена: SameStem=true с «ь»); адверсариальный ревьюер сессии поймал ДО лендинга, откат + два регресс-гвоздя (SameStem + dstFormPresent; пара Линь/линию инертна — заменить на Линь/линий при касании) + NB-комментарий в данных. **Finding-1 ОСТАЁТСЯ ОТКРЫТЫМ → строка 91 (выбор владельца):** приёмка склонений мягкознаковых имён стеммером НЕВОЗМОЖНА — (а) сид/терминолог перечисляет `decl.forms[]` для -нь/-ль имён (естественно ложится на Decl-эмиссию) или (б) anchor-gated матч; + прямой тест-гвоздь на дизайн-кейс добавить при решении. Граница плотности (`enabled` серий через Go-константу `cjkScriptNames`) — пре-существующая, дописана в строку 79. Строка 87 ЗАКРЫТА (02.08, оркестратор №9). ✅ ## D39.75 — ФИКС-ПАК БАНКА ПРИНЯТ И ЗАЛЕНДЕН (все 9 пунктов строки 87 отработаны; приёмка исполнением + 3-агентное адверсариальное ревью: 14/15 CONFIRMED · 1 PARTIAL · 0 REFUTED; голден независимо: маскированный дифф ПУСТ, двинулся только `embedded_version`): **СДЕЛАНО** — (б) head-finality В ДАННЫХ (`script-series.txt` + `SeriesHeadFinal`; zh/ja/ko функционально идентичны — пин-тест; синтетический head-initial скрипт заводится данными) · (в) лживый комментарий Batch переписан на правду (ChunkIdx фолдится в RequestHash) + `BatchRunes`-WARN на оверсайз-серию (НЕ режет — резка убила бы со-батч) · (г) `classify_types` при выключенном гейте = fail-loud + 5 config-тестов · (д) мутационные тесты neuter-фолда (версия двигается; mined-scope: BASE байт-идентичен — draft-волна не перепокупает) · (ж) дистилл-фикстура BANK-FULL (150 поверхностей побайтно = боевому TSV; тест требует ТОЧНОГО членства 4 серий и id=0 для 方源/元石/元海) · (и) `TokenizeWords``text.TokenizeLetters` — консолидация чистая (слои однонаправленны) И ПОБОЧНО ЗАКРЫЛА РЕАЛЬНУЮ ЩЕЛЬ: старый токенизатор рвал слово на mid-word U+0301 («сло́во»→[сло во] — воспроизведено на копии старого кода), decl-пост-чек промахивался на ударениях. **НЕ ДЕЛАТЬ с контрактом в код** — (е) стеммер НЕ заводится в voice (направления несимметричны: SelfRef-стемминг безопасен, NG-стемминг = шум; контракт-блок voice.go:368-378, фактура сверена) · (з) Q5-инструкция реалий УЖЕ в `terminologist.md`/`classifier.md` — причём с D39.45 (мисатрибуция отчёта «D39.58» только усиливает клейм), PromptSHA256 не двигался. **(а) ОТКАЧЕН — МАНДАТ САМОПРОВЕРКИ СРАБОТАЛ ПО НАЗНАЧЕНИЮ:** «ь» в `decl_suffix` закрыл бы «Фан Юаню», но неотличим по форме от коллизии мягкознаковых имён с лексикой («Синь»↔«синий/синим» — контрфактика воспроизведена: SameStem=true с «ь»); адверсариальный ревьюер сессии поймал ДО лендинга, откат + два регресс-гвоздя (SameStem + dstFormPresent; пара Линь/линию инертна — заменить на Линь/линий при касании) + NB-комментарий в данных. **Finding-1 ОСТАЁТСЯ ОТКРЫТЫМ → строка 91 (выбор владельца):** приёмка склонений мягкознаковых имён стеммером НЕВОЗМОЖНА — (а) сид/терминолог перечисляет `decl.forms[]` для -нь/-ль имён (естественно ложится на Decl-эмиссию) или (б) anchor-gated матч; + прямой тест-гвоздь на дизайн-кейс добавить при решении. Граница плотности (`enabled` серий через Go-константу `cjkScriptNames`) — пре-существующая, дописана в строку 79. Строка 87 ЗАКРЫТА (02.08, оркестратор №9). ✅
## D39.76 — SOFTSIGN-DECL ЗАМЕР ПРИНЯТ, ОБА ВОПРОСА РЕШЕНЫ (строка 91; замер исполнен бэкенд-сессией по слову владельца «замеры → решать вместе с оркестратором»; eval-конвенция `eval/softsign-decl/`, пин-харнесс на боевом стеммере, $0, два адверсариал-прогона author≠reviewer): **факты** — (1) разрыв реален, но МАЛ и локализован: пер-чанковый честный промах ~47 на 25 глав, почти весь = «Винный червь»; «Фан Юань» = 0 (номинатив всегда рядом); раннее «~26» снято вторым путём (артефакт мелкого блока, свип 800→12000); (2) наивное «ь» (A1) отвергнуто ОКОНЧАТЕЛЬНО — вред глобальный, книго-независимый (SameStem → Postcheck И SpoilerLeaks везде); (3) **anchor-gated (C) СЛОМАН адверсариал-прогоном самой сессии**: коллизию ПЕРЕНОСИТ на класс «[титул]+[ь-фамилия]», числовой класс не защищает («пятого ранга»×13 — якорь общий), ноль коллизий этой книги = ТРАНСЛИТ-ВЕЗЕНИЕ ⇒ в ядро на одно-парном свидетельстве нельзя; (4) сид-перечень честно назван ручным трудом, но для 12 имён = ~10 строк YAML ВНЕ ядра (generic containsWholeWord, ноль строк Go). **РЕШЕНИЯ (оркестратор + владелец): (Q1) стопгэп A — ДА**: сид-формы «Винный червь» И «Фан Юань»; формы пишет бэкенд-сессия, подпись владельца обычным сид-циклом; тем же касанием гвоздь Линь/линию→Линь/линий + прямой позитивный тест «Фан Юаню» через forms[] (закрывает PARTIAL D39.75); memory_version → штатный repin, перекупок нет; **(Q2) finding-1 ЗАКРЫТ на A; C снят в ЗАГЕЙЧЕННЫЙ ТРИГГЕР** — реопен только при второй паре живьём, где кросс-парный полигон-замер (перенос + числовой класс, ≥2 пары) — ГЕЙТ любой правки ядра. Общность: путь A = ноль строк Go, grep ядра на пара/книго-литералы пуст. Строка 91 → «стопгэп в работе, закрытие по его лендингу» (02.08, оркестратор №9). ✅

View file

@ -0,0 +1,99 @@
# SOFTSIGN-DECL (finding-1) — отчёт оркестратору для совместного решения с владельцем
> **✅ ПРИНЯТ И ЗАЛЕНДЕН; ОБА ВОПРОСА РЕШЕНЫ (оркестратор №9 + владелец, 02.08.2026, D39.76).** Спот-чеки приёмки: пин харнесса через rev-parse (build.sh:17) · счёт dst сверен (150 строк / 147 уник.) · durable-сырьё и оба адверсариал-прогона на месте · контрфактика «Синь/синим» бьётся с независимой проверкой фикс-пака. **Решения: (Q1) СТОПГЭП A — ДА**: сид-формы «Винный червь» И «Фан Юань» (цена нулевая, спойлер-точность протагониста важна); формы пишет бэкенд-сессия (детерминированная морфология, не вкус), подпись владельца обычным сид-циклом; сдвиг `memory_version` → штатный repin, перекупок нет; тем же касанием — гвоздь Линь/линию→Линь/линий и ПРЯМОЙ позитивный тест «Фан Юаню» через forms[] (закрывает PARTIAL ревью D39.75). **(Q2) finding-1 ЗАКРЫВАЕТСЯ на A; C (движковый anchor) — в ЗАГЕЙЧЕННЫЙ ТРИГГЕР**: реопен только при второй паре живьём, кросс-парный полигон-замер (перенос «[титул]+[ь-фамилия]» + числовой класс, ≥2 пары) = гейт любой правки ядра. Основание: A1 глобально вреден; anchor-gated сломан адверсариал-прогоном (переносит коллизию; чистота книги = транслит-везение); измеренный промах мал и локализован (~47 пер-чанк/25 глав, почти весь «Винный червь», «Фан Юань»=0).
**Что:** исследование finding-1 (мягкознаковый декл-разрыв банк-пост-чека), отпочковавшегося от
BANK_FIXPACK §а при лендинге D39.75 (бэклог-строка 91). **Кто/где:** бэкенд-сессия; по прямому указанию
владельца замер проведён в eval-конвенции (`eval/softsign-decl/`, пин-харнесс, $0). **Дисциплина:** 2-й
путь счёта · вскрытие единиц глазами · author≠reviewer ДВА прогона (дизайн + код/рекомендация). Владелец:
«провести замеры, решать вместе с оркестратором» — отсюда этот отчёт. **Строить/править — по слову
владельца; ядро Go этой сессией НЕ трогалось.**
## Вопрос
`declinedFormPresent` не принимает склонённую мягкознаковую форму («Фан Юаню»~«Фан Юань»): стеммер §3 «ь»
не стрипает. Наивное «добавить «ь» в `decl_suffix`» отвергнуто в fix-pack (глобальная коллизия
«Синь/Линь»→«синий/линия»). Чем закрывать: (A) сид-перечень декл-форм · (C) движковый anchor-gated
матч · (B) ничего. И — не ляжет ли решение книго/языко-зависимо в ЯДРО (вопрос владельца).
## Метод
Харнесс `eval/softsign-decl/main.go` на БОЕВОМ стеммере (`lang.NewTargetStemmer`), `build.sh` пинит
бэкенд коммитом (78b7b34) через `git archive`, `replace`-модуль вне репо — прецедент pkg7/minerharness.
Корпус: банк `~/books/gu-zhenren/coldrun-a/BANK-FULL.tsv` (147 уник. dst) × боевой 25-глав-выход
`acceptance/guzhenren-25ch-ru.txt` (37 480 слов). Сырьё+2 адверсариал-прогона — durable
`~/books/gu-zhenren/softsign-decl/`. Четыре правила матчинга: A0 (боевое, «ь» не стрипается) · A1
(наивное глобальное «ь») · A2 (anchor=точный) · A3 (anchor=норм-стем).
## Находки (с исправлениями самопроверки — обе ошибки мои)
1. **Разрыв реален, но МАЛ.** Occurrence-level 259 окон (184 склонённых «Фан Юань» = Юаня 152/Юаню 19/Юанем 7/Юане 6 + 67 «Винного червя» + хвост).
Но пост-чек срабатывает ПО-ЧАНКОВО: на реальном размере чанка (~12k токенов) честный промах =
**~47 на 25 глав, почти весь — ОДИН термин «Винный червь»**; «Фан Юань» → **0 per-chunk** (номинатив
всегда рядом). ⚠ Моё раннее «~26» было артефактом мелкого блока (1.5k симв) — снято 2-м путём (свип
800→12000 симв: 57→26→13→7→4). Число — прокси (не боевой чанкер).
2. **Код харнесса аудирован TRUSTWORTHY** (author≠reviewer, статик): 6/6 NO-BUG — `stemAug` доказуемо
faithful (реестровые суффиксы все на гласную → ь-финал no-op под реальным реестром), якорь не
лицензирует сам себя (`norm[k]=false ⟹ exact[k]=false`), `loadBankDst`=147 сверено с файлом (150
строк, 3 дубля dst). Числа окон код-верифицированы + воспроизведены 2-й Python-реализацией.
3. **A1 (наивное «ь») отвергнут корректно — вред ГЛОБАЛЬНЫЙ, книго-независимый.** M4:
`softSameStem("Синь","синим")=true`, `("Линь","линий")=true`. Голое «ь» поражает глобальный
`SameStem`, а через него весь путь `declinedFormPresent` → и Postcheck, и SpoilerLeaks, в любой книге.
4. **Adversarial-прогон 1 (дизайн) сломал A3:** anchor-gated НЕ закрывает коллизию — **ПЕРЕНОСИТ** её с
одно-словного класса на форму `[титул]+[ь-фамилия]` (гипотетич. «старейшина Синь» ложно примет
«старейшина синего»). В gu-zhenren 0 коллизий — **транслит-везение** (CJK-стемы юан/шэн не русские
слова), НЕ свойство гейта → доказательство безопасности **пара-зависимо**. Числовой класс НЕ защищён
реально на корпусе: «пятого ранга» ×13, «шестого ранга» ×10 — якорь «ранга» общий, гейт даёт ноль
защиты. Поправка: A3 ТРОГАЕТ SpoilerLeaks (общий путь), спасает лишь observability-статус.
5. **Adversarial-прогон 2 (рекомендация) поймал мою противоречивость:** я звал сид-перечень «нулём
действия», а он — РУЧНОЙ труд. Сверено по коду: `decl.forms` руко-писаны в сиде
([memseed.go:89](../../../backend/internal/membank/memseed.go#L89)→[memory.go:315](../../../backend/internal/membank/memory.go#L315));
майнер морфологию НЕ майнит (его «decl» = отвергнутые поверхности, miner_emit.go:60); генератора
склонений в Go нет. Для ВСЕГО мягкого класса сид-перечень = «142/142-null», что §3 и убивал.
## Общность (ключевой вопрос владельца) — решение остаётся ВНЕ ядра
- Рекомендуемый путь (A) — данные сида `decl.forms`, матч **generic** `containsWholeWord`
([mempostcheck.go:158](../../../backend/internal/membank/mempostcheck.go#L158)): **ноль строк Go**, новая
пара кладёт свои формы в свой сид, Go не трогается → инвариант «пара, которой в репо нет, без правки
Go» выполнен. Grep ядра `membank`/`stemmer` на книго/пара-ЛИТЕРАЛЫ и lang-ВЕТКИ — пусто (единственный
хит — иллюстративный коммент-пример 方源→Фан Юань в `mempostcheck.go:128`, не ветка кода).
- Движковый (C) ТРОНУЛ бы алгоритм `declinedFormPresent` (ядро membank) + «ь» в `target-ru.txt`
(lang-данные). Алгоритм generic — архитектурно чисто ЕСЛИ строить; но его БЕЗОПАСНОСТЬ валидирована на
одной паре → в ядро на одно-парном свидетельстве нельзя. Именно это и есть «плохое решение в ядре»,
которого владелец не хочет.
## Опции для решения
| | Что | Плюсы | Минусы |
|---|---|---|---|
| **A** | Сид-перечень декл-форм 12 ВИДИМЫХ мягких канон-имён («Винный червь»; «Фан Юань» если важен SpoilerLeaks) | дёшево (~10 строк YAML), точный матч, ноль коллизии, **вне ядра**, закрывает ~весь измеренный промах | ручной труд; не масштабируется на хвост; per-book |
| **B** | Ничего + NB-коммент/регресс-гвоздь (уже в HEAD) | ноль риска/работы | ~47 ложняков/25 глав остаются (у шумовой планки) |
| **C** | Движковый СЛОЙНЫЙ (tail-restricted anchor + стоплист ь-кардиналов) | общий once-done, любая будущая книга бесплатно; данные в lang, алгоритм generic | трогает ядро; safety (перенос/числа) НЕ измерена (M4=3 пары, 1 книга); нужен кросс-парный гейт-замер ПРЕЖДЕ стройки |
## Рекомендация (на совместное решение)
- **Сейчас: A (+B).** Сид-перечень «Винного червя» (+«Фан Юань» при нужде SpoilerLeaks) — закрывает
измеренный промах вне ядра; NB-коммент + гвоздь остаются; поправить инертный гвоздь «Линь/линию» →
«Линь/линий». В ядро — ничего.
- **C — НЕ строить на одно-парном свидетельстве.** Если решаем закрывать системно, сперва ЗАКАЗАТЬ
полигону кросс-парный корпус-замер частоты ложняков переноса ([титул]+[ь-фамилия]) и числового класса
на ≥2 парах (zh→ru + ja→ru/en→ru) как ГЕЙТ; только положительный замер оправдывает правку ядра.
- Честный исход-кандидат: **закрыть finding-1 на A, снять со строки 91**, C оставить как загейченный
бэклог-триггер (не открытый долг).
## Что решить вместе с владельцем
1. Делаем стопгэп A? Кто пишет сид-формы (полигон / владелец канона)?
2. Заказываем кросс-парный гейт-замер под C — или закрываем finding-1 на A и C снимаем в загейченный триггер?
## Артефакты
- `eval/softsign-decl/``main.go` · `build.sh` · `README.md` (методика+цифры+пределы, исправлен).
- `~/books/gu-zhenren/softsign-decl/``softsign_probe_out.txt` · `adversarial-review.txt` (дизайн) ·
`code-recommendation-audit.txt` (код+рекомендация).
- backend HEAD (D39.75): NB-коммент `target-ru.txt:231-237` · гвозди `stemmer_test.go`/`memdecl_test.go`.
## Честные пределы
Одна книга (gu-zhenren zh→ru); M4 = 3 руко-выбранные пары; per-chunk промах — прокси (не боевой чанкер,
faithful — через `tmctl export`); чистота A3 на корпусе — транслит-везение, НЕ доказательство общей
безопасности. Числа окон код-верифицированы и 2-м путём; интерпретации (перенос/числовой класс) —
предварительны по CLAUDE.md §4 до вебновелл-кросс-парного среза.

View file

@ -0,0 +1,136 @@
# softsign-decl — разрыв мягкого знака в декл-пост-чеке банка (fix-pack §а, finding-1)
Замер $0 к backend-бэклог-строке 91 (finding-1): чем закрывать разрыв, когда мягкознаковое имя
(«Фан Юань», «Винный червь») склоняется («Фан Юаня», «Винного червя»), а стеммер §3 «ь» не стрипает,
и потому декл-форму НЕ принимает. Наивное «добавить «ь» в `decl_suffix`» отвергнуто в fix-pack (глобальная
коллизия «Синь/Линь»→«синий/линия»). Вопрос: движковый anchor-gated матч ЛУЧШЕ ли сид-перечисления — и
безопасен ли он на реальном корпусе, а не на бумаге.
## Метод (конвенция полигона)
- Харнесс `main.go` — БОЕВОЙ стеммер `lang.NewTargetStemmer(lang.TargetChecksFor("ru"))`; `build.sh`
материализует `go.mod`+`replace` ВНЕ репо, пин бэкенда на коммит (`git archive`) — прецедент
pkg7/minerharness. Ноль сети, ноль моделей, $0. Пин прогона: `78b7b34` (HEAD на момент замера — «ь»
уже реверсирован, D39.75).
- Корпус: банк `~/books/gu-zhenren/coldrun-a/BANK-FULL.tsv` (147 уник. dst) × боевой 25-глав-выход
`~/books/gu-zhenren/acceptance/guzhenren-25ch-ru.txt` (37 480 слов, editor=glm-5, приёмка Ф1).
- Сырьё/выход — durable `~/books/gu-zhenren/softsign-decl/` (правило 9): `softsign_probe_out.txt`
(отчёт харнесса), `adversarial-review.txt` (author≠reviewer прогон).
- Правило 10 (вскрытие единиц + 2-й путь счёта): каждый агрегат ниже сверен независимым `grep -oE`
по боевому выходу; A0-реимплементация харнесса сверена с реальным (unexported) `dstFormPresent`
in-package пробой — 0/29 расхождений — до порта на экспортные символы.
Четыре правила матчинга декл-окна (база-цельнословная не меняется — она уже ловит номинатив):
- **A0** — боевое: `declinedFormPresent` (mempostcheck.go:169-191), «ь» НЕ стрипается.
- **A1** — наивное: «ь» в реестр, на КАЖДЫЙ компонент, БЕЗ якоря (отвергнутое; для контроля вреда).
- **A2** — anchor-gated: мягкий стрип разрешён, если ДРУГОЙ компонент совпал ТОЧНО.
- **A3** — anchor-gated: мягкий стрип разрешён, если ДРУГОЙ компонент совпал по НОРМАЛЬНОМУ стему (⊇ A2).
## Цифры
### Разрыв реален, но КОНЦЕНТРИРОВАН и много-словный
29 из 147 dst несут мягкознаковое слово. Захват окон над A0 (occurrence-level):
| dst | слов | soft→stem | A0 | A3 | A3A0 | статус |
|---|---|---|---|---|---|---|
| Фан Юань | 2 | юань→юан | 324 | 508 | **+184** | TRUE (склонение хвоста «Юаня/Юаню/Юанем/Юане», якорь «фан» точный) |
| Винный червь | 2 | червь→черв | 46 | 113 | **+67** | TRUE (оба слова склонны: «Винного червя»; A2 промахивает ВСЕ 67) |
| ветвь Чи | 2 | ветвь→ветв | 0 | 3 | +3 | TRUE (soft в ГОЛОВЕ, якорь «чи» точный) |
| ветвь Фан | 2 | ветвь→ветв | 1 | 3 | +2 | TRUE |
| демонический путь | 2 | путь→пут | 1 | 2 | +1 | TRUE («демонического пути») |
| горная крепость | 2 | крепость→крепост | 0 | 1 | +1 | TRUE («горной крепости») |
| девять рангов | 2 | девять→девят | 1 | 2 | +1 | **МЯГКАЯ НЕТОЧНОСТЬ** (см. ниже) |
Итого A3A0 ≈ **259 окон**, 258 истинных + 1 мягкая. A2A0 = 189 (A2 промахивает 70 истинных
«Винного червя» и др. — нет ТОЧНОГО якоря → A2 хуже A3).
### Практический эффект — на ПОРЯДОК меньше 259, и число НЕ робастно
Пост-чек срабатывает ПО-ЧАНКОВО (наличие любой принятой формы в чанке), не по вхождениям. Частые
имена почти всегда имеют номинатив в том же чанке. «Склонён-ТОЛЬКО (номинатив отсутствует)» —
СИЛЬНО зависит от размера блока (2-й путь счёта, самопроверка поймала завышение):
| блок ~симв | Фан Юань | Винный червь | Мочэнь | Чилянь | ИТОГО/25 глав |
|---|---|---|---|---|---|
| 800 | 32 | 22 | 2 | 1 | 57 |
| 1500 | 8 | 16 | 1 | 1 | 26 |
| 3000 | 0 | 12 | 1 | 0 | 13 |
| **6000** | **0** | **6** | **1** | **0** | **7** |
| **12000** | **0** | **4** | **0** | **0** | **4** |
Боевой чанк ≈ 12k ТОКЕНОВ (~612k симв) → честный per-chunk промах = **~47 на 25 глав, почти весь —
«Винный червь»**; «Фан Юань» на реальном размере чанка → **0** (номинатив всегда рядом). Прежняя оценка
«~26» была артефактом блока 1.5k симв (меньше боевого чанка) — снята. ⚠ Это ПРОКСИ (не боевой чанкер;
faithful — через `tmctl export` границ чанков). Порядок величины (одноцифровой, один термин) робастен.
### A1 отвергнут корректно — вред ГЛОБАЛЬНЫЙ, книго-независимый
M4: `softSameStem("Синь","синим")=true`, `("Линь","линий")=true`, `("Тень","теней")=true` — стем
совпадает («син/лин/тен»). Голое «ь» в реестр поражает глобальный `SameStem`, а через него — весь путь
`declinedFormPresent`, т.е. и `Postcheck`, и `SpoilerLeaks`, в любой книге. Единственный функциональный
потребитель `SameStem``declinedFormPresent` (mempostcheck.go:181); `seeding.go:138` только
конструирует стеммер; `voice.go` его НЕ подключает.
## Adversarial-ревью (author≠reviewer) — что оно сломало
A3 **не закрывает** коллизию Синь/Линь — оно её **ПЕРЕНОСИТ** с одно-словного класса на форму
`[общий-титул] + [ь-фамилия]` (самая частая много-словная форма имени в жанре):
- **Перенос (структурно ВЕРНО, здесь НЕ реализовано):** гипотетический банк-термин «старейшина Синь»
под A3 ложно примет «старейшина синего» (титул «старейшина» — нормальный якорь, «синего»→«син»
мягко). В gu-zhenren этого НЕТ: 18 из 30 soft-строк — CJK-транслит (юан/шэн/чилян/мочэн), чьи
3-руновые стемы просто не русские слова. Чистый прогон — **транслит-везение корпуса, не свойство
гейта.** Форма-риска в банке есть («старейшина школы», «вождь четвёртого поколения»); реализуется в
книге с русско-коллизионной фамилией. (Проверка: «старейшины синеватый» ×1 в выходе есть, но
«синеватый»→«синеват»≠«син» — не сработало бы; точный «старейшина синего» — конструкт, не корпус.)
- **Числовой класс — системно и НЕ защищён (реально на корпусе):** каждый ь-финальный кардинал
(девять/десять/пять/шесть…) мягко сливается с ординалом/косвенной формой. В выходе: «пятого ранга»
×13, «шестого ранга» ×10, «девятого ранга» ×1 — поверхность 24+ вхождения; якорь («ранга») — общее
слово, гейт даёт **ноль защиты**. «девять рангов»~«девятого ранга» — та самая 1 реализованная мягкая
неточность. Класс растёт со счётом рангов (плотный в культивации).
- **Поправка по SpoilerLeaks:** мой тезис «A3 не трогает SpoilerLeaks» — неверно обоснован.
`declinedFormPresent` достижим из `SpoilerLeaks` (mempostcheck.go:254) → A3 его МЕНЯЕТ. Спасает не
«неприкосновенность», а то, что SpoilerLeaks — observability-only, не диспозиция (mempostcheck.go:241):
мягкий ложняк там = шум, не флип гейта. A3 всё же СТРОГО лучше A1 для SpoilerLeaks (закрывает
одно-словный глобальный яд), но не чист (много-словный титул+фамилия остаётся).
- **Ни один вариант не доминирует:** min-стем-гейт бесполезен («юан» и «син» оба 3 руны — не разделить);
tail-restricted (soft только на последнем компоненте) точнее здесь, но теряет «ветвь Чи/Фан» (голова
склоняется) и всё равно ловит хвост-фамилию; стоплист коллизий — хорош как ДОБАВКА, плох соло
(открытый список — форма, от которой `target-ru.txt:19` уже предостерегает); сид-перечисление — золото
для подписного канона, но не масштабируется на авто-майненный хвост.
## Вывод и рекомендация (на ратификацию, НЕ строить без слова владельца)
> Заострено после 2-го адверсариал-прогона (аудит кода+рекомендации). Код харнесса — TRUSTWORTHY
> (6/6 NO-BUG, 147 dst сверено с файлом). Рекомендация исправлена: §3 ниже НЕ «ноль действия».
1. **Разрыв реален, но мал:** ~47 ложных промахов/25 глав на реальном размере чанка, почти весь —
ОДИН термин «Винный червь» («Фан Юань» → 0 per-chunk). Числа окон код-верифицированы.
2. **Голое A3 НЕ рекомендуется:** переносит коллизию на титул+фамилию (риск в другой книге) и не
защищает числовой класс; чистота на gu-zhenren — транслит-везение (пара-зависимое доказательство).
3. **Стопгэп для finding-1 — сид-перечисление декл-форм для 12 ВИДИМЫХ мягких канон-имён**
(«Винный червь»; «Фан Юань» если важен SpoilerLeaks): `declForms` матчатся `containsWholeWord` ТОЧНО —
ноль стемминга, ноль коллизии, ноль правок Go; данные книжного канона в сиде — легитимная общность.
⚠ Честно: `decl.forms`РУКО-ПИСАНЫЙ сид ([memseed.go:89](../../backend/internal/membank/memseed.go#L89)),
майнер морфологию НЕ майнит (его «decl» = ОТВЕРГНУТЫЕ поверхности, miner_emit.go:60); генератора
склонений в Go нет. Значит для ВСЕГО мягкого класса это = ручной труд «142/142-null», который §3
и убивал → сид-перечень оправдан ТОЛЬКО как ограниченный стопгэп на горстку видимых имён, НЕ системно.
4. **Движковый anchor-gated матч — не «отложить» отмашкой, а ЗАГЕЙТИТЬ на корпус-замере** частоты
ложняков переноса ([титул]+[ь-фамилия]) и числового класса — они НЕ измерены (M4 = 3 руко-выбранные
пары, одна книга = предварительно, CLAUDE.md §4), а не опровергнуты. Форма, если строить — СЛОЙНАЯ
(tail-restricted + стоплист ь-кардиналов), данные в `target-ru.txt`, алгоритм generic; но ядро Go не
трогать, пока кросс-парный замер (≥2 пары) не оправдает.
5. Backend-действие сейчас: NB-коммент + регресс-гвоздь (`stemmer_test.go`,
`TestSoftSignNamesDoNotCollideWithCommonWords`) ОСТАЮТСЯ как страховка от наивного ре-адда «ь».
Гвоздь «Линь/линию» инертен — заменить на «Линь/линий» (M4 подтверждает: «линий»→«лин»).
6. **Долгий общий дом (НЕ существует сегодня):** майнер-морфология (наблюдать склонённые поверхности,
а не кодировать «ь») был бы пара-агностичен — но это ОТДЕЛЬНЫЙ механизм bank-autonomy, не бесплатный
и не «минер уже майнит» (ранняя формулировка была неверна — такого пути нет).
## Воспроизвести
```
cd eval/softsign-decl && ./build.sh <work-dir> HEAD
<work-dir>/softsign-decl/softsign-decl \
-bank ~/books/gu-zhenren/coldrun-a/BANK-FULL.tsv \
-output ~/books/gu-zhenren/acceptance/guzhenren-25ch-ru.txt \
-report ~/books/gu-zhenren/softsign-decl/softsign_probe_out.txt
```
Прогон ~135с (O(слова×термины×режимы)). go.mod/replace — вне репо; второго модуля в git не появляется.

43
eval/softsign-decl/build.sh Executable file
View file

@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Собирает softsign-decl КАК МОДУЛЬ ВНЕ РЕПО (прецедент pkg7/minerharness): исходник живёт в eval/ (ревью,
# воспроизводимость), а go.mod + `replace` материализуются в рабочем каталоге вне git. Второго go.mod в
# репозитории не появляется — сборка/vet бэкенда его не видят.
#
# ./build.sh <work-dir> [commit]
#
# work-dir — куда положить модуль и пин-копию бэкенда (скретчпад сессии).
# commit — какой коммит бэкенда пинить (по умолчанию HEAD). Пин обязателен: параллельная бэкенд-сессия
# правит рабочее дерево, и `replace` на него дал бы невоспроизводимый прогон.
set -euo pipefail
WORK="${1:?usage: build.sh <work-dir> [commit]}"
COMMIT="${2:-HEAD}"
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SHA="$(git -C "$REPO" rev-parse --short "$COMMIT")"
PIN="$WORK/pinned-$SHA"
MOD="$WORK/softsign-decl"
mkdir -p "$PIN" "$MOD"
if [ ! -d "$PIN/backend" ]; then
git -C "$REPO" archive "$COMMIT" backend | tar -x -C "$PIN"
fi
cp "$(dirname "${BASH_SOURCE[0]}")/main.go" "$MOD/main.go"
cp "$PIN/backend/go.sum" "$MOD/go.sum"
{
echo "module textmachine/backend/softsign-decl"
echo
sed -n '/^go /p' "$PIN/backend/go.mod"
echo
echo "require textmachine/backend v0.0.0"
echo
sed -n '/^require (/,/^)/p' "$PIN/backend/go.mod"
echo
echo "replace textmachine/backend => $PIN/backend"
} > "$MOD/go.mod"
cd "$MOD"
GOFLAGS=-mod=mod GOPROXY=off go build -o "$MOD/softsign-decl" .
echo "built: $MOD/softsign-decl (backend pinned at $SHA in $PIN/backend)"

337
eval/softsign-decl/main.go Normal file
View file

@ -0,0 +1,337 @@
// Command softsign-decl измеряет разрыв мягкого знака в декл-пост-чеке банка (fix-pack §а finding-1) на
// БОЕВОМ стеммере, НЕ ТРОГАЯ репозиторий. Прецедент — pkg6 `labels/` и pkg7 `minerharness`: отдельный
// Go-модуль ВНЕ репо с `module textmachine/backend/<имя>` и `replace textmachine/backend => <пин-копия>`;
// имя обязано начинаться с `textmachine/backend/`, иначе Go запретит импорт `internal/`. Сборка/пин —
// `build.sh` (git archive <commit>), чтобы незакоммиченные правки параллельных сессий не меняли результат.
//
// Что мерит: для каждого dst банка — приходит ли ПРИНЯТАЯ форма в боевой 25-глав-выход, под четырьмя
// правилами матчинга декл-окна:
// A0 — БОЕВОЕ поведение: declinedFormPresent (mempostcheck.go:169-191) — «ь» НЕ стрипается.
// A1 — наивное: «ь» добавлен в реестр стрипа, применяется к КАЖДОМУ компоненту, БЕЗ якоря (отвергнутый).
// A2 — anchor-gated: мягкий стрип на компоненте разрешён, если ДРУГОЙ компонент совпал ТОЧНО.
// A3 — anchor-gated: мягкий стрип разрешён, если ДРУГОЙ компонент совпал по НОРМАЛЬНОМУ стему (⊇ A2).
// A0 — построчный порт боевого кода на экспортных символах lang; паритет с реальным (unexported)
// dstFormPresent сверен отдельно в membank-пробе (0/29 расхождений) до порта. Ноль сети, ноль моделей, $0.
package main
import (
"flag"
"fmt"
"os"
"sort"
"strings"
"unicode"
"textmachine/backend/internal/lang"
"textmachine/backend/internal/text"
)
type mode int
const (
modeA0 mode = iota
modeA1
modeA2
modeA3
)
// stemAug моделирует «добавить голый «ь» в реестр decl_suffix»: стрипнуть длиннейший реестровый суффикс;
// если ничего не стрипнуто, а слово кончается на «ь» и стем остаётся ≥ minStemRunes(3), стрипнуть «ь».
// Зеркалит longest-first (реальный суффикс всегда бьёт 1-руновый «ь»).
func stemAug(s lang.TargetStemmer, w string) string {
w = strings.ToLower(w)
if st := s.Stem(w); st != w {
return st
}
r := []rune(w)
if len(r) >= 4 && r[len(r)-1] == 'ь' {
return string(r[:len(r)-1])
}
return w
}
func softSameStem(s lang.TargetStemmer, a, b string) bool {
la, lb := strings.ToLower(a), strings.ToLower(b)
if la == lb {
return true
}
return stemAug(s, la) == stemAug(s, lb)
}
// containsWholeWord — порт mempostcheck.go:197-211 (буквенная граница на обоих концах, по рунам).
func containsWholeWord(hay, form []rune) bool {
n := len(form)
if n == 0 || n > len(hay) {
return false
}
for i := 0; i+n <= len(hay); i++ {
eq := true
for k := 0; k < n; k++ {
if hay[i+k] != form[k] {
eq = false
break
}
}
if !eq {
continue
}
if (i == 0 || !unicode.IsLetter(hay[i-1])) && (i+n == len(hay) || !unicode.IsLetter(hay[i+n])) {
return true
}
}
return false
}
// windowMatch — совпадает ли окно outWords[i:i+n] с базовыми словами bw под правилом m.
func windowMatch(s lang.TargetStemmer, outWords, bw []string, i int, m mode) bool {
n := len(bw)
anyExact, anyNorm := false, false
norm := make([]bool, n)
soft := make([]bool, n)
for k := 0; k < n; k++ {
ow, bwk := outWords[i+k], strings.ToLower(bw[k])
if ow == bwk {
anyExact = true
}
norm[k] = s.SameStem(ow, bw[k])
soft[k] = softSameStem(s, ow, bw[k])
if norm[k] {
anyNorm = true
}
}
for k := 0; k < n; k++ {
switch m {
case modeA0:
if !norm[k] {
return false
}
case modeA1:
if !soft[k] {
return false
}
case modeA2:
if !(norm[k] || (soft[k] && anyExact)) {
return false
}
case modeA3:
if !(norm[k] || (soft[k] && anyNorm)) {
return false
}
}
}
return true
}
func countWindows(s lang.TargetStemmer, outWords, bw []string, m mode) int {
n := len(bw)
if n == 0 || n > len(outWords) {
return 0
}
c := 0
for i := 0; i+n <= len(outWords); i++ {
if windowMatch(s, outWords, bw, i, m) {
c++
}
}
return c
}
func firstWindowText(s lang.TargetStemmer, outWords, bw []string, m mode) string {
n := len(bw)
for i := 0; i+n <= len(outWords); i++ {
if windowMatch(s, outWords, bw, i, m) {
return strings.Join(outWords[i:i+n], " ")
}
}
return ""
}
// present — порт dstFormPresent: базовая цельнословная форма ИЛИ декл-окно под правилом m.
func present(s lang.TargetStemmer, noutRunes, baseRunes []rune, outWords, bw []string, m mode) bool {
if containsWholeWord(noutRunes, baseRunes) {
return true
}
return countWindows(s, outWords, bw, m) > 0
}
func loadBankDst(path string) ([]string, error) {
raw, err := os.ReadFile(path)
if err != nil {
return nil, err
}
lines := strings.Split(string(raw), "\n")
seen := map[string]bool{}
var out []string
for i, ln := range lines {
if i == 0 || strings.TrimSpace(ln) == "" {
continue
}
f := strings.Split(ln, "\t")
if len(f) < 2 {
continue
}
dst := strings.TrimSpace(f[1])
if dst == "" || seen[dst] {
continue
}
seen[dst] = true
out = append(out, dst)
}
return out, nil
}
func main() {
var (
bankP = flag.String("bank", "", "BANK-FULL.tsv (col2 = dst)")
outP = flag.String("output", "", "боевой target-выход (txt)")
repP = flag.String("report", "", "куда писать отчёт (durable ~/books/...)")
tgt = flag.String("tgt", "ru", "целевой язык")
)
flag.Parse()
if *bankP == "" || *outP == "" || *repP == "" {
fmt.Fprintln(os.Stderr, "usage: softsign-decl -bank B -output O -report R [-tgt ru]")
os.Exit(2)
}
dsts, err := loadBankDst(*bankP)
if err != nil {
fmt.Fprintln(os.Stderr, "bank:", err)
os.Exit(1)
}
rawOut, err := os.ReadFile(*outP)
if err != nil {
fmt.Fprintln(os.Stderr, "output:", err)
os.Exit(1)
}
s := lang.NewTargetStemmer(lang.TargetChecksFor(*tgt))
if !s.Enabled() {
fmt.Fprintln(os.Stderr, "stemmer inert for", *tgt)
os.Exit(1)
}
nout := text.NormalizeTargetForm(string(rawOut))
noutRunes := []rune(nout)
outWords := lang.TokenizeWords(nout)
var b strings.Builder
pf := func(f string, a ...any) { fmt.Fprintf(&b, f, a...) }
pf("SOFT-SIGN DECL PROBE — bank=%d dst, output=%d words, tgt=%s\n", len(dsts), len(outWords), *tgt)
pf("A0=live(no «ь») · A1=naive global «ь» · A2=anchor:exact · A3=anchor:norm\n")
pf("========================================================\n\n")
type row struct {
dst string
nWords int
softWord, softStem string
a0Win, a1Win, a2Win, a3Win int
a0Base bool
a2New, a3New string
}
var soft []row
for _, dst := range dsts {
base := text.NormalizeTargetForm(dst)
bw := lang.TokenizeWords(base)
var sw, ss string
for _, w := range bw {
r := []rune(w)
if len(r) >= 4 && r[len(r)-1] == 'ь' {
sw, ss = w, string(r[:len(r)-1])
break
}
}
if sw == "" {
continue
}
soft = append(soft, row{
dst: dst, nWords: len(bw), softWord: sw, softStem: ss,
a0Win: countWindows(s, outWords, bw, modeA0),
a1Win: countWindows(s, outWords, bw, modeA1),
a2Win: countWindows(s, outWords, bw, modeA2),
a3Win: countWindows(s, outWords, bw, modeA3),
a0Base: containsWholeWord(noutRunes, []rune(base)),
a2New: firstWindowText(s, outWords, bw, modeA2),
a3New: firstWindowText(s, outWords, bw, modeA3),
})
}
sort.Slice(soft, func(i, j int) bool { return soft[i].a3Win-soft[i].a0Win > soft[j].a3Win-soft[j].a0Win })
pf("M1/M2. SOFT-SIGN TERMS (%d of %d dst) — occurrence-level windows captured\n", len(soft), len(dsts))
pf("dst | words | soft→stem | nomBase? | A0 A1 A2 A3 | A3A0 | A3 first-new\n----\n")
var gA3multi, gA3single, gA2 int
for _, r := range soft {
g3 := r.a3Win - r.a0Win
gA2 += r.a2Win - r.a0Win
if r.nWords > 1 {
gA3multi += g3
} else {
gA3single += g3
}
nt := ""
if g3 > 0 {
nt = r.a3New
}
pf("%-30s | %d | %s→%s | nom=%v | A0=%d A1=%d A2=%d A3=%d | +%d | %s\n",
r.dst, r.nWords, r.softWord, r.softStem, r.a0Base, r.a0Win, r.a1Win, r.a2Win, r.a3Win, g3, nt)
}
pf("\nGAP (occurrence windows over A0): A3 multi=%d single=%d | A2 total=%d\n", gA3multi, gA3single, gA2)
// M3: presence flips over ALL dst (worst case: every term vs whole book)
pf("\nM3. PRESENCE FLIPS over ALL %d dst (A0-miss → variant-present)\n", len(dsts))
type flip struct{ dst, win string }
var f1, f2, f3 []flip
for _, dst := range dsts {
base := text.NormalizeTargetForm(dst)
br := []rune(base)
bw := lang.TokenizeWords(base)
if present(s, noutRunes, br, outWords, bw, modeA0) {
continue
}
if present(s, noutRunes, br, outWords, bw, modeA1) {
f1 = append(f1, flip{dst, firstWindowText(s, outWords, bw, modeA1)})
}
if present(s, noutRunes, br, outWords, bw, modeA2) {
f2 = append(f2, flip{dst, firstWindowText(s, outWords, bw, modeA2)})
}
if present(s, noutRunes, br, outWords, bw, modeA3) {
f3 = append(f3, flip{dst, firstWindowText(s, outWords, bw, modeA3)})
}
}
dump := func(name string, fs []flip) {
pf("%s new presences: %d\n", name, len(fs))
for _, x := range fs {
pf(" %s ⟶ [%s]\n", x.dst, x.win)
}
}
dump("A1 (naive «ь»)", f1)
dump("A2 (anchor=exact)", f2)
dump("A3 (anchor=norm)", f3)
in := func(fs []flip, d string) bool {
for _, x := range fs {
if x.dst == d {
return true
}
}
return false
}
pf("\nA1-ONLY presences (removed by anchor gate A3) — collision-suspect set:\n")
nOnly := 0
for _, x := range f1 {
if !in(f3, x.dst) {
pf(" %s ⟶ [%s]\n", x.dst, x.win)
nOnly++
}
}
pf(" (count=%d)\n", nOnly)
// M4: confirmed collision class (book-independent) under global soft SameStem vs anchor gate
pf("\nM4. CONFIRMED COLLISION CLASS (fix-pack §а) — global soft (A1) vs single-word anchor gate\n")
for _, p := range [][2]string{{"Синь", "синим"}, {"Линь", "линий"}, {"Тень", "теней"}} {
pf(" A1 softSameStem(%q,%q)=%v (stems %q/%q) | anchor gate: lone word, no anchor ⟶ never soft\n",
p[0], p[1], softSameStem(s, p[0], p[1]), stemAug(s, p[0]), stemAug(s, p[1]))
}
if err := os.WriteFile(*repP, []byte(b.String()), 0o644); err != nil {
fmt.Fprintln(os.Stderr, "write report:", err)
os.Exit(1)
}
fmt.Print(b.String())
fmt.Fprintf(os.Stderr, "\nreport written: %s\n", *repP)
}