Issue the track-A backend build-now pack and the track-B chunking-cohesion researcher prompt for the architectural reset

This commit is contained in:
Claude (backend session) 2026-07-13 01:45:42 +03:00
parent 225abc0930
commit d42d01e75a
2 changed files with 128 additions and 0 deletions

View file

@ -0,0 +1,63 @@
# Промт: сессия-БЭКЕНД — Трек A, пак-1 (структурная гигиена + память-корень + export-contract), 2026-07-13
> Рождён из арх-ресета **D39** (`docs/architecture/05-decisions-log.md`) и синк-аудита (`docs/architecture/08-sync-audit-ledger.md`, `09-target-architecture.md`). Это **build-now** трек: чистые фиксы, ресёрч НЕ нужен. Параллельно идёт трек B (полигон-ресёрч нарезки/когезии) — **не твоя зона, не трогай `eval/`**.
## Кто ты и зона
Бэкенд-сессия TextMachine (Go-пайплайн издательского перевода zh/ja/en→ru). **Зона записи — `backend/` только.** Читать можно всё; расхождения — пингом оркестратору в `docs/PROGRESS.md` (не правь чужие зоны). **Сессия не коммитит** — код ревьюит и лендит оркестратор после приёмки.
## Онбординг (порядок)
1. `CLAUDE.md` (гардрейлы) → `docs/architecture/09-target-architecture.md` (целевые слои, §2 слои 4/6/7/2-сеам, §4 трек A) → `docs/architecture/08-sync-audit-ledger.md` (находки этого пака: `L3-*`, `L5-normalization-fused-*`, `L8-*`).
2. `docs/architecture/05-decisions-log.md`: **D39** (арх-ресет), D30.1 (редактор БИЛИНГВ), D2 (диспозиции), D8/D24.4 (снапшот/база dst), D30.3/D33.1/D35.4a (санитайзер/strip-export), D38.3 (инфра-пак).
3. `docs/experiments/00-provider-quirks.md` (ПЕРЕД любыми правками, если тронешь вызовы — тут не должно, но правило).
4. `backend/README.md` + релевантный код (см. задачи).
## ЖЁСТКИЕ гардрейлы (из CLAUDE.md)
- **НИКОГДА не читать `.env`.** 18+ уровень 3 — не открывать `eval/data/*corpus*`, `/home/ubuntu/books/` без прямой задачи (тут не нужно).
- **Снапшот-дисциплина = деньги.** Любая правка, меняющая рендер запроса / выбор инъекции / текст выхода → меняет снапшот (Р6). Это ГРОМКИЙ `--resnapshot` (переоплата книги). **Ты НЕ пере-прогоняешь книгу** (это гейтится треком B). Твоя обязанность: (а) правильно **fold**-ить новую версию поведения в снапшот (`render.go`/`snapshot.go`, паттерн `coverageSnap`/`sanitizerSnap`); (б) обновить golden-фикстуры (`internal/pipeline/testdata/golden/`) под новое поведение — **golden = инвариант №8 (D23)**, обновление только под ратифицированную D39 смену поведения (она ратифицирована — этот пак); (в) в отчёте перечислить, какие снапшот-версии сдвинулись.
- **Мандат самопроверки (решение владельца, CLAUDE.md):** после кода — ЯВНЫЙ бэкенд-ревью **ИСПОЛНЕНИЕМ**: `go build/vet/gofmt/test -race ./...` зелёные; каждый новый класс/фикс запинен РЕАЛЬНЫМ тестом (firing + non-firing/FP-guard); каждую нетривиальную правку прогони на сконструированном входе и покажи ДО/ПОСЛЕ. Полигон/бэкенд регулярно багуют — не на веру.
- **Git-дисциплина мультисессий:** НЕ коммить; `git status` — твои правки только в `backend/`. Не трогай `START_PROMT.MD`, `docs/`, `eval/`.
## ЗАДАЧИ (4; независимы, порядок по ROI/риску)
### T1 — Память: код-корень терм-дрейфа (слой 4) · находки `L3-seed-workaround-not-code-root`, `L3-recurrence-*`, `L3-suppressor-disposition-blind-right-fix`, `L3-editor-block-stale-monolingual-D1`
**Проблема (CONFIRMED по коду):** терм-дрейф «починили» промоутом сида (D38.5), а **код-корень жив**. `suppressContained` (`memory.go:615-641`) **disposition-слепой**: `validSuppressor` гейтит только на `spoilerBlocked`, НЕ на доверии → более длинный **draft/ambiguous** ключ подавляет вложенный **approved** (напр. draft `四代族长` съедает approved `族长`), а сам не инъектится (editor-блок CONFIRMED-only, `memory.go:489`) → читатель получает ничего. Хуже: подавленный термин **не попадает** в `memSel.injected` → post-check и retrieval-state его НЕ видят (дроп тихий И нелогируемый — нарушает обещание research/13 «тихую деградацию → в громкую»).
**Сделать:**
1. **Disposition-gate на suppressor.** `validSuppressor` должен требовать, чтобы более длинный матч был **не ниже по доверию**, чем вложенный, который он подавляет: суппрессор с `dispositionFor` = AMBIGUOUS (draft/auto/collision-prone) **не подавляет** вложенный, чей `dispositionFor` = CONFIRMED (approved). Сохрани верный longest-match, когда длинный ≥ доверия короткого (approved `四代族长` по-прежнему бьёт approved `族长`). Реши краевые (equal-length, оба draft — как сейчас). Спот-верифицируй, что промоутнутые D38.5 термы теперь работали бы и БЕЗ промоута (regression-safety на будущее).
2. **Громкий лог дропа.** Подавление approved-по-draft фиксируй в retrieval-state (новое поле/счётчик — напр. `n_suppressed_by_lower_trust` + detail) ИЛИ в общий канал наблюдаемости, чтобы дроп был виден оператору. Не молчать.
3. **Убрать устаревшую D1-моно-рационализацию** в комментах `renderEditorConstraintBlock` (`memory.go:469-503`): редактор теперь БИЛИНГВ (D30.1). Это **коммент/рационализация**, поведение CONFIRMED-only оставь как есть (флаг открытого вопроса «давать ли билингв-редактору src→dst» — в отчёт оркестратору, НЕ реализовывать).
**Снапшот:** меняется выбор инъекции → bump `memnorm`/memory-версии → снапшот-fold + golden. Тест: сконструируй синт-чанк (draft-длиннее-approved) — покажи ДО (approved дропнут+тих) / ПОСЛЕ (approved инъектится ИЛИ дроп логируется). Зеркаль enforce-логику как в reseed-verify, но это КОД — верь Go.
### T2 — Export-contract: нормализация каждого финала (слой 6) · находки `L5-normalization-fused-to-flag-path`, `L5-stripcosmetic-duplicates-nfkc`, `L5-sanitizer-version-churn-*`, `L5-diacritics-class-lost`
**Проблема (CONFIRMED):** нормализация вплавлена во FLAG-путь санитайзера (`stripCosmetic`) — один и тот же косметический дефект (U+3000-отступы, полноширина) чинится на флагнутом чанке, но уезжает СЫРЫМ на чистом (`cmd/tmctl/render.go:31` пишет FinalText дословно). Плюс `stripCosmetic` руко-катает NFKC-fold, дублируя `norm.NFKC` из `memnorm.go`.
**Сделать:**
1. **Единый export-contract слой:** одна детерминированная нормализация, применяемая к КАЖДОМУ финальному тексту перед экспортом (NFKC-fold через `norm.NFKC` + пробелы/CJK-пунктуация/U+3000-нормализация + опц. combining-диакритика→NFC, закрывает потерянный класс `L5-diacritics-class-lost`). Это слой D29.1a, который D-лог откладывал.
2. **Санитайзер → чистый ДЕТЕКТОР:** он только ФЛАГует по-настоящему невосстановимое; нормализацию у него забирает export-contract. `stripCosmetic` перестаёт дублировать NFKC. Сократи churn-регексы (`L5-sanitizer-version-churn`) там, где их заменяет единый нормализатор.
3. Взаимодействие с D35.4a strip-and-export: сам strip-механизм ВЕРНЫЙ (`L5-strip-export-mechanism-sound`) — не ломай его; но нормализация теперь общая, а не только на флаге.
**Снапшот/golden:** меняется текст экспорта → снапшот-fold + golden обновить. ⚠ Не тронь легит-кейс `L5-legit-cjk-gloss-stripped` (гло́сса `(羅漢拳)` в скобках) — это **открытый вопрос владельцу** (в отчёт, НЕ решай сам: узкий whitelist или конвенция — за владельцем). Тесты: чистый чанк с U+3000/полуширина/диакритикой — ДО (уезжает сырым) / ПОСЛЕ (нормализован).
### T3 — Сеамы расширяемости + слой-2 сеам (слои 7, 2) · находки `L8-*`, `L4-adding-a-pair-is-a-rewrite-not-config`
**Проблема:** расширения, которые проект вот-вот делает (Ф2-annotator/voice-роль, пары языков), падают на грязные сеамы.
**Сделать (все — чистые рефакторы, поведение zh→ru НЕ меняется):**
1. **Реестр `role→инъекция`** (`chunkrun.go:134-140`): `map[role]injectionRenderer` (или стратегия из конфига) вместо рукоправимого switch — чтобы новая роль = данные + один renderer, не правка switch.
2. **Target-aware readability-гейты** (`L8-readability-gates-target-blind`): весь readability-набор (санитайзер + cheap-гейты) сейчас хардкодит target=ru и стреляет безусловно — любой не-ru target даст ложные флаги. Загейти за `TargetLang` (early no-op при target≠ru ИЛИ per-target реестр), зеркаля pair-aware `coverage/classify`. Прод zh→ru не меняется.
3. **Слой-2 СЕАМ — pair-keyed резолв промпта/правил** (решение владельца D39: сеам сейчас, контент zh→ru): стадия резолвит промпт из **pair-keyed слоя** (`src→tgt[×genre]`), а не из фикс-пути yaml. `Book.LangPair()` (мёртвый код `book.go:193`) оживает как ось. **Наполнить ТОЛЬКО zh→ru** (сегодняшний `translator.md`/`editor.md`-контент переносится в zh→ru-пакет). **Fail-loud** на отсутствующую пару (не молчаливый дефолт в zh — закрывает латентный баг: ja-книга сейчас едет через «китайский паратаксис»-промпт). **Язык промпта = свойство пакета** (сегодня русский — но как свойство, не хардкод). Снапшот обязан fold-ить биндинг пара→промпт. Прод zh→ru рендерит тот же SHA (поведение-нейтрально) — проверь исполнением.
4. **De-смазка strip-and-export** (`L8-sanitizer-strip-smeared-5-files`, `L8-stripcosmetic-recomputed-twice`): один resolver `classification→(disposition, exportText)`, считающий strip ОДИН раз; `runStage`/escalation/resume потребляют resolved-текст, а не каждый ре-branch-ится на `FlagSanitizerStripped`.
5. **Снести мёртвое:** сироты-промпты `analyst.md`/`terminologist.md`/дубль `editor-mono.md` (если реально не референсятся — проверь grep; если editor-mono живой фолбэк, wire его конфигом под snapshot/golden); мёртвый `gatesEnabled()` (`pipeline.go:164`, 0 вызовов, врёт); вынести `foldModelWire()` (`snapshot.go:235-280`, tripwire на 3-ю модель-ось уже стоит).
**Снапшот:** T3 — поведение-нейтрально для zh→ru; докажи исполнением (тот же снапшот/golden на прод-конфиге). Пункт 3 (pair-резолв) — самый тонкий: снапшот должен fold-ить пару, но SHA промпта zh→ru не измениться.
### T4 — Детерминированный per-run quality-report (слой 5, детерм. часть) · находка `H5-no-in-loop-quality-signal`
**Проблема:** владелец просил телеметрию качества с 1-го дня (п.25/п.31); research/18 §C1 #10 пометил авто-оценку «СЕЙЧАС», её молча спустили в Ф2. Сигналы УЖЕ считаются (cheap-гейты, regression-guard, glossary post-check, echo/CJK), но не агрегированы в читаемый per-run сигнал качества.
**Сделать (ЛЁГКО — переиспользуй существующее, НЕ строй судью):** агрегируй уже-считаемые детерминированные сигналы в **per-run quality-report** (напр. `tmctl report` / расширение `status`): предл./нарратив-абзац (KPI претензии-1), диалог-тире-консистентность, CJK-утечка rate, glossary-консистентность (D10), число-дрейф (regression-guard), echo-rate. Per-chunk + агрегат по книге. **Только наблюдаемость, НЕ гейт.** Семантический span-судья (inversion/omission-бэкстоп претензии-2) — НЕ здесь: он ресёрч-зависим (форму даст трек B), в пак-2.
**Снапшот:** read-only проекция (как `status`) → снапшот не трогает. Тест на живом store-срезе (можно синт).
## Что НЕ делать (в отчёт оркестратору, не реализовывать)
- Семантический inversion/omission-судья (пак-2, после трека B).
- Наполнение не-zh→ru пар (слой 2 — только сеам сейчас).
- Diff-based редактор / декаплинг edit-единицы / логическая нарезка — это **трек B** (ресёрч ПЕРЕД постройкой).
- Решение по CJK-глоссам в скобках (`L5-legit-cjk-gloss`) — вопрос владельцу.
- Пере-прогон книги — гейтится треком B.
## Deliverable / отчёт оркестратору
Отчёт в ответе (НЕ в PROGRESS — туда пишет оркестратор): по каждой T — что сделано, `file:line`, ДО/ПОСЛЕ на реальном/синт-входе, какие снапшот-версии сдвинулись, какие golden обновлены и ПОЧЕМУ, результат `build/vet/gofmt/test -race`. Явный **само-ревью исполнением** (мандат): перечисли, что пинал реальным тестом, что прогнал руками. Открытые вопросы (билингв-редактор src→dst; CJK-глоссы; editor-mono судьба) — списком оркестратору. **Не коммить.** Оркестратор верифицирует исполнением (второй рубеж) и лендит.

View file

@ -0,0 +1,65 @@
# Промт: сессия-РЕСЁРЧЕР — логическая нарезка + меж-чанковая когезия + дизайн эмпирики (трек B), 2026-07-13
> Рождён из арх-ресета **D39** (`docs/architecture/05-decisions-log.md`, `09-target-architecture.md` §2 слой 1, §4 трек B). Это **ресёрч ПЕРЕД постройкой** для сцепленных концернов **1 (разделение переводчик/редактор), 2 (нарезка), 4 (частично)**. Ты НЕ пишешь прод-код и НЕ гоняешь платную эмпирику — ты (1) добываешь best-practices, (2) проектируешь реализуемый чанкер+когезию, (3) выдаёшь ПРЕ-РЕГИСТРИРОВАННЫЙ дизайн полигон-эмпирики, которую потом исполнит полигон-сессия.
## Зачем эта сессия (мета)
Потолок художественности — в НАШЕЙ нарезке/проходах, не в моделях (D39). Три сцеплены: редактор репараграфизует ВНУТРИ ~1500-токенного чанка → нарезка ограничивает потолок дискурс-переверстки и «понимания связей». Владелец: **нарезка нетривиальна** — глава может быть >> загружаемого чанка, резать надо по **логическим** единицам (статический код, фоллбеки, интернет-best-practices), а не «все китайские книги такие, грузим главы». Нужно спроектировать это правильно И спроектировать эксперимент, который разрешит открытые вопросы, а не соберёт ложную сходимость (полигон делал это трижды — D32.4).
## Зона и дисциплина
- **Зона записи — `docs/research/` только** (новый отчёт, напр. `docs/research/19-chunking-cohesion.md`). Ничего не коммитишь — лендит оркестратор после верификации первоисточников (как research/1518).
- **Гардрейлы (CLAUDE.md):** НЕ читать `.env`; 18+ уровень 3 — не открывать `eval/data/*corpus*`, `/home/ubuntu/books/` (кроме метаданных/структуры, если понадобится оценить размеры глав — тогда ТОЛЬКО счётчики, не содержимое explicit).
- **Правило двух направлений:** несущий клейм → первоисточник; аномалия/best-practice тула → офиц. дока. Не абсорбируй фреймворк-маркетинг как факт.
- **Анти-анкоринг (как research/18):** §A своего вывода замораживай (sha256) ДО чтения нашего стека/предыдущих отчётов, чтобы независимость была реальной.
- **Мандат самопроверки (CLAUDE.md):** несущие клеймы верифицируй адверсариально своим воркфлоу (author≠reviewer внутри сессии: твой «CONFIRMED» — по первоисточнику, не по вторичке); отметь, где сходимость общая-ногой-литературы, а не 3 независимых голоса.
## Онбординг
1. `CLAUDE.md``docs/architecture/09-target-architecture.md` (§2 слой 1 — целевой чанкер; §4 трек B — вопросы) → `08-sync-audit-ledger.md` дорожка **L2** (все находки нарезки) + `L1` (контракт переводчик/редактор).
2. `docs/architecture/05-decisions-log.md` **D39** + D30.2 (`:366` — reflow-механизм открытый вопрос) + D35 (`:471` — декаплинг = un-ratified кандидат).
3. **Код нарезки** (грунтовка, не по заголовкам): `backend/internal/pipeline/chunker.go` (жадная упаковка абзацев в `targetChunkTokens=1500` const, спуск до предложений; границы бюджетные), `ingest.go` (как формируются главы), `chunkrun.go` (чанк = единица И черновика И редактуры; инъекция только глоссарий — меж-чанковой когезии нет), `render.go`/`config/pipeline.go` (`STMDepth`/`OverlapTokens` — мёртвые заглушки).
4. **Предыдущая эмпирика:** `docs/experiments/14-quality-empirics.md` (кривая размера чанка §2Б.4; A-ref ±1 §2.4; P1c глава-целиком §2.3) + `docs/research/18-quality-levers.md` §A (Ось-4: держать чанк МЕЛКИМ + carryover; глоссарий ≈14% дискурс-ошибок, дейксис ~37%, эллипсис ~29%) + `16-reader-ide-alignment.md`, `12-*` (дискурс-нормы, кросс-предложенческая когезия).
## ⚠ ЦЕНТРАЛЬНЫЙ КОНФЛИКТ, который сессия ОБЯЗАНА адресовать
**exp14 §2Б.4** намерял: крупнее чанк = дешевле выходных токенов И лучше абзацы (оптимум ~3200c/глава, 0 ретраев) → «edit=крупная единица». **research/18 §A Ось-4** заключает ОБРАТНОЕ для прода: держать чанк МЕЛКИМ (малый retry-blast-radius, Lost-in-Middle), а когезию давать кэшированным running-summary/carryover — «а НЕ размером единицы». Оба клейма grounded, но **противоречат по размеру edit-единицы**. Твой дизайн эмпирики должен этот конфликт РАЗРЕШИТЬ (на retry-adjusted-cost + на реальном вебновелл-срезе, не PD-классике), а не выбрать сторону догадкой.
## ЗАДАЧИ
### Задача 1 — Best-practices логической/семантической нарезки (интернет + академия)
Добудь и адверсариально верифицируй, КАК правильно нарезать крупный НАРРАТИВНЫЙ текст на логические единицы, когда глава >> окна модели:
- Инженерные best-practices: recursive/semantic splitting, sentence-window / parent-document, discourse/scene-boundary detection, topic segmentation (TextTiling и потомки), overlap-стратегии — с их РЕАЛЬНЫМИ ограничениями (не маркетинг фреймворков).
- Как это делают CAT/пром-MT тулы и переводчики-практики (сегментация по смысловым блокам, не по строкам).
- Академия по кросс-предложенческой когезии, релевантная нарезке: Voita (дейксис/эллипсис/когезия), DelTA / running-summary, document-level MT context windows.
**Выход:** реализуемый в СТАТИЧЕСКОМ Go-коде дизайн: (а) стратегия `logical` (сцена/диалог/тема-граница) с **фоллбек-лестницей** и инвариантом «никогда не резать предложение»; (б) какие сигналы границы детектируемы БЕЗ модель-вызовов (дёшево — владелец: «не модель-вызовами размечать чанк»); (в) конкретные фоллбеки при провале детекции. Рассмотри ВСЕ кейсы, не только «1-2-3-4 мелкие главы влезли в чанк» (это простейший).
### Задача 2 — Дизайн меж-чанковой когезии
Спроектируй механизм, закрывающий претензию-2 «понимание связей» при чанк-изоляции + zh zero-anaphora:
- running bilingual summary + carryover соседних единиц (оживить `STMDepth`/`OverlapTokens`), cache-friendly (порядок кэша важен — research/18);
- ±1 reference-контекст (exp14 дал null на PD-срезе — но домен-mismatch: нужны РЕАЛЬНЫЕ кросс-граничные трапы вебновеллы);
- как это НЕ ломает деньги/снапшот/детерминизм (read-only контекст, fold в снапшот).
### Задача 3 — Дизайн контракта переводчик/редактор (концерн 1)
research/07 предписывает узкие мандаты + диффы, не полную перегенерацию; прод-редактор = ОДНА full-regen с 4 мандатами (причина инверсий D34.3). Спроектируй (для эмпирики, не для прода):
- арм **«переводчик отдаёт структурный ~верный черновик»** vs «редактор-переписыватель» — **НИКОГДА не тестировался** (exp14 держал модель черновика константой);
- diff-based редактор (search/replace + детерм. apply) как узкий проход — оценка ROI (blast-radius, COGS, omission-safety).
### Задача 4 — ПРЕ-РЕГИСТРИРОВАННЫЙ дизайн полигон-эмпирики (для исполнения полигоном)
Спроектируй эксперимент, разрешающий концерны 1/2/4 БЕЗ ложной сходимости. Не полный факториал (24 ячейки — неподъёмно) — **набор целевых 2-арм контрастов к общему якорю** на едином **МАРКИРОВАННОМ вебновелл-срезе** (не PD-классика — гейт «вне претрейна»):
- **Q1 (нарезка):** `граница greedy vs logical` при фикс. edit-единице → чинит ли логическая граница когезию (претензия-2).
- **Q2 (edit-единица, РАЗРЕШАЕТ КОНФЛИКТ):** `edit=чанк vs edit=глава/крупная` на **retry-adjusted** COGS + когезия.
- **Q3 (когезия):** `нет vs running-summary/carryover` при МЕЛКОМ чанке → закрывает ли carryover кросс-границу (клейм research/18).
- **Q4 (контракт):** `где reflow: переводчик vs редактор vs отдельный-пасс` + арм сильного переводчика.
- **Обязательно:** маркированный набор КРОСС-ГРАНИЧНЫХ трапов на вебновелл-срезе (аудит: §D-1 «locus когезии не размечен»); methodology-guard D32.4 (fidelity-first агрегация, leave-one-out судей, катастроф-скрин к победителю тоже, per-call кап, пре-регистрация ЗАМОРОЖЕНА коммитом ДО первого платного вызова, каждый скрипт персистит usage/cost).
## Полигон-синк — ОТВЕТЫ получены (2026-07-13), ВПЛЕТИ в дизайн
Оркестратор синканулся с полигон-сессией 14/14б. Факты (grounded по артефактам, всё ВНЕ git в `exp14/`):
1. **Translate-арм НЕ гонялся:** frontier-as-ПЕРЕВОДЧИК спот-чек (14:148) планировался, но `exp14/costs.jsonl` — только РЕДАКТОРСКИЕ армы (ре-редактуры фикс. flash-черновика). Draft-swap/translate-плеча НЕТ. → **«переводчик отдаёт структуру» (Q4) — чистое поле, ни одного датапоинта.**
2. **Реюз (дёшево):** кривая размера — выходы `exp14/sizecurve/{17,13}-{800c,1600c,3200c,whole}.txt` + `sizecurve.json`; исходник = детерм. `chapter_source()` из `material.json`; границы байт-воспроизводимы (жадный `rechunk(budget)` детерминирован). A-ref — `exp14/arms/A-ref-{prev,both}/{11.1,24.1}.txt` + `material.json→trap_chunks`. **`A-ref-next` НЕ гонялся** (только prev/both) — next-supported/катафора-плечо ОТСУТСТВУЕТ.
3. **Кросс-граничный null = ДОМЕН-АРТЕФАКТ, не бесполезность рычага:** чистого next-supported/катафора-трапа в раннем срезе не нашлось; T5/T6 локально самодостаточны → A-ref-prev байт-идентичен «чинить нечего» (14:93/257/290). Маркированного кросс-граничного набора НЕТ. §D-1 (locus когезии не размечен) в силе.
4. **Сцен-граница — СОЗНАТЕЛЬНО не гонялась:** докстринг `exp14_sizecurve.py:10-11` — ранняя арка 蛊真人 **структурно плоская** (1 предл./строка, мало сцен-маркеров) → «сцена vs жадная» слабо различима на ЭТОМ тексте. Не тулинг/время — домен.
**СКВОЗНОЙ ВЫВОД (несущий для дизайна):** три из четырёх пробелов (Q1/Q3/Q4) — непротестированные допущения на НЕПОДХОДЯЩЕМ домене (плоская ранняя арка 蛊真人), а НЕ отрицательные результаты. Прямые следствия для §D:
- **Домен-пригодность — ПЕРВЫЙ шаг эмпирики.** Сначала **характеризовать структуру целевой книги** (蛊真人 целиком, не только ранняя арка: есть ли сцен-маркеры, кросс-главные зависимости, разброс длины глав) — ТОЛЬКО метаданные/структура, не explicit-содержимое. Если книга плоская и дальше → это САМО ПО СЕБЕ находка: логическая/сцен-граница для НЕЁ малополезна, доминирующий рычаг = внутри-чанк верность (T1-floor) + размер edit-единицы, а не граница. Не строить сцен-чанкер под домен, который его не задействует.
- **Трап-набор Q1/Q3/Q4 должен быть на срезе С выраженной сцен-структурой + реальными кросс-граничными зависимостями** (маркированный, вебновелл, вне претрейна) — иначе снова неинформативный null. Выбор среза обоснуй характеризацией (шаг выше).
- **Дешёвый путь (от полигона):** реюзать кривую (Q2) + A-ref-prev/both как есть; дозаказать только `A-ref-next` + translate-плечо (Q1 реюзит те же 2 T-трапа почти бесплатно); маркированный кросс-граничный + сцен-структурированный набор разблокирует Q3+Q4 разом.
## Deliverable
`docs/research/19-chunking-cohesion.md`: §A (заморожена sha256, ДО чтения стека) · §B (best-practices нарезки+когезии, реализуемый Go-дизайн + фоллбеки) · §C (дизайн контракта t/e) · §D (пре-регистрированный арм-дизайн Q1Q4 + маркированный трап-набор + methodology-guard) · §E (открытые вопросы владельцу/бэкенду). Несущие клеймы — с первоисточником; отметь общую-ногу-литературы vs независимые голоса. Оркестратор верифицирует по первоисточникам и лендит; полигон-эмпирику по §D запускаю отдельным промтом ПОСЛЕ (author≠reviewer). **Ничего не коммить.**