textmachine/docs/archive/reports/GENERALITY_PHASE2_2026-08-01.md

142 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ОБЩНОСТЬ ФАЗА 2 — rewrite-пакеты П0П4 + шестёрка + малая пачка. Отчёт бэкенд-сессии, 2026-08-01
> **✅ ПРИНЯТ И ЗАЛЕНДЕН (оркестратор №9, 01.08.2026, D39.64).** Приёмка исполнением (author≠reviewer): собственный прогон `go build`/`go vet`/`go test -race ./...` = 14/14 · майнер-парити воспроизведён байт-в-байт (`n=13618 catastrophe{方源:0 蛊:1 蛊师:2 古月:22} recall@proposed=0.9655`) · все 7 приёмочных тестов PASS свежим прогоном · **Ш-1 сверен НЕЗАВИСИМОЙ классификацией диффа `capture.golden` (не маской их теста): 86+86=172 строки, key-by-key сравнение payload — ровно 5 осей §4; content_hash/disp/flag/detail, wire-тела и stage_text — 0 изменений** (156 из 172 строк = распространение фолда SnapshotID в чекпойнт-хеши, каузально — те же 5 осей) · адверсариальное ревью 6 агентами: ни одно несущее утверждение НЕ опровергнуто.
> Ниты (существа не меняют): (1) счёт флагов §5 = **9** позиций, не «10» (off-by-one эхо-блока); (2) дрейф номеров строк — `repair.go:574`→577 · `runner.go:391`→400-403 · `pipeline.go:832-841`→839-848 · `sanitizer.go:432`→431; (3) флаг 2: «ратифицированный тест» — частично мёртвая best-effort-ветка (ja-ru падает раньше ассерта; контракт фолбэка реально держат комментарий `pipeline.go:839-848` + голден-фикстура) — блокер настоящий, рекомендация в силе; (4) флаг 5: размеченный корпус `~/books/gu-zhenren/labels/` физически ЕСТЬ на стенде — реальный барьер = утраченный в эфемерном scratch харнесс замера + вердикт-риск K-рубрики; отказ держится как скоуп-решение; (5) байт-идентичность манифест-less пака в тесте не ассертится (в одном бинаре невозможно) — доказана независимой пробой HEAD-vs-дерево: `langpack-v2-a28ed743c99c` оба раза; (6) заявка «per-package 0/172» пост-хок непроверяема — подтверждён кумулятив.
> Находки сверх отчёта → бэклог: остаточные Cyrillic-хардкоды пар-гейтед DC-чекеров (`checks/repair.go:131` · `checkers.go:457,474`) — строка 79; при включении ручки #77 задокументировать общий счётчик attempt с length-ре-геном и рост `maxTokensForAttempt` (wire-параметр). Флаги §5 — очередь владельца (бэклог, строка 14).
**Промт:** `docs/BACKEND_GENERALITY_PHASE2_SESSION_PROMPT.md` (оркестратор №9, санкция владельца D39.62/D39.63).
**Режим:** $0 — код+тесты, НОЛЬ платных вызовов моделей, `--resnapshot` НЕ запускался, сессия НЕ коммитит.
**Карта-истина:** `GENERALITY_RESEARCH_2026-07-31.md` (принята D39.60): §3 якоря · §5 трасса второй пары · §6 цены · §9 план · §10 чего НЕ делать.
## 1. Эхо-блок (≤10 строк)
1. **П0П4 + 2 из 6 шестёрки + 1 из 2 малой пачки построены и верифицированы исполнением; 10 позиций помечены с инженерными причинами** (не тихо пропущены — флаг через владельца по мандату).
2. **Голден вердикт-нейтрален по всему пакету: `0 verdict/wire change line(s), 172 version-only` (Ш-1)** — сдвинулись ТОЛЬКО хеши 5 снапшот-осей, ни один вердикт/провод-байт на паре zh/ja→ru.
3. **Майнер-парити EXACT сохранён:** `n=13618`, катастрофы `{方源:0 蛊:1 蛊师:2 古月:22}`, recall@proposed 0.9655 — консолидация классов письма движок не тронула.
4. **`go test -race ./...` = 14/14 пакетов зелёные; build/vet/gofmt чисты по всем моим файлам.**
5. **Живой баг ko/Hangul ЗАКРЫТ (строка 75):** эхо-детектор меряет ОБЪЯВЛЕННОЕ письмо источника (`sourceScriptShare`), CJK-leak санитайзера ловит Hangul — корейское/английское эхо больше не слепое пятно.
6. **Дыра эмбед-плоскости ЗАКРЫТА (строка 76, П0):** `lang.EmbeddedVersion()` фолдится в снапшот — правка байта `target-ru.txt`/`injection.txt` = громкий resnapshot (мутационный тест доказывает).
7. **Цель-шов слоя 7 снят по данным (П1):** `isRuTarget` (6 сайтов) → `TargetActive()`/`TargetScriptNonLatin()`; книга `target_lang: en` проходит слой 7 инертно ПО ОТСУТСТВИЮ данных, без Go-ветки (мутационный тест).
8. **Самозадокументированный долг репэйнут (П1):** токенизатор цели с алфавитом ИЗ ДАННЫХ + U+0301-фолд закрывает #11 и `repair.go:182-189` ОДНИМ швом — линт и репэйр-скан на нём, дрейф невозможен.
9. **Самый жёсткий блокер слоя данных снят (П4):** манифест-по-каналам — источник без пиньинь-морфологии грузится без Palladius-файлов; **обратно-совместимо, БЕЗ бампа `packAlgoVersion`** (манифест-less пак байт-идентичен).
10. **Флаги (10): ё-фолд · segmentation-громкая · EstimateTokens-N-коэфф · encoding-аллоулист · 4 дефекта пака-21 (K4b/inner_marker/гомоглиф/OffLanguage) · billed-decode #78** — каждый с причиной и рекомендованным дизайном в §5.
---
## 2. Что построено по пакетам (file:line)
### П0 — «байты есть версия» (предусловие) ✅
- `internal/lang/embedded.go`: `EmbeddedVersion()` (embed-v1 + sha256 всех `data/*` в фикс-лекс-порядке, framing как у `Load()`); чистый `hashEmbeddedFiles([]embeddedFile)` вынесен для мутационного теста.
- `internal/pipeline/snapshot.go:389`: поле `EmbeddedVersion string json:"embedded_version"` рядом с `LangpackVersion`, фолд БЕЗУСЛОВНЫЙ (эмбед всегда присутствует, используется каждой книгой).
- **Приёмка (мутационный тест `TestEmbeddedVersionMutation`):** правка байта `target-ru.txt` И `injection.txt` — каждая двигает `EmbeddedVersion` ⇒ громкий resnapshot, не тихая смена вердиктов. PASS.
### П1 — цель-шов (слой 7) ✅ (кроме ё-фолда — §5)
- **Реестр целей из эмбед-данных** (`embedded.go` `TargetChecksFor`): Go-мапа `targetCheckFiles` удалена; реестр ДЕРИВИТСЯ из `data/target-<tgt>.txt` по имени файла.
- **Токенизатор цели из данных + U+0301** (`text/runes.go` `TokenizeScript(s, ws)`): алфавит-цель приходит `word_script` из `target-ru.txt` (→ `unicode.Cyrillic`); комб-марка (Mn) не рвёт слово и дропается — «сло́во»→«слово» (#11). `TokenizeCyrillic` = ru-дефолт-обёртка (§10 «значение по умолчанию»).
- **ЕДИНЫЙ шов, долг репэйнут** (`checks/checkers.go` `Checkers.tokenizeWords` + `checks/repair.go` `brokenWordCandidates`): и `lintYofikation`, и `lintBrokenWord`, и репэйр-скан висят на `c.wordScript` + одинаковом Mn-фолде — вердикт-нейтральность линт↔репэйр держится by construction. Комментарий-долг `repair.go:182-189` переписан на «REPAID».
- **`isRuTarget` → инертность-по-данным** (6 сайтов): `chunkrun.go:52`, `waverun.go:386,500`, `repair.go:574``r.checkers.TargetActive()` (есть цель-данные); `quality.go:215`, `repair.go:208``r.checkers.TargetScriptNonLatin()` (латинский остаток). `isRuTarget` удалён из `disposition.go`.
- **Гейт на `ExportNormalize`** ($0): `(c *Checkers) ExportNormalize` — no-op для цели без данных; 7 пайплайн-сайтов (waverun ×5, export.go, quality.go) → `r.checkers.ExportNormalize`. На CJK-цели `、→,` больше не порча.
- **`ruSanitizer` → поле Checkers** (`sanitizer.go`): 4 пар-init-компилированных RE (preamble/trailing/edit-meta/invalid-sign) → per-run поля `Checkers`, компиляция из цель-данных; `SanitizeOutput` = метод `*Checkers`; свободная `SanitizeOutput` — документированная ru-дефолт-обёртка для тестов (41 тест-сайт не тронут).
- Бамп `CheapGateVersion` v5→**v6** (токенизатор — алгоритм cheap-gate).
- **Приёмка (`TestTargetSeamInertness`):** цель без данных (→en) — `TargetActive()=false`, `tokenizeWords→nil`, sanitizer-паттерн-классы инертны; ru активна; ru-токенизатор фолдит U+0301. PASS.
### П2 — скрипт-шов источника ✅ (закрывает живой баг ko)
- **Данные:** новый `internal/lang/data/lang-script.txt` (lang→scriptname, объявляется, не нюхается): zh→han, ja→han+hiragana+katakana, ko→hangul+han, en→latin, ru→cyrillic. `internal/lang/script.go`: реестр `scriptRanges` (ОДИН на весь движок, `checks` резолвит word_script через него же), `LangScripts()`, `IsCJKScriptLang()`.
- **`cjkShare``sourceScriptShare(out, scripts)`** (`disposition.go`): меряет долю ОБЪЯВЛЕННОГО письма источника; `classifyInput.SourceScripts` ставится из `r.checkers.SourceScripts()` (2 caller: chunkrun, repair). en-эхо (латиница) и ko-эхо (Hangul) теперь детектируемы. Флаг `cjk_artifact` и детейл-вокабуляр СОХРАНЕНЫ (стор-вердикт не переименован).
- **`isCJKLang` → данные:** `isCJKTarget``lang.IsCJKScriptLang`; `sourceEchoExposure` (`runner.go:391`) → то же. Case-insensitive (сохранён старый lower/trim).
- **Репэйр script-guard** (`repair.go:435`) → `c.SourceScripts()` (тот же source-script notion, не хардкод Han+кана). `*Checkers.SetSourceScripts` ставится в `loadLangPack`.
- **Hangul-решение (санитайзер):** `isCJKLeakRune` (`sanitizer.go`) += Hangul — Hangul-ран в Cyrillic-выходе = утечка, target-side, source-agnostic. Бамп `SanitizerVersion` v6→**v7**.
- Бамп `classifierVersion` v1→**v2**.
- **Приёмка (`TestSourceScriptShareAndTarget`, `TestSecondPairDryRun`):** Hangul под ko-источником share ~1 (был слепой), под ja ~0; LangScripts reachable для zh/ja/ko/en/ru (эхо-детектор не спит молча). PASS.
### П3 — нарезка/оценка ✅ (3 позиции флагнуты — §5)
- **`話` в chapter_unit** (`cjk-section.txt`, ДАННЫЕ): доминирующая единица ja-вебновелл (第1話) — .txt-книга больше не становится ОДНОЙ главой. Голден (第N章) нейтрален. Тест `TestChapterUnitJaWebnovel`.
- **`sourceAbbrevs` по языку книги** (`chunker.go`): `var sourceAbbrevs = lang.SentenceAbbrev("en")` удалён; `abbrevs` протянут `SplitChunks→chapterDraftChunks→packSentences→splitSourceSentences→isAbbrevBefore`; runner-хелпер `r.sentenceAbbrevs()`. CJK-источник → пустой набор, не консультируется.
- **Generic-детект глав** (`chunker.go` `matchHeaderLine` + `lang/langpack.go` `parseHeading`): `units` СДЕЛАН опциональным (правило без units = маркер+число, «Chapter 12»); терпимость пробела маркер↔число; unit-bearing путь (zh 章) сохранён (гард `第一次`). Тест `TestStripHeadingGenericLatinMarker`.
- **Консолидация класса письма + вторая копия арифметики** (`text/runes.go` `DenseScript`/`DenseSparseCounts`): ОДИН дом sizing-таксономии; `render.EstimateTokens`, `chunk.TokenClassCounts`, `membank.glossaryLineTokens`, `text.SignificantLen`, `membank.spacedPhoneticScript` — все на нём. Значения идентичны (голден нейтрален).
- Бамп `chunkerVersion` v5→**v6** (generic-heading + srcabbrev — алгоритм нарезки).
### П4 — пак как механизм ✅
- **Табличный список опциональных файлов** (`langpack.go` `Load`): 4 копипаст-блока (heading/dc-checkers/speech-cue/terminology) → таблица `{dir, name, apply}` + цикл; порядок фолда в хеш СОХРАНЁН (голден нейтрален).
- **Манифест по каналам** (`langpack.go` `readManifest` + `Pack.channels`/`HasChannel`): опциональный `manifest.txt` в каталоге источника объявляет каналы `source-morphology`/`transliteration`; `Load` читает и `validate()` требует ТОЛЬКО объявленные; **манифест-less пак = все каналы = БАЙТ-ИДЕНТИЧЕН (нет бампа `packAlgoVersion`, нет перепокупки существующих паков)** — манифест-байты фолдятся лишь при наличии. Майнер получает инертный канал + WARN (`runner.go` `loadLangPack`).
- **Новые файлы книгой не оверлеятся** — УЖЕ обеспечено: аллоулист оверлея = `srcFiles`+`pairFiles`, fail-loud на любой другой файл (`LoadWithOverlay`). Зафиксировано, ничего не добавлял.
- **Приёмка (`TestManifestChannelsGateRequiredFiles`):** источник с `channel source-morphology` грузится БЕЗ Palladius-файлов; манифест-less пак версией = байт-идентичен, манифест-с-обоими-каналами двигает версию (drift-proof). PASS.
### Дешёвая шестёрка ✅ 2/6 (4 флагнуты — §5)
- **#11 U+0301** — ЗАКРЫТ токенизатором П1 (выше).
- **`translitInterjections` → данные** (строка 26): Go-литерал `cheapgates.go``translit_interjection` в `target-ru.txt`; поле `Checkers.translitInterjection`; `lintTranslitInterjections` → метод `*Checkers`. Значения идентичны.
### Малая пачка ✅ 1/2 (#78 флагнут — §5)
- **#77 ре-ген N=1 перед эскалацией для `cjk_artifact`** (`config/pipeline.go` `RegenerateEchoBeforeEscalate` + `stagerun.go`): опциональная ручка, **дефолт 0 = текущее поведение** (эхо эскалирует сразу); при >0 эхо ре-генерит на той же модели N раз до хопа (D39.61: эхо на 0731 стохастично по вызову, ре-ген ≈7.6× дешевле). **Гейт D19.2 НЕ ослаблен ни на байт** — меняется только ОТВЕТ на эхо. Retries не фолдится в снапшот ⇒ голден нейтрален.
---
## 3. Самоверификация исполнением (команды/числа)
| Проверка | Команда | Результат |
|---|---|---|
| build | `go build ./...` | EXIT 0 |
| vet | `go vet ./...` | чисто |
| gofmt (мои файлы) | `git diff --name-only \| grep .go \| xargs gofmt -l` | пусто (все форматированы; `llm.go` — ПРЕД-существующее, не мой diff, не трогал) |
| гонки | `go test -race ./...` | **14/14 пакетов ok** (pipeline 81s, store 15s) |
| голден Ш-1 | `TM_UPDATE_GOLDEN=1 go test ./internal/pipeline -run TestGoldenDeterminism -v` | **`0 verdict/wire change line(s), 172 version-only line(s)`** — кумулятивно по всему пакету |
| майнер-парити | `TM_MINER_PARITY=1 go test ./internal/miner -run Parity -v` | **`n=13618 catastrophe{方源:0 蛊:1 蛊师:2 古月:22} recall@proposed=0.9655`** — EXACT |
| мут. П0-байт | `go test ./internal/lang -run TestEmbeddedVersionMutation` | PASS (target-ru.txt И injection.txt двигают версию) |
| мут. П1-инертность `target_lang: en` | `go test ./internal/checks -run TestTargetSeamInertness` | PASS (слой 7 инертен по отсутствию данных) |
| мут. П2-Hangul | `go test ./internal/pipeline -run TestSourceScriptShareAndTarget` | PASS (ko-Hangul share ~1, был 0) |
| сухой прогон 2-й пары | `go test ./internal/lang -run TestSecondPairDryRun` | PASS (LangScripts reachable zh/ja/ko/en/ru — эхо не спит молча) |
| 2-я пара loud-stop | инспекция `config/pipeline.go:899-908` | `bad(...)` на отсутствующий промпт называет путь — ja→ru/en→ru доходят до ГРОМКОГО промпт-отказа, не тихого засыпания; мои правки silent-sleep НЕ добавили (П2 УБИРАЕТ en/ko слепые пятна) |
**Дисциплина «вывод на агрегате до вскрытия единиц»:** каждый снапшот-двигающий пакет верифицирован per-package golden Ш-1 отдельно (П0 сам по себе 0/172; П1 кумулятивно 0/172; П2 0/172; П3 0/172; финал 0/172) — не собирал зелёный агрегат до вскрытия по-пакетно.
## 4. Протокольная сводка сдвинутых снапшот-осей (перекупок на этой фазе НЕТ — D39.63)
Стендовый корпус одноразовый; `--resnapshot` НЕ запускался; следующий замер = свежий мини-прогон на новом стеке. Механика фолдов построена для эры боевых книг после МАСШТАБА. Оси, которые пакет СДВИНУЛ (при будущем resnapshot дадут громкий стоп, вердикты не двигаются):
| Ось | Было → Стало | Пакет | Тип |
|---|---|---|---|
| `embedded_version` | (нет) → `embed-v1-…` | П0 | **новая ось** (безусловный фолд) |
| `CheapGateVersion``style_check_version` | `cheapgate-v5-…``cheapgate-v6-target-tokenizer-combmark` | П1 | бамп (токенизатор) |
| `SanitizerVersion` | `sanitizer-v6``sanitizer-v7-hangul-leak` | П2 | бамп (Hangul-leak) |
| `classifierVersion``classifier_version` | `classify-v1-…``classify-v2-refusal+srcscript-echo015+loop` | П2 | бамп (source-script echo) |
| `chunkerVersion``chunker_version` | `chunker-v5-…``chunker-v6-generic-heading+srcabbrev` | П3 | бамп (generic-heading+abbrev) |
Плюс DATA-плоскость (покрыта `embedded_version` + `LangpackVersion`): `target-ru.txt` (+word_script, +translit_interjection), `cjk-section.txt` (+話), новый `lang-script.txt`. `packAlgoVersion` НЕ бампался (манифест обратно-совместим). Голден `capture.golden` перезахвачен ($0 fake-replay) — 172 хеш-строки, 0 вердиктных.
## 5. Позиции, помеченные на владельца (флаг, не тихий пропуск — мандат D39.62)
Каждая — с причиной и рекомендованным дизайном; ни одна не сделана «тихой интерпретацией».
1. **ё-фолд `NormalizeTargetForm`→данные (П1).** РАСХОЖДЕНИЕ с задокументированной позицией: код трактует ё↔е-фолд как «generic orthography» (`cheapgates.go:305-308`; `memoryNormAlgoVersion` вшивает `yofold` как алго-константу). `text` — намеренный script-agnostic лист (не импортирует `lang`), а `NormalizeTargetForm` зовётся в ~13 сайтах через ВЕРДИКТ-НЕСУЩИЙ банк (`memvoice`/`mempostcheck`/`memory`/`checkers`/`voice`) — чистый вынос = смена сигнатуры core-примитива + сдвиг `memory_version` с симметрично-фолд-риском, ради спекулятивной не-ru цели. Приёмка П1 (en→ru/→en инертны) УЖЕ достигнута гейтом `TargetActive`. **Рек.:** target `char_fold ё е` в данных + per-run `text.TargetForm{fold}` протянутый из `*Checkers`/банка, ru = значение-по-умолчанию. Держу до подписи (мандат «расхождение промта с кодом = пинг, не тихая интерпретация»).
2. **segmentation-фолбэк = громкая ошибка (П3.D).** РАСХОЖДЕНИЕ с РАТИФИЦИРОВАННЫМ ТЕСТОМ: `config/prompt_pack_test.go:193,236-238` явно проверяет, что пар-конфиг «только с коридором» СОХРАНЯЕТ generic-фолбэк (1797/3200/1.1978/0.3852); комментарий `pipeline.go:832-841` документирует, что голден-фикстура НА НЕГО ОПИРАЕТСЯ и релокация отвергнута least-mechanism §12.1. D39.59 («терпимость к своим данным = воркэраунд») новее и план на него ссылается — НО громкий фолбэк ломает этот тест-контракт и требует, чтобы КАЖДЫЙ пар/пайплайн-конфиг объявлял полный блок segmentation. **Рек.:** объявить segmentation в голден-`pipeline.yaml` (те же числа → голден нейтрален) + сделать фолбэк громким; подтвердить, что владелец готов сломать контракт corridor-only-фолбэка. Блокирующего исполнения без live-аудита конфигов ($0) не делал.
3. **EstimateTokens N-коэффициент из данных (П3.E).** Сделана КОНСОЛИДАЦИЯ разбросанного класса (§П3). Полный «N классов из данных» = смена `config.Fertility{CJK,Other}` (2 поля) на map — снапшот-фолдящийся config-тип + вся арифметика читающая `.CJK`/`.Other`; коэффициенты для новой пары НЕ калибруемы ($0, токенизатора deepseek-v4 в репо нет — отчёт §10/§11). **Рек.:** `Fertility` как per-script-class map с ru-дефолтом-значением; коэффициенты офлайн-калибровкой когда появится боевой токенизатор.
4. **encoding-аллоулист из данных (П3.F).** Ядро — ДЕКОДЕРЫ (GB18030/Shift-JIS) — принципиально Go/x-text, данными декодер не добавить. Текущий «zh→GB18030» скоуп (`ingest.go` `autoDecodeSource`) корректен для ЕДИНСТВЕННОГО не-UTF-8 источника в скоупе; пустой-source-случай (`sourceLang==""`→пробует GB18030) — тонкость, чей data-drive меняет поведение unknown-source. **Рек.:** `source-encoding.txt` (lang→encoding-name) + Go name→decoder-реестр (как script-реестр), скоуп из данных, декодеры остаются Go; ja Shift-JIS = отдельная декодер-проводка (сегодня намеренно fail-loud).
5. **4 дефекта пака-21: #2 K4b-атрибуция, #4 inner_marker-вето-на-тире, гомоглиф-детектор, строгий OffLanguage.** Это K-рубрика defect-класс, чья КОРРЕКТНОСТЬ верифицируется только против размеченного корпуса пакета-6 (ВНЕ git — отчёт §11.7). Гомоглиф-детектор ФУНКЦИОНАЛЬНО СУЩЕСТВУЕТ (`sanitizer.go:432` `tk.mixed` mixed Cyrillic+Latin). Строгий OffLanguage ЯВНО оговорён отчётом/промтом (36а: `甲等→класс Цзя` не ловит, D39.58 утечку алфавита НЕ воспроизвёл 0/150 — «не заявлять как дешёвый выигрыш»). #4/#2 — глубокая семантика (диалог-тире mixing rule) вердикт-риск без стенда. **Рек.:** взять на пакет-чекеров с доступом к `books/gu-zhenren/labels/` (свежий мини-прогон), не $0-код-фаза.
6. **#78 billed 2xx-decode-fail → request_log (ОБЯЗАНА).** Корректная реализация требует per-billed-attempt reserve+settle+уникальный-checkpoint (money/ledger/checkpoint-key путь): транспорт-ретраи billed-decode живут ВНУТРИ одной пайплайн-резервации (`httpllm.go:352-371` `billedDecodeSeen`, cap 1), провайдер списал N раз, зарезервировано на 1. Точная цена НЕИЗВЕСТНА (undecodable body → нет usage → оценка). Схема УЖЕ готова (`store.RequestLog.Estimated` дословно называет «billed decode failure»), но settle оценки в леджер трогает контур согласия Р6/потолки. D39.61 УЖЕ документирует это как известную ≤$0.009/сессия НИЖНЮЮ границу. **Рек.:** `LLMResponse.BilledDecodeFails int` из ретрай-цикла + `BilledDecodeError` несёт `PriorBilledFails`; пайплайн зеркалит существующий terminal-decode settle+log (`stagerun.go:537-552`, `Estimated=true`) per extra-billed-attempt. Money-чувствительно — не $0-хастл.
## 6. Критик полноты
**Что этот отчёт/пакет НЕ содержит и содержать не может:**
1. **Ни одного платного вызова.** Вся верификация — детерминированные unit/golden/parity (fake-replay). Поведение на РЕАЛЬНОЙ второй паре живьём не мерено (нет ja/en-книги на стенде) — приёмка «доходит до промпт-отказа» статическая (код + dry-run), не боевая.
2. **Голден — книга БЕЗ langpack (ja).** Путь с загруженным паком (zh-ru) байт-в-байт голденом не пинится; манифест-по-каналам верифицирован СИНТЕТИЧЕСКИМ паком (`TestManifestChannelsGateRequiredFiles`), не голденом. Для ведра A голден — не защита; прямой замер `pack.Version()` (рецепт §6 отчёта) сохранён как инструмент.
3. **10 позиций флагнуто** (§5) — из них 4 (encoding, #4 inner_marker, частично #78) «граничные» (мог бы сделать при большем бюджете, но money/schema/label-set-риски перевесили в $0-код-фазе). Владелец волен сузить/расширить.
4. **`EstimateTokens` коэффициенты (1.1978/0.3852) остаются zh-ru-выведёнными** для ВСЕХ пар — консолидация убрала дубли класса письма, но НЕ откалибровала per-script (невозможно $0).
5. **Санитайзер глубже цель-шва НЕ обобщён:** `detectLatinInsertion`/`scriptTokens`/invalidSign-семантика остаются Cyrillic-target-специфичны (гейтятся `TargetActive`/`TargetScriptNonLatin`, вне скоупа П1 — §10 не просит обобщать scriptTokens).
6. **Голден `capture.golden` перезахвачен** (172 хеш-строки) — не закоммичен; при приёмке оркестратор сверяет Ш-1 «0 verdict/wire».
7. **Параллельная полигон-сессия** писала в `docs/archive/reports/POLYGON_BANK_*` — её файлы не трогал (зоны не пересеклись, как D39.63 подтвердил).
**Приёмочный критерий каждого пакета — «пара, которой нет в репо, проходит слой без правки Go» — достигнут для П0/П1/П2/П4 (мутационные+синтетические тесты доказывают) и для generic-heading/話/abbrev части П3; частично для П3 (3 флага).**
**СТОП — приёмка оркестратора. Сессия НЕ коммитит; `--resnapshot` НЕ запускался.**