@startuml pipeline
title TextMachine — поток перевода книги (2026-07-12, синхронизировано с D1–D38.1)\nПометки: [OK] = построено · [Ф1*] = остаток Фазы 1 · [Ф2] = планово
skinparam wrapWidth 260

start
:Импорт книги [OK]: txt / epub по spine,
ruby-захват, spine-reconciliation fail-loud,
GB18030-детект/конверсия (реальные zh .txt — не UTF-8, D18/D20)
(тихая потеря главы невозможна);
:Сегментация [OK]: главы -> чанки ~1-2k токенов
(sentence-pack, quote-depth, lossless);
:Сид глоссария [OK]: ручной YAML + ruby-кандидаты
(ja-книга: kana-написания имён — aliases руками, D16.4)
· сид v2 ПОДПИСАН владельцем (57 терминов, D34)
· status:draft НЕ инъектится в editor-констрейнт — reseed промоут грейдов (D38)
· автопопуляция G1 [Ф1*/Ф2]: спот=локаль / рендер=облако;
:Analyst: book brief (map-reduce) [Ф2];
:Terminologist: глоссарий + style sheet до перевода [Ф2];
note right
  snapshotID [OK] пинит: brief, чанкер, план стадий,
  capability, память (content-hash), context-assembly.
  ЛЮБОЙ resnapshot = переоплата книги (D15) —
  до content-addressed reuse онгоинг не продаётся.
end note

while (Остались главы?) is (да)
  while (Остались чанки главы?) is (да)
    :Сборка контекста [OK]: кэш-префикс (system+brief)
    + селективная инъекция глоссария
    (Aho-Corasick, спойлер-hard-reject,
    disposition CONFIRMED/AMBIGUOUS/REJECT, sticky)
    + retrieval_state запись;
    :NSFW-классификатор 0-3 [Ф2 — требует
    спеки и метрики приёмки];
    if (Уровень 3: несовершеннолетние?) then (да)
      :Чанк НЕ переводится: скип + флаг
      (книга продолжается);
    else (нет)
      if (Уровень 2: explicit?) then (да)
        :Канал B v2 [D19.1/D22.1]: переводчик-ДЕФОЛТ Mistral (18/18)
        → эскалация Grok 4.3 (reasoning-ON)
        → локальная abliterated 8b (скрин/фолбэк)
        · DeepSeek explicit ЗАПРЕЩЁН (ToS), violence OK
        · судьи 18+ Grok+Gemini (эротика→Grok primary, Gemini fail-closed);
      else (0-1)
        :Канал A [OK]: DeepSeek V4 Flash
        (thinking ON — эхо-мина);
      endif
      :Translator [OK]: черновик
      (C2 [Ф2]: N ГЕТЕРОГЕННЫХ кандидатов, D13.2);
      if (Ядро C2/C3: селекция? [Ф2]) then (да)
        :Judge-селектор: 11+ повторов со свапом
        позиций, Bradley-Terry
        (кандидаты разных семейств);
      else (C1)
      endif
      :Intrinsic classify [OK]: refusal-blacklist,
      CJK-echo, empty, loop — ДО length
      (усечённый отказ не ретраится платно);
      :Coverage-гейт [OK, opt-in]: sent_cov + len_ratio
      (только translator-роль);
      if (Вердикт чанка?) then (транзиентный: length/empty)
        :same-model retry, ось attempt,
        бОльший max_tokens (после loop-чека) [OK];
      elseif (контент-провал: echo/excision/refusal) then (детерминированный)
        if (escalate_to задан И бюджет есть?) then (да)
          :Single-hop эскалация [OK]: на ДРУГУЮ модель
          (ровно 1 хоп, editor pinned) — хоп ограничен
          per-model флором min_max_tokens 8000 (D24.3);
          :РЕ-ГЕЙТ фолбэка [OK]: classify + coverage
          заново — не прошёл, значит флаг остаётся;
        else (нет)
          :Флаг чанка (skip+flag+continue, D2) [OK];
        endif
      else (ok)
      endif
      :Editor [OK]: БИЛИНГВАЛЬНАЯ редактура (флип D1→D30.1) —
      вход = черновик + ИСХОДНИК + CONFIRMED dst-констрейнты ·
      дискурс-reflow-промпт (Ван Цуй) + репараграфизация 1:N ·
      кандидат glm-5, свап→mistral/deepseek-pro (D38.1) ·
      верность → fidelity re-gate (D34.3, полигон) + omission-гард [Ф2, D38];
      :Output-санитайзер [OK, opt-in c1] (D30.3/D33) —
      ведущие преамбулы / хвостовые «Основные правки» (gemini-утечка 6/6) /
      латиница-врезки / markdown-### / CJK-Han-в-выходе [в стройке D38.1] —
      flag+skip (D2), вердикт-ось;
      :Post-check финала [OK]: decl-aware,
      CONFIRMED-only (union: базовый dst ВСЕГДА в проверяемых формах,
      D24.4 — закрывает nominative_gap) — флаггер по умолчанию,
      жёсткий гейт opt-in за подписью владельца;
      :Чекпоинт [OK]: settle + checkpoint одной tx
      (в TM коммитится только прошедшее гейты);
    endif
  endwhile (нет)
  :Граница главы: телеметрия + паспорт
  качества [Ф1*] · батч-подтверждение терминов auto->approved —
  ЧЕЛОВЕК или судья чужого семейства [Ф2] —
  безлюдный авто-апрув = риск G1
  · резюме главы/арки + гейт фактичности [Ф2];
  note right
    Outage/системный класс (503-storm, потолок):
    circuit-breaker -> ПАУЗА + resume (D4/D12),
    НЕ mass-swap провайдера.
  end note
endwhile (нет)

:Очередь флагнутых чанков -> человек
· redrive точечно [Ф1*] (сейчас только
--resnapshot ценой всей книги — D15);
:Книжный QA-проход [Ф2]: консистентность по всей
книге, регрессия ты/вы, морфо-гейт рода;
:Экспорт txt/epub/TMX + отчёт [Ф1*]: tmctl export (канон. ассемблер)
+ annotations.json · нормализация выхода (strip ведущий ###)
· флагнутый чанк НЕ дропать в пусто (export-фикс D35.4a)
· стоимость по стадиям, флаги, журнал творческого вклада;
stop
@enduml
