diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 8fcce3ef..ae314601 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -1,13 +1,14 @@ # Журнал прогресса -> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-08, голова D39.117; хендофф №14→№15 — D39.107). ⚠⚠ **ИНЦИДЕНТ 08.08 00:13 (D39.113): агент моей панели откатил незакоммиченные правки СЕМИ файлов чужих сессий** — `git checkout -- .` в реальном дереве вместо песочницы. Пинг полигона в этом файле ВОССТАНОВЛЕН из бэкапа 00:08; безвозвратно потеряны правки отчёта эксп-21, промта полигона, Приложения А контракта и трёх скриптов `eval/role_topology/`. Коммиты целы. Инвентарь и норма изоляции панелей — D39.113. ⚠ **Оркестраторов сейчас ДВА, зоны разведены явно (решение владельца 07.08):** №15 — приёмка ПЛАТФОРМЫ (исполнена, D39.109–D39.114: P1+P2 приняты, фикс-пак P3 принят и заленден `99f049c` — девять строк регистра закрыты, 8/8 моих посадок поймано, PD-80 и PD-91 пере-проверены исполнением; записи верифицированы независимым агентом, поправки — D39.112) · ВТОРОЙ, параллельный — приёмка ПОЛИГОНА (эксп-21 ПРИНЯТ — D39.117; промт эксп-22 выдан). **Номер второму НЕ выдан намеренно:** канонический счётчик один и живёт в `ORCHESTRATOR_SESSION_PROMPT.md`, а выдавать номер сессии, которой я не писал промт, — второй носитель состояния. Одновременно не запускаются; CURRENT-STATE ведут оба, каждый пишет про свою зону и чужую строку не трогает. +> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-08, голова D39.118; хендофф №14→№15 — D39.107). ⚠⚠ **ИНЦИДЕНТ 08.08 00:13 (D39.113): агент моей панели откатил незакоммиченные правки СЕМИ файлов чужих сессий** — `git checkout -- .` в реальном дереве вместо песочницы. Пинг полигона в этом файле ВОССТАНОВЛЕН из бэкапа 00:08; безвозвратно потеряны правки отчёта эксп-21, промта полигона, Приложения А контракта и трёх скриптов `eval/role_topology/`. Коммиты целы. Инвентарь и норма изоляции панелей — D39.113. ⚠ **Оркестраторов сейчас ДВА, зоны разведены явно (решение владельца 07.08):** №15 — приёмка ПЛАТФОРМЫ (исполнена, D39.109–D39.114: P1+P2 приняты, фикс-пак P3 принят и заленден `99f049c` — девять строк регистра закрыты, 8/8 моих посадок поймано, PD-80 и PD-91 пере-проверены исполнением; записи верифицированы независимым агентом, поправки — D39.112) · ВТОРОЙ, параллельный — приёмка ПОЛИГОНА (эксп-21 ПРИНЯТ — D39.117; промт эксп-22 выдан). **Номер второму НЕ выдан намеренно:** канонический счётчик один и живёт в `ORCHESTRATOR_SESSION_PROMPT.md`, а выдавать номер сессии, которой я не писал промт, — второй носитель состояния. Одновременно не запускаются; CURRENT-STATE ведут оба, каждый пишет про свою зону и чужую строку не трогает. > - **Сессия №15 (07.08, ИСПОЛНЕНА):** **приёмка платформы P1+P2 — ПРИНЯТО и ЗАЛЕНДЕНО `fcdab81`** (62 файла, +7066/−252; D39.109). Адверсариально: своя батарея с живым PostgreSQL 18.4 (скипов ноль) · 45 СВОИХ мутаций (33 поймано, 8 выжило, 4 моих посадки негодны и разобраны) · живые пробы на боевом бинаре (PD-2 отпускает на 30.0 с; RFC 9207 сверен у Google) · панель 7 линз с опровергателем на каждую находку. Ратифицировано 6 решений (срок сессии 30 суток — **CONFIRM владельца 07.08 получен** · `iss` авторизационного ответа + миграция 00008 · §13 политики сессий · ломающие изменения зоны · `MemoryMax=80%`+`OOMPolicy=continue` · PD-71 риском). Регистр зоны доведён до **PD-107**. На момент приёмки открытыми были тридцать семь строк, весом major — три: PD-80 (вход выключается ~3 rps, и 429 колбэка добивает начатые входы) плюс PD-95 и PD-105, поднятые эрратой как задание эмиттеру. ⚠ **Числа здесь ИСТОРИЧЕСКИЕ — это то, что нашла приёмка;** живой счёт регистра меняется с каждым фиксом зоны и берётся командой `python3 docs/scripts/counts.py`, а не из этой строки (норма D39.112: один носитель на факт). **Живой уязвимости нет.** ⚠ **ЭРРАТА 07.08 (поймано вопросом владельца, не процессом):** приёмка пропустила, что **D39.106 п.3 снял пайп-транспорт** («PD-59 superseded; пайп-путь `supervisor.go` P1 = дев-режим»), и приняла зонную секцию «канал остаётся stdout» как живое решение. Ратифицированная форма — транзиентный systemd-юнит на прогон, платформа НЕ родитель, события = `events.jsonl` каталога книги, платформа ТЕЙЛИТ с курсором (`research/25` §Форма; родитель+пайп 0/15 голосов). Исправлено: секция журнала помечена superseded, PD-95 переписан и поднят в вес, PD-92 понижен до info, PD-105 повышен, PD-60 пере-диспозиционирован; вердикт лендинга не меняется (код и был дев-путём по D39.107 п.3). ⚠ Пять строк реестра — движковые по существу и должны быть разрулены ДО промта эмиттера (строка 103): PD-95 (транспортная история зоны устарела против D39.106 в двух местах — эмиттер-сессия прочтёт её как задание) · PD-105 (дубль `seq` = убитый платный прогон против норматива «дубль не ошибка»; при тейле файла повторная доставка — норма) · PD-79 (строковый `"null"` в цене = ноль денег) · PD-99 (argv на INFO — деньги/book-id при воркере) · PD-107 (удаление аккаунта обходит гарантию PD-25) · **PD-60 и PD-61** (обратное давление и сброс буфера — свойства эмиттера, задаются дешевле ДО постройки, чем миграцией после; PD-60 переформулируется под файл-транспорт). **Потолок прогона РЕШЁН владельцем 07.08 и ратифицирован формой (D39.110):** шкала в интерфейсе от минимума (ноль нельзя) до баланса аккаунта ⇒ Р7 не амендируется, «выключено» не существует как состояние. Добор: единица шкалы — ГЛАВЫ, не доллары (иначе амендмент D39.84) · потолок в `book.yaml` НЕ пишется, движку нужен приём на прогон — НОВАЯ строка **145** · максимум шкалы = баланс минус открытые холды. **Фри-тир:** ответ дан нормой (автогрант без якоря — не стандарт; `email_verified` Google якорем не является), предложение оркестратора — на бете дефолт в НОЛЬ и начисление руками, при платежах $5 вместе с суточным потолком; **ждёт слова владельца** (PD-104, там же расхождение док↔код: реестр обещает ноль, код начисляет $5) · **приёмка экспов 18/19/20 ИСПОЛНЕНА и залендена** (D39.108: приняты с ревью-шапками; §5.2 экспа 20 — «со слов»; деньги сессии полигона $2.0720; квирк §3б отозван, §3а в силе; D21.4/D21.10 закрыты) · **эксп-21 «топология ролей» — промт выдан** (`POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT.md`: скрин моделей по 7 ключам → бейк-офф топологий на невиданном срезе; потолки ПРЕДВАРИТЕЛЬНЫЕ ≈$7.3 стадиями; **ЗАПУСК = слово владельца**) · строки 135–144 заведены, 103/106/134/65/55/12 пере-диспозиционированы · дальше по D39.107 п.3: промты эмиттера (бэкенд) и денег шва (платформа) — по команде · **S3 «слой данных» ПРИНЯТ и заленден `60595f6` (D39.115): контракт 0.2.0 в каноне, копии байт-равны, блоки компаньона 2.14–2.16 внесены; сессия нашла ТРИ ошибки оркестратора — «баланс минус холды» (вычитание дважды, пере-мерено), `nullable: true` невалиден в 3.1, инструкция внутри нормативного дока протухла от исполнения; норма «не ходить в чужую зону» амендирована: не ПИСАТЬ, а читать код для сверки — можно и нужно** · вахта deepseek-v4-pro — пере-проба маппинга вшита в Ф1 эксп-21 · мини-проба флора 44 — одобрена, промт не выдан. **Открыто на владельце:** прогон Sol-пакетов руками (строка 150) · кредиты xAI (арбитр grok + судья 18+) · запуск эксп-22 (промт выдан, D39.117) · передача платформы · Приложение А `14-api-contract` (незакоммичено) · **НОВОЕ 08.08 (D39.115, фронт):** продуктовое слово «остановлена: лимиты» (сжатие вашей фразы сделала сессия, В-3) · **К-13/Ф-31:** упереться в СВОЙ потолок прогона и остаться без кредита сегодня неразличимо — `paused_reason` имеет одно значение, и первому фраза врёт · **В-4/Ф-30:** глава без заголовка показана голым номером, синтез «Глава N» запрещён К-3 · **фри-тир (PD-104):** дефолт в ноль и начисление руками против автогранта $5 с суточным потолком · **Приложение А (строка 148):** брать реконструкцию с баннером или заполнять заново · 116 (порог подан) · мини-проба 44 · подпись денежного шага 46 · лист В-3+К-6 · вопрос платформы (авто-резюме `paused`). +> - **Сессия №15 (08.08, приёмка бэкенда): фикс-пак банка (128+129+130-минимум) ПРИНЯТ и ЗАЛЕНДЕН `bccf2d8` (D39.118).** Приёмка четырёхконтурным воркфлоу (слепой дифф · пере-ран заявлений · 8 посадок в копии зоны · охота вне карты) + дофикс-раунд: блокер lint (клейм «батарея зелёная» был ложным — признано) · мёртвый WARN 130 (само-исключение сырого seed) · 2 дыры пинов space-run · инертный `bankParseVersion` · 3 тихих отказа канала семей — ВСЕ закрыты; ре-чек: battery EXIT=0 целиком, 685→717 тестов, пере-посадки 3/3 CAUGHT. Ратифицировано D39.118: сдвиг edit-волны bank-only принят (слово владельца) · bankdata-плоскость вне волнового фолда · лог вместо миграции для эвиктнутых. Строки 128/129 закрыты, 130 пере-скоуплена, заведены 154–159. Верификация эффекта — §6 отчёта, гейт: первый холодный прогон. **АКТИВНОГО промта бэкенда нет** — следующий (эмиттер 103 + деньги шва 135/145) по слову владельца (D39.107 п.3). > - **Сессия параллельного оркестратора (приёмка полигона, 08.08, D39.117):** **эксп-21 ПРИНЯТ** — гейты пере-гнаны исполнением (`verify_report.py` 90/90 код 0 · `itog.py` код 0); подтверждения владельца по тратам и агент-судейству получены, риг-девиация ратифицирована (девиация от промта оркестратора, не решение владельца). Несущее (числа — ИТОГ отчёта 21 и D39.117, здесь не дублируются): **работает ТОПОЛОГИЯ, а не жилец** (нога 2×2) · **черновик — главный рычаг качества финала**, самая недоинвестированная роль · закон-блок ОБЯЗАТЕЛЕН (двойное подтверждение) · роутинг/обратная связка/ремонт-как-замена — отклонены. Диспозиции: 65 ЗАКРЫТА (жилец = цена) · 142 принята формой «пре-гейт перед редактором» · 106 не закрыта (довод, не опровержение) · 55 частично (остаток = чистый zh-срез, заказ повторён). **Промт эксп-22 «панель жильцов» выдан** (149) · Sol-арбитраж вместо слепого чтения (150) · строки 151–153 заведены · три провод-факта в quirks 00. ⚠ Величины эксп-21 предварительны до чистого zh-среза. > - **Сделано (сводно; детали — D-лог и архив-слайсы):** Ф0 ✅ · Ф1-инфра ✅ · арх-ресет D39 (7 слоёв, паки 11–16) ✅ · паки 17 «канал B» · 18 «долги» · 19 «голос/состояние» · 20 «банк+терминолог» ✅ (D39.26–28/31/41–56) · мини-прогон (D39.37) и ХОЛОДНЫЙ прогон (D39.58: recall банка 0.918/0.980, банк приходит переведённым) приняты · полигон-пакеты 5–8, 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.59–78) → **ФРОНТ-ЭРА открыта** (D39.81–100: зоны `frontend/`+`platform/` живые, контракт API ратифицирован). Развилка блокера 0731 решена вариантом (б) и ИСПОЛНЕНА (D39.87/91: `reasoning_effort:"low"` черновику + ручка эффорта бэнк-ролям, код `553f1a3`); отладочный прогон C не стартовал ⇒ **строка 16 жива и оси голоса 13б без данных**; пак экрана 46 — дизайн заморожен (D39.92 п.1 + D39.93), промт ждёт выдачи; coldrun-b фаза C заморожена чекпойнтом — легитимный исход (D39.86); эталон денег/поведения — coldrun-a (read-only). Числа и хроника закрытых паков — D-лог D39.79–97, сюда НЕ дублируются. > - **Горизонт (D39.62/67, освежён D39.95):** ре-проба flash ИСПОЛНЕНА и строка 74 закрыта (D39.86/91; порог 6/6 → пере-ратификация выборочным, строка 116; проба Q2 ИСПОЛНЕНА — research/24, D39.102: семейства не окупаются, остаток = рецензент спорных кластеров при ре-пробе 74; эмиссия Q7 — по слову) → **ДОБОР ИДЕАЛА** (первым прогоном: оси голоса 24 · авто-режим · цена 16; жильцы ролей решаются ДО прогона отдельным эксп-22 — строка 149 · веса K1–K12 13а · вне-претрейн чекпоинт 55) → ВТОРАЯ ПАРА живьём (ja→ru; преп 81) → МАСШТАБ → пилот Ф2.5 (гейт резюме-строки 80; строки 62–68, 85) → Ф3 ридер-IDE (69–71). **Стоячие:** ToS-триггер 25.10 · Ш-2 до go1.27 (⚠ + x/text-таблицы Unicode 17 тем же тулчейном — строка 119/реестр 108) · проба провода исполнена и 117 закрыта (D39.97), конфиги 112 залендены — платные прогоны разблокированы. > - **Стек:** draft deepseek-v4-flash thinking-ON (банкнота: ⚠ канал в shipping-c1 НЕ включён — жив ран-локальным конфигом книги, строка 140) **⚠0731** → терминолог (та же модель, батчи, экран `target_script`) → editor deepseek-v4-pro БИЛИНГВ ИНТЕРИМ (⚠ эксп-21/D39.117: топология ПОДТВЕРЖДЕНА — второй проход покупает +2.5 ошибки/ед. при неразличимости жильцов dspro/glm-5, прежний вывод exp20 «на dspro отрицателен» опровергнут; закон-блок ОБЯЗАТЕЛЕН — строка 134; величины предварительны до чистого zh-среза; ⚠ вендор АНОНСИРОВАЛ смену маппинга эффорта pro «early August 2026» — вахта в реестре 108; glm-5 резерв) → судья gemini (Ф2, полигон); канал B Mistral+grok; ~$0.85/ранобэ (D30.4) — 112 залендена (D39.97), пере-калибровка цены при следующем платном прогоне. -> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). **СЧЁТ ОЧЕРЕДИ на 08.08 (D39.117, скриптом по таблице; обновлять при каждом лендинге):** всего **127** строк · зона бэкенд **64** строго (ячейка ровно «бэкенд») / **84** широко ⚠ (испр. 08.08: было 62/79 — мой счётчик читал колонки СЛЕВА и на строке 127 с `seed|ruby|auto` внутри ячейки принимал за зону слово «ruby»; теперь колонки читаются с конца, а битая форма строки — расхождение, а не тишина) (ячейка содержит «бэкенд») · **блокеров очереди 0**, платные прогоны разблокированы · «скоро» **36** (2·4·18·46·49·55·99·100·101·103·108·109·113·114·116·118·119·120·121·125·126·128·129·130·134·135·136·138·139·140·**142**·143·145·148·**149·150**) · гейт-строки эксп-22: 55·153 (плюс 150 — руки владельца); строка 5 — остаток гейчен ре-пробой 74 (D39.102 п.2); остальное «когда-нибудь». ⚠ **Счёт — НИЖНЯЯ граница долга, а не потолок:** трекер содержит только замеченное, и 02.08 дважды за $0 свежие глаза вытащили из кода дефекты, которых в нём не было (релей фронта → строки 99/100/102; приёмочное ревью → третий шов `repair.go:384` в 104 и честность `quality.go:436` в 105). Лента ✅ выше — про ЗАКРЫТЫЕ паки, читать её как «долга нет» неверно (разбор — вопрос владельца 02.08, D39.89). +> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). **СЧЁТ ОЧЕРЕДИ на 08.08 (D39.118, скриптом по таблице; обновлять при каждом лендинге):** всего **131** строка · зона бэкенд **67** строго (ячейка ровно «бэкенд») / **88** широко (ячейка содержит «бэкенд»; ⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0**, платные прогоны разблокированы · «скоро» **35** (2·4·18·46·49·55·99·100·101·103·108·109·113·114·116·118·119·120·121·125·126·134·135·136·138·139·140·**142**·143·145·148·**149·150**·154·157) · гейт-строки эксп-22: 55·153 (плюс 150 — руки владельца); строка 5 — остаток гейчен ре-пробой 74 (D39.102 п.2); остальное «когда-нибудь». ⚠ **Счёт — НИЖНЯЯ граница долга, а не потолок:** трекер содержит только замеченное, и 02.08 дважды за $0 свежие глаза вытащили из кода дефекты, которых в нём не было (релей фронта → строки 99/100/102; приёмочное ревью → третий шов `repair.go:384` в 104 и честность `quality.go:436` в 105). Лента ✅ выше — про ЗАКРЫТЫЕ паки, читать её как «долга нет» неверно (разбор — вопрос владельца 02.08, D39.89). > - Архивы хроники: `archive/PROGRESS-2026-07-04-10.md` (D31) · `-10-13` (D39.6-гигиена) · `-13-25` (стройка паков 11–16, rerun2) · **`-25-31` (паки 17–20 · мини-прогон · полигон-пакеты 5–8 · ToS · холодный прогон; D39.26–58)** · **`-08-01-02` (сессии №9/№10: общность · качество банка · coldrun-b · открытие фронта/платформы; D39.59–90, срез D39.105)**. Записи ниже — живой хвост (№11+, эра D39.91+). ## Бэклог (ЕДИНЫЙ, собран 26.07, актуализация 04.08 D39.99/D39.101; правки — только через оркестратора) @@ -61,8 +62,8 @@ | 36 | Кластеризация майнера глотает родовые титулы (族长/学堂家老 в кластере 葛家) — закрыто на границе сборки входа, сама кластеризация не чинилась | бэкенд | когда-нибудь | отдельное решение | D39.43, D39.45 | | 36б | **Второе мнение по банку**: рецензент ДРУГОЙ моделью, несогласия — отдельной колонкой подписной таблицы (судья-с-декоем в роли рецензента; решает владелец, D39.46-ограничение не бьёт). ⚠ **Бэкенд-стройки НЕТ** (D39.69 закрыл по нужности); замер ИСПОЛНЕН (research/24, D39.102) — остаток = строка 5: рецензент спорных КЛАСТЕРОВ при ре-пробе 74, роутинг family/series-юнитами; переживёт замер → тонкая колонка наблюдаемости, не гейт | полигон (замер) → бэкенд (только если переживёт) | когда-нибудь (слот при ре-пробе 74, остаток строки 5) | замер остатка → решение | D39.69, D39.90, **D39.102** | | 36г | **Проводной формат каналов пересказан прозой в каждом пар-промпте, парсер в Go, связи нет** — формат в шаблон движка (`{{banknote_format}}`); линты держат класс, дублирование остаётся | бэкенд | когда-нибудь (со следующей правкой промптов) | отдельное решение (Р5) | D39.58 | -| 37 | **Квадратичности: `AttachKWIC`** (16.8 с / 2000 кандидатов; фикс — многошаблонный поиск; кандидат-носитель — опция фикс-пака 128, Aho-Corasick в membank готов) + src-правило банкноты при промахе чанк-пути (строка × длина книги; на 10 главах не видна) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.1, D39.58 | -| 38 | Смета не видит пере-покупку прохода терминолога на каждой итерации подписи (роль не пишет `chunk_status`, не видна `projectRebill`) · хвост приёмки №13 (СО СЛОВ слепого ревью, НЕ верифицировано): адрес чекпойнта батча = ординал при частотной сортировке растущего набора кандидатов ⇒ реюз чекпойнтов прохода ~0 на инкрементальной книге (`terminology.go:925-931`) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.2, D39.102 | +| 37 | **Квадратичности: `AttachKWIC`** (16.8 с / 2000 кандидатов; фикс — многошаблонный поиск; ⚠ опция фикс-пака 128 НЕ взята — «чисто не ложится»: автомат в `membank` неэкспортирован, вынос в общий пакет = рефакторинг слоя, `terminology` PURE не может импортировать банк-стор — отчёт пака §4 п.5, D39.118) + src-правило банкноты при промахе чанк-пути (строка × длина книги; на 10 главах не видна) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.1, D39.58, D39.118 | +| 38 | Смета не видит пере-покупку прохода терминолога на каждой итерации подписи (роль не пишет `chunk_status`, не видна `projectRebill`) · хвост приёмки №13: адрес чекпойнта батча = ординал при частотной сортировке ⇒ реюз чекпойнтов прохода ~0 на инкрементальной книге — **механика ПОДТВЕРЖДЕНА КОДОМ фикс-паком (§2 отчёта, D39.118):** G1 двигает состав юнитов и те же ординалы, на первом прогоне после пака перекупаются все бэнк-батчи (центы) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.2, D39.102, D39.118 | | 39 | S12 частичен: `malformedSeparatorAt` не ловит подмену слова разделителя и обрыв токена (комментарий обещает) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.3 | | 40 | `bankTokenBudget`: worst-case зашит zh→ru (признанная утечка §0; CJK-цель недобирает вдвое) | бэкенд | когда-нибудь | отдельное решение | D39.45, PACK20_BANK_BUILD §8.5.4 | | 41 | golden: вторая фикстура С langpack (сейчас пинится только фолбэк-путь) ; + golden-счётчики голоса (хвост D39.58) | бэкенд | когда-нибудь | отдельное решение | D39.37(6) | @@ -75,9 +76,7 @@ | 48 | Направленная банкнота — вернуться по замеру покрытия терминолога | бэкенд | когда-нибудь | отдельное решение | D39.42 | | 48а | **Серийный шаринг банка** — РЕАЛИЗАЦИЯ (экспорт подписанного глоссария как сид-YAML следующей книги серии; спойлер-окна плющатся в since_ch=0); контракт round-trip держится тестом, самой фичи нет | бэкенд | когда-нибудь (перед второй книгой серии) | отдельное решение | D39.42 задел (а), PACK20_BANK_BUILD З-а | | 48б | **Импорт «оригинал + чужой перевод» как режим данных терминолога** (target-агностичный вход есть контрактом; сам режим + провенанс источника + юр-сторона в юр-пакете) | бэкенд/владелец | когда-нибудь | отдельное решение + Ф2.5 (юр) | D39.42 задел (б), PACK20_BANK_BUILD З-б | -| 128 | **Фикс-пак банка (вход §G research/24, класс D39.71):** G1 семейный со-батч из ПАР-ДАННЫХ (имя=префикс/реалия=суффикс, без транзитивности, серия сильнее семьи; + многорунные модификаторы серий — 十一转 рвёт со-батч равнодлинности на ранге 11; + майнерские containment-пары в один юнит) · G2 intra-run `ConsolidationConflicts` ($0; 18/149 на живом банке) · G3 наблюдаемость (Signals/Invented/Conf в стоп-таблицу · ловушка числового хвоста ParseReply · alias-джойн подписной карты `miner_emit.go:242` — владелец подписывает, не видя alias-рендерингов · имена эвиктнутых при NEvicted · per-batch спросили/ответили + WARN на пустой ответ батча/классификатора) · G5 счёт голосов по нормализованной форме + Via-провенанс фолда (первый-выигрывает врёт на wire) · опции: перф 37 (Aho-Corasick в membank готов) · гигиена (мёртвая колонка `BanknoteTruncated` + стейл-комменты · NoDst-префикс-матч для латиница-target). Цена фолда: перекупка бэнк-батчей один раз (центы), волны/снапшоты не двигаются; вне снапшота — G2 и печать (G5 двигает wire, аудит промта) | бэкенд | **скоро — САНКЦИОНИРОВАН владельцем 04.08 (D39.103 п.1), ПРОМТ ВЫДАН** (`docs/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md`) | фикс-пак одним промтом | D39.102, D39.103, research/24 §G | -| 129 | **Банкнота-парсер теряет хвост многословного dst** (находка приёмки №13 против клейма A10): `banknote.go:236` берёт `parts[1]` голым при 3-польном формате — «Фан Юань» с двойным пробелом банкует полу-имя «Фан», хвост уезжает в колонку типа и падает в `"term"`; ре-джойн терминолога (`terminology.go:880-885`) ровно этот класс чинит с комментарием. Фикс = ре-джойн середины при последнем поле ∈ закрытому словарю типов; двигает observed → авто-банк (memory_version там, где случай реален) — цену назвать при выдаче | бэкенд | скоро (хвостом 128 либо отдельно) | малое касание | D39.102 п.3 | -| 130 | **emitRankCap × writeAutoBank: терм, выпавший из топ-200, МОЛЧА стирается из авто-банка посреди книги** — `miner_emit.go:119-123` кап ДО эмиссионных фильтров (seed/rejects слотов НЕ освобождают — исключаются после капа), `mining.go:448-460` перезапись файла целиком без мерджа против «накопительного» замысла пака-20; оплаченная консолидация теряется, редактор теряет строку банка (по D39.104 — закон на проводе) без сигнала; FL-3 ратифицирован ДО авто-провода D39.42 — взаимодействие не ратифицировалось. Минимум $0 = дифф старого/нового авто-файла + WARN с именами; накопительный мердж/освобождение слотов — СТОП-решение (двигает банк → memory_version) | бэкенд | скоро | $0-минимум + СТОП-решение | D39.102 п.3 | +| 130 | **emitRankCap × writeAutoBank — ОСТАТОК после фикс-пака (D39.118):** $0-минимум ИСПОЛНЕН (дифф старого/нового авто-файла + WARN с именами выпавших; само-исключение сырого seed закрыто `unsignedEngineSurfaces` дофиксом приёмки); остаток = накопительный мердж авто-банка / освобождение слотов seed-rejects — СТОП-решение владельца (двигает банк → memory_version); материал для решения даст WARN со ВТОРОГО прогона (§6 п.8 отчёта пака) | владелец → бэкенд | когда-нибудь (гейт: WARN второго прогона) | СТОП-решение | D39.102 п.3, **D39.118** | | 131 | **Кап инъекции не считает маркер и гендер-ноты**: `glossaryLineTokens` бюджетирует только «src → dst» (`memory.go:512-515` против рендера `:698-708`) — авто-книга (все строки Ambiguous с ⟨проверить⟩) превышает `glossary_token_budget` ~на 40–60% при budget 800; биллинг/потолки компенсированы (резервация по фактическому рендеру, `stagerun.go:469-477`), сам кап не исполняется. Фикс двигает состав инъекций → RequestHash → перекупка волн ⇒ СТОП-решение с названной ценой. ⚠ После строки 134 (единый блок, маркер снят с провода — D39.104) превышение пере-замерить: состав рендера сменится | бэкенд | когда-нибудь | СТОП-решение | D39.102 п.3 | | 132 | **Стойкий (пост-ретрайный) аутедж ТОЛЬКО банк-провайдера валит весь ран** вопреки коммент-контракту «optional step never aborts» (`terminologist.go:630-634` — деградация только на ceiling; транспортные ретраи гасят transient, `httpllm.go:126-160`; потерь нет — чекпойнты реплеятся за $0): решить — деградировать в «термы неконсолидированы»+WARN либо честно переписать коммент | бэкенд | когда-нибудь | малое касание через СТОП-решение | D39.102 п.3 | | 134 | **Дата-правка инжект-заголовков под доктрину D39.105** (единый закон-блок редактора вместо двухсекционки · оговорка ОБЛАСТИ употребления · снятие маркера ⟨проверить⟩ с провода; статусы строк и подписная таблица НЕ меняются): кандидат-тексты — §B промта пробы 18; **ГЕЙТ ПАЛ (D39.108):** текст = ОТПРАВЛЕННАЯ строка пробы 18 БЕЗ оговорки области (девиация №1; оговорка опровергнута §A.4 — НЕ вносить); двигает рендер → RequestHash → перекупка, цену назвать при внесении | бэкенд | скоро | малое касание | D39.104 п.2, **D39.108** | @@ -102,6 +101,13 @@ | 151 | **Отказной режим связки**: эхо-мина черновика воспроизводима на материале (глава 11 — 3/3 попыток; частота 31% на zh), связка покрыла 9/10 подряд идущих глав против 10/10 у однопроходки — единственный довод ПРОТИВ связки во всём эксп-21; движку нужен fallback при невозможности годного черновика (вариация ре-гена · эскалация модели черновика · деградация в однопроходку) | владелец → бэкенд | когда-нибудь (до МАСШТАБА) | СТОП-решение | **D39.117**, exp21 §14 | | 152 | **Слипание абзацев — слепое пятно детерминированного контура**: батарея на тех же текстах даёт ДРУГОЙ порядок армов (`D` — худший по судье — лучший по правилам), расхождение локализовано в слипании, которого не проверяет ни одно правило; правило в батарею полигона + кандидат в гейты движка | бэкенд/полигон | когда-нибудь | малое касание + тест | **D39.117**, exp21 §13 | | 153 | **Чистый контраст мандата перевёрстки**: `D/D_` загрязнён (объём промта ×1.92 + вёрсточная строка + правило чэнъюй); уравненные промты и пере-гон ≈$0.35; по грязному контрасту мандат ВРЕДИТ по оси ФОРМА (−1.09 из −3.31 `D/A`) | полигон | когда-нибудь (опция эксп-22 Ф3 — реши сессия) | замер | **D39.117**, exp21 §16.3 | +| **— ХВОСТЫ ФИКС-ПАКА БАНКА (D39.118) —** | | | | | | +| 154 | **Одноруновая голова семьи** (`蛊`/`转`/`窍` едет в отдельном вызове от 12 своих поверхностей — якорь семьи обязан быть ≥2 рун) — включается ОДНОЙ строкой данных `family_containment_runes han 1`, Go не трогается; не включена: цена в размере юнитов не замерена | бэкенд | скоро (гейт: замер размеров юнитов на первом холодном прогоне, вместе со 157) | строка данных по замеру | **D39.118**, отчёт §5 | +| 155 | **Скрипт-слепой резолв семей/серий**: han-правила режут кану и хангыль (синтетика: 24 катаканных имени с общим アリ → батч 8036 рун при бюджете 6000); живого вреда нет — пары в репо нет; та же слепота у серий уже в HEAD | бэкенд | когда-нибудь (преп ja→ru, с 81/120) | ja-пак | **D39.118**, отчёт §5 | +| 156 | **`banknote_truncated` — ПОЛ, а не счёт**: обрыв, срезавший сам разделитель, флага не даёт; буквальный фикс зажёг бы колонку на каждом обрыве в прогонах без канала — нужен гейт по `Gates.Banknote.Enabled` | бэкенд | когда-нибудь | малое касание | **D39.118**, отчёт §5 | +| 157 | **Пере-подтвердить `family_max_members=24` и `families_held`** на длинной книге (24 калиброван на дистилляции в 150 поверхностей; кап эмиссии 200 + реверс-секция дают другой список); если `families_held` велик — ослабить гард до «родство по любому члену юнита» вместо «по корню серии» | бэкенд | скоро (гейт: первый холодный прогон, §6 отчёта) | замер → решение | **D39.118**, отчёт §7 п.7 | +| 158 | **Уверенность не гейтится данными пары**: канал снимает третью колонку у любой пары, чей промпт её попросит; у пары с ДВУХпольным промптом узкий риск «Пик␣␣99» (число ≤100 за двойным пробелом уедет в conf); при нужде — дата-декларация пары | бэкенд | когда-нибудь | дата-декларация | **D39.118**, отчёт §4 п.6/§7 п.8 | +| 159 | **Durable-имена эвиктнутых** (`retrieval_state.evicted_detail` = миграция; сегодня лог, и приёмка ратифицировала «этого достаточно») — заводить только при доказанной потребности, одним касанием с идемпотентностью миграций 49а | бэкенд | когда-нибудь (гейт: доказанная потребность) | миграция с 49а | **D39.118**, отчёт §7 п.2 | | 49 | **Этапы Б+В спеки D15.2** (content-addressed resume / `guard_hash` — D39.31 сознательно не строил) ; этап В = tmctl export-контракт D29.1 (annot-v1 · цвет-мап+rollup · политика красных fail-closed) + операторский протокол-документ релиза гендер-твиста (D5.1): сам механизм УЖЕ построен — until_ch-правка → точечный re-edit со сметой и $0-пере-пином (`repin.go`/`rebill.go`, D39.42 п.5/D39.45) | бэкенд | скоро (ПОДТЯНУТА D39.81: annot-v1 = источник замечаний для фронта — критический путь подключения) | отдельное решение (annot-половина — по контракту 14, D39.99) | D39.34(4), D33 п.5, D39.81 | | 49а | **ALTER-шаги миграций v8–v14 не идемпотентны вопреки шапке `migrate.go:9-11`** (полу-применённая БД не сходится; счётчик версий скрывает) — находка критика полноты пака-19 | бэкенд | когда-нибудь | отдельное решение | D39.56, PACK19_BUILD §6.9 | | 50 | F3-остаток идемпотентности | бэкенд | когда-нибудь | отдельное решение | D39.34(4) | @@ -111,7 +117,7 @@ | **— ПОЛИГОН (кандидаты пакетов) —** | | | | | | | 55 | **`dialogue_dash` мерить только на невиданном тексте** (подогнан под 蛊真人; цифры мини-прогона аргументом не считаются) ; расширено до вне-претрейн чекпоинта целиком: r-коэффициенты exp01/08 · precision чекеров · частота эха · чистовик exp15-выводов ; + arity-полоса паспорта (D29.2г): решить — dialogue_dash покрывает диалоговую половину или мерить (D39.73). **Частично закрыта эксп-21 (D39.117):** направление главного вывода воспроизведено на чистом en-материале (узнавание 1/5), $0-довесок исполнен частично; **срез эксп-21 НЕ купил** (главный zh-замер на книге 4/5, без пинга) — остаток = неконтаминированный zh-срез | полигон | скоро (эксп-22 Ф0 — повторный ЖЁСТКИЙ заказ, стоп при неисполнимости) | эксп-22 | D39.37(4), D39.40, D39.46, D39.108, **D39.117** | | 56 | Ёфикатор/санитайзер-классы не размечены (§6.5 отчёта пакета-6) | полигон | когда-нибудь | полигон-пакет | D39.46, CURRENT-STATE | -| 57 | Пере-замер «контексты — главный рычаг» на трудной выборке пакета-7 с боевой сборкой (до него kwic-веса/семантику не трогать; перф-опция AttachKWIC в фикс-паке 128 легитимна — семантика не меняется) — напряжение с D39.46 названо, не отменено | полигон | когда-нибудь | полигон-пакет | D39.50 | +| 57 | Пере-замер «контексты — главный рычаг» на трудной выборке пакета-7 с боевой сборкой (до него kwic-веса/семантику не трогать; перф-хвост AttachKWIC — строка 37: фикс-пак 128 закрыт D39.118, опция в нём не взята, семантика не менялась) — напряжение с D39.46 названо, не отменено | полигон | когда-нибудь | полигон-пакет | D39.50, D39.118 | | 58 | **Не покрыто пакетом-8**: вторая книга/пара/модель · строка `drafts:` · ось `batch_runes` · разметчики-модели (не люди) · precision роли на «расширенном, но осмысленном» материале ; + контрастивный регрессионный сьют по каталогам режимов отказа (12-*) · чистовик exp15-выводов | полигон | когда-нибудь | полигон-пакет | POLYGON_PREMEASURE §1.8/§2.5/§3.5/§7.6 | | 59 | **Вендор-чек префикс-кэша ZAI/GLM** (на нём стоит вся кэш-экономика W1/Q2c) ; + GLM context-overflow гард (finish=model_context_window_exceeded — NOT-do пака-12 без решения) ; + Mistral-strip гейт message-builder (research/21 §1.1: extra_forbidden на reasoning-поля; ЛАТЕНТЕН при нашем single-shot wire — гейт перед прод-путём mistral в канале B / любым multi-turn; D39.74) | полигон | когда-нибудь (до МАСШТАБА) | полигон-пакет | D39.34(6) | | 60 | Scheduler-aware волны под peak-valley DeepSeek (прямой COGS-рычаг) | полигон/бэкенд | когда-нибудь (до МАСШТАБА) | отдельное решение | D39.34(6) | @@ -213,7 +219,11 @@ S3 упёрлась в замок (контракта нет) — по слов ## Бэкенд -**⟶ Свежее состояние бэкенда: пак стандартов + дофикс приняты и залендены (D39.96/97, `e8d4ac0`…`0e64efe`; точка входа `make battery`); АКТИВНЫЙ промт бэкенда — `docs/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md` (фикс-пак банка 128, санкция D39.103); ниже — хроника до №11.** **⟶ Приёмка №11 (D39.91, 02.08): пак ниже ПРИНЯТ, код заленден `553f1a3`; поправки приёмки (метка flash+pro · хеш по эквивалентности · `capability.go:78`) — в ревью-шапке отчёта и D39.91.** +**⟶ Свежее состояние бэкенда: ФИКС-ПАК БАНКА принят и заленден (D39.118, `bccf2d8`; ревью-шапка отчёта первична); АКТИВНОГО промта бэкенда НЕТ — следующий (эмиттер строки 103 + денежные строки шва) по слову владельца (D39.107 п.3); точка входа `make battery`; ниже — пинг пака и хроника до №11.** **⟶ Приёмка №11 (D39.91, 02.08): пак ниже ПРИНЯТ, код заленден `553f1a3`; поправки приёмки (метка flash+pro · хеш по эквивалентности · `capability.go:78`) — в ревью-шапке отчёта и D39.91.** + +**ФИКС-ПАК БАНКА «КЛАСТЕРЫ + НАБЛЮДАЕМОСТЬ» (строка 128 + хвост 129 + $0-минимум 130) — ИСПОЛНЕН 08.08, ждёт приёмки.** Отчёт: [archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md](archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md). Деньги $0 (платных вызовов ноль), дерево НЕ коммичено, чужая зона (`eval/`) не тронута. Сделано: **G1** — `DetectFamilies`+`MergeUnits` рядом с `DetectSeries`, батчи ЮНИТАМИ (серия ⊕ семья ⊕ containment-пара), параметры семей — данные скрипта; критерий промта выполнен (линейка `一转…十二转` держится одним юнитом, равнодлинные серии не регрессируют); на реальном корпусе банка coldrun-a — 150 поверхностей → 16 юнитов, наибольший 20, отказов 0 · **G2** `ConsolidationConflicts` (прогон против САМОГО СЕБЯ — класс, которого канон-проверка не видит) · **G3** стоп-таблица += сигналы/`invented`/уверенность/конвенций/противоречия, третье поле уверенности в промпт zh-ru, alias-джойн подписной карты (карта строится из тех же кандидатов, что таблица), имена эвиктнутых, per-batch «спросили/ответили» + WARN на пустой ответ рендера И классификатора, честный `TestTerminologistEmptyReplyIsLoud` · **G5** голос по фолду целевой формы при показе сырых форм + честная агрегация Via · **129** ре-джойн многословного dst в парсере банкноты · **130** дифф авто-банка с именами выпавших (без накопительного мерджа — граница владельца) · опции: `BanknoteTruncated` (колонка была структурно недостижима) и мятый `⟦TM-NO-DST⟧`. **Два адверсариальных ревью исполнены** по санкции владельца — одиночное и МНОГОАГЕНТНОЕ (13 опусов: шесть линз → опровергатели → синтез, $0). Второе нашло четыре major, которых не увидели ни соло-проход, ни первое: **измеренный регресс парсера банкноты на замороженном эталоне coldrun-a** (реплей 56 блоков: −6 строк, +0, при неизменном `parse_fail` — тихо; трактовка «неизвестное последнее поле = часть перевода» портила строки с типом вне словаря и роняла обратный порядок) · **перевод АЛИАСА становился dst терма и ехал на провод** на $0-пути при выключенном гейте — ровно тот вред, ради которого заводился `Via` · **третье поле не-число молча приклеивалось к переводу** («наставник 95%» как канон при `bad_lines=0`) · **`Held` считался по попытке**, и отчёт трижды называл ценой гарда несуществующий случай. Плюс: ordinal-очередь ревью (единственная разрешённая D39.102 форма уверенности) была обещана и не реализована; WARN строки 130 бил ложной тревогой по штатному циклу подписи; `bankParseVersion` не был поднят при изменённом правиле парса. Всё закрыто; одиннадцать мутаций пере-проверены исполнением и убиты. Первое ревью: нашло 1 major (гард «серия сильнее семьи» растворял семью ЦЕЛИКОМ, включая не-серийных членов — та же химера §B4 через гард, который её должен был предотвращать), переусердствовавший тест родства (5 ложных придержаний на корпусе), задвоенный счётчик, `Conf=0` неотличимый от «нет уверенности», мёртвый параметр парсера и 4 выжившие мутации; **всё закрыто, мутации пере-проверены исполнением и убиты**. **`make battery` зелёная ЦЕЛИКОМ** (build·vet·fmt·**lint**·test) + `-race` на затронутых пакетах. ⚠ Первая редакция заявляла «батарея зелёная», прогнав только build/vet/test — гейт lint был КРАСНЫЙ (3× errcheck), поймано приёмкой. Фикс-лист приёмки исполнен целиком: блокер lint · **MAJOR: WARN строки 130 был структурно МЁРТВ в проде** (`ownerHandled` получал сырой seed, а тот со второго прогона содержит собственные строки движка ⇒ дифф всегда пуст; risk-2 self-exclusion, который файл обходит в двух других местах; мой тест это маскировал рукодельной map) · две дыры пинов на space-run-форме · `bankParseVersion` теперь реально логируется с прогоном · три тихих отказа канала семей (опечатка в script-колонке, пол-таблица, рассинхрон словаря типов с `nickname`) · неназванная девиация ранжирования дописана в §4. тестов 685 → 717 (+33, удалён 1 вместе с недостижимой веткой, которую он пинил). **Фолд (ИСПРАВЛЕНО ревью):** ДРАФТ-волна не двинулась (голден прошёл без пере-захвата, `Source:"mined"` исключён из BASE), а **edit-волна двигается bank-only** — пак меняет поле dst дельты, значит `memory_version`; сдвиг громкий (`--resnapshot`) и репинится за $0 для единиц без терма, но для частотного терма это почти вся книга ⇒ **решение владельца, вопрос в §7 отчёта**. ⚠ **Девиация, требующая слова оркестратора:** данные семей положены НЕ в `internal/lang/data/script-series.txt`, как предлагал промт, а в отдельную bank-плоскость `internal/lang/bankdata/` — иначе `EmbeddedVersion` сдвинул бы снапшот ОБЕИХ волн (и без права на $0-репин), что прямо противоречит §3 промта. **§7 отчёта разделён на ДВА списка:** три пункта требуют решения (принимается ли сдвиг edit-волны bank-only · durable-хранение имён эвиктнутых = миграция · двойной пробел в `coldrun-a`), и пять предложены СТРОКАМИ БЭКЛОГА для оркестратора (одноруновая голова семьи — включается строкой данных, гейт замер · скрипт-слепой резолв семей/серий на кану и хангыль — долг общности к преп ja→ru · `banknote_truncated` как пол, а не счёт · пере-подтверждение `family_max_members=24` и `families_held` на длинной книге · уверенность не гейтится данными пары). В таблицу бэклога сам не писал — её ведёт оркестратор. + +**→ ПРИЁМКА №15 (08.08, D39.118): ПРИНЯТ и заленден `bccf2d8`.** Вопросы §7 закрыты все (сдвиг edit-волны принят словом владельца · миграция не заводится, строка 159 · двойной пробел закрыт замером 0/585 внутренних); девиация bankdata-плоскости и инверсия ранжирования ратифицированы; строки 128/129 закрыты, 130 пере-скоуплена, 154–159 заведены. Поправки приёмки — ревью-шапка отчёта (сдвиг и при выключенном гейте · classify-чекпойнты перекупаются · зазор зеркальной фикстуры принят риском). *(Закрытые бэкенд-записи 01–02.08 — общность фаза 2 · качество банка (оба этапа) · фикс-пак банка · finding-1 · пакет-чекеров · мелкая пачка · coldrun-b · ручка эффорта — в [archive/PROGRESS-2026-08-01-02.md](archive/PROGRESS-2026-08-01-02.md).)* diff --git a/docs/README.md b/docs/README.md index 97929c33..4feddc5d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,7 +16,7 @@ - `research/` — фактура ресёрчей 01–25; у принятых — ревью-шапки, часть тел под ⚠ superseded: **читай баннер прежде содержимого**. Ключевые для навигации: 15 голос · 16 ридер-IDE · 17 внешняя критика · 18 рычаги качества · 19 нарезка · 20 банк-майнинг · 21 обзор транспорта · 22 доменные харнессы · 23 шов движок↔платформа (транспорт superseded D39.106) · 25 холодное ревью шва — форма D39.106, отвергнутые альтернативы, требования к эмиттеру (читать перед любым кодом стыка) · 24 арбитраж банка (ПРИНЯТ D39.102: консилиум закрыт классом, вход фикс-пака банка — §G). - [PROGRESS.md](PROGRESS.md) — журнал: CURRENT-STATE + **ЕДИНЫЙ БЭКЛОГ** (единственный трекер) + живой хвост хроники. НЕ источник решений. - `scripts/counts.py` — **производные числа доков считаются им, а не руками** (голова по трём носителям · счёт очереди и зон · вес открытых строк регистра платформы); `--check` даёт ненулевой код на расхождении. Его же зовёт зонный хук `scripts/githooks/pre-commit` при коммите, задевающем D-лог или PROGRESS — предупреждает, не блокирует. Заведено по D39.112 п.5б: голова отставала трижды у трёх разных оркестраторов. -- Активные хендофф-промты сессий (состав обновляется при каждом лендинге — норма D39.80): [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояния не дублирует) · [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md) (полигон, отложен) · **платформа: ОТРАБОТАН ЦЕЛИКОМ** — четыре сессии (P0 D39.107 · P1+P2 D39.109 · фикс-пак P3 D39.114); текст в архиве, [`archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md`](archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md), копия с баннером ещё лежит в зоне. Следующий промт платформы — по слову владельца (реконсилятор/тейлер/юниты, D39.107 п.3(3)) · **фронт: S3 ОТРАБОТАН и ПРИНЯТ D39.115** (контракт 0.2.0 в каноне, копии байт-равны, слой данных построен); текст в архиве, [`archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md`](archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md). Промт S4 — по слову владельца. Зонные журналы фронта/платформы — `frontend-PROGRESS.md` / `platform-PROGRESS.md` в их зонах (решение владельца 04.08: прогресс зон только там). **Бэкенд: [BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md](BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md)** (фикс-пак банка, строка 128+129; санкция D39.103) · **Полигон: [POLYGON_TENANT_PANEL_SESSION_PROMPT.md](POLYGON_TENANT_PANEL_SESSION_PROMPT.md)** (эксп-22 «панель жильцов»; санкция D39.117, запуск = слово владельца) · **эксп-21 ОТРАБОТАН и ПРИНЯТ** (D39.117; отчёт `experiments/21-role-topology.md`), текст промта в архиве — [`archive/prompts/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT_2026-08-06.md`](archive/prompts/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT_2026-08-06.md). Очередь и состояние — только CURRENT-STATE. +- Активные хендофф-промты сессий (состав обновляется при каждом лендинге — норма D39.80): [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояния не дублирует) · [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md) (полигон, отложен) · **платформа: ОТРАБОТАН ЦЕЛИКОМ** — четыре сессии (P0 D39.107 · P1+P2 D39.109 · фикс-пак P3 D39.114); текст в архиве, [`archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md`](archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md), копия с баннером ещё лежит в зоне. Следующий промт платформы — по слову владельца (реконсилятор/тейлер/юниты, D39.107 п.3(3)) · **фронт: S3 ОТРАБОТАН и ПРИНЯТ D39.115** (контракт 0.2.0 в каноне, копии байт-равны, слой данных построен); текст в архиве, [`archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md`](archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md). Промт S4 — по слову владельца. Зонные журналы фронта/платформы — `frontend-PROGRESS.md` / `platform-PROGRESS.md` в их зонах (решение владельца 04.08: прогресс зон только там). **бэкенд: фикс-пак банка ОТРАБОТАН и ПРИНЯТ D39.118** (код `bccf2d8`; отчёт с ревью-шапкой — [`archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md`](archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md); текст промта в архиве — [`archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md`](archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md)); следующий промт бэкенда (эмиттер строки 103 + деньги шва) — по слову владельца · **Полигон: [POLYGON_TENANT_PANEL_SESSION_PROMPT.md](POLYGON_TENANT_PANEL_SESSION_PROMPT.md)** (эксп-22 «панель жильцов»; санкция D39.117, ЗАПУЩЕН 08.08 — сессия живая) · **эксп-21 ОТРАБОТАН и ПРИНЯТ** (D39.117; отчёт `experiments/21-role-topology.md`), текст промта в архиве — [`archive/prompts/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT_2026-08-06.md`](archive/prompts/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT_2026-08-06.md). Очередь и состояние — только CURRENT-STATE. - Зоны фронта (чужие, читать при касании стыка; каждая ведёт СВОЙ зонный бэклог — единый бэклог их строк не принимает, D39.84): [../frontend/](../frontend/) — веб-интерфейс: промт фронт-сессий S0–S7 + [STACK_DECISIONS.md](../frontend/docs/STACK_DECISIONS.md) (пины версий точными числами и ловушки, сверены с вебом 02.08) + [BACKLOG.md](../frontend/docs/BACKLOG.md) · [../platform/](../platform/) — SaaS control plane: README + [BACKLOG.md](../platform/BACKLOG.md) (П-1..П-5) + `docs/` (промт P0 · зонный журнал `platform-PROGRESS.md`). - `archive/` — история ([правила архива](archive/README.md)): закрытые промты (`prompts/`) · отчёты с ревью-шапками (`reports/` — на них ссылаются приёмки) · исполненные арх-доки (`architecture/`) · слайсы хроники `PROGRESS-*.md`. Инструкции оттуда не исполнять. - Диаграммы: [../backend/docs/components.puml](../backend/docs/components.puml) · [../backend/docs/pipeline.puml](../backend/docs/pipeline.puml) — дом рядом с кодом (D39.80), правятся бэкендом одним коммитом с кодом; вручную НЕ рендерить (владелец смотрит PlantUML-расширением VS Code). diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index 7366e939..ccce79eb 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -1,4 +1,4 @@ -# Журнал решений оркестратора — контракт D1–D39.117 (развязки 04.07 · пакеты 09–10.07 · приёмка/качество-первым/пивот/эмпирика 11–12.07 · арх-ресет+стройка пере-прогонного стека 13–19.07) +# Журнал решений оркестратора — контракт D1–D39.118 (развязки 04.07 · пакеты 09–10.07 · приёмка/качество-первым/пивот/эмпирика 11–12.07 · арх-ресет+стройка пере-прогонного стека 13–19.07) > **⟶ КАРТА АКТУАЛЬНОСТИ (ревизия D31, продлена до D38.2 [12.07]; исторические записи ниже НЕ переписываются — дисциплина D23.3).** Читая контракт целиком, держи под рукой, что чем перекрыто: > ⚠ **Навигация (актуализация 07.08, эра D39.1xx):** append-only-дисциплина (D23.3) означает, что @@ -1674,3 +1674,15 @@ API-529-долг закрыт: 8-осевой refute-by-default воркфлоу **6. Хвосты в трекер:** строки **149–153** заведены (эксп-22 · Sol-арбитраж · отказной режим связки · слипание абзацев · чистый контраст мандата); строки **12 и 82** получили $0-прототипы эксп-21 (`battery.check_numbers` — синтетика 16/16 · `battery.check_gender` по карточкам сида, 86–112 сверок/арм) — указатели внесены в их тела, сами строки живы (движковые гейты не построены); кредиты xAI — в лист владельца; три провод-факта эксп-21 §8 внесены в quirks 00 (Gemini fail-closed приходит БЕЗ объекта `message` · `gpt-5.6-luna` без ручки эффорта — пустой оплаченный выход · `glm-5` гасится `extra_body`). **7. Поправка к D39.113:** строка таблицы потерь «незакоммиченные правки промта — параллельный оркестратор» — ошибочная атрибуция: HEAD `73a7e7a` и был финальной версией промта параллельного оркестратора, его правки не терялись. Чьи модификации были в дереве — достоверно неизвестно; вероятно, полигона (его пинг предлагает правку требования стр.59 того же файла), и тогда их суть уцелела в пинге. Буква D39.113 не переписывается (D23.3) — читать через эту поправку. + +## D39.118 — ФИКС-ПАК БАНКА (строки 128+129+130-минимум) ПРИНЯТ И ЗАЛЕНДЕН: семьи термов со-батчатся юнитами, наблюдаемость подписи построена, дофикс-раунд закрыл major приёмки (08.08). ✅ + +**1. Вердикт:** ПРИНЯТ, код заленден **`bccf2d8`** (27 файлов, +2935/−201; деньги пака $0). Метод — четырёхконтурный воркфлоу приёмки: слепой дифф-ревьюер с мнением ДО чтения отчёта · пере-ран всех заявлений исполнением · 8 своих посадок в копии зоны вне репозитория (6 CAUGHT сразу, 2 выжившие) · охота вне карты отчёта; затем дофикс-раунд сессии и ре-чек (battery целиком EXIT=0 · `-race` EXIT=0 · счёт тестов 685→717 подтверждён независимо · пере-посадки 3/3 CAUGHT, выживших 0). Механика и полный фикс-лист — ревью-шапка `archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md` и пинг «Бэкенд» PROGRESS; здесь не дублируются (D39.112). + +**2. Находки приёмки, закрытые дофиксом:** клейм «батарея зелёная» первой редакции был ложным — lint не гонялся и был красным (3× errcheck), исправлено с честным признанием в отчёте · MAJOR вне карты: WARN строки 130 структурно мёртв в проде — `ownerHandled` на сыром seed само-исключал строки движка со второго прогона; закрыт `unsignedEngineSurfaces(seed)` + e2e-тест двумя реальными прогонами через стор · две дыры пинов на space-run-форме (conf-хвост и ре-джойн банкноты отключались незаметно) · `bankParseVersion` не потреблялся ничем — теперь логируется на стопе, v2.1/v2.2-артефакты различимы · три тихих отказа канала семей: script-колонка валидируется по реестру диапазонов, пол-таблица отвергается, словарь типов синхронизирован (`CandidateTypes` с `nickname` + правило пары + пин покрытия каждого типа). + +**3. Ратифицировано:** **сдвиг edit-волны bank-only ПРИНЯТ** (слово владельца 08.08 «не против реснапшота»; сдвиг громкий `--resnapshot`, `moveBankOnly` даёт $0-репин юнитам без терма; уточнение приёмки: двигается и при выключенном гейте терминолога, classify-чекпойнты перекупаются тем же центовым разом) · **bankdata-плоскость** — отдельный `//go:embed` вне волнового фолда со своей `BankDataVersion` (вместо колонки `script-series.txt` — та фолдится в `EmbeddedVersion` и перекупила бы драфт-волну без права $0-репина; девиация ратифицирована как правильный шов) · **инверсия ранжирования семей** (размер прежде длины якоря; спековый порядок ломал критерий линейки 转) — принята, девиация дописана в §4 отчёта по требованию приёмки · **имена эвиктнутых — лог, миграция НЕ заводится** (гейт: доказанная потребность; строка 159, вместе с 49а) · **«двойной пробел» закрыт замером:** 0 внутренних прогонов на 585 строк эталона (пере-ран приёмкой; наивный grep без rstrip даёт 55 хвостовых — парсер их триммит). + +**4. Строки трекера:** **128 и 129 ЗАКРЫТЫ** · **130 пере-скоуплена** (минимум исполнен; остаток = накопительный мердж/слоты — СТОП-решение владельца, материал даст WARN со второго прогона) · **заведены 154–159** (одноруновая голова семьи · скрипт-слепой резолв к ja→ru · `banknote_truncated`-пол за гейтом канала · пере-подтверждение `family_max_members=24` · conf без гейта данных пары · durable-имена эвиктнутых) · дописаны 37 (вынос Aho-Corasick = рефакторинг слоя, «чисто не ложится») · 38 (ординальная механика подтверждена кодом: G1 двигает состав юнитов — на первом прогоне после пака перекупаются все бэнк-батчи, центы) · 57 (ссылка на фикс-пак закрыта). Остаточный принятый риск: пин покрытия типов работает по зеркальной фикстуре `zhFamily` — рассинхрон зеркала со shipped-строками пином не ловится. + +**5. Верификация эффекта** — §6 отчёта (10 конкретных проверок по артефактам, $0); гейт — первый холодный прогон: `families=`/`families_held=` · химера 古月/转 в стоп-таблице · `self_conflicts=` · колонка `confidence` при не выросшем `bad_lines` · WARN диффа авто-банка со второго прогона. Активного промта бэкенда после этого лендинга НЕТ — следующий (эмиттер строки 103 + денежные строки шва) по слову владельца (D39.107 п.3). diff --git a/docs/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md b/docs/archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md similarity index 97% rename from docs/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md rename to docs/archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md index e9a90e5f..566269e3 100644 --- a/docs/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md +++ b/docs/archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md @@ -1,5 +1,7 @@ # Промт бэкенд-сессии: ФИКС-ПАК БАНКА «КЛАСТЕРЫ + НАБЛЮДАЕМОСТЬ» (строка 128, + хвост 129) +> ⚠ **ОТРАБОТАН ЦЕЛИКОМ И ПРИНЯТ (D39.118, 08.08.2026, код `bccf2d8`).** Исполнен бэкенд-сессией 08.08 с дофикс-раундом по адверсариальной приёмке; отчёт с ревью-шапкой — [`../reports/BANK_CLUSTER_FIXPACK_2026-08-08.md`](../reports/BANK_CLUSTER_FIXPACK_2026-08-08.md) (шапка первична). Инструкции ниже НЕ исполнять — архив. + **Выдан 04.08.2026, оркестратор №13, по санкции владельца 04.08 (зафиксирована D39.103 п.1; гейт строки 128 снят) и D39.102. Актуализирован 08.08 оркестратором №15 по слову владельца (пост-эксп-21 сверка: 22/22 якорей подтверждены по HEAD, дельта D39.104–D39.117 противоречий не дала).** Ты — бэкенд-сессия. Зона записи: `backend/` (код+тесты+puml тем же коммитом-пакетом) + отчёт `docs/archive/reports/BANK_CLUSTER_FIXPACK_2026-08-XX.md` (дату проставь сам) + пинг в `docs/PROGRESS.md` секция «Бэкенд». «Строка N» здесь и ниже = ID строки ЕДИНОГО БЭКЛОГА (таблица «Бэклог» в `docs/PROGRESS.md`). **НЕ коммитишь** — дерево готовишь, лендит оркестратор. ⚠ **Живую параллельную зону определяй `git status` + CURRENT-STATE В НАЧАЛЕ сессии — имя зоны в этом абзаце протухает быстрее промта.** На актуализацию 08.08: платформа принята целиком (D39.109/D39.114), фронт S3 принят (D39.115), эксп-21 принят и заленден (D39.117); живой сосед — полигон эксп-22 «панель жильцов» (`eval/tenant_panel/`, `docs/experiments/22-*`, секция «Полигон» в `docs/PROGRESS.md`). Чужого не трогать и не «прибирать»: 08.08 такая правка стоила семи файлов (D39.113). **Деньги: $0 — платных вызовов НЕТ вообще**; тесты и голден локально. Перекупка бэнк-батчей случится на следующем живом прогоне — в пак не входит, её цену только НАЗВАТЬ в отчёте. **Первый деливерабл — эхо-блок ≤10 строк** (как понял скоуп · четыре работы + хвост · инварианты · что вне скоупа; подтверждения не жди). diff --git a/docs/archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md b/docs/archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md new file mode 100644 index 00000000..76d498ba --- /dev/null +++ b/docs/archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md @@ -0,0 +1,196 @@ +# Отчёт бэкенд-сессии: ФИКС-ПАК БАНКА «КЛАСТЕРЫ + НАБЛЮДАЕМОСТЬ» (строка 128 + хвост 129 + $0-минимум 130) + +> **⟶ РЕВЬЮ-ШАПКА ПРИЁМКИ (оркестратор №15, 08.08.2026, D39.118): ПРИНЯТ И ЗАЛЕНДЕН `bccf2d8`.** Приёмка адверсариальная, четыре контура: слепой дифф-ревьюер (мнение ДО отчёта) · пере-ран заявлений исполнением · 8 своих посадок в копии зоны (6 CAUGHT сразу; 2 выжившие добиты дофиксом) · охота вне карты отчёта (5 находок, 1 major). Дофикс-раунд закрыл ВСЁ: блокер lint (3× errcheck) · MAJOR «WARN строки 130 структурно мёртв» (само-исключение через сырой seed) · 2 дыры пинов на space-run-форме · инертный `bankParseVersion` · 3 тихих отказа канала семей. Ре-чек дофикса: `make battery` целиком EXIT=0 (lint 0 issues) · `-race` EXIT=0 · 685→717 подтверждён независимым счётом · пере-посадки 3/3 CAUGHT. **Поправки приёмки к телу:** клейм «батарея зелёная» ПЕРВОЙ редакции был ложным (признано в §3 честно) · сдвиг edit-волны происходит и при ВЫКЛЮЧЕННОМ гейте терминолога (дельта пишется на $0-пути mining-стопа) и перекупает также classify-чекпойнты (контент батча делит рендер) — уточнение к §2 · замер §7.3 «0/585» = ВНУТРЕННИХ прогонов пробелов (наивный grep без rstrip даёт 55 хвостовых хитов, парсер их триммит) · пин покрытия типов работает по зеркальной фикстуре `zhFamily` — рассинхрон зеркала со shipped-строками пином не ловится (принято риском). Решения §7 ратифицированы D39.118. + +**Исполнен 08.08.2026 по промту `docs/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md` (выдан 04.08, актуализирован 08.08; после приёмки — в архиве промтов).** Зона: `backend/`. **Деньги: $0** — платных вызовов не было ни одного; вся батарея локальная. **НЕ коммичено** — дерево передаётся оркестратору. Живой сосед на момент сессии — полигон эксп-22 (`eval/tenant_panel/`, `eval/role_topology/absjudge.py`): не тронут, `git status` до и после чист по чужой зоне. + +--- + +## §1. Что сделано — по работам, с `file:line` + +### G1. Семьи термов и со-батчинг юнитами + +| Что | Где | +|---|---| +| Данные семей (per-script, НЕ Go-константы) | `backend/internal/lang/bankdata/family-morphology.txt` | +| Загрузчик + резолв по языку + версия плоскости | `backend/internal/lang/bankdata.go` (`FamilyMorphology`, `BankDataVersion`) | +| `DetectFamilies` рядом с `DetectSeries` | `backend/internal/terminology/series.go:199-295` | +| `MergeUnits` (серия ⊕ семья ⊕ containment → один юнит) | `backend/internal/terminology/series.go:314-394` | +| `Batch`/`orderByUnit` переведены на словарь ЮНИТОВ | `backend/internal/terminology/terminology.go:1119`, `series.go:115-142` | +| Проводка + WARN на отказ слияния | `backend/internal/pipeline/terminologist.go:301-323` | +| Резолв параметров на ЗАГРУЗКЕ (fail-loud на опечатку типа) | `backend/internal/pipeline/terminologist.go:126-158` | + +**Слияние и два гарда (правлено по адверсариальному ревью, см. §4а).** Юниты сливаются семьёй; **серия придерживает ТОЛЬКО своих членов** (семья формируется без них), а не отменяет слияние целиком; кап членов отказывает слиянию. Оба случая — это семья, которую владелец встретит разрезанной, поэтому оба СЧИТАЮТСЯ (`MergeStats{Refused, Held}`) и попадают в один WARN. Тест родства — «делят руну» (в плотном письме руна = морфема), а не подстрока. + +**Правила (как ратифицировано промтом).** Имя — общая ПРЕФИКС-морфема ≥2 рун; реалия (`term|place|title`) — общая СУФФИКС-морфема ≥2 рун (head-final); асимметрия и обе длины — данные. Якорем семьи может быть и сам кандидат — иначе голова семьи уезжает в другой вызов; ⚠ якорь обязан быть ≥2 рун, поэтому ОДНОРУНОВАЯ голова (`蛊`, `转`, `窍`) под это не подпадает и остаётся в отдельном вызове от своей семьи — класс НЕ покрыт, см. §5. Containment-канал (`元海 ⊂ 元海空窍`, оба mined) — отдельный генератор с тем же механизмом; якорь ≥2 рун, чтобы одна общая морфема не смела полбанка в один вызов. + +**(а) Многорунные модификаторы серий — критерий выполнен.** `一转…九转` — равнодлинная серия; `十一转`/`十二转` — три руны и в неё не попадают. Выбранная форма — НЕ отдельное правило серия-канала, а **слияние юнитов**: семья с якорем `一转` (containment/суффикс) пересекается с серией, и юниты сливаются. Линейка 1..12 держится ОДНИМ батч-юнитом — пин `TestFamilyKeepsAVariableLengthRankLineWhole`. Равнодлинные серии не регрессируют: у двухрунных поверхностей нет собственного суффикс-корня ≥2 рун, семья про них молчит — пин `TestFamilyDoesNotRegressAnEqualLengthSeries`. + +**(б) Майнерские containment-пары** — `TestContainmentPairSharesAUnit`. + +**Наблюдённый эффект на реальном корпусе** (`testdata/bankfull-surfaces.txt` — дистилляция банка coldrun-a, 150 поверхностей; `TestFamiliesOnBankFullFixtureAreBoundedAndWhole`): **150 кандидатов → 14 юнитов, наибольший 20, отказов по капу 0, придержано серией 2**. Содержательно юниты правильные: вся линейка `转` (12 членов вместе с `一转蛊师`/`九转境界`), композиционный куст `元海/真元/空窍` (10 — ровно тот, на котором §A4 намерил внутри-прогонные противоречия), клан `古月` + построенные на нём поверхности (20, включая `方源`/`方正`/`族长`/`四代族长`). Два «придержания» — это ранговый юнит `转`, которому гард не дал поглотить чужие реалия-семьи (`巅峰`, `蛊虫`): они модифицируются рангом, но морфологически к нему не относятся. Цена придержания названа честно ниже. + +### G2. `ConsolidationConflicts` + +`backend/internal/terminology/terminology.go:918-941` — тонкий брат `CanonConflicts`: тот же containment + `lexemeSubset`, правая сторона — консолидации ТЕКУЩЕГО прогона. Вызов `terminologist.go:424-437` рядом с канон-проверкой; WARN с именованными парами, счётчик `terminologyResult.SelfConflicts`, per-term `Contradictions` → колонка стоп-таблицы (`mining.go`, `renderBankStopTable`, `cmd/tmctl/render.go`). $0, evidence-сторона, не фолдится. Пины: `TestConsolidationConflictsCatchesTheRunContradictingItself`, `TestSelfContradictionIsReportedAtTheStop`. + +### G3. Наблюдаемость арбитража + +- **(а) `BankStopRow`** += `Signals` (сигналы §C2-3 ТОП-варианта — решил печатать по строке, а не по-вариантно: подписывают строку, а не вариант), `Invented` (норм-dst ∉ вариантов черновиков, сравнение под тем же фолдом целевой формы), `Conf`, `Conventions`, `Contradicts` — `mining.go:244-310`. Стоп-таблица и stdout-баннер печатают всё это (`mining.go:renderBankStopTable`, `cmd/tmctl/render.go:103-153`). +- **(б) Третье поле «уверенность 0–100»** — `backend/prompts/zh-ru/terminologist.md` (дата-правка + шапка с ратифицированной ГРАНИЦЕЙ применения). Парсер: `terminology.go:1022-1027` + `confidenceField` (`:1073`) — **девиация от буквы промта, см. §4 п.1**. +- **(в) `reasoning_content`** в схему НЕ заведён (проверено grep'ом — его там и не было). +- **(г) Находки приёмки:** + - **alias-джойн подписной карты** — `proposalsFromObserved` заменён на `proposalsFromCandidates` (`mining.go:404-427`): карта теперь строится из ТЕХ ЖЕ кандидатов, что и стоп-таблица, поэтому предложение, пришедшее через алиас кластера, попадает в note представителя по построению, а не вторым джойном, который надо руками держать в согласии. Провенанс алиаса едет в note (`miner_emit.go`: `DstProposal.Via` + `viaNote`). Пин `TestSignatureMapJoinsAliasProposals`. + - **имена эвиктнутых** — `chunkrun.go:168-236` (`recordEvicted`/`reportEvicted`) + аксессор `membank.PickedEntry.Src()`; отчёт один на волну (`waverun.go`, после драфт-волны). **Форма хранения — ЛОГ, без миграции схемы** (обоснование и альтернатива — §4 п.4). Пин `TestEvictedBankRowsAreNamed`. + - **per-batch «спросили N / ответили M» + WARN на ПУСТОЙ ответ** — рендер `terminologist.go:337-360`, классификатор `terminologist.go:530-548`. Ложной тревоги на батчах, до которых бюджет не дошёл, нет: `bankRoleRun.attempted` отделяет «вызвали и получили пусто» от «не вызывали». + - **`TestTerminologistEmptyReplyIsLoud`** переписан на два подслучая — прозу (старая ветка) и НАСТОЯЩИЙ пустой completion (`miningstop_join_test.go`). Имя теста перестало врать. +- **(д) $0-минимум строки 130** — `mining.go:525-575`: дифф старого и нового авто-файла при `writeAutoBank` + WARN с ИМЕНАМИ выпавших термов, названным `rank_cap` и советом «промоутни в mined_delta, тогда это сид-поверхность и её больше не срежет». **ГРАНИЦА соблюдена**: накопительного мерджа нет, слоты не освобождаются, `memory_version` не двигается — пин `TestAutoBankRewriteNamesDroppedTerms` проверяет и то, и другое. + +### G5. `foldVariants` + +`terminology.go:222-296`. Голос считается по классу целевой формы (`NormalizeTargetForm` инжектится как функция — пакет остаётся пар-агностичным), показывается СЫРАЯ форма (представитель — самая частая сырая форма класса). Рядом со `Spread()` (сырых форм) появился `Conventions()` (классов). Via при фолде агрегируется честно: если хоть один вклад пришёл на СВОЙ ключ — вариант прямой; если все через алиасы — перечисляются все. Пины: `TestFoldVariantsCountsConventionsAndShowsRawForms`, `TestFoldVariantsKeepsViaProvenanceHonest`. + +### Хвост 129. Парсер банкноты + +`banknote.go:236-274`. Тип опознаётся по ЗАКРЫТОМУ словарю на ПОСЛЕДНЕМ поле, остальное — src + dst с ре-джойном (зеркало дисциплины `terminology.ParseReply`). Восстановление порядка колонок обобщено на разъехавшийся dst: src — одно поле при любом чтении, поэтому «объявленный порядок» и «обратный» отличаются только тем, какое поле берётся за src. Пин `TestParseBanknoteRejoinsASplitRendering` (обе формы + «неизвестное последнее поле — часть dst, а не молча выброшенная колонка» + обратный порядок с разъехавшимся dst, который до пака был parse_fail в обеих версиях). + +**Нашёлся ли двойной пробел в артефактах.** `~/books/gu-zhenren/coldrun-a/` **не читал**: доступ к нему в этой сессии не проверялся, а промт разрешает только чтение замороженного эталона, не требует его. **Цена фолда названа честно: неизвестна** — авто-банк изменится ровно на тех строках банкноты, где модель поставила двойной пробел внутри dst; поиск по эталону — задача одного `grep` при следующем касании артефактов, вопрос вынесен в §5. + +### Опции + +- **`BanknoteTruncated`** (гигиена) — СДЕЛАНО, вариантом «честно провести флаг»: колонка была структурно недостижима (`truncatedGeneration` пинился в `false`), теперь читается из finish-причины (`banknote.go:352-362`). Поведение finish=stop-only НЕ тронуто — кандидаты по-прежнему не принимаются, `NLines` по-прежнему 0. Пин `TestBanknoteTruncatedIsReachable`. Миграции не потребовалось. +- **`NoDst`** — СДЕЛАНО: узкий матч испорченного сентинела (`«⟦TM-NO-DST⟧»`, `⟦TM-NO-DST⟧.`) — `terminology.go:1096-1103`, пин `TestParseReplyAcceptsAMangledDeclineSentinel`. Отказ — это РЕШЕНИЕ §C2-7, а до пака мятый сентинел считался сломанной строкой. +- **Перф `AttachKWIC` через Aho-Corasick (строка 37)** — **НЕ делал**, см. §4 п.5. + +--- + +## §2. Фолд-ось и голден (обязательная секция) + +**Предъявление, ИСПРАВЛЕННОЕ по многоагентному ревью.** Первая редакция §2 утверждала «волны и снапшоты книг НЕ двинулись» без оговорки — это **неверно и опровергнуто исполнением**. Верно так: **ДРАФТ-волна не двинулась; EDIT-волна двигается, и двигается bank-only**. + +- **Драфт-волна цела.** Строки авто-банка — `Source:"mined"`, а BASE-версия банка их исключает (`membank/memory.go:349`), поэтому черновые чекпойнты резюмятся за $0. Проверено ИСПОЛНЕНИЕМ (см. ниже). +- **Edit-волна двигается.** Пак меняет ПОЛЕ dst в дельте: источник предложений сменился с сырого драфт-порядка (`proposalsFromObserved`) на ранжированные и фолднутые кандидаты (`proposalsFromCandidates`). На одинаковом входе это даёт другой `memory_version` тремя независимыми механизмами (пере-ран рядом с HEAD-функцией через настоящие `DeltaYAML → LoadGlossarySeed → ComputeVersionScoped`): (i) ре-ранжирование §C2-3 против «сколько чанков предложило»; (ii) фолд орфографии §G5; (iii) алиас-маршрутизация — **этот третий канал ЗАКРЫТ** правкой по ревью, см. §4-0(ж). ENRICHED-версия (`memory.go:348`) — вход снапшота edit-волны, значит он сдвигается. +- **Цена названа.** Сдвиг НЕ тихий (`stagerun.go` требует явный `--resnapshot`) и классифицируется `moveBankOnly` ⇒ `repin.go` отдаёт $0-репин каждой единице, в инъекцию которой терм не попадает. Платятся только единицы, где терм реально встречается. Для частотного терма (фамилия протагониста) это может быть почти вся книга — **это решение владельца, а не гигиена**, и оно вынесено вопросом в §7. + +Что проверено ИСПОЛНЕНИЕМ и держится: + +1. `git status` по `backend/internal/lang/data/` — **пусто**: ни один файл ВОЛНОВОЙ плоскости не тронут, значит `lang.EmbeddedVersion()` байт-стабилен. ⚠ Это ВХОД волновой плоскости, а не содержимое банка — именно эту разницу первая редакция §2 и смешала. +2. `TestGoldenDeterminism` — **PASS без пере-захвата** `testdata/golden/capture.golden`. Голден пинит snapshot id обеих волн и `request_hash` каждого вызова; если бы снапшот сдвинулся, он бы упал первым. +3. `TestTerminologyIsNotSnapshotFolded` — PASS. +4. Новый пин `TestBankPlaneIsOutsideTheWaveFold` (`internal/lang/bankdata_test.go`) держит это ВПЕРЁД: файл семей не должен попадать в набор, который хеширует `EmbeddedVersion`. + +**Что двигается.** Состав батчей терминолога → `RequestHash` бэнк-батчей: G1 (состав юнитов), G3 (промпт-файл в system-сообщении) и G5 (фолд-счёт и Via меняют строку `drafts:` на проводе) двигают их ОДНИМ разом. Перекупка — центовая (весь проход терминолога на 10-главном стенде — $0.0057, D39.90). Вне снапшота и вне провода: G2 целиком, печать стоп-таблицы, дифф авто-банка, список эвиктнутых. + +**⚠ Расхождение с промтом, разрешённое в пользу §3 промта.** Промт §2 G1 предлагал положить параметры семей в `internal/lang/data/script-series.txt` «новой колонкой или соседний файл». Проверено по коду: `internal/lang/data/*` целиком хешируется в `lang.EmbeddedVersion()` (`embedded.go:72-82`), а `EmbeddedVersion` фолдится в снапшот ВОЛНЫ **безусловно** (`snapshot.go:381-389,442`). Любая правка там сдвинула бы снапшот обеих волн, и `classifySnapshotMove` (`repin.go:61-91`) классифицировал бы это как `moveOther` — то есть **без права на $0-репин**: перекупалась бы вся драфт-волна книги, а не центовые бэнк-батчи. Это прямо противоречит §3 промта («волны/снапшоты книг НЕ двигаются») и ратифицированной позиции «терминология не фолдится» (`config.TerminologyGate`, `TestTerminologyIsNotSnapshotFolded`). Выбрана «соседний файл» в буквальном смысле — **отдельная embed-плоскость** `internal/lang/bankdata/` со своим `//go:embed` и своей версией `BankDataVersion()`, которая логируется с прогоном (`terminologist.go`, поле `bank_data=`) и фолдится там, где ей место — в содержимом батча, то есть в `RequestHash` бэнк-батчей. Байты по-прежнему ЕСТЬ версия; они просто не выдают счёт за волну, которую не могут изменить. + +**Наблюдение по батч-чекпойнтам (строка 38, только наблюдение, работа в пак не входит).** Бэнк-батч адресуется ординалом (`chunk.Chunk{Chapter: 0, ChunkIdx: i}`, `terminologist.go`), а порядок батчей — частотный (`Batch` → `sort.SliceStable` по `batchFreq`). G1 меняет СОСТАВ юнитов, значит меняет и суммарную частоту батчей, значит двигает те же ординалы: на первом прогоне после пака перекупаются все бэнк-батчи, а не только те, чей текст изменился. Цена та же центовая, но механика именно такая — «со слов» строки 38 подтверждается кодом. + +**Голден-счётчики волн** прошли БЕЗ пере-захвата (см. п. 2 выше). Пере-захвата голдена в паке НЕ было. + +--- + +## §3. Самопроверка (мандат 12.07) + +- **`make battery` — ЗЕЛЁНАЯ ЦЕЛИКОМ** (build · vet · fmt · **lint** · test), локально, $0. ⚠ Первая редакция отчёта заявляла «батарея зелёная», прогнав только build/vet/test: гейт `lint` не гонялся и был КРАСНЫЙ — 3× errcheck в новом `bankfixpack_test.go` (`runToSignatureStop` возвращает sentinel-ошибку `*WaveSignatureStop`, и её отбрасывание errcheck ловит). Поймано приёмкой; клейм был ложным, теперь предъявляется тем, что названо. +- `-race` на всех затронутых пакетах (`internal/pipeline` 83 с, `terminology`, `miner`, `cmd/...`) — EXIT 0. +- **Дифф `^func Test` — ИСПОЛНЕНИЕМ** (`git grep HEAD` против рабочего дерева, не по памяти): **было 685, стало 717, добавлено 33, удалён 1**. Удалён `TestParseBanknoteTruncationTolerated` — вместе с недостижимой веткой, которую он пинил (см. §1 «Опции»); его заменил `TestParseBanknoteShortLastLineIsAParseFail`. Новые: `TestAutoBankRewriteNamesDroppedTerms` · `TestBankPlaneIsOutsideTheWaveFold` · `TestBankStopTableCarriesTheArbitrationRecord` · `TestBanknoteTruncatedIsReachable` · `TestConsolidationConflictsCatchesTheRunContradictingItself` · `TestContainmentPairSharesAUnit` · `TestDetectFamiliesGroupsBySharedRootAsymmetrically` · `TestEvictedBankRowsAreNamed` · `TestFamiliesOnBankFullFixtureAreBoundedAndWhole` · `TestFamilyChannelOffIsTheSeriesMap` · `TestFamilyDoesNotRegressAnEqualLengthSeries` · `TestFamilyKeepsAVariableLengthRankLineWhole` · `TestFamilyMergeRefusesAnOversizeUnit` · `TestFamilyMorphologyForZhIsLive` · `TestFamilyMorphologyIsData` · `TestFamilyMorphologyRefusesCorruptRows` · `TestFoldVariantsCountsConventionsAndShowsRawForms` · `TestFoldVariantsKeepsViaProvenanceHonest` · `TestParseBanknoteRejoinsASplitRendering` · `TestParseReplyAcceptsAMangledDeclineSentinel` · `TestParseReplyTakesTheConfidenceFieldBeforeRejoining` · `TestSelfContradictionIsReportedAtTheStop` · `TestSignatureMapJoinsAliasProposals` · `TestSeriesHoldsOnlyItsOwnMembers` · `TestFamilyMergesAcrossASeriesWhenTheRootIsShared` · `TestBankStopRowCarriesTheWinningVariantsSignals` · `TestTerminologistBudgetCutIsNotReportedAsAnEmptyReply` · `TestParseBanknoteShortLastLineIsAParseFail`. Изменён на месте один: `TestTerminologistEmptyReplyIsLoud` (стал двухподслучайным — проза + настоящий пустой completion). +- **Изменены сигнатуры** (обновлены все вызовы, включая тесты): `terminology.Merge(+foldDst)`, `terminology.ParseReply(+conf map)`, `Batch(seriesID→unitID)`, `pipeline.writeAutoBank(+ctx)`, `bankStopRows(+terminologyResult)`. +- **Фикстура** `projectOpts` получила поле `glossaryTokenBudget` (0 → историческое 800, все прежние проекты байт-идентичны) — иначе ветка эвикции недостижима из теста. +- **archguard-тесты** не трогал; `backend/.env` не читал; PUML не рендерил (правка `backend/docs/pipeline.puml` — текстовая, синтаксис-ловушки из памяти учтены: `;` внутри метки нет, строк, начинающихся со спец-терминатора, нет). +- **МНОГОАГЕНТНОЕ АДВЕРСАРИАЛЬНОЕ РЕВЬЮ — ИСПОЛНЕНО** по санкции владельца: 13 агентов-опусов (шесть независимых линз → опровергатель на каждую → синтез), $0, ~46 минут. Результат — §4-0-БИС: четыре major, включая ИЗМЕРЕННЫЙ регресс на замороженном эталоне и вред, ехавший на провод. Все закрыты; **одиннадцать мутаций пере-проверены исполнением и убиты** (родство-подстрока · инвертированный ранг семей · игнор разделителя · алиас-dst · несчитаемая битая уверенность · статистика по попытке · ordinal-порядок · плюс четыре из первого прохода). ⚠ Счётчик воркфлоу «36 выжило / 0 опровергнуто» — артефакт моего скрипта (id находок не сматчились с вердиктами опровергателей); реальное опровержение выполнено, его результаты — в тексте синтеза, и часть находок им снята. +- **АДВЕРСАРИАЛЬНОЕ ревью №1 (author≠reviewer, одиночное) — ИСПОЛНЕНО** отдельным агентом по санкции владельца: дифф + окружающий код + ТЗ + замеры-основания, с мутационным тестированием. Нашёл 1 major (см. §4а), 1 дыру-майнор и 4 выжившие мутации; опроверг три клейма этого отчёта. **Все находки закрыты в коде и тестах**, четыре мутации пере-проверены исполнением и теперь УБИТЫ (`M1` гард серия-vs-семья · `M2` игнор `attempted` · `M3` сигналы не заполняются · `M4` инертный путь отдаёт копию). Батарея под `-race` на затронутых пакетах — зелёная. +- **Ревью исполнением своего кода (соло, до адверсариального).** Что пере-проверял отдельно и чем: детерминизм `MergeUnits` (никакого выхода из итерации по map — id раздаются по отсортированным корням) · инертный путь (`TestFamilyChannelOffIsTheSeriesMap` требует ТОТ ЖЕ объект-словарь) · `Spread()` для кандидатов, собранных вне `Merge` (`Forms=0` → считается как 1, обратная совместимость) · «уверенность» не ломает двухпольный ответ (`TestParseReplyTakesTheConfidenceFieldBeforeRejoining`, подслучай `plain`) · ложная тревога пустого батча при срезе бюджетом (отсечено `attempted`) · кап семей — подобран НЕ на глаз, а прогоном по реальному корпусу при cap ∈ {8,12,16,24,32,∞}: 16 разрезает клан `古月` (6 отказов), 24 не отказывает ничему, дальше 24 ничего не меняет. + +--- + +## §4. Девиации от промта и почему + +**0-ТРИ (фикс-лист приёмки, всё мелкое — но одно структурное).** +- **БЛОКЕР: `make battery` была красной** — см. §3; клейм отчёта исправлен. +- **MAJOR: WARN строки 130 был структурно МЁРТВ в проде.** `ownerHandled` получал СЫРОЙ seed из стора, а тот со ВТОРОГО прогона авто-режима содержит собственные mined/auto-строки движка (`seedGlossary` засеивает авто-банк на старте, `seeding.go:83-93`) ⇒ каждый выпавший терм читался как «владелец решил», дифф всегда пуст, предупреждение не могло сработать НИКОГДА. Это risk 2 (self-exclusion), который сам файл документирует и обходит `unsignedEngineSurfaces` в двух других местах — и не обходил здесь. Мой тест это МАСКИРОВАЛ: кормил рукодельную map мимо стора. Стало: `ownerHandled(unsignedEngineSurfaces(seed), rejects)` + тест ДВУМЯ реальными прогонами (терм уходит из дельты между ними, строки движка в сторе есть) — посадка «сырой seed» теперь убивается. +- **Две дыры пинов, обе на SPACE-RUN-форме:** conf-тесты и тесты 129 кормили только ТАБ-строки, где `join(fields[1:]) == fields[1]`, поэтому и снятие уверенности на пробельном пути, и ре-джойн банкноты можно было отключить незаметно. Добраны пробельные формы; обе посадки убиты. +- **`bankParseVersion` ничем не потреблялся** — не логировался и не фолдился, комментарий «logged with the run» лгал, артефакты v2.1 и v2.2 были неотличимы, то есть бамп подавался как механизм против дрейфа, а механизма не было. Стало: печатается на стопе (`bank-mining: draft-side proposals folded`, вместе со `slice_version`), комментарий честен. +- **Три ТИХИХ отказа канала семей** — класс, который пак сам объявил нетерпимым: опечатка в script-колонке гасила канал молча (валидации не было, и флагманский тест общности объявлял `devanagari`, который резолвер молча дропал — тест не доказывал ничего); `family_affix` без `family_min_members` = канал молча выключен; словарь типов рассинхронен — `nickname` легитимен в банкнот-канале и доезжает до `DetectFamilies`, но `loadFamilyParams` его отвергал, а текст ошибки врал про состав словаря. Стало: скрипт валидируется по реестру диапазонов, пол-таблица отвергается, введён `terminology.CandidateTypes` (шире классификаторского `Types` ровно на `nickname`, с объяснением почему), сообщение об ошибке перечисляет реальный набор, и пара получила правило для `nickname`. + +**0-БИС (правки по МНОГОАГЕНТНОМУ ревью, шесть линз + опровергатели + синтез, всё опусами; 13 агентов, $0).** Ревью нашло то, что соло-проход и первый адверсариальный пропустили: +- **(ж) MAJOR: парсер банкноты дал РЕГРЕСС на замороженном эталоне.** Реплей 56 реальных блоков coldrun-a: **−6 строк против HEAD, +0**, при `banknote_parse_fail` НЕИЗМЕННОМ во всех шести — то есть тихо. Механизм воспроизведён мной лично: трактовка «последнее поле не из словаря ⇒ часть перевода» портит строку, чей третий столбец — тип ВНЕ словаря (`clan`, `event`, `proverb`, `onomatopoeia` — 1.25% эталона): `古月|Гу Юэ|clan` → dst «Гу Юэ clan»; а на ОБРАТНОМ порядке src становится ненаходимым и строка выбрасывается совсем. Исправлено принципом «разделитель несёт информацию»: строка с ТАБОМ или ПАЙПОМ прочитана позиционно (семантика HEAD), эвристика словаря применяется только к строке, разбитой прогоном пробелов — там, где неоднозначность и возникает. Дефект «Фан␣␣Юань», ради которого делался хвост 129, при этом чинится ЛУЧШЕ: в позиционном чтении он схлопывается внутри колонки. **`bankParseVersion` поднят до v2.2** — правило парса изменилось, а тег версии в первой редакции остался прежним, что и есть тот дрейф, ради которого версия разделена надвое. +- **(з) MAJOR: перевод АЛИАСА становился dst терма и ехал на провод.** `props[0]` после моей правки мог быть предложением, пришедшим через алиас кластера — и попадал в `st.Dst`, то есть в строку банка, которую рендерит инъекция (`memory.go:699-724`), причём на $0-пути, БЕЗ модели и при ВЫКЛЮЧЕННОМ гейте терминолога. Ровно тот вред, ради предотвращения которого `Via` и заводился, — через правку, которая `Via` и вводила. Исправлено: `st.Dst` берётся только из предложения, сделанного НА СВОЕЙ поверхности; алиасные перечисляются в note со своим Via. +- **(и) MAJOR: третье поле, не являющееся голым числом, молча приклеивалось к переводу.** `师父⇥наставник⇥95%` давал канон «наставник 95%» при `bad_lines=0` — форма проходит `wellFormedLemma`, проходит экран языка, не эхо. Класс НОВЫЙ: промпт v3 сам просит третье поле. Исправлено тем же принципом разделителя: в таб/пайп-строке третья колонка ЕСТЬ колонка уверенности, нечитаемое значение считается (`ReplyStats.BadConfidence`) и НИКОГДА не склеивается. +- **(к) MAJOR: `MergeStats.Held` считался по попытке, а не по итогу.** Из трёх «придержаний» на корпусе одно было ложным (`蛊师` и `一转蛊师` в итоге оказывались в ОДНОМ юните), и отчёт трижды называл ценой гарда именно несуществующий случай. Считается по ФИНАЛЬНОМУ разбиению: реально разрезаны `巅峰` и `蛊虫`, придержаний 2. +- **(л) MAJOR: две мутации в ядре пака выживали** — родство подстрокой вместо морфемы и инвертированный ранг семей (обе меняют СОСТАВ вызовов, то есть деньги, при зелёной батарее). Закрыты пином точных чисел И ФОРМЫ разбиения плюс кейсом «серия `等资质` и семья `{丙等,丙等资,丙等资质}` обязаны слиться через общую руну `等`». +- **(м) MINOR: WARN строки 130 срабатывал на ШТАТНЫЙ цикл подписи.** Промоут в `mined_delta` или отклонение в `mined_rejects` убирает терм из дельты НАМЕРЕННО, а дифф печатал его как молчаливую потерю и советовал сделать то, что владелец только что сделал. Исправлено: обе владельческие двери исключены из диффа. +- **(н) MINOR: единственная РАЗРЕШЁННАЯ D39.102 форма уверенности не была реализована.** Число печаталось и не использовалось, хотя промпт и два комментария обещали ordinal-очередь ревью. Реализовано ровно там, где ему место: капнутый stdout-обзор (surface «что читать») сортируется «сначала неуверенное», полная стоп-таблица остаётся в ключевом порядке (reference-документ). +- **(о) Лгущие комментарии сняты:** `mining.go` больше не утверждает «с выключенным гейтом дельта байт-идентична» (это перестало быть правдой из-за (ж)/(з)); док поля `banknote_truncated` больше не описывает удалённую tolerance-ветку и честно назван полом (обрыв, срезавший разделитель, он не видит); комментарий про `蛊 среди 蛊-*` больше не выдаёт непокрытый класс за работающий; ссылка на удалённую `proposalsFromObserved` поправлена. + +**0 (правки по первому, соло-адверсариальному ревью).** +- **(а) MAJOR: гард «серия сильнее семьи» растворял семью целиком.** Было: если хоть один таргет нёс чужой серийный корень — слияние отменялось ВСЁ, включая не-серийных членов; клан `古月` из пяти имён, три из которых образуют `雄`-серию, рассыпался на синглтоны — ровно та химера §B4, которую канал и строится закрыть, и приходила она через гард, который должен был её предотвращать. Блок при этом не считался ничем. Стало: придерживается только конфликтующий таргет, остаток семьи сливается, факт считается `MergeStats.Held` и попадает в WARN. Пин `TestSeriesHoldsOnlyItsOwnMembers` (мутация «убрать гард» теперь убивается). +- **(б) Тест родства был подстрочным и переусердствовал.** Замер на реальном корпусе: 5 семей придержаны ЛОЖНО — серия `等资质` против семьи `{丙等, 丙等资, 丙等资质}`: ни одна строка не содержит другую, хотя они очевидно делят морфему `等`, чья согласованность и есть предмет. Стало: «делят руну» = делят морфему (плотное письмо); придержаний на корпусе 11 → 3, и все три по делу. +- **(в) Дубли групп задваивали счётчик.** Аффиксный и containment-каналы законно описывают один и тот же набор с двух сторон; дедуп ПОСЛЕ ранжирования (выживает самое специфичное описание) — придержаний 6 → 3, число в WARN стало означать то, что написано. +- **(г) `Conf=0` был неотличим от «уверенности нет».** Обе печати прятали строку с уверенностью 0 — ровно ту, ради которой ordinal-ревью и существует. Стало: отсутствие = −1, ноль печатается. +- **(д) Мёртвый параметр `truncatedGeneration` снесён** вместе с недостижимой веткой и стейл-комментом (вторая половина опции промта; первую — проведение флага через finish — сделал сразу). +- **(е) Три дыры в тестах** (мутации выживали): гард серия-vs-семья · `attempted` · заполнение `Signals`. Закрыты пинами, мутации пере-проверены исполнением. + +1. **Уверенность снимается по ПОЛЮ, а не регуляркой ` \d{1,3}` по хвосту строки.** Промт просил «числовой хвост ` \d{1,3}` снять КАК conf ДО ре-джойна». Буквальная форма съедает легитимный перевод, кончающийся числом («Пик 108»), у пары, чей промпт просит два поля. Реализовано: если полей ≥3 И последнее поле целиком 1–3 цифры в 0…100 — это уверенность. «Пик 108» — одно поле (один пробел, сплиттер режет по ≥2 пробелам), так что не задевается вовсе; проверено тестом в обе стороны. Число вне 0…100 остаётся частью перевода. +2. **`DetectFamilies` возвращает `[]Family`, а не `map[string]int`.** Слияние обязано знать ЯКОРЬ семьи, чтобы исполнить правило «серия сильнее семьи ТОЛЬКО при несовпадающих корнях»; из голых id якорь не восстановить. Итоговый `map[string]int` отдаёт `MergeUnits` — то есть контракт «на вход `Batch` идёт тот же словарь» соблюдён. +3. **«Серия сильнее семьи» реализована как ПРИДЕРЖАНИЕ серийного таргета, а не как исключение серийных членов из семей и не как отмена слияния.** Черновик §G предлагал «серийные члены из семей исключаются»; промт это уже амендировал 转-случаем. Исключение членов не выполняет критерий (а): при нём `十一转` навсегда остаётся снаружи. Реализовано: юниты сливаются, если якорь семьи и корень серии делят морфему (`sharesMorpheme`); если нет — серия сохраняет СВОИХ членов, а семья формируется без них, и факт считается. **Цена придержания, названная честно (пере-мерена по ИТОГУ, а не по попытке):** на корпусе это 2 случая вида «реалия-семья, модифицированная рангом» — `巅峰` и `蛊虫` оказываются в другом вызове, чем `一转巅峰`/`一转蛊虫`. Альтернатива — разрешить слияние — даёт ранговый юнит-свалку; выбран гард + счётчик + WARN, чтобы решение было видно на холодном прогоне, а не выведено из банка, который сам себе противоречит. +4. **Имена эвиктнутых — в ЛОГ, а не «рядом с `NEvicted`» в строке `retrieval_state`.** Промт требовал форму БЕЗ новой миграции схемы; свободной TEXT-колонки в таблице нет (все шесть `*_detail` заняты), а класть список эвиктнутых в чужую колонку (`trust_gate_detail`) — нечестно. Лог — вторая наблюдаемая плоскость движка, и именно её читают при бюджетных событиях. **Вопрос владельцу/оркестратору:** если список нужен durable — это колонка `evicted_detail` и миграция; заводить её без слова не стал. +5. **Перф `AttachKWIC` через готовый Aho-Corasick — НЕ делал.** Автомат живёт в `membank` неэкспортированным (`memory.go:882-927`). «Чисто» это не ложится: либо `terminology` начинает зависеть от `membank` (инверсия слоя — пакет объявлен PURE, «no I/O, no network», и банк-стор в него импортировать нельзя), либо автомат выносится в новый общий пакет, что уже рефакторинг за пределами скоупа пака. Промт разрешал опцию «только если чисто ложится» — не ложится. +6. **Ранжирование семей инвертировано против буквы ТЗ.** §2 G1 требует «специфичный длинный корень бьёт короткий, ЗАТЕМ большая семья»; реализовано наоборот — сначала размер, потом длина якоря. Причина: при спековом порядке containment-якорь `一转` (2 руны) обходит корень `转` (1 руна) и рвёт ранговую линейку на пары, то есть буквальный порядок ЛОМАЕТ критерий §2(а) того же ТЗ. На корпусе порядок кода строго лучше, и он запинен формой разбиения. Девиация не была объявлена в первой редакции §4 — поймано приёмкой, ратифицировано. +7. **Снятие уверенности не гейтится данными пары** — канал работает для любой пары, чей промпт-файл попросит третье поле. Риск-остаток назван: у пары с ДВУХпольным промптом легитимный перевод, чьё последнее слово — голое число ≤100, отделённое ДВОЙНЫМ пробелом («Пик␣␣99»), потеряет это число в уверенность. Уже, чем буквальная форма промта, но не ноль; если понадобится — это дата-декларация пары, отдельным касанием. +8. **`~/books/gu-zhenren/coldrun-a/` не читал** (см. хвост 129 выше): цена фолда 129 названа как «неизвестна», а не выдумана. + +--- + +## §5. Чего НЕ сделал и почему + +- **G4 (кластерный роутинг)** — по промту в пак не входит (правило дизайна замера строки 5, кода не требует). +- **Накопительный мердж авто-банка и освобождение слотов `emitRankCap`** — СТОП-решение владельца; сделан ровно $0-минимум (дифф + имена). +- **Строка 38 (ординальная адресация чекпойнтов)** — только наблюдение, см. §2. +- **Строка 140 (декларация банкнота-канала в shipping-c1)** — вне пака; чинил только ПАРСЕР. +- **`term`-класс эмиссии, равноправный совет, кросс-модельные веса, self-consistency, селекция из вариантов, отказ-сигнал, эмбеддинг-фетч** — закрыто числами D39.102, не строил. +- **ОДНОРУНОВАЯ голова семьи (`蛊`, `转`, `窍`) — класс НЕ покрыт.** Якорь обязан быть ≥2 рун, иначе одна общая морфема якорит полбанка; на дистилляции это значит, что `转` (кандидат банка) едет в другом вызове, чем 12 несущих его поверхностей. Включается ОДНОЙ строкой данных (`family_containment_runes han 1`), без правки Go. Не включил, потому что цена (размер юнитов) не замерена — предмет холодного прогона, не догадки. Строка бэклога — §7 п.4. +- **Семейные правила резолвятся по ЯЗЫКУ и применяются к поверхностям любой письменности.** `FamilyMorphology("ja")`/`("ko")` отдают han-правила и режут аффиксы по кане и хангылю. Замерен эффект на синтетике: 24 катаканных имени с общим «アリ» → один юнит → батч 8036 рун при бюджете 6000. Пары ja/ko в репо нет, та же скрипт-слепота уже в HEAD у серий — это норма-долг по ревью-вопросу общности, а не живой дефект. Строка бэклога — §7 п.5. +- **`banknote_truncated` — ПОЛ, а не полный счёт.** Обрыв, срезавший сам разделитель, флага не даёт (ранний возврат по пустому блоку выше проверки finish); по эталону это большинство length-обрывов. Буквальный фикс («ставить флаг и при пустом блоке») сделал бы ХУЖЕ — зажёг бы колонку на каждом обрыве переводчика в прогонах вообще без банкноты; нужен гейт по `Gates.Banknote.Enabled`, и это отдельное касание. Строка бэклога — §7 п.6. + +--- + +## §6. План верификации эффекта на следующем ХОЛОДНОМ прогоне (D39.103 п.1) + +Конкретно, что смотреть и где. Всё $0 — читается из артефактов прогона, отдельных вызовов не требует. + +1. **Семьи вообще заработали.** В логе строка `terminology finished` — поля `families=`, `families_refused=`, `families_held=`. Ожидание: `families` заметно >0 (⚠ поле печатает число ДЕТЕКТИРОВАННЫХ ГРУПП, а не юнитов: на дистилляции 37 групп → 14 юнитов), `families_refused=0`, `families_held` малое (на дистилляции — 2). Если `families=0` — канал инертен, и первое, что проверять, это `bank_data=` в строке `terminology render: estimate before any call` (плоскость данных доехала) и `source_lang` книги. +2. **Химера семьи на границе батча ЗАКРЫТА — прямая проверка.** В стоп-таблице (`.db.bank-stop.txt`) взять клан `古月` и линейку `转`: все члены каждого должны иметь СОГЛАСОВАННЫЙ dst (одна конвенция клана, одна голова ранга). До пака `ds1-b0` дал все шесть членов слитно, `ds1-b2` — все семь раздельно (research/24 §B4). Если расхождение осталось — смотреть `families_refused`/`families_held` и WARN «renders OVER the size budget»: значит юнит разъехался по батчам или по капу. +3. **Юнит не разъехался по батч-бюджету.** WARN `terminology: a batch renders OVER the size budget` — считать, сколько раз. Ненулевое количество ожидаемо и легитимно (юнит держится целым по дизайну), но если их много, следующий шаг — поднять `gates.terminology.batch_runes` (конфиг, не код), а не резать юниты. +4. **G2 нашёл то, ради чего строился.** Поле `self_conflicts=` в `terminology finished` и WARN «consolidations of THIS run contradict each other» с именами. Основание-ожидание: 18/149 на живом банке (§A4). Ноль на большой книге — подозрительно, надо перепроверять `lexemeSubset` на реальных формах, а не радоваться. +5. **Уверенность доехала и не врёт.** В стоп-таблице колонка `confidence=`. Проверять ДВЕ вещи: (i) она вообще непустая — значит модель выдаёт третье поле и парсер его снял; (ii) `bad_lines` в `terminology finished` НЕ вырос против прошлого прогона — если вырос, модель ломает формат из-за третьего поля, и это откат промпт-правки, а не повод её терпеть. Полезность (сортирует ли она ревью честно) меряется глазами владельца на первом же листе: строки с низкой уверенностью должны быть теми, которые он и правда правит. +6. **`Invented` — класс, который надо прочитать первым.** В стоп-таблице пометка `INVENTED`. Ожидание: доля небольшая; каждая такая строка — консолидация, которой не предлагал ни один черновик. Это легитимно (роль видит всю книгу), но это же и первое место, где ищется выдумка. +7. **`Conventions` против `Spread`.** Строки, где `spread` заметно больше `conventions`, — чистая орфографическая дробь, которую фолд теперь склеил; именно на них §C2-3 раньше делил доказательства. Если таких строк ноль — фолд не сработал (проверять `NormalizeTargetForm` на паре). +8. **Строка 130 видна.** WARN `bank-mining: terms that were in the auto-bank are NOT in the one this run just wrote` с именами. На первом прогоне его не будет (нечего диффить); он появится на ВТОРОМ и дальше. Если появился — это и есть материал для решения владельца по накопительному мерджу. +9. **Эвикция названа.** WARN `memory: the injection token budget DROPPED bank rows` с именами и `rows=`. Если он есть — банк не доезжает до модели, и это отдельный разговор про `glossary_token_budget`, а не про терминолога. +10. **Деньги.** `terminology render: estimate before any call` (до вызовов) против `cost_usd`/`classify_cost_usd` в `terminology finished`; ожидание — перекупка бэнк-батчей ОДИН раз, порядок центов, никакого касания волновых чекпойнтов (их $0-резюм должен пройти, что видно по `tm_hit`/`resume` в отчёте прогона). + +--- + +## §7. Вопросы оркестратору и предложенные строки бэклога + +**РЕШЕНО оркестратором/владельцем при приёмке (войдёт в D-ноту лендинга):** + +- **§7.1 — сдвиг edit-волны bank-only ПРИНЯТ.** Слово владельца («не против реснапшота») совпало с рекомендацией сессии: новый dst лучше старого, сдвиг громкий, репин $0 там, где терма нет. +- **§7.2 — миграцию под имена эвиктнутых НЕ заводим:** лог достаточен; durable-форма уходит строкой бэклога с гейтом «доказанная потребность», вместе со строкой 49а. +- **§7.3 — закрыто замером** (0 прогонов ≥2 пробелов на 585 строк эталона). +- **Девиация bankdata-плоскости РАТИФИЦИРОВАНА** — отдельный embed вне волнового фолда вместо `script-series.txt` признан правильным швом: иначе перекупалась бы вся драфт-волна. +- **Инверсия ранжирования семей ПРИНЯТА** по корпусному пину; объявлена девиацией §4 п.6 (в первой редакции отсутствовала). + +**Историческая формулировка вопросов (для читателя D-ноты):** + +1. **Edit-волна двигается bank-only — принимается ли цена?** Пак меняет поле dst дельты (ранг §C2-3 и фолд орфографии вместо сырого драфт-порядка), значит `memory_version`, значит снапшот edit-волны. Сдвиг громкий (`--resnapshot`) и репинится за $0 для каждой единицы, где терма нет; платятся только единицы, где он встречается — для фамилии протагониста это почти вся книга. Альтернатива, если цена не принимается: держать dst дельты на предложениях СВОЕЙ поверхности в исходном драфт-порядке (тогда карта подписи снова разойдётся со стоп-таблицей — это и был дефект, который §G3 чинил). Моя рекомендация: принять, потому что новый dst лучше старого, а перекупка разовая и видимая. +2. **Имена эвиктнутых durable?** Сейчас — лог (миграции не заводил, см. §4 п.4). Столбец `retrieval_state.evicted_detail` — это миграция, нужно слово. +3. **Двойной пробел в `coldrun-a`** — искать ли (одна `grep`-команда по замороженному эталону) и в чьей это сессии; я в артефакты не ходил. ⚠ Замер многоагентного ревью уже дал ответ по эталону: **0 прогонов ≥2 пробелов на 585 строк**, то есть класс, ради которого делался хвост 129, на этой книге не встречается ни разу — фикс остаётся верным, но его цена по эталону нулевая, а не отрицательная только после правки §4-0(ж). + +**Предлагаю СТРОКАМИ БЭКЛОГА** (таблицу ведёт оркестратор, я в неё не пишу): + +4. **Одноруновая голова семьи** — `蛊`/`转`/`窍` в отдельном вызове от своей семьи; включается строкой данных `family_containment_runes han 1`, гейт — замер размеров юнитов на холодном прогоне. Вес: скоро (то же касание, что и п. 7). +5. **Скрипт-слепой резолв семей/серий** — han-правила применяются к кане и хангылю; норма-долг общности, живого вреда нет (пары в репо нет), но при первой ja-книге это батч 8036 рун вместо двух в бюджете. Вес: когда-нибудь (к преп ja→ru, строка 81). +6. **`banknote_truncated` — пол, а не счёт** — обрыв, срезавший разделитель, невидим; фикс требует гейта по `Gates.Banknote.Enabled`, иначе шум на каждом обрыве в прогонах без канала. Вес: когда-нибудь. +7. **Пере-подтвердить `family_max_members = 24` и `families_held`** на первом холодном прогоне: 24 откалиброван на дистилляции в 150 поверхностей, у книги в 1000 глав список кандидатов другой (кап эмиссии 200 + реверс-секция). Если `families_held` велик — гард ослабить до «родство по любому члену юнита» вместо «по корню серии». Вес: скоро (гейт — тот же прогон, что и §6). +8. **Уверенность не гейтится данными пары** — канал снимает третью колонку у любой пары, чей промпт её попросит; у пары с ДВУХпольным промптом остаётся узкий риск («Пик␣␣99»). Если понадобится — дата-декларация пары. Вес: когда-нибудь.