textmachine/backend/docs/pipeline.puml

131 lines
9.2 KiB
Text
Raw Permalink 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.

@startuml pipeline
title TextMachine — поток перевода книги (2026-08-08, синхронизировано с D1D39.25, пост-пак-16: волновой исполнитель; + блокеры контракта 99/100/101/125/145)\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-банку одним упорядоченным проходом;
:МАНИФЕСТ глав и чанков [OK] (строка 100): сайдкар
рядом с БД — project_db + .manifest.json, атомарная запись ·
СТАБИЛЬНЫЙ id главы = хеш ИНГЕСТИРОВАННОГО текста главы
(переживает пере-чанковку и правку соседней главы) ·
id ЮНИТА, наоборот, умирает с разрезом: глава + тег разреза + leader-индекс ·
ключ годности = исходник+чанкер+сегментация+форма пайплайна+пак+embed+norm ·
пишет любой write-путь, до прогона — команда tmctl manifest;
:ЭКСПОРТ БАНКА [OK] (строка 125): project_db + .bank.json —
весь банк тремя статусами, id из ключа уникальности
(не автоинкремент glossary.id) · пишется на границах стадий;
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 (потолки книга/день · потолок ПРОГОНА
--ceiling-usd перекрывает книжный book_usd, строка 145,
в хеши не входит) → вызов →
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 исключены);
:ТЕРМИНОЛОГ [OK]: Merge(WHICHWHAT) → KWIC → ранг §C2-3
(голос по ФОЛДУ целевой формы, сырые формы в показе) →
батчи ЮНИТАМИ: серия (равнодлинная) + СЕМЬЯ
(общий корень: имя-префикс либо реалия-суффикс, данные скрипта)
и containment-пара — юнит целиком в ОДИН вызов, кап членов;
:$0-экраны: канон-конфликты · КОНФЛИКТЫ СВОИХ ЖЕ
консолидаций · label-mismatch → стоп-таблица
(сигналы топ-варианта · invented · уверенность · конвенций);
:Сайдкары стопа [OK]: .bank-stop.txt — человеку ·
.bank-stop.json — машине (строка 101): ПОЛНАЯ таблица,
списки списками, «роль промолчала» = null, не 0 ·
плюс обновление экспорта банка;
: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) ·
ПОФАЗНЫЙ прогресс draft N/M и edit N/M в юнитах (строка 99) —
сквозной счётчик стоит на нуле всю черновую волну ·
quality-report (структурный KPI + residual-скан
RepairCandidates = замер остатка для решения о repair) ·
очередь флагнутых → человек (redrive точечно);
note right
Источник манифеста для status и export по умолчанию —
ПЕРСИСТ (строка 100), а не пере-нарезка: 1.4 с CPU → 0.05-0.12 с
на книге 23 МБ. Протухший ключ = откат на полную нарезку,
подать устаревший знаменатель нельзя по построению.
Пере-нарезку сохраняют пути, которым нужен ТЕКСТ:
export --pairs, контент-ветка ре-билла, quality-report.
end note
:Экспорт $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