@startuml pipeline title TextMachine — поток перевода книги (2026-07-25, синхронизировано с D1–D39.25, пост-пак-16: волновой исполнитель)\nПометки: [OK] = построено · [FLAG] = построено за enabled:false · [Ф2] = планово skinparam wrapWidth 260 start :Открытие Runner [OK]: строгий конфиг-стек (book.yaml + configs/pairs/<пара> + pipeline-*.yaml + models.yaml, KnownFields-декод), langpack пары + книжный overlay langpack_extend, промпт-конвенция prompts/<пара>/<роль>.md (fail-loud); :Ingest [OK]: txt (главы по \\f) / epub по spine, GB18030-детект/конверсия, ruby-захват, NormalizeSource; :Сид банка ДО снапшота [OK]: glossary_seed + ruby-кандидаты + mined_delta (Source:mined — только в ENRICHED) − mined_rejects · материализация BASE- и ENRICHED-банка; :Чанкинг [OK]: draft-чанки по ВЫХОДНОМУ токен-бюджету (SegBudget пары: фертильность CJK/other), edit-единицы декаплены · precompute sticky по BASE-банку одним упорядоченным проходом; note right Снапшот per-wave [OK]: draft-волна пинит BASE-банк, edit-волна — ENRICHED (обогащение двигает ТОЛЬКО edit — «переоплата ОДНА», D30.9/D39.12). Фолдятся: BriefHash, langpack Version(), промпт-SHA, capability, версии вердикт-осей. Правка данных между прогонами = громкий --resnapshot. Внутри снапшота: $0-резюм (rerun2 — доказан ×3 арма). end note partition "ВОЛНА ДРАФТА [OK] (∥ workers, по draft-чанкам)" { :Сборка контекста [OK]: кэш-префикс (system+brief) + src→dst-инъекция глоссария из precomputed selection (Aho-Corasick, trust-gate, спойлер-hard-reject, sticky); :runStage [OK]: чекпойнт-хит → $0-реклассификация · иначе Reserve (потолки книга/день) → вызов → Settle+чекпойнт ОДНОЙ tx → classify ПОСЛЕ денег; :Банкнота ⟦TM-BANK-v1⟧ [FLAG]: срез с RAW-драфта до classify · чистый драфт → derived-чекпойнт; if (Вердикт чанка? [OK]) then (транзиент: length/empty) :same-model retry, удвоение max_tokens (до regenerate_before_escalate); elseif (контент-провал: echo/refusal/loop) then (детерминированный) :Refusal причино-агностичен (D12/D39.25): детектим ФАКТ отказа, не причину · single-hop эскалация escalate_to под budget_usd + РЕ-ГЕЙТ · иначе flag+skip+continue (D2); else (ok) endif } if (Майнинг вкл. И дельта непуста? [OK]) then (да) :МАЙНИНГ-СТОП: MineBank по нормализованному источнику против контраста (сид и reject-set исключены) → signature map → прогон ОСТАНОВЛЕН (exit 3); :Владелец: каждый терм → promote в mined_delta (approved+dst) ИЛИ decline в mined_rejects; :Ре-ран: драфт $0-резюм · пустая дельта → авто-континью; else (нет / выкл) endif partition "ВОЛНА РЕДАКТУРЫ [OK] (∥ по edit-единицам, ENRICHED-банк)" { :Единица = конкатенация member-выходов драфта (редактор НИКОГДА не пере-рендерит драфт — инвариант) · флагнутый member ВЫБРАСЫВАЕТСЯ из редактуры (c-lite, D39.18); :СВЕЖИЙ memory.Select по источнику единицы над ENRICHED → CONFIRMED-констрейнты билингв-редактору (deepseek-v4-pro ИНТЕРИМ, D39.22 · glm-5 резерв); :runStage: тот же контур reserve→вызов→settle+чекпойнт, ретраи/эскалация/ре-гейт — как в драфте; :Гейты финала [OK]: intrinsic classify всегда · санитайзер D30.3 (косметика → strip + экспорт flagged) · глоссарный post-check (флаггер всегда, гейт opt-in) · cheap-гейты v4 → retrieval_state (observability, НЕ вердикт); :Repair-петля [FLAG] (пак-16, D39.24) — суб-шаг финальной стадии: checks.RepairCandidates (позиционная детекция, вердикт-нейтральная) → ≤N таргет-вызовов по span, промпт prompts/<пара>/repair/<класс>.md → 6 гардов + ПОЗИТИВНЫЙ ре-гейт + анти-удаление · ⟦TM-NOCHANGE⟧ = успех-декляйн · фикс → derived tm-repair-v1 · ВКЛЮЧЕНИЕ платного пути = решение владельца по замеру остатка; :Чекпойнт финала [OK]: в TM коммитится только прошедшее гейты · ApplyHeading на первую единицу главы; } :Read-модели $0 [OK]: tmctl status (wave-aware) · quality-report (структурный KPI + residual-скан RepairCandidates = замер остатка для решения о repair) · очередь флагнутых → человек (redrive точечно); :Экспорт $0 [OK]: манифест-ре-чанк + final-строки chunk_status, checks.ExportNormalize байт-в-байт с translate, --pairs (source-колонка), счётчики pending/ghost/ConfigDrift; note right Канал B (18+) [пак-17, в дизайне]: generic content-labels × provider-capabilities (D39.25) — в движке НЕТ понятия «18+». Сейчас интерим: Adult bool + channel:adult ТИП-изоляция + линт. Ф2: голос/состояние D21, native-Gemini судья, C2/C3. end note stop @enduml