158 lines
11 KiB
Text
158 lines
11 KiB
Text
@startuml components
|
||
title TextMachine — компоненты бэкенда (2026-07-12, синхронизировано с 05-decisions-log D1–D38.1)\nПометки: [OK] = построено · [Ф1*] = остаток Фазы 1 · [Ф2]/[Ф3] = планово
|
||
skinparam componentStyle rectangle
|
||
skinparam wrapWidth 200
|
||
|
||
actor "Владелец / редактор\n(очередь флагов, подтверждение терминов,\nподпись сида v2 = approved-инвариант (D34),\nарбитр читаемости слепых прогонов [2 претензии, D35],\nBWS-оценка пилота)" as HUMAN
|
||
|
||
package "Интерфейсы" {
|
||
component "CLI tmctl: translate / report [OK]\n+ status / redrive [Ф1*]" as CLI
|
||
component "HTTP API (IDE) [Ф3]" as API
|
||
}
|
||
|
||
package "Оркестратор" {
|
||
component "Проект книги [OK]\n(translation brief, brief_hash,\nконфиг ядра C0/C1/C2/C3)" as PROJ
|
||
component "Импорт txt/epub [OK]\n(главы -> чанки, ruby-захват,\nspine-reconciliation fail-loud)" as IMP
|
||
component "Durable jobs [OK]\n(чанк-чекпоинты, resume, kill-9-инвариант;\ncontent-addressed reuse — гейт онгоинга [Ф1.5])" as JOBS
|
||
component "Пайплайн-раннер [OK]\n(циклы/ретраи/single-hop эскалация\nс РЕ-ГЕЙТОМ = код; состав стадий/модели/\nпороги = конфиг; disposition D2)" as RUNNER
|
||
component "Экспорт txt/epub/TMX + отчёт\n(паспорт качества главы) [Ф1*]" as EXP
|
||
}
|
||
|
||
package "Агентные роли (промпт-конфиги)" {
|
||
component "Translator: черновик [OK]\n(C2: N ГЕТЕРОГЕННЫХ кандидатов [Ф2])" as ROLE_TR
|
||
component "Editor [OK] БИЛИНГВАЛЬНЫЙ (флип D1→D30.1)\n(вход = черновик + ИСХОДНИК + CONFIRMED dst-констрейнты);\nдискурс-reflow-промпт (Ван Цуй) + репараграфизация 1:N;\nкандидат glm-5, свап→mistral/deepseek-pro (D38.1);\nверность → fidelity re-gate (D34.3, полигон) + omission-гард [Ф2, D38]; пилот-арм D13.1 = ПОДТВЕРЖДАЮЩИЙ" as ROLE_ED
|
||
component "Analyst: book brief [Ф2]" as ROLE_AN
|
||
component "Terminologist / автопопуляция\nглоссария [Ф1*/Ф2]\n(спот=локаль, рендер=облако — exp06)" as ROLE_TERM
|
||
component "Annotator: пре-пасс [Ф2]\n(speaker-ID, регистр, чэнъюй-маски)" as ROLE_ANN
|
||
component "Judge / Selector [Ф2]\n(билингвальный, судья-анкета MQM;\nsecond-opinion чужого семейства\nна эскалированных чанках)" as ROLE_JU
|
||
component "Line/Continuity Editor [Ф2+]" as ROLE_LE
|
||
}
|
||
|
||
package "QA-гейты (без LLM)" {
|
||
component "Intrinsic classify [OK]\n(refusal/CJK-echo ДО length, loop-детект)" as QA_CJK
|
||
component "Coverage / excision [OK, opt-in]\n(sent_cov + len_ratio, порт оракула)" as QA_COV
|
||
component "Глоссарный post-check [OK]\n(decl-aware, CONFIRMED-only;\nфлаггер по умолчанию, гейт opt-in)" as QA_GLOS
|
||
component "Output-санитайзер [OK, opt-in c1] (D30.3/D33)\n(ведущие преамбулы / хвостовые «Основные правки» —\ngemini-утечка 6/6 / латиница-врезки / markdown-###;\nCJK-Han-в-выходе — в стройке D38.1); flag+skip D2" as QA_SANITIZE
|
||
component "Дешёвые гейты Ф1 [Ф1*]:\nтире-линтер, ёфикатор,\nтранслит-междометия, число-гейт\n+ диалог-парность-флаггер (D29.1д) + omission-гард (D38)" as QA_CHEAP
|
||
component "Морфо-гейт рода + канцелярит\n+ T-index [Ф2] (Python-сайдкар)" as QA_MORPH
|
||
component "Валидатор Палладия/Поливанова B6 [Ф2]\n(ruby-reading = ground truth)" as QA_TRANSLIT
|
||
}
|
||
|
||
package "pkg/llm" {
|
||
component "Роутер роль -> модель [OK]" as LLM_RT
|
||
component "Capability-слой [OK]\n(budget_field/temperature/reasoning;\nэхо-мина DeepSeek fail-fast;\nper-model флор min_max_tokens 8000/kimi 16000, D24.3;\ngpt-5.4 reasoning=low в редакторе — medium режет вывод, D38.6)" as LLM_CAP
|
||
component "NSFW-классификатор 0-3 [Ф2]\n(НЕ специфицирован — нужна метрика приёмки;\nуровень 3 = скип чанка + флаг)" as LLM_NSFW
|
||
component "Failover [OK, НЕ подключён]\nтолько local->cloud для local-ролей (D4);\nоблачные draft/edit: пауза+resume, НЕ своп" as LLM_FO
|
||
component "Адаптеры OpenAI-совместимые [OK]:\nDeepSeek / GLM / Kimi / xAI / OpenAI / Mistral /\nllama-server; нативный Gemini [Ф2]" as LLM_AD
|
||
component "Кэш-раскладка префикса [OK]\n+ Batch (только Gemini-судья/QA) [Ф2]" as LLM_BC
|
||
}
|
||
|
||
package "Банк памяти книги (SQLite на книгу) [OK: v2]" {
|
||
component "Глоссарий v2 [OK]\n(sense, alias-граф, decl, gender=hidden,\ntranslit_policy, ревизии);\nсид v2 ПОДПИСАН владельцем (57 терминов, D34);\nstatus:draft НЕ инъектится в editor-констрейнт\n(CONFIRMED-only) — reseed промоут грейдов (корень терм-дрейфа, D38)" as MEM_GLOS
|
||
component "Горячий путь [OK]: Aho-Corasick,\nнормализация NFKC/trad2simp/kana/ignorables,\nспойлер-окна since/until (hard-reject),\ndisposition CONFIRMED/AMBIGUOUS/REJECT,\nsticky; фиксы границ D16 [OK]" as MEM_HOT
|
||
component "Ruby-захват [OK] -> сид auto-кандидатов;\nreading как матч-поверхность [Ф1*, D16.4]" as MEM_RUBY
|
||
component "retrieval_state per-chunk [OK]\n(наблюдаемость инъекции/вытеснений)" as MEM_RS
|
||
component "Резюме глава->арка->книга [Ф2]\n+ гейт фактичности резюме (реестр D1)" as MEM_SUM
|
||
component "Series bible: ты/вы-журнал, род [Ф2]" as MEM_SB
|
||
component "Векторный слой [Ф2, low-trust A7]\n(bge-m3, только кандидаты на ревью)" as MEM_VEC
|
||
}
|
||
|
||
package "Деньги и наблюдаемость [OK]" {
|
||
component "Ledger: reserve -> settle+checkpoint\nодной tx, потолки книга/день,\nescalation-бюджет" as OBS_LG
|
||
component "Премиум-бюджет: budget_usd =\nclamp(price x (1-margin) - base, 0, cap)\n(D11; жёсткие $-гейты сняты)" as OBS_QB
|
||
component "request_log + trace + retrieval_state" as OBS_TEL
|
||
}
|
||
|
||
package "Eval / Полигон (зона eval/)" {
|
||
component "Пилот-харнесс Ф2.5\n(BWS, memory-eval M0-M3, судья-панель;\nчинится до прогона — D13.5;\nблокеры: корпус вне претрейна, аннотаторы ≥3,\nбилингв-якорь, судья-дублёр 18+ — чистый ключ снят D27)" as EV_PILOT
|
||
component "Refusal/excision-бенчмарк [OK]\n(18+ эмпирика ПОЛНА: violence exp10 + erotica exp11;\nканал B v2 собран, D14.4 закрыт)" as EV_RB
|
||
component "Диагностик-харнесс качества\n(exp12→14b: нарезка×промпт, слепые читки,\nfidelity re-gate; трек «мерить→строить» D26–D38.1)" as EV_DIAG
|
||
}
|
||
|
||
cloud "LLM-провайдеры" {
|
||
component "DeepSeek V4: -flash = draft (thinking ON —\nэхо-мина; сохранён exp13/D32) · -pro = escalate-хоп\n(флор min_max_tokens 8000, D24.3);\nexplicit ЗАПРЕЩЁН ToS, violence OK (D14.1)" as P_DS
|
||
component "xAI Grok 4.3: эскалация канала B (reasoning-ON),\nпервичный судья эротики; НЕ редактор\n(reasoning-off из редакторских ролей снят = no-op, D30.1);\nключ единый С data-sharing, off перед продом (D27)" as P_XA
|
||
component "gemini-3.1-pro-preview (голый слаг→404):\nсудья SFW/violence, но fail-closed на эротике\n(PROHIBITED_CONTENT); премиум-эскалация редактора\nТОЛЬКО за санитайзером (D30.1); billing additive_total (D22.3)" as P_GM
|
||
component "GLM (glm-5 = ДЕФОЛТ билингв-редактор, D30.1) /\nKimi (НЕПРИГОДЕН как редактор — обрезки/таймауты) /\nOpenAI (GPT-5 фронтир-арм — в дефолт НЕ нужен, D38)" as P_OTH
|
||
component "Mistral — переводчик-ДЕФОЛТ канала B (18/18, D22.1);\nкандидат СМЕНЫ дефолт-редактора (чинит инверсии,\nкоторые glm валит, дешевле) — бейк-офф прозы (D38.1)" as P_MI
|
||
component "llama-server (GPU 8GB: скрининг,\nabliterated канала B, эмбеддинги,\nСПОТ-экстракция)" as P_LL
|
||
}
|
||
|
||
database "SQLite" as DB
|
||
|
||
CLI --> PROJ
|
||
API --> PROJ
|
||
PROJ --> IMP
|
||
IMP --> JOBS
|
||
JOBS --> RUNNER
|
||
RUNNER --> EXP
|
||
RUNNER --> ROLE_TR
|
||
RUNNER --> ROLE_ED
|
||
RUNNER --> ROLE_AN
|
||
RUNNER --> ROLE_TERM
|
||
RUNNER --> ROLE_ANN
|
||
RUNNER --> ROLE_JU
|
||
RUNNER --> ROLE_LE
|
||
RUNNER --> QA_CJK
|
||
RUNNER --> QA_COV
|
||
RUNNER --> QA_GLOS
|
||
RUNNER --> QA_SANITIZE
|
||
RUNNER --> QA_CHEAP
|
||
RUNNER --> QA_MORPH
|
||
RUNNER --> QA_TRANSLIT
|
||
|
||
ROLE_TR --> LLM_RT
|
||
ROLE_ED --> LLM_RT
|
||
ROLE_JU --> LLM_RT
|
||
ROLE_AN --> LLM_RT
|
||
ROLE_TERM --> LLM_RT
|
||
|
||
LLM_RT --> LLM_CAP
|
||
LLM_CAP --> LLM_AD
|
||
LLM_NSFW ..> LLM_RT : выбор канала A/B [Ф2]
|
||
LLM_FO ..> LLM_AD : только local-роли (D4)
|
||
LLM_BC ..> LLM_AD
|
||
LLM_AD --> P_DS
|
||
LLM_AD --> P_XA
|
||
LLM_AD --> P_GM
|
||
LLM_AD --> P_OTH
|
||
LLM_AD --> P_MI
|
||
LLM_AD --> P_LL
|
||
LLM_NSFW ..> P_LL : классификатор 0-3 [Ф2]
|
||
|
||
RUNNER --> MEM_HOT
|
||
MEM_HOT --> MEM_GLOS
|
||
MEM_HOT --> MEM_RS
|
||
IMP --> MEM_RUBY
|
||
MEM_RUBY --> MEM_GLOS
|
||
MEM_HOT ..> MEM_SUM : [Ф2]
|
||
MEM_HOT ..> MEM_SB : [Ф2]
|
||
MEM_HOT ..> MEM_VEC : [Ф2], не в горячем пути
|
||
|
||
HUMAN --> CLI : запуск, флип гейтов (за подписью)
|
||
HUMAN <-- EXP : отчёт, паспорт качества, флаги
|
||
HUMAN --> MEM_GLOS : подтверждение терминов auto->approved\n(безлюдный режим = осознанный риск G1/G2)
|
||
HUMAN <.. EV_PILOT : BWS-оценка (пилот Ф2.5)
|
||
HUMAN <.. EV_DIAG : слепая читка-арбитраж (2 претензии, интерим)
|
||
|
||
LLM_RT --> OBS_LG
|
||
OBS_LG --> OBS_QB
|
||
LLM_AD --> OBS_TEL
|
||
RUNNER --> OBS_TEL
|
||
|
||
JOBS --> DB
|
||
MEM_GLOS --> DB
|
||
MEM_RS --> DB
|
||
OBS_TEL --> DB
|
||
OBS_LG --> DB
|
||
|
||
EV_PILOT ..> OBS_TEL : golden-set реплей [Ф2]
|
||
EV_RB ..> LLM_NSFW : калибровка роутинга
|
||
|
||
note bottom of HUMAN
|
||
Петля человека — несущая опора safety
|
||
(все защиты кончаются флагом):
|
||
ёмкость G2 меряется пилотом (D13),
|
||
flag-rate/главу — первый замер.
|
||
end note
|
||
@enduml
|