textmachine/docs/architecture/02-mvp-plan.md

20 KiB
Raw Blame History

План MVP (v3.2, 2026-07-12)

⚠ ПОПРАВКА 22.08 (оркестратор №18, аудит доков): ФАЗОВАЯ РАМКА КАК ПОСЛЕДОВАТЕЛЬНОСТЬ МЕРТВА, и это несущая поправка — тело ниже держит HTTP API+SSE и IDE-фронт в «Фазе 3, после MVP», хотя обе работы ПОСТРОЕНЫ и приняты (платформа — D39.100…D39.154, фронт — S0S4, D39.135), а Фазы 1 и 2 не закрыты. Читать раздел как перечень ПРЕДМЕТОВ, а не как порядок: что построено — шапка-таблица 09-target-architecture.md, что делается сейчас — CURRENT-STATE в ../PROGRESS.md.

СТАТУС-АПДЕЙТ 25.07 (оркестратор №7): точка-во-времени v3.2 (12.07) исполнена, курс ушёл дальше через арх-ресет D39. Ф0 , Ф1-инфра ; из «Осталось до приёмки Фазы 1» построено — D39.2 (границы доверия памяти D16) · D15.3 (tmctl status+redrive) · D30.3 (санитайзер) · D38.3/D39.5 (tmctl export, D29.1) · D39.10/D39.14/D39.17 (автопопуляция G1 Go-майнером; предложение реестра superseded). Пере-прогон 25 глав исполнен и прочитан (D39.20), планка ≤2 НЕ пройдена, эксп закрыт владельцем (D39.22) ⇒ этап B и пилот Ф2.5 НЕ открыты; редактор = deepseek-v4-pro ИНТЕРИМ (glm-5 резерв, mistral вон), не grok. Интерим-18+ ниже читать через D39.25 (в движке НЕТ понятия «18+»: content-labels × provider-capabilities; канал B вживую = пак-17). Актуальный курс — CURRENT-STATE в ../PROGRESS.md + голова D-лога; правило «при конфликте побеждает D-лог» в силе.

Цель MVP (бриф, п. 24): бэкенд переводит целую книгу целиком — консистентно, дёшево, с учётом стоимости. Интерфейс — CLI; HTTP API закладываем как тонкий слой (Фаза 3), IDE-фронт — после бэкенда. История редакций v2→v3.2 — в git и в нотах, которые её вызвали (D1D17, D18/D24/D25, D26D31). При конфликте этого плана с D-логом — источник истины D-лог.

Дорожка данных (параллельно всем фазам, владелец + сессия «Полигон»)

Лицензионные издания для золотого набора, выравнивание, глоссарии, отбор 2535 глав пилота, refusal-корпус (вкл. explicit-фрагменты — гейтят 18+ руку), замеры токенизации. Чекпоинт (новый, гейтит валидность эмпирики): 35 глав реальных вебновелл zh/ja вне претрейна — довалидация r-коэффициентов (exp01/08), precision гейтов на терсных репликах (exp07), частота эха вне классики. Вся текущая эмпирика снята на PD-классике из претрейна — до вебновелл-среза пороги считаются предварительными.

Фаза 0 — Каркас. ЗАВЕРШЕНА (04.07, приёмка на живых ключах)

Порт ядра vojo (llm/ledger/obs/store), SQLite + идемпотентные миграции, durable jobs + чанк-чекпоинты, translation brief + brief_hash, YAML-конфиги C1/C2 (граница «конфиг vs код» Р2). Приёмочный инвариант денег — committed == SUM(checkpoints); резюмируемость и «≤1 вызов» перечислены в приёмке Фазы 1 ниже.

Фаза 1 — Перевод целой книги (текущая; машинерия в основном построена)

Построено (журнал: вехи 12.5, шаги 3a4 — с ревизии D31 в ../archive/PROGRESS-2026-07-04-10.md): capability-слой (D3.1) + эхо-мина-гейт DeepSeek; runner-цикл по главам/чанкам + disposition skip/flag/continue (D2, 12 flag_reasons); coverage-гейт (порт Python-оракула, opt-in, precision 0/57 — exp07); single-hop эскалация с ре-гейтом и бюджетом (D12); чанкер v4 + импорт txt/epub + ruby-захват (D9); банк памяти v2 (нормализация, Aho-Corasick, спойлер-окна, трёхсторонний disposition, decl-aware post-check-флаггер, ruby-сид); монолингвальный редактор с dst-констрейнтами глоссария (D1) (→ флипнут D30.1: БИЛИНГВ, реализация в пакете D15.2 этап А); snapshotID покрывает память/context-assembly/capability (F1/D5.2/D8).

Осталось до приёмки Фазы 1:

  • ПОСТРОЕНО (адрес — шапка-таблица 09-target-architecture.md): границы доверия памяти D16 (D39.2) · tmctl status+redrive (D15.3) · дешёвые гейты 04-unhappy §6/§9 (checks.cheapgates, v2 — D20.4) · output-санитайзер D30.3 (checks/sanitizer.go) · автопопуляция G1 — Go-майнером (internal/miner, D39.10/D39.14/D39.17), а не спот-локалью из exp06. Живой остаток: диалог-флаггер парности (D29.1д) — в internal/checks его нет; чек-лист ja-книги — kana-написания сид-имён вносить aliases руками (D16.4).
  • Реальный прогон end-to-end приёмочной книги 蛊真人 zh→ru (D18; ja→ru понижен до второго прогона при появлении ja-epub). (этап A 10.07 — D24; этап B НЕ открыт: пере-прогон исполнен, планка не пройдена — шапка, D39.20/D39.22.)
  • Режим онгоинга (add-chapters) — сдвинут в Фазу 1.5: гейтится resume-экономикой (D15.2 — content-addressed reuse чекпоинтов или селективный redrive; спека в Фазе 1, реализация Ф1.5). До этого онгоинг не продаётся.
  • Экспорт txt/epub + отчёт (D29.1): ПОСТРОЕНО ЦЕЛИКОМ, включая выдачу ФАЙЛОМ — ⚠ испр. 10.09: прежний текст говорил только про «ассемблер-часть» и был верен до D39.175. Ассемблер: tmctl export + checks.ExportNormalize + паспорт-rollup (pipeline.ChapterPassport). Сборка книги в файл: пакет backend/internal/bookfile/ (container.go · epub.go · model.go · txt.go), сшивка backend/internal/pipeline/bookbuild.go, глагол backend/cmd/tmctl/main.go, греп case "build" (D39.175 — движковая половина, D39.194 — платформенная дверь: EPUB платного перевода выдан живьём). НЕ построено (греп по backend/, platform/, frontend/ — 0 хитов): annotations.json, политика красных, цвет-мап+GREY, human_override LOCK; плюс release-state лестница D25.1 — ЗАКРЫТА владельцем 05.09 (D39.205): копия БЕЗ пометки = книга БЕЗ ЕДИНОГО ПРОПУСКА, гранулярность — ЮНИТ. Открытого на владельце здесь НЕТ. ⚠ испр. 05.09: reader-facing артефакт УЖЕ ЕСТЬ (EPUB настоящего платного перевода выдан через API 04.09, D39.194). ⚠ Испр. 10.09: хвост про «открытый вопрос владельца ЗДЕСЬ И СЕЙЧАС» СНЯТ — он пересказывал вопрос, который закрыт D39.205 п.1 («ступень одна — книга без единого пропуска»), что говорит и первая половина этой же строки, и docs/product-requirements.md («Открытого на владельце по ПТ-44 НЕТ»). Вторая половина хвоста («что печатать на титуле») пуста по построению: титульной СТРАНИЦЫ в EPUB нет, уведомление едет в первый документ spine, а слова — ДАННЫЕ (backend/configs/langpacks/ru/reader.txt, ключи notice.holes/notice.ghost).

Правило 18+: приёмочный корпус — только SFW. Маршрутизация чувствительного контента — не «канал B» фиксированным составом (состав D19.1/D22 отставлен паком-17: D39.25/D39.26D39.28, шапка 09-target-architecture.md), а content_labels × accepts_labels. Живые ограничения данных: DeepSeek для explicit ЗАПРЕЩЁН его ToS (D14.1); ⚠ эскалация на grok reasoning-ON НЕ снимает эхо на архаичном плотно-ханьском (D22.5); эротику судит только Grok — Gemini fail-closed PROHIBITED_CONTENT (D22.6); OpenAI в explicit-роутинг не включать; refusal-blacklist-гейт перед коммитом в TM обязателен (ветка content_filter мертва у OpenAI-совместимых — exp07; у Gemini 3.x жива составной строкой — D21.9). L3-скрин обязателен до первой erotica-книги в проде (D22.7 + D25.4).

Приёмка Фазы 1 (v3.1, по D11/D10/D1.1/D18/D24):

  1. SFW-книга 蛊真人 zh→ru (D18) end-to-end этапами с чекпоинтами владельца (этап A 25 глав D24; этап B ~300 глав) с резюмируемостью; kill -9 → потеря максимум одного вызова. (ja→ru том — второй прогон при появлении ja-epub.)
  2. Деньги: телеметрия точна (ledger корректно биллит reasoning/cache-поля по квиркам провайдеров), эскалация уважает конфигурируемый budget_usd; мягкий sanity-якорь ~$0.7/ранобэ (до-флиповый exp08; после D30.1 ~$0.85 — D30.4; пере-съём exp08 v3). Жёсткие пороги $0.6/$5 сняты (D11).
  3. Глоссарная консистентность всех approved-терминов ≥98% по процедуре Р7/D10 (names-only — под-метрика). ⚠ Гейт меряет самосогласованность, НЕ конформность Палладию/Поливанову (B6 — Фаза 2; ruby-reading уже даёт ground-truth для ja — валидатор желателен раньше, см. 07-ревью).
  4. Coverage-гейт ловит ≥90% искусственных пропусков на мини-наборе; ноль молчаливых потерь глав (spine-reconciliation).
  5. Честная оговорка (D1.1): приёмка Фазы 1 НЕ содержит критерия верности — same-length mistranslation до билингвального судьи Фазы 2 не контролирует ничто. Не маскировать coverage-гейтом.

Фаза 2 — Качество: судья, NSFW, гейты второй очереди

⚠ v3: фаза перегружена (~25 механизмов из 04-unhappy + net-new) — при старте пересмотреть горизонт и порезать на вехи; ниже состав по приоритету.

  • Judge-роль (билингвальный, судья-анкета узких вопросов с MQM-весами — паттерн LiTransProQA/DITING, НЕ холистический скор; словарь тегов ошибок в request_log с первого дня фазы), C2/C3 как конфиги (C2 — только гетерогенные кандидаты, D13.2); second-opinion судья чужого семейства на Gemini-эскалированных чанках (self-preference).
  • Пре-пасс Annotator (04-unhappy «Следствия» п.1: speaker-ID, регистровый трекер, чэнъюй-маски — питает 8+ режимов отказа; в v2-плане отсутствовал — внесён).
  • Чувствительный контент: механизм построен паком-17 (content-labels × accepts_labels, D39.25/D39.26D39.28) — чанк-классификатор 03 и «каналы A/B» упразднены. Остаётся в Ф2: детектор молчаливых вырезаний, refusal-мониторинг.
  • Интеграция llama-server (скрининг, abliterated канала B, эмбеддинги bge-m3 — второй эшелон, low-trust A7).
  • Python-сайдкар качества: CometKiwi (валидировать на ru-литературе до доверия) + морфо-гейт рода (жалоба №1 читателей; pymorphy, вкл. глагол прош. вр. — C3 реестра) + гейт ты/вы по series-bible-lite + канцелярит-чеклист Галь; кандидат: T-index как офлайн-метрика translationese (готовое решение, 0.5B — влезает в стенд).
  • B6: валидатор Палладия/Поливанова — ПОСТРОЕНА ТОЛЬКО ПАЛЛАДИЙ-ПОЛОВИНА (⚠ испр. 02.09). Поливанов-валидатора в коде НЕТ: его таблицы = данные ja-пары, которых в репо нет (ruby-reading — их ground-truth). Грепы обеих половин — 06-memory-risk-registry.md, абзац «Гейты … ИСПОЛНЕНЫ»; улика долга — 13-tech-debt-anchors.md, греп Поливанов-валидатор.
  • Резюме глава→арка→книга + гейт фактичности резюме (D1 реестра — у резюме нет post-check-аналога). Ты/вы-журнал ПОСТРОЕН — address_pairs (D7-Amendment-1/D21 п.2), speech deprecated D39.55.
  • Batch API (50% только Gemini-судье/QA — exp08), нативный Gemini-адаптер (safety-контроль судьи, rf-замер), стриминг keep-alive.
  • Eval-харнесс (golden-set реплей, свип порогов); регрессионный сьют из чек-листа «особо опасных ошибок» (12-common-failures §16: отрицание, перепутанный субъект, внутренняя речь→прямая).

Приёмка: 18+ книга проходит пайплайн без молчаливых потерь (детектор + refusal-бенчмарк на explicit-корпусе); гейт рода/ты-вы работает; C2/C3 запускаются конфигом.

Фаза 2.5 — Пилот 4 рук (решающая точка)

Протокол: experiments/09-pilot-protocol.md + обязательные поправки D13 (шесть пунктов, тело — слайс ../archive/architecture/05-decisions-D1-D38.md, греп ^## D13; полигон вносит их в док и харнесс ДО пре-регистрации). Решения пилота: ядро C0C3, go/no-go ставки памяти (банк vs длинный контекст + adversarial-рука), валидность LLM-судьи (κ vs IAA, s*), think-ON/OFF (вкл. grok после reasoning-буфера в EstimateUSD), D1 моно-vs-билингв (→ D30.1: решён досрочно exp12, арм остаётся ПОДТВЕРЖДАЮЩИМ), Annotator A/B, flag-rate G2 (первый замер сделан этапом A: 5.3% — D24; в пилоте — minutes/flag, D25.6). 23 главы 18+ в корпусе — замер отказов по ролям (вкл. пробу Mistral, D14.2). Побочная ценность: человеческие BWS-данные zh/ja→ru — уникальный актив (академия пары не покрывает, WMT-лит. трек мёртв с 2024).

Фаза 3 — Продуктовизация (после MVP)

HTTP API + SSE для IDE-фронта — ПОСТРОЕНЫ и приняты вне фазовой рамки (platform/internal/httpapi/stream.go, D39.100…D39.154; фронт S0S4, D39.135), см. ⚠-поправку в шапке; выравнивание Bertalign (параллельное чтение, полноценный импорт reference-переводов прошлых томов); TMX/TBX; биллинг Stripe/Paddle (EU-SaaS, $/€; BYOK/ЮKassa отменены — Р5/Р8); batch-планировщик внепиковых окон DeepSeek; кандидаты из Р2: консультант поп-культуры, tool-calling, webfetch культурного контекста; «судья-над-судьёй» — редкий фронтир-аудит отчёта книги (идея владельца V3.3, ратифицирована как кандидат).

Вне скоупа MVP

IDE-фронтенд (закладываем только API), B2B white-label, дистилляция своей 714B модели (логируем long-CoT синтетику — рецепт DRT/LitMT; в 2026 линия дозрела до «14B ≈ Sonnet на литпереводе» — стратегический бэклог снижения editor-затрат), ru→en направление, автоматическая публикация куда-либо (Р8). Переписывание бэкенда на другой язык — закрыто до пост-пилота (решение владельца 09.07; нужен конкретный триггер, где Go упирается).

Метрики успеха MVP (v3)

Деньги (sanity-якоря ~$0.7/ранобэ, ~$11/вебновелла-500, селективный премиум ≤$25 — exp08; жёсткие $-гейты сняты D11) · глоссарная консистентность ≥98% · ноль молчаливых потерь · резюмируемость с потерей ≤1 вызова — те же критерии, что «Приёмка Фазы 1» выше, здесь не дублируются. Сверх них:

  1. Качество: статистически значимый win rate >50% (биномиальный тест, α=0.05, ≥150 человеческих попарных сравнений, пре-регистрация MDE — D13.4) против baseline «DeepSeek+селективный глоссарий» (уровень VseGPT).
  2. Чувствительный контент: explicit-корпус проходит пайплайн без молчаливых вырезаний, подтверждено детектором. ⚠ испр. 02.09: прежняя формулировка «канал B (Grok + abliterated, интерим D14)» СНЯТА — в движке нет понятия «18+» и нет фиксированного состава канала, маршрут = content_labels × accepts_labels (D39.25/D39.26D39.28; живые ограничения данных — «Правило 18+» выше).