textmachine/docs/archive/reports/BANK_FIXPACK_2026-08-02.md

18 KiB
Raw Blame History

Отчёт: ФИКС-ПАК БАНКА (бэклог-строка 87 + Q5) — D39.71

ПРИНЯТ И ЗАЛЕНДЕН (оркестратор №9, 02.08.2026, D39.75). Приёмка исполнением: build/vet/-race все пакеты · майнер-парити EXACT · голден сверен независимо (86/86 строк, маскированный дифф ПУСТ; двинулся только embedded_versionmemory_version/prompt_sha256/content_hash/все вердикты побайтно на месте) · 3-агентное адверсариальное ревью: 14/15 клеймов CONFIRMED, 1 PARTIAL, 0 REFUTED. Ключевое подтверждено контрфактикой: с возвращённым «ь» SameStem("Синь","синим")=true — откат (а) верен, регресс-гвозди работают (3 из 4 пар; пара Линь/линию инертна — заменить на Линь/линий при касании); (з) даже сильнее заявленного — инструкция реалий в промптах с D39.45, не D39.58. PARTIAL: дизайн-кейс «Фан Юаню»→«Фан Юань» закреплён только комментарием + анти-коллизионным ассертом — прямой гвоздь добавить при решении finding-1 (строка 91). Combmark-щель (и) воспроизведена живьём на копии старого кода («сло́во»→[сло во]) и закрыта. Ниты: тихий head-final-дефолт незаявленного скрипта (осознанно, все 4 текущих объявлены) · BatchRunes лёгкий overcount (+2/блок, самосогласован). Finding-1 → строка 91 (выбор владельца); граница плотности cjkScriptNames → дописка 79. Строка 87 ЗАКРЫТА.

Дата: 02.08.2026 · Сессия: бэкенд (продолжение банк-пака D39.68/69) · Зона: backend/ + этот отчёт · Деньги: $0 (ни одного платного вызова; --resnapshot/--resnapshot-эквивалент не запускался; голден пере-захвачен фейк-провайдером) · Статус: НЕ закоммичено — лендит оркестратор.

Вердикт-тройки (по мандату D39.68; «не делать с обоснованием» — легитимно для в/е/и)

# Пункт Вердикт Что сделано / обоснование
а decl_suffix +«ь», палладиевский класс ОТКАЧЕНО — предложенный фикс ФЛАВЕД (адверс. находка) → ПИНГ Bare «ь» был добавлен, затем ОТКАЧЕН: адверсариальное ревью (подтверждено white-box) нашло, что стрип «ь» неотличим по форме от ВРЕДНОЙ коллизии. «юань»→«юан» (нужный выигрыш) и «синь»→«син» (коллизия) — идентичная форма 4-рунного мягкознакового имени→3-рунный стем, ни одно min-stem-правило их не разделяет. Топ-фамилии Палладия «Синь/Линь» (辛/信/新, 林) схлопываются на «син/лин» = стемы общих слов «синий/линия»: Bank.SpoilerLeaks на отклонённой «Синь» выдаёт ЛОЖНЫЙ спойлер-лик на любом «синий» (направление ШУМА, против precision-дисциплины); Postcheck маскирует дроп «Синь» на любом «синем» (safe-направление, но частота много выше допущения D24.4 — «имена не рекуррируют случайно»; тут рекуррирует ОБЩЕЕ слово). Симметрия «нь/ль/й/ью» проанализирована, но нерелевантна — корень в самом «ь». РЕШЕНИЕ: не тащить коллизию; NB-коммент в target-ru.txt + регресс-гвоздь TestSoftSignNamesDoNotCollideWithCommonWords (падает, если «ь» вернут). Finding 1 (палладий) остаётся ОТКРЫТЫМ в safe-направлении — правильный путь пингом.
б head_final → данные СДЕЛАНО head-finality вынесена из Go-константы в data/script-series.txt (head_position<TAB>script<TAB>final|initial). SeriesMorphology резолвит head-final через SeriesHeadFinal(script) (данные; дефолт для незаявленного плотного скрипта = final, CJK-норма). Плотность (enabled) по-прежнему cjkScriptNames — предсуществующая граница общности, НЕ трогалась (пинг ниже). Тест: TestSeriesMorphologyUnchanged (zh/ja/ko→true,true; en/ru/unknown→false,false) + TestSeriesHeadFinalIsDataDriven (синтетический initial-скрипт резолвится head-initial без правки Go; corrupt-строки — loud).
в Лживый коммент Batch + оверсайз-серия СДЕЛАНО (WARN) Коммент Batch переписан на правду: порядок ДЕТЕРМИНИРОВАН (стабильная сортировка по чистой функции контента) → $0-resume держится, НО ординал батча фолдится в request-hash (потребитель адресует batch i как ChunkIdx i), значит хеш НЕ независим от порядка (смена частот → сдвиг ординалов → перепокупка затронутых батчей). Оверсайз-серия: вердикт WARN, не резать (резать серию убивает со-батчинг §1; тихо оставить — против дисциплины «no silent degradation»). Добавлен terminology.BatchRunes + WARN в терминологисте, называющий over-cap-юнит (мина cap-8000). Тест: TestBatchRunesFlagsOversize.
г classify_types при выкл. гейте СДЕЛАНО При enabled:false, classify_types:true — раньше ТИХИЙ no-op (runClassifier достижим только через включённый гейт, и валидация была вложена в if tg.Enabled). Теперь else if tg.ClassifyTypes → bad(...) (fail-loud, класс «гейт, который не может выстрелить»). Тесты: valid-load · нет classifier.md · budget≤0 · неизвестная classify_model · выкл.гейт+classify_types (terminology_classify_test.go).
д Мутационный тест neuter-фолда СДЕЛАНО memneuter_test.go по образцу memvoice-пина: TestNeuterRowMovesTheBankVersion (строка gender:neuter двигает memory_version) + TestNeuterFoldRespectsTheMinedScope (mined-only neuter фолдится в enriched, НЕ в base — draft-волна не перепокупает; гвоздит порядок hasNeuter-после-continue). Честная оговорка в комментарии теста: тег neuter-directive-v1 НЕ black-box-изолируем от уже-фолдящегося поля gender — тесты пинят наблюдаемый контракт.
е Voice-checker × стеммер НЕ ДЕЛАТЬ (контракт в код) Стеммер НЕ заводится в voice-канал. Обоснование (записано в voice.go): имена уже приходят склонённо-осведомлёнными (Forms = база + перечисленные decl-формы, тот же decl.forms[]); accept-biased стеммер поверх добавил бы лишь риск стем-коллизий/мис-атрибуции чекеру с доктриной precision-over-recall. Для SelfRef/NG стеммер НЕ единонаправленно безопасен: стем SelfRef подавил бы ложный self-ref-флаг (безопасно), но стем NG РАСШИРИЛ бы матч запретной леммы (шум) — противоположные направления на одном чекере. Склонение SelfRef/NG — забота ДРАЙВЕРА (перечислять формы из сида, как уже Forms), не match-time стеммера.
ж Дистилл-фикстура BANK-FULL СДЕЛАНО Поверхности books/gu-zhenren/coldrun-a/BANK-FULL.tsv (150) → terminology/testdata/bankfull-surfaces.txt (пар тест-данные). TestDetectSeriesOnBankFullFixtureIsStable пинит ТОЧНО 4 серии по реальному голова-скелету: 转-ранг {一二三四五六九转} (7), 等-грейд {甲乙丙丁等} (4), 等资质 {甲乙丙等资质} (3), 阶-тир {初中高阶} (3). «Ноль блоба» = каждая серия РОВНО равна ожидаемой группе (лишний член = провал), а не эвристика «≤N членов» (легитимная 7-членная ранг-серия — не блоб). 方源/元石/元海 вне.
з Q5 — реалии в пар-промпты НЕ ДЕЛАТЬ (уже есть) → ПИНГ Инструкция «реалии по смыслу; транслитерация — именам» УЖЕ присутствует в terminologist.md §26-27 (закоммичено с D39.58) и classifier.md §10-27 (с harm-примером 元石→«юаньши»). Это ровно те два реалия-рендерящих промта, что НЕ снапшот-фолдятся (терминология-гейт) → «перекупок нет» уже соблюдено. Переводчик/translator-banknote рендерят реалии инлайн, НО их промт снапшот-фолдится (draft-стадия) → правка перекупила бы draft-волну, против «перекупок нет» → исключены сознательно. Итог: PromptSHA256 НЕ двинулся (голден подтверждает).
и Дубль токенизации СДЕЛАНО (консолидация) lang.TokenizeWords теперь делегирует в новый text.TokenizeLetters (script-agnostic, combining-mark-aware), разделяющий ядро с text.TokenizeScript. Слой соблюдён: lang импортирует text (не наоборот; цикла нет — сборка/vet зелёные). Побочно чинит combining-mark щель в decl-пост-чеке (стресс-акцент больше не рвёт слово). Тест: text.TestTokenizeLetters (в т.ч. совпадение с TokenizeScript на односкриптном тексте).

Метрики / приёмка

  • go build ./... · go vet ./...зелёные.
  • go test -race ./...зелёные, все пакеты (в т.ч. internal/miner майнер-парити EXACT, internal/pipeline голден).
  • Новые тесты: lang (2 функции series + soft-sign регресс-гвоздь), config (5 classify-веток), membank (2 neuter + анти-коллизия «Синь»), terminology (BANK-FULL фикстура + BatchRunes), text (TokenizeLetters).

Голден-протокол (пере-захват ОДИН раз в конце)

  • TM_UPDATE_GOLDEN=1 go test ./internal/pipeline/ -run TestGoldenDeterminism — 86 строк изменилось.
  • Маскированный дифф (sed 's/^[+-]//; s/[0-9a-f]{12,}/HEX/g' | sort | uniq -u) — ПУСТ: каждое изменение отличается ТОЛЬКО в hex-токенах → вердикт-нейтрально.
  • Оси (HEAD vs new, точечная сверка; голден пере-захвачен ДВАЖДЫ — второй раз после отката «ь», финальный авторитетный):
    • embedded_version: embed-v1-37bf9699835fembed-v1-3df4329e3b9eЕДИНСТВЕННЫЙ корень (NB-коммент target-ru.txt (а) + новый script-series.txt (б); функциональных данных «ь» в файле НЕТ после отката).
    • Каскад: snapshot_draft/snapshot_edit, все request-хеши (final_hash = «request_hash авторитетного чекпойнта», chunkstatus.go:31 — АДРЕС, не хеш текста; request-log hash=) — сдвинулись как адресация, фолдящая снапшот.
    • НЕ двинулись: memory_version, content_hash, prompt_sha256 (⇒ (з) не правил промт), render_format_version, и ВСЕ dispositions/flags/finish/degraded/cost/tokens.
  • Общность: греп ДОБАВЛЕННЫХ engine-Go-строк (без комментов/тестов/данных) на CJK/пар/книго-литералы — пусто. Движок остаётся общим (пара не-из-репо заведётся без правки Go; head-position — данные).

Самопроверка исполнением + адверсариальное ревью (author≠reviewer)

Самопроверка (алгоритмы · соответствие стандартам репо · правильность предложенных фиксов): соло-проход пере-верифицировал каждый пункт исполнением (тесты · маскированный голден · греп-общность · точечная сверка осей) и не нашёл дефектов сам.

Адверсариальное ревью (Workflow wf_fea3802b-5a1: 5 refute-biased ревьюеров по измерениям × refute-verify; 7 агентов, 0 ошибок):

  • 1 ПОДТВЕРЖДЁННАЯ находка (medium) — акцептирована и ИСПРАВЛЕНА: коллизия bare «ь» (пункт (а) выше). Ревьюер репродуцировал white-box против реального кода; я независимо пере-верифицировал (SameStem("Синь","синим")=true, dstFormPresent(«Синь», …синим…)=true; до диффа — false). Действие: откат «ь» + регресс-гвоздь + пинг. ЭТО и есть ценность мандата само-проверки — флавед-фикс пойман ДО лендинга.
  • 1 ОТВЕРГНУТА (refuted): критика комментария об исключении «й» — верно по механике (пре-существующий safe-направленный miss на не-гейтящем флаггере), но НЕ дефект, вносимый диффом; исключение «й» — осознанное задокументированное решение (и «й» всё равно не закрыл бы «Юаньхай» из-за коллизии с «-ая»).
  • 4 из 5 измерений (б·в+и·г+д·общность/ж/е/з): findings пусты — 0 дефектов.

Пинги оркестратору (расхождение промта с кодом · открытые решения)

  1. (а) finding 1 НЕ закрыт — нужен НЕ-стеммерный механизм (РЕШЕНИЕ владельца). Предложенный «ь» флавед (см. выше). Палладиевский мягкознаковый gap («Фан Юаню»~«Фан Юань») требует одного из: (1) сид-перечисление decl-форм для мягкознаковых имён собственных (тот же драйвер-путь, что записан для (е) — точный матч, коллизия невозможна; вне бэкенд-скоупа, задача полигона/сида); либо (2) anchor-gated soft-final матч — новая ДАННЫЕ-категория мягких окончаний + правило «декл-матч требует ≥1 ТОЧНО совпавшего компонента-якоря», так что одиночные «Синь» без якоря не матчатся, а «Фан Юань» матчится через якорь «Фан». Вариант (2) — новое ДИЗАЙН-решение (по моему уроку — валидировать на корпусе и ратифицировать, не совать в фикс-пак реактивно). Прошу выбор владельца.
  2. (з) уже сделано: Q5-инструкция реалий уже в terminologist.md §26-27 (D39.58)/classifier.md — фикс-пак предполагал её отсутствие. Правки не требуется; PromptSHA256 не двинулся (в отличие от ожидания приёмки).
  3. (б) граница общности: данными вынесена ТОЛЬКО head-finality; enabled (плотность) по-прежнему piggyback на Go-константе cjkScriptNames — новый плотный скрипт всё ещё требует Go-строки там (предсуществующая граница, вне (б)-скоупа). Полной дата-общности серий — отдельная задача, если нужна.
  4. docs/BACKEND_BANK_FIXPACK_SESSION_PROMPT.md в рабочем дереве несёт ЖИВУЮ правку владельца (снят «$0/очерёдность»-абзац, переписана строка приёмки на «селф ревью») — НЕ моя, не трогал (чужой незакоммиченный файл).

СТОП — приёмка оркестратора.