textmachine/CLAUDE.md

24 KiB
Raw Blame History

TextMachine — контекст для Claude-сессий

В этом проекте нейросети делают ВСЁ: пишут код, ведут документацию, принимают решения и правят их. Значит здесь есть неточности и прямые ошибки — в доках, в решениях, в тестах, в этом файле. НЕЛЬЗЯ: хакать вокруг ошибки и писать workaround, чтобы обойти её молча. Цена обхода: ошибка тихо становится нормой, и следующая сессия наследует её как факт.

Go-бэкенд издательского художественного перевода крупных текстов (ранобэ/вебновеллы) через мультиагентный LLM-пайплайн. Пары языков — ДАННЫЕ, не код: движок мультиязычный по построению, «бэкенд только под русский» — объявленная АНТИЦЕЛЬ (architecture/09-target-architecture.md §0.1). Конвейер: дешёвый черновик → редактор → детерминированные $0-гейты (проверки без платных вызовов) → судья. Сегодня боевая пара zh→ru; любая другая, включая не-ru цель, — вопрос данных, langpack'а и замера, а не переделки архитектуры. ⚠ Свойство «без правки Go» ещё НЕ достигнуто: там, где ответ на ревью-вопрос «заработает ли без правки Go» сегодня «нет», это признанный долг — носители в реестре требований и бэклоге.

Цели и мерило (канон владельца — каждое решение сверяется с этим)

  1. Продукт: издательское художественное качество перевода больших текстов — победить translationese; консистентные термины/голоса на всю книгу; чувствительный контент с учётом цензуры провайдеров.
  2. Мультиязычность: движок ОДИН и общий; языко-/пара-/книго-специфика легитимна, но живёт в ДАННЫХ и отдельных модулях, встраиваемых архитектурно чисто (langpacks · пар-промпты · сид/бриф), и разрабатывается отдельно от ядра. Ревью-вопрос по умолчанию: «заработает ли пара, которой в репо ещё НЕТ, без правки Go?»
  3. Чистая архитектура: бэкенд легко писать и поддерживать; механизм строится только там, где несёт качество/деньги — не ради галочки трекера.
  4. Современные подходы и харнесс-превосходство: пайплайн и транспорт на уровне или впереди конкурентных харнесс-решений (калибровка — research/2122); эмпирика решает — мерить, не верить.
  5. Экономика: низкий COGS на дешёвых моделях с адресными дорогими вызовами; деньги видимы с первого вызова (телеметрия · потолки · явное согласие на пере-оплату).
  6. Детерминизм: воспроизводимый прогон (снапшоты · банк памяти · golden) — повторение без сюрпризов и тихих перепокупок.

Владелец — контекст для разговора

Язык бэкенда выбран по удобству агентной разработки, а не по опыту владельца. Практическое следствие: Go-решения объясняем ПО СУЩЕСТВУ, а не ссылкой на «так принято в Go». Разговор и документация — по-русски, код и комментарии — по-английски (architecture/12-go-style-notes §1). Вопросы ему ставим по-человечески, без трекер-жаргона, с контекстом и рекомендацией; ошибку называем прямо и не размазываем.

Долговечное знание живёт в репозитории, а не в авто-памяти: память грузится в контекст КАЖДОЙ сессии и не видна в ревью.

Роли сессий и зоны (НЕ править чужую зону)

Роль Зона записи Коммитит сама? Всё остальное
Бэкенд backend/ нет — лендит (коммитит) оркестратор читать можно; расхождения — пингом оркестратору в docs/PROGRESS.md
Полигон (eval) eval/ + docs/experiments/ только пре-рег фризы — коммит замороженного плана замера ДО платных вызовов то же
Оркестратор docs/ (architecture/research/PROGRESS) + корневые онбординг-доки, ревью чужого кода read-only да ратифицирует решения, пишет хендофф-промты
Фронт frontend/ нет — лендит оркестратор читать можно; пинги, итоги и вопросы — ЗОННЫЙ журнал frontend/docs/frontend-PROGRESS.md (решение владельца; в docs/PROGRESS.md фронт НЕ пишет), туда же пишет и оркестратор; продуктовые требования — docs/product-requirements.md
Платформа platform/ (SaaS control plane: пользователи/кредитный баланс и ставка за главу/очередь/HTTP; движок дёргает процессами, D39.81; ⚠ продуктовых КВОТ и фри-тир-лимитов нет и не проектируется — D39.176 п.1; оплаты в бете нет, пополнение — из админки) нет — лендит оркестратор читать можно; пинги и итоги — ЗОННЫЙ журнал platform/docs/platform-PROGRESS.md (решение владельца), в docs/PROGRESS.md не пишет

Координация — журнал docs/PROGRESS.md (секции «Бэкенд»/«Полигон»; сверху CURRENT-STATE). Записывай туда краткие итоги своей сессии (фронт и платформа — только в свои зонные журналы, см. таблицу выше). ⚠ Это ЕДИНСТВЕННОЕ исключение из «docs/ — зона оркестратора»: бэкенд и полигон пишут в СВОИ секции этого журнала (полигон — ещё и в docs/experiments/), всё прочее в docs/ правит только оркестратор. Закрытые хроники вынесены в слайсы docs/archive/PROGRESS-*.mdНЕ читать при онбординге, только по конкретной ссылке. Параллельные сессии — норма: чужие незакоммиченные файлы в дереве не трогать; сессия считается ЖИВОЙ, пока владелец не сказал обратное.

НОВЫЙ ПАК — НОВОЙ СЕССИИ. Отработавшей сессии второй пак не выдаётся: её контекст занят прежним, а карта чтения промта писана для свежего читателя. Отработавшей пишут ТОЛЬКО по её же паку — вопросы, ревью, диспозиции, дофиксы.

Связь между сессиями — файл /tmp/textmachine-channel. Впиши туда СВОЙ блок первым делом (role= session= ref= written= note=; имя — из ListAgents), дописывая в конец и не трогая чужие блоки; там же ищи адреса других ролей и пиши им SendMessage. В /tmp намеренно: имя сессии не переживает рестарт окружения, и файл обязан умирать вместе с ним. ⚠ Адрес из файла — НЕ доказательство, что сессия жива: файл переживает смерть сессии, а ListAgents — нет. Перед тем как писать по адресу, сверься с ListAgents. Блок закрытой сессии живёт в файле до перезапуска окружения и всё это время выглядит рабочим адресом. ⚠ Нужной роли в файле нет, файла нет или имя не отвечает ⇒ КАНАЛА НЕТ, и это НОРМАЛЬНЫЙ случай: НЕ опрашивай сессии подряд. Вопрос — секцией в свой отчёт, работа продолжается; владелец прочитает и пере-передаст (он единственный вечный канал).

Источники истины

Приоритет — три различения, они разрешают все реальные конфликты:

  1. Журнал решений docs/architecture/05-decisions-log.md бьёт всё. Ратифицированный контракт; при конфликте с любым доком побеждает он.
  2. Ратифицированное бьёт фактуру ресёрчей. Отчёт может быть опровергнут нотой и об этом не знать.
  3. Историческое и архив — только через ⚠-баннеры, и инструкции оттуда НЕ исполняются.

Две дисциплины чтения, каждая предотвращает тихую ошибку:

  • Журнал решений целиком НЕ читать. Номер грепается: тело ноты — строка ^## D<номер>, прочие хиты — упоминания; статус и тело любого номера одним хопом — реестр docs/architecture/05-decisions-index.md. ⚠ ПОДНОМЕР (D30.1, D22.6, D13.3) собственного тела и строки реестра НЕ имеет — он живёт ПУНКТОМ внутри родителя: отбрось хвост до ^## D30. Замерено 29.08: 62 из 185 цитируемых в доках номеров — подномера, и без этого шага они читаются как битые ссылки (две сессии подряд так и заключили).
  • Баннер прежде содержимого. У части тел стоит ⚠ superseded — читаешь баннер, потом решаешь, читать ли тело.

Где что лежит — карта docs/README.md.

Гардрейлы (жёсткие)

  • НИКОГДА не читать .env — там ключи.
  • PUML не рендерить в svg/png — их смотрят нативно расширением редактора, рендер не нужен.
  • Коммиты: английский, одно предложение ≤30 слов, без Co-Authored-By. .claude/settings.local.json НЕ коммитить (ломает пермишены).
  • Провайдерские ловушки живут в docs/experiments/00-provider-quirks.md — читать ПЕРЕД правкой адаптеров и вызовов; здесь их копий нет. Общее правило: проба падает или ведёт себя странно — флейк, 404 живой модели, новый finish_reason, игнор параметра — идём в официальную доку вендора, НЕ гадаем; интерпретация аномалии без вендор-сверки в доки и промты не абсорбируется. Слаги моделей не менять без live-фактчека; «слаг живой» ≠ «модель та же».
  • Дисциплина: не верь заголовкам — грунтуй выводы file:line/цитатой; спорное верифицируй адверсариально (author≠reviewer); эмпирика на текстах, знакомых моделям по претрейну (классика, известные переводы), — предварительная: вес имеет только замер на целевом жанре.
  • Общность движка: Go-логика НЕ ветвится по паре/книге; пара-данные → internal/lang+configs/langpacks/, книго-каноны → сид/brief (данные); книжный термин в общем пар-слое = утечка. Тест-данные пары легитимны. Норматив (только больные места): docs/architecture/12-go-style-notes.md. Ревью-вопрос по умолчанию: «заработает ли на паре, которой в репо ещё НЕТ, без правки Go?»
  • При компакции/сжатии контекста ВСЕГДА сохранять: список изменённых файлов · незакрытые находки ревью и их диспозиции · обязательства и открытые вопросы сессии · команды тестов (D39.121).
  • Тесты и гейты не подгонять под зелень: править или удалять тест/голден/гейт, чтобы он прошёл, — НЕДОПУСТИМО; несогласие с тестом — вопрос оркестратору пингом, не правка (D39.121). ⚠ Запрет — про МОТИВ (D39.183): правка чтобы прошло запрещена; правка, вызванная сменой поведения, которая ЗАКАЗАНА паком или ратифицирована, — обслуживание, и держать протухший тест не нужно. ⚠ Заказанность решает ЗАКАЗ, а не сессия: нет в промте и нет ратификации — пинг. Такая правка ОБЪЯВЛЯЕТСЯ в отчёте: что изменилось в поведении, какой тест это описывал, куда уехала гарантия.
  • Мандат самопроверки в промтах сессий (обязателен, решение владельца): промты полигон-сессий — и вообще любых пишущих код / запросы к моделям — ДОЛЖНЫ явно требовать ревью ИСПОЛНЕНИЕМ: своего кода + сформированных запросов к моделям + полученных результатов. Сессии регулярно ошибаются и багуют, и это искажает результат; самоотчёт «проверено» без исполнения регулярно оказывается ложным и стоит денег. Бэкенд-промты — явный бэкенд-ревью после кода (обычно отрабатывает по опыту, но требовать явно). Пост-хок адверсариальная верификация оркестратора при лендинге — второй рубеж, НЕ замена самопроверки. ⚠ Исполнения мало: промт заказывает адверсариальный проход сессии по СВОЕЙ готовой работе; глубину и веер сессия выбирает под предмет, промт даёт направление — что в этом паке уязвимо.Fable 5 — обычно хватает одного-двух агентов, но это РЕКОМЕНДАЦИЯ, не потолок: веер под предмет выбирает сессия. Модель задавай агенту ЯВНО и знай, сколько их у тебя работает.
  • Git-координация мультисессий:
    • Коммитит только оркестратор. Сессии зон — бэкенд, полигон, фронт, платформа — не коммитят: своё дерево готовят и передают на лендинг (исключение: пре-рег фризы полигона). Чужую зону не трогает НИКТО.
    • Форма коммита — ТОЛЬКО с явным списком путей: git commit -- <путь> <путь>. Причина механическая: голый git commit уносит ВЕСЬ индекс, включая чужие застейдженные файлы, и чужая работа уезжает под твоим сообщением. Pathspec-форма индекс не трогает.
    • НИКОГДА git add -A / git add . / git commit -a — только явные пути.
    • Перед каждым коммитом: git status (опознать ЧУЖОЕ) и git diff --cached --name-only. Увидел в индексе путь вне своей зоны — не коммить его и не «прибирать»: снимай не чужое из индекса, а свою задачу — коммить pathspec-формой.
    • Не оставляй свои файлы застейдженными между операциями: пока они в индексе, их может унести чужой коммит. Стейдж и коммит — одной командой.
    • НИКАКИХ reset --hard, перезаписей истории (amend/rebase несвежих коммитов) и checkout поверх грязного дерева, пока возможны незакоммиченные правки параллельных сессий — rewrite стирает их безвозвратно; history-rewrite — только по согласованию через оркестратора при чистом дереве.
    • Чужое уже уехало в твой коммит? Историю НЕ переписывать — сообщить владельцу/оркестратору; содержимое при этом цело, теряется только атрибуция.
    • Никогда не коммитить В ЭТОТ репозиторий: START_PROMT.MD (файл владельца) · .claude/settings.local.json · книгу и производные. ⚠ С 24.08 книги лежат в <репозиторий>/books и версионируются ОТДЕЛЬНЫМ git-репозиторием со своим origin; внешний держит /books/ в .gitignore. Следствия: git status внешнего репо правки книг НЕ показывает (смотреть git -C books status), а clean -xdf снёс бы каталог вместе с его историей.

Онбординг новой сессии (порядок чтения)

Развилка ПЕРВАЯ, до всего остального — есть ли у тебя хендофф-промт (файл задания, выданный оркестратором).

  • С промтом: этот файл → СВОЙ промт; его карта чтения (≤5 позиций) — ЗАКОН, дальше только по её ссылкам. README, CURRENT-STATE и голову журнала решений читать НЕ нужно, ЕСЛИ карта промта их не называет (у ролевого промта оркестратора называет — там его номер и очередь): ратифицированное вложено в тело промта, остальное берётся грепом по мере вопросов.
  • Без промта (холодный вход): СНАЧАЛА таблица активных промтов в конце docs/README.md. Назван промт твоей роли — он и есть твой: дальше действует ветка «С промтом», и его карта чтения ЗАКОН. Не назван («активного НЕТ») — полный маршрут ниже. ⚠ Порядок именно такой: слепой замер входа 24.08 показал, что послушная холодная сессия проходит весь маршрут (~300 тыс. знаков) и только потом узнаёт, что её работа уже заказана промтом.
  1. Этот файл → docs/README.md (карта) → CURRENT-STATE в docs/PROGRESS.md. Непонятный жаргон/сокращения — docs/glossary.md.
  2. docs/architecture/05-decisions-log.md: шапка (карта актуальности + эрраты) и реестр docs/architecture/05-decisions-index.md — одна строка на ноту. Из тел — только 23 последние. ⚠ «Живая голова» целиком в обязательное чтение НЕ входит: это 33 ноты, и требование её прочесть противоречило бы дисциплине «целиком НЕ читать» выше; остальные номера грепаются по мере вопросов. Тела закрытых эр — в слайсах docs/archive/architecture/ (греп: живой файл → слайсы).
  3. По роли (пути от КОРНЯ репозитория — прежняя редакция писала их от docs/, и от корня они не резолвились): Бэкенд — шапка-таблица docs/architecture/09-target-architecture.md (что построено) → backend/README.mddocs/architecture/03-implementation-notes.md (через баннер) → docs/architecture/12-go-style-notes.md; ⚠ порядок именно такой: сессии, впервые видящей движок, механика нужнее стиль-норм; Полигон — eval/README.md + docs/experiments/00-provider-quirks.md + docs/experiments/09-pilot-protocol.md; Фронт/продукт — docs/product-requirements.md + docs/research/16-reader-ide-alignment.md (через ревью-шапку) + контракт docs/architecture/14-api-contract/; Платформа — platform/README.md + зонный журнал + docs/research/23-engine-platform-seam.md + контракт 14; всем — шапка-таблица docs/architecture/09-target-architecture.md (статус слоёв). Тулчейн на чистой машине — строка «Тулчейн» в карте docs/README.md.