textmachine/platform
2026-08-02 15:14:13 +03:00
..
BACKLOG.md Ratify D39.85: industry-standard engine-platform seam recorded in research 23, event stream plus materialization plus artifacts, anti-patterns banned, emitter row opened 2026-08-02 03:38:35 +03:00
go.mod Ratify D39.84: frontend and platform stacks pinned, eight owner decisions recorded, zone backlogs split out, four engine work rows opened, translation never indexable 2026-08-02 03:04:23 +03:00
README.md Ratify D39.88: zone sessions commit their own zone only, never others, with pathspec commit protocol written into root guardrails, frontend prompt and platform readme 2026-08-02 15:14:13 +03:00

platform — control plane (SaaS-слой)

Зона записи новой сессии «Платформа». Пусто: заведено под будущий сервис, кода ещё нет.

⚠ Коммит-права и git-протокол (решение владельца 02.08, D39.88 — читать ДО первого коммита)

Право коммита у платформенной сессии ЕСТЬ — но ровно на свою зону: «свою часть коммить, чужую не трогать НИКОГДА». Канон — ../CLAUDE.md, §Гардрейлы; сюда вынесено, потому что отдельного промта платформы ещё нет, а правило нужно ДО первой строки кода.

  1. Коммить только пути внутри platform/. Ничего за её пределами — ни docs/, ни backend/, ни frontend/, ни корневых файлов. Нужна правка вне зоны — пинг владельцу, её сделает оркестратор.
  2. Форма коммита — ТОЛЬКО с явным списком путей: git commit -- platform/<файл>. Механика, не стилистика: голый git commit уносит ВЕСЬ индекс, включая чужие застейдженные файлы, и чужая работа уезжает под твоим сообщением (02.08 это случилось дважды — e9a6bb2, b98afb5).
  3. НИКОГДА git add -A, git add ., git commit -a.
  4. Перед каждым коммитом: git statusgit diff --cached --name-only; чужой путь в индексе не «прибирать», а обойти pathspec-формой.
  5. Свои файлы не держать застейдженными между шагами — стейдж и коммит одной командой.
  6. НИКАКИХ reset --hard, amend/rebase несвежих коммитов, перезаписи истории; чужие незакоммиченные файлы не трогать.
  7. Чужое уехало в твой коммит — историю НЕ переписывать, сообщить владельцу.
  8. ⚠ Ревью-гард модулей (D39.85): путь Go-модуля платформы никогда не вкладывать под путь движка — иначе он получит доступ к backend/internal/* по правилу префикса.

Что здесь будет

Сервис между фронтом и движком перевода. Всё, что относится к ПОЛЬЗОВАТЕЛЯМ и не относится к переводу:

  • аутентификация и аккаунты (подписки и оплата — ПОСЛЕ MVP, решение владельца 02.08: в MVP оплаты нет и денежных полей в интерфейсе нет);
  • библиотека книг: чья книга, права доступа, хранение исходников и экспортов;
  • учёт токенов и денег на пользователя (сырьё уже считает движок: request_log + internal/ledger), потолки и гейт бюджета ДО старта задачи;
  • очередь задач и запуск воркеров, статусы прогонов, ретраи;
  • SSE-поток прогресса и живой стоимости во фронт.

Чего здесь НЕ будет

Перевода. Движок (../backend/) остаётся как есть: один процесс на книгу, свой SQLite под эксклюзивным flock (store.Open — «один процесс владеет файлом проекта»). Платформа его ЗАПУСКАЕТ как воркер, а не поглощает. Причина та же, по которой движок не ветвится по паре языков: пользователи и квоты ничего не меняют в проводе запроса, значит им нечего делать в кодовой базе, где каждый байт свёрнут в снапшот-хеш.

Известное требование к движку (не забыть)

Глобальный брокер конкурентности. pipeline/ratelimit.go строит рейт-гарды НА ПРОГОН, а лимит провайдера — на весь аккаунт. N параллельных пользователей = N независимых гардов против общего лимита (в комментарии там зафиксировано: mistral валит ~48% вызовов под параллелизмом). Воркер должен отпрашиваться у платформы перед вызовом. Это единственная по-настоящему новая механика на стыке.

Стек

Пины и обоснования — ../frontend/docs/STACK_DECISIONS.md §5 (общий документ решений по обоим новым сервисам; исследование 02.08).

Коротко: Go 1.26.4 · стандартный net/http + ServeMux без роутер-библиотеки · pgx v5.10.0 · goose v3.27.3 · очередь River v0.42.0 на том же Postgres · govulncheck гейтом CI. Redis не заводим нигде — зафиксировано как архитектурное «нет».

Прогресс наружу — SSE, события пушит воркер, а не фронт опрашивает read-model. Аутентификация — одна серверная сессия в Postgres, два способа предъявления: __Host-кука для браузера и Authorization: Bearer для десктопа и CLI; эндпоинты про куки не знают ничего.