Actualise the docs zone: archive two executed prompts with outcome banners, unstale the prompt map and the live backend prompt, and stop the canon companion calling itself a draft

This commit is contained in:
heaven 2026-08-08 02:59:40 +03:00
parent 7166dc4f18
commit 3b62b0650a
6 changed files with 461 additions and 6 deletions

View file

@ -1,6 +1,6 @@
# Промт бэкенд-сессии: ФИКС-ПАК БАНКА «КЛАСТЕРЫ + НАБЛЮДАЕМОСТЬ» (строка 128, + хвост 129)
**Выдан 04.08.2026, оркестратор №13, по санкции владельца 04.08 (зафиксирована D39.103 п.1; гейт строки 128 снят) и D39.102.** Ты — бэкенд-сессия. Зона записи: `backend/` (код+тесты+puml тем же коммитом-пакетом) + отчёт `docs/archive/reports/BANK_CLUSTER_FIXPACK_2026-08-XX.md` + пинг в `docs/PROGRESS.md` секция «Бэкенд». **НЕ коммитишь** — дерево готовишь, лендит оркестратор. ⚠ В дереве живёт ЧУЖОЕ: `platform/*` (модифицированный и новый, ждёт приёмки P0) — не трогать и не «прибирать». **Деньги: $0 — платных вызовов НЕТ вообще**; тесты и голден локально. Перекупка бэнк-батчей случится на следующем живом прогоне — в пак не входит, её цену только НАЗВАТЬ в отчёте.
**Выдан 04.08.2026, оркестратор №13, по санкции владельца 04.08 (зафиксирована D39.103 п.1; гейт строки 128 снят) и D39.102.** Ты — бэкенд-сессия. Зона записи: `backend/` (код+тесты+puml тем же коммитом-пакетом) + отчёт `docs/archive/reports/BANK_CLUSTER_FIXPACK_2026-08-XX.md` + пинг в `docs/PROGRESS.md` секция «Бэкенд». **НЕ коммитишь** — дерево готовишь, лендит оркестратор. ⚠ **Состояние дерева сверь `git status` В НАЧАЛЕ сессии — этот абзац устаревает быстрее промта.** На 08.08: платформа принята и залендена целиком (D39.109/D39.114), фронт S3 принят (D39.115), а ЖИВАЯ параллельная работа — полигон эксп-21: `eval/`, `docs/experiments/21-role-topology.md` и секция «Полигон» в `docs/PROGRESS.md`. Чужого не трогать и не «прибирать»: 08.08 такая правка стоила семи файлов (D39.113). **Деньги: $0 — платных вызовов НЕТ вообще**; тесты и голден локально. Перекупка бэнк-батчей случится на следующем живом прогоне — в пак не входит, её цену только НАЗВАТЬ в отчёте.
**Первый деливерабл — эхо-блок ≤10 строк** (как понял скоуп · четыре работы + хвост · инварианты · что вне скоупа; подтверждения не жди).
@ -34,4 +34,4 @@
## §4. Самопроверка и СТОП
Гардрейлы, задеваемые работами: **`backend/.env` НЕ читать** · **PUML не рендерить в svg/png** (владелец смотрит расширением). Мандат 12.07: ревью ИСПОЛНЕНИЕМ своего кода + явный бэкенд-ревью после кода. Вся батарея (`go build ./... && go vet ./... && go test ./...`) зелёная; archguard-тесты не трогать. Отчёт: что сделано по каждой работе с `file:line` · девиации от этого промта с причинами · фолд-предъявление §3 · чего НЕ сделал и почему · **план верификации эффекта на следующем ХОЛОДНОМ прогоне** (D39.103 п.1; что и как смотреть — назвать конкретно). Пинг в PROGRESS «Бэкенд» кратко. **СТОП — приёмка оркестратора** (адверсариальная, клеймы пере-проверяются исполнением).
Гардрейлы, задеваемые работами: **`backend/.env` НЕ читать** · **PUML не рендерить в svg/png** (владелец смотрит расширением). Мандат 12.07: ревью ИСПОЛНЕНИЕМ своего кода + явный бэкенд-ревью после кода. Вся батарея (`go build ./... && go vet ./... && go test ./...`) зелёная; archguard-тесты не трогать. Отчёт: что сделано по каждой работе с `file:line` · девиации от этого промта с причинами · фолд-предъявление §3 · чего НЕ сделал и почему · **план верификации эффекта на следующем ХОЛОДНОМ прогоне** (D39.103 п.1; что и как смотреть — назвать конкретно). Пинг в PROGRESS «Бэкенд» кратко.**Протокол правки этого файла (куплен инцидентом D39.113):** ТОЛЬКО append в свою секцию «Бэкенд»; CURRENT-STATE и чужие секции не касаться; `git status` до и после. Если файл модифицирован чужой сессией — пинг в ОТЧЁТ, вливает оркестратор. **СТОП — приёмка оркестратора** (адверсариальная, клеймы пере-проверяются исполнением).

View file

@ -24,7 +24,12 @@
## Задачи (по приоритету)
### 1. Сид-обогащение 蛊真人 — ГЕЙТИТ ЭТАП B (D24.4)
### 1. Сид-обогащение — ⚠ ИСПОЛНЕНО (D32), НЕ ИСПОЛНЯТЬ ЗАНОВО
> Влито в `guzhenren-seed-v2.yaml`; императив ниже относится к МЁРТВОМУ `guzhenren-seed.yaml` v1 и
> оставлен как история. Правка v1 = работа впустую плюс смена content-hash памяти и лишний resnapshot.
#### Историческое тело 蛊真人 — ГЕЙТИТ ЭТАП B (D24.4)
- Пройти все 49 записей `guzhenren-seed.yaml`: дописать **мн.ч. (все падежи мн.ч., где термин счётный)** в `decl.forms` — этап A дал 18 ложных промахов класса inflection_gap (元石→«первокамней/первокамни/первокамнями», 凡人→«смертных/смертными», 蛊师→«гу-мастеров»). Именительный ед.ч. дублировать НЕ нужно (код с пакета №5 всегда проверяет базовый dst — D24.4).
- Не менять dst/статусы/окна (白凝冰 gender=hidden — не трогать, D19.3). Изменение сида = memory content-hash (D8) → resnapshot: координируется оркестратором ВМЕСТЕ с лендингом бэкенд-пакета №5 — один resnapshot на всё.

View file

@ -2,7 +2,7 @@
Проект: издательский художественный перевод крупных текстов (книги, ранобэ, вебновеллы; zh/ja/en→ru) мультиагентным пайплайном поверх LLM API. Go-бэкенд + веб-фронт ридер-IDE (Ф3) + платформа (SaaS control plane, `platform/`, D39.81). Цели и мерило — канон в [../CLAUDE.md](../CLAUDE.md); онбординг сессий — там же. Стартовый бриф владельца: [../START_PROMT.MD](../START_PROMT.MD) — **живой документ**, его V-идеи разобраны в реестр требований (ниже).
**Состояние проекта НЕ здесь.** Очередь, курс, бэклог — CURRENT-STATE в шапке [PROGRESS.md](PROGRESS.md); решения — [architecture/05-decisions-log.md](architecture/05-decisions-log.md) (при конфликте с любым доком побеждает он). Эта страница — только карта «что где лежит».
**Состояние проекта НЕ здесь** — кроме одной строки ниже, и это осознанное исключение: строка «активные промты» отвечает на вопрос «какой файл мой», без которого холодная сессия выбирает роль сама (нашёл слепой онбординг-замер 08.08). Всё остальное состояние — Очередь, курс, бэклог — CURRENT-STATE в шапке [PROGRESS.md](PROGRESS.md); решения — [architecture/05-decisions-log.md](architecture/05-decisions-log.md) (при конфликте с любым доком побеждает он). Эта страница — только карта «что где лежит».
## Карта
@ -16,7 +16,7 @@
- `research/` — фактура ресёрчей 0125; у принятых — ревью-шапки, часть тел под ⚠ superseded: **читай баннер прежде содержимого**. Ключевые для навигации: 15 голос · 16 ридер-IDE · 17 внешняя критика · 18 рычаги качества · 19 нарезка · 20 банк-майнинг · 21 обзор транспорта · 22 доменные харнессы · 23 шов движок↔платформа (транспорт superseded D39.106) · 25 холодное ревью шва — форма D39.106, отвергнутые альтернативы, требования к эмиттеру (читать перед любым кодом стыка) · 24 арбитраж банка (ПРИНЯТ D39.102: консилиум закрыт классом, вход фикс-пака банка — §G).
- [PROGRESS.md](PROGRESS.md) — журнал: CURRENT-STATE + **ЕДИНЫЙ БЭКЛОГ** (единственный трекер) + живой хвост хроники. НЕ источник решений.
- `scripts/counts.py`**производные числа доков считаются им, а не руками** (голова по трём носителям · счёт очереди и зон · вес открытых строк регистра платформы); `--check` даёт ненулевой код на расхождении. Его же зовёт зонный хук `scripts/githooks/pre-commit` при коммите, задевающем D-лог или PROGRESS — предупреждает, не блокирует. Заведено по D39.112 п.5б: голова отставала трижды у трёх разных оркестраторов.
- Активные хендофф-промты сессий (состав обновляется при каждом лендинге — норма D39.80): [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояния не дублирует) · [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md) (полигон, отложен) · **платформа: [../platform/docs/PLATFORM_SESSION_PROMPT.md](../platform/docs/PLATFORM_SESSION_PROMPT.md) — ОТРАБОТАН (P0 ПРИНЯТ D39.107; P1+P2 ПРИНЯТЫ и залендены D39.109, регистр до PD-107); следующий промт платформы — по слову владельца (реконсилятор/тейлер/юниты, D39.107 п.3(3))** · фронт: `frontend/docs/S3_SESSION_PROMPT.md` (замок ОТКРЫТ — контракт ратифицирован D39.99; первый шаг — правки спеки: D39.100 + **новые В-трис/В-кватер от №15, D39.110** — управляемый потолок в главах и запрет проектировать кросс-origin, CORS в платформе нет). Зонные журналы фронта/платформы — `frontend-PROGRESS.md` / `platform-PROGRESS.md` в их зонах (решение владельца 04.08: прогресс зон только там). **Бэкенд: [BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md](BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md)** (фикс-пак банка, строка 128+129; санкция D39.103) · **Полигон: [POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT.md](POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT.md)** (эксп-21 «топология ролей»: скрин моделей → бейк-офф топологий на невиданном срезе; потолки предварительные, ЗАПУСК = слово владельца; D39.108). Очередь и состояние — только CURRENT-STATE.
- Активные хендофф-промты сессий (состав обновляется при каждом лендинге — норма D39.80): [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояния не дублирует) · [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md) (полигон, отложен) · **платформа: ОТРАБОТАН ЦЕЛИКОМ** — четыре сессии (P0 D39.107 · P1+P2 D39.109 · фикс-пак P3 D39.114); текст в архиве, [`archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md`](archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md), копия с баннером ещё лежит в зоне. Следующий промт платформы — по слову владельца (реконсилятор/тейлер/юниты, D39.107 п.3(3)) · **фронт: S3 ОТРАБОТАН и ПРИНЯТ D39.115** (контракт 0.2.0 в каноне, копии байт-равны, слой данных построен); текст в архиве, [`archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md`](archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md). Промт S4 — по слову владельца. Зонные журналы фронта/платформы — `frontend-PROGRESS.md` / `platform-PROGRESS.md` в их зонах (решение владельца 04.08: прогресс зон только там). **Бэкенд: [BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md](BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT.md)** (фикс-пак банка, строка 128+129; санкция D39.103) · **Полигон: [POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT.md](POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT.md)** (эксп-21 «топология ролей»**ЗАПУЩЕН и оплачен стадиями, сессия ЖИВАЯ**; приёмка у ПАРАЛЛЕЛЬНОГО оркестратора, не №15; D39.108, инцидент восстановления — D39.113). Очередь и состояние — только CURRENT-STATE.
- Зоны фронта (чужие, читать при касании стыка; каждая ведёт СВОЙ зонный бэклог — единый бэклог их строк не принимает, D39.84): [../frontend/](../frontend/) — веб-интерфейс: промт фронт-сессий S0S7 + [STACK_DECISIONS.md](../frontend/docs/STACK_DECISIONS.md) (пины версий точными числами и ловушки, сверены с вебом 02.08) + [BACKLOG.md](../frontend/docs/BACKLOG.md) · [../platform/](../platform/) — SaaS control plane: README + [BACKLOG.md](../platform/BACKLOG.md) (П-1..П-5) + `docs/` (промт P0 · зонный журнал `platform-PROGRESS.md`).
- `archive/` — история ([правила архива](archive/README.md)): закрытые промты (`prompts/`) · отчёты с ревью-шапками (`reports/` — на них ссылаются приёмки) · исполненные арх-доки (`architecture/`) · слайсы хроники `PROGRESS-*.md`. Инструкции оттуда не исполнять.
- Диаграммы: [../backend/docs/components.puml](../backend/docs/components.puml) · [../backend/docs/pipeline.puml](../backend/docs/pipeline.puml) — дом рядом с кодом (D39.80), правятся бэкендом одним коммитом с кодом; вручную НЕ рендерить (владелец смотрит PlantUML-расширением VS Code).

View file

@ -38,7 +38,7 @@ openapi.yaml РЯДОМ (байт-копия зонной frontend/docs/api-cont
> каждое решение, чем оно обосновано, что осталось открытым. При расхождении по ФОРМЕ
> побеждает YAML; при вопросе «почему так» — этот файл.
>
> **Статус: черновик фронт-сессии S3 на ратификацию.** Дом ратифицированной копии —
> **Статус: РАТИФИЦИРОВАН — D39.99 (04.08), контракт 0.2.0 (D39.115, 08.08).** Дом канона — этот каталог; `frontend/docs/api-contract/openapi.yaml` — байт-зеркало. ⚠ Испр. оркестратором №15 08.08: файл называл себя черновиком на ратификацию четверо суток ПОСЛЕ ратификации — тот же класс, что шапка `info` спеки.
> `docs/architecture/14-api-contract/`, зона оркестратора; перенос делает он, генерация типов
> после ратификации идёт из перенесённой копии — контракт первичен, код вторичен.
>

View file

@ -0,0 +1,336 @@
> ⚠⚠ **ПРОМТ ОТРАБОТАН — исторический, НЕ задание.** Исполнен двумя фронт-сессиями (04.08 и 08.08),
> **ПРИНЯТ и заленден D39.115** (`60595f6`): контракт **0.2.0** в каноне, канон и зонная копия
> байт-равны, блоки компаньона 2.142.16 внесены, слой данных построен. **Список «Правки спеки»
> ниже ИСПОЛНЕН целиком — не исполнять заново: спека уже 0.2.0, и повторная правка откатит
> ратифицированный контракт.** Живое состояние зоны — `frontend-PROGRESS.md`; хвосты — `BACKLOG.md`
> (Ф-29 · Ф-30 · Ф-31/К-13 · Ф-32); следующий промт зоны (S4) выдаёт оркестратор по слову владельца.
> Архивная копия — `docs/archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md`.
# Промт: фронт-сессия S3 — слой данных
Ты — фронтенд-сессия TextMachine, четвёртая по счёту. Зона записи — **только `frontend/`**;
сессия не коммитит — лендит оркестратор (протокол — стоящий промт `FRONTEND_SESSION_PROMPT.md`
§«Зона и git», он в силе целиком). Пре-коммит хук стоит и самоустанавливается при `npm install`.
> Промт написан сессией S2 по просьбе владельца — как передача с той точки, где S2 встала.
> Ратифицирует и правит его оркестратор; при расхождении с его хендофф-промтом побеждает тот.
## Входное состояние (04.08, проверено исполнением, а не заявлено)
- **Пройдено S0S2:** план · инструменты и скриншот-цикл · `tokens.css` по замерам референса ·
оболочка трёх панелей (`src/shell/`) · примитивы `src/ui/` на `react-aria-components` ·
витрина `/showcase` и нагрузочный `/scale` (2284 раздела, 1200 терминов).
- `npm run check` — 5 гейтов (prettier · eslint тип-осведомлённый · stylelint · tsc · vitest,
**77 тестов**), `npm run check:full` — + сборка + три скриншота с гейтом доступности axe.
Всё зелёное на 04.08.
- **Данные всё ещё синхронная фикстура:** `src/api/` отдаёт объекты из `src/mock/` напрямую.
Это диспозиция Ф-15, а не недосмотр: асинхронность приезжает вместе с MSW, то есть в S3.
- **Гейты, которые ты застаёшь:** одно место для цвета и размера (TSX-половина в
`eslint.config.js`, CSS-половина в `stylelint.config.js`) · три шва — фикстуры видит только
`src/api/`, глобальный CSS только `src/main.tsx`, `react-aria-components` только `src/ui/`
закрытые и для статического, и для динамического импорта · сеть запрещена вне `src/api/`
во всех транспортах (`fetch`/`EventSource`/`WebSocket`/`XMLHttpRequest`, включая
`window.*`) · тест общности: код языка не зашивается в разметку, стили не ветвятся по
`:lang(…)` · контракт-тест токенов и структурные тесты CSS-модулей.
- Правки S2 и дофикс по ревью ЗАЛЕНДЕНЫ (`02872b6`) — восстанавливать нечего, дерево фронта чистое.
В дереве могут лежать незакоммиченные файлы ДРУГИХ зон (параллельные сессии — норма): не трогать
и не «прибирать».
## Замок снят (оркестратор №14, 05.08)
Контракт существует и ратифицирован (`docs/architecture/14-api-contract/`, D39.99), строка 95
закрыта, вторая сторона контракта — платформа — уже написана и принята: её скелет живёт в
`platform/` и ратифицированные ответы платформы вошли в список правок спеки ниже. Раздел «Если
замок закрыт» оставлен как исторический — исполнять его НЕ надо. Один сохраняющийся запрет:
не начинать «пока на своих типах, потом поправим» — моки, снятые не с того контракта, разойдутся
с API, ровно ради чего строка 95 и заводилась.
## Обязательное чтение до кода (порядок)
1. `frontend/docs/FRONTEND_SESSION_PROMPT.md` — стоящий промт: сценарий §3, жёсткие ограничения
§4, «как работать» §7. **Его не редактировать.** ⚠ Раскладка §2 частично устарела — её
перевешивают решения владельца из журнала зоны.
2. `frontend/docs/frontend-PROGRESS.md` целиком: «Текущее состояние» · «Решения владельца по продукту» ·
«Открытые вопросы» · хронику 04.08 (в ней — что S2 построила, где отошла от референса и что
поправило ревью оркестратора).
3. `frontend/docs/FRONTEND_PLAN.md` — §0.1 (карта канона: что читать перед чем), **§0.2
(транспорт: с движком фронт не разговаривает никогда — это ратифицированный анти-паттерн,
D39.81/D39.85)**, §5.4 и §5.4.1 (формы обхода гейтов и названные границы), **§6 (что уже
известно про движок и как это меняет форму данных — читать до первой строки типов)**.
4. `frontend/docs/STACK_DECISIONS.md` — §2 пины (там уже названы `@tanstack/react-query` и `msw`),
§5 транспорт и правила стрима, §7 риск ре-ингеста. Библиотеки сам не выбирай и версии
по памяти не «обновляй»: твои знания об экосистеме устарели, сверка — live по npm.
5. `docs/research/23-engine-platform-seam.md``docs/README.md` требует читать его **перед любым
кодом стыка**; форма событий и правило ре-синка оттуда.
6. `frontend/docs/BACKLOG.md` — строки **Ф-14** (вход фронта в контракт), **Ф-15** (закрывается
этой сессией), Ф-19, Ф-21.
7. `references/*.png` и `.shots/*.png` — открой и посмотри до первой правки.
## Правки спеки — ПЕРВЫЙ шаг S3 (список актуализирован оркестратором №15, 07.08: добавлены В-трис и В-кватер)
Контракт ратифицирован. Спеку правишь ты: минорный бамп версии, регенерация типов, батарея,
компаньон-К-таблица получает статусы. **Ниже — ПОЛНЫЙ список; он вырос с 04.08**, потому что
платформа ответила на свои К-вопросы и владелец сменил модель лимитов. Порядок правок твой,
но ни одна не «на потом»: спека — нормативная поверхность, и на ней уже стоит код платформы.
**А-нуль. Шапка `info` спеки уже исправлена оркестратором №15 (07.08) — НЕ возвращай её обратно.**
Три дня после ратификации файл называл себя «DRAFT of frontend session S3 — not a ratified
contract» и ссылался на компаньон по пути, которого рядом с каноном нет. Сейчас там сказана
правда: ратифицирован D39.99, канон в `docs/architecture/14-api-contract/`, зонная копия —
байт-зеркало, компаньон = `README.md` рядом с каноном. **Твоё в этом пункте одно:** строка
`version` всё ещё `0.1.0-draft` — бампни её первым же действием (минорный бамп, как и сказано
ниже), и байт-сверку копий из пункта Д делай уже с этой шапкой.
**А. Решения владельца 04.08 (D39.100).**
1. **К-1:** десять статусов приняты — статусов больше не трогать.
2. **К-8:** `BookStatus` получает 11-е значение **`paused`** (резюмируемый стоп; в `failed` не
мапить — спека это уже запрещает). Оповещение «перевод остановлен: лимиты исчерпаны».
3. **К-5:** `eta_seconds` в прогресс-модель (движок отдаёт, `status.go:112`; поле опциональное).
4. **К-3:** метка главы — ИЗ ДАННЫХ книги; зашитых форм «Глава N» не существует, легальна книга
без номеров и глав вовсе. Проверь спеку И фикстуры на зашитую форму.
**Б. Ратифицированные ответы платформы. Это уже НЕ вопросы — это форма, которую спека обязана
выразить.**
> ⚠ Ссылки на `platform/docs/*` ниже и в разделе Г — **происхождение, а не задание.** Всё, что тебе
> нужно, приведено в этом промте целиком. В зону платформы ходить НЕ надо: там прямо сейчас живая
> сессия, её документы движутся, и промт, который зависит от чужого живого файла, ломается ровно в
> тот момент, когда сосед его правит. Если всё же полезешь — только читать, и знай, что читаешь
> черновик.
5. **К-4 (ревизия):** счётчик пер-КНИЖНЫЙ, одно и то же число несут все книго-скоупные чтения и
`id` кадра потока. Прозой в спеку: ревизия монотонна В ПРЕДЕЛАХ скоупа и между скоупами не
сравнивается · отбрасывание устаревшего чтения — обязанность клиента · докачка по
`Last-Event-ID` читает **`revision >= R`**, не `>` (одна транзакция = одна ревизия, но
НЕСКОЛЬКО кадров; строгое «больше» теряет кадры-братья) · после транзакции ПОЛНОЙ ЗАМЕНЫ
(банк пересобирается целиком, пере-чанковка заменяет главы) сервер обязан выдать
`resync_required`: дельта-чтение удаления выразить не может.
6. **К-7 (пагинация):** keyset-курсор на КАЖДОМ списочном ответе, `?limit=&cursor=`,
`next_cursor: string|null` присутствует ВСЕГДА (добавить позже — значит молча отрезать хвост
у клиента, который поля не читает). Дефолты: главы 5000 · банк 1000 · замечания 500.
Курсор привязан к СТРУКТУРНОЙ эпохе (поколение манифеста / `chunker_version`), **НЕ к
ревизии книги**: ревизия бампается на каждой материализации, и привязка к ней даёт вечный
рестарт пагинации во время прогона на книге в 5000 глав. Отклонение протухшего курсора —
обязанность СЕРВЕРА (MUST), клиент её исполнить не может: курсор непрозрачен.
7. **К-12 (экспорт):** опрос, а не пуш. `202` + `Location`; статус-чтение отдаёт `ready:false`
с заголовком **`Retry-After`**, объявленным ЯВНО как заголовок этого 200-ответа (RFC 9110
определяет его для 503 и 3xx — на 200 общая семантика не действует, поэтому объявляем сами).
8. **CSRF:** браузерный клиент обязан слать заголовок **`X-TM-Client`** на небезопасных запросах
cookie-пути. Место — описание `sessionCookie`. Несущим является ПРИСУТСТВИЕ заголовка,
значение любое: не выдумывай токенную семантику.
9. **`Run.paused_reason`** — машинная причина паузы либо `null`; фразу рисует клиент, API несёт
состояние. **Значение ровно одно и оно уже занято платформой: `credit_exhausted`.** (В редакции
этого промта от 05.08 стояло `limits_exhausted` — ошибка оркестратора, значение должно совпадать
с тем, что пишет платформа, иначе клиент не опознает причину.)
**В. Решение владельца 05.08 — модель лимитов СМЕНИЛАСЬ.** Не подписка с окнами, а **БАЛАНС
кредитов** («покупка токенов как у OpenRouter»). Следствия для спеки:
10. Окон и `resets_at` НЕТ. Экран показывает ОСТАТОК, а не «сбросится через». Денежные СУММЫ
по-прежнему на провод не идут (D39.84) — процент остатка, не доллары.
11. Прежняя инструкция этого промта «API лимитов проектирует платформа, в спеку не выдумывать»
ОТМЕНЕНА: форма ответила (`GET /v0/usage`), и её надо выразить — но БЕЗ полей окон. Форма
приведена ЗДЕСЬ целиком, ходить за ней в чужую зону не нужно и не надо (промт, зависящий от
живого документа соседней зоны, ломается ровно тогда, когда сосед его правит):
```yaml
Usage:
required: [state, remaining_percent]
properties:
state: { enum: [ok, low, exhausted] } # low — порог показа предупреждения
remaining_percent: { type: integer, minimum: 0, maximum: 100 }
paused_reason: { enum: [credit_exhausted], nullable: true }
```
Процент считается от суммы грантов аккаунта, не от «лимита периода»: периодов больше нет.
`Run.paused_reason` несёт то же значение на прогоне. Сумм нет ни в каком виде (D39.84).
(В редакции 05.08 этот пункт слал за схемой в `PLATFORM_DIRECTION.md` §2 — там её нет, там
денежная модель; ошибка оркестратора.)
**В-бис. Поверхность входа — появилась в P1, в спеке её нет** (добавлено оркестратором 05.08 после
приёмки платформы P1; в редакции этого промта от 05.08 утра этого пункта не было, потому что кода
входа ещё не существовало).
Платформа построила OIDC-вход. Четыре ручки живут ВНЕ версионного префикса, как `/healthz`, потому
что это механика сессии, а не контрактная поверхность:
| Ручка | Метод | Что делает |
|---|---|---|
| `/auth/login` | GET | начинает вход, редиректит к провайдеру; принимает `?return_to=<путь на этом сайте>` |
| `/auth/callback` | GET | завершает вход, ставит сессионную куку, редиректит на `return_to` либо на дефолт |
| `/auth/logout` | POST | завершает ЭТУ сессию |
| `/auth/logout-all` | POST | завершает ВСЕ сессии пользователя («выйти везде») |
15-бис. **Описать их в КОМПАНЬОНЕ, в `openapi.yaml` не тащить** — решение оркестратора как
владельца контракта. Клиенту нужно знать три вещи: куда вести на вход, что `return_to` принимает
только путь этого сайта (сервер молча заменит чужой на дефолт — открытый редирект закрыт), и что
обе `POST`-ручки лежат на cookie-пути, то есть требуют `X-TM-Client` из пункта 8.
Отказ входа — `problem+json`, как везде; различать причины отказа клиент не может и не должен.
**Г. Ограничения скорости, которые спека обязана удержать** (замер и разбор —
`platform/docs/PLATFORM_DIRECTION.md` §4; для тебя это правила, а не предложения):
12. **Юниты читаются только пер-главно.** Пер-книжной ручки юнитов не заводить никогда —
на этом стоит вся память клиента (рабочий набор 27 КБ против ~62 МБ).
13. **Экспорт — артефакт по ссылке;** сборка текста книги на клиенте запрещена явно.
14. **Сервер ВПРАВЕ склеивать события прогресса**, клиент обязан терпеть скачки счётчиков —
записать в описания событий (иначе прогон на 9500 юнитов = неограниченный источник рендера).
15. **Заголовок главы ограничен по длине на сервере** — единственная неограниченная строка в
списке из 5000 строк.
**В-трис. Управляемый потолок прогона — РЕШЕНИЕ ВЛАДЕЛЬЦА 07.08, поверхности в спеке нет**
(добавлено оркестратором №15 по приёмке платформы P2, D39.109/D39.110; в редакции 05.08 этого
пункта не было — решения не существовало).
Проблема, которую это решает: перевод книги стоит денег, и человек должен уметь сказать «не
больше вот столько» ДО старта, а не узнавать пост-фактум. Сегодня потолок живёт только в конфиге
книги на стороне движка, и управлять им нельзя вообще.
Форма, ратифицированная владельцем: **шкала в интерфейсе от минимума до максимума**, ноль выбрать
НЕЛЬЗЯ (подсвечивается серым — прогон с нулевым потолком не начнётся), виджет выбираешь сам
(ползунок — предложение владельца, не мандат). Три вещи в этой форме — «делай РОВНО так», потому
что каждая куплена проверкой:
16. **Единица шкалы — ГЛАВЫ, а не доллары.** Не «поставить $3», а «перевести до N глав». Причина
жёсткая: D39.84 запрещает денежные суммы на пользовательском проводе и экране, и П-5 показывает
процент ровно поэтому. Доллары на этой шкале = амендмент D39.84, а он не выдан. Побочная
выгода: минимум шкалы объясняет себя сам — одна глава.
17. **Максимум шкалы = ДОСТУПНЫЙ остаток.****Первая редакция этого пункта говорила «баланс МИНУС открытые холды» — ошибка оркестратора, вычитание дважды; исправлено 08.08 по находке самой S3 (D39.115).** Холд — дебет в момент взятия, поэтому баланс уже без него.
Платформа берёт холд на сумму потолка ДО спавна прогона, поэтому шкала, упёртая в полный
баланс, запирает всё на одну книгу и вторую начать нельзя. Два числа платформа уже различает.
18. **Это потолок ПРОГОНА, не книги.** Он едет со стартом прогона и не является свойством книги;
в спеке ему место рядом с созданием прогона, а не в модели книги.
⚠ Чего в спеке НЕ выражать: пересчёт «глав → деньги». Он живёт на платформе (по оценке движка) и
наружу не выходит ни в каком виде. Поверхность отдаёт границы шкалы и выбранное значение в главах.
**В-кватер. ФРОНТ ЖИВЁТ НА ТОМ ЖЕ ORIGIN, что платформа — сегодня это не выбор, а факт**
(замер приёмки №15 на живом бинаре, строка PD-96 регистра платформы).
CORS-слоя в платформе нет вовсе: preflight `OPTIONS` с чужим `Origin` получает 401 от гарда
сессии, заголовков `Access-Control-*` нет ни на одном ответе. Значит браузерный клиент с другого
origin неработоспособен как класс, а не «требует настройки». Для тебя два следствия: в деве ходи
через прокси dev-сервера на тот же origin (не напрямую на порт платформы), и **не проектируй ничего
вокруг кросс-origin запросов** — если продукт когда-нибудь потребует отдельный домен фронта, это
отдельная работа платформы, и она не сделана. Заголовок `X-TM-Client` (пункт 8) при этом обязателен
и на same-origin: он не про CORS.
**Д. После правок:** байт-сверка зонной спеки с ратифицированной копией
(`docs/architecture/14-api-contract/openapi.yaml`); расхождение отдай оркестратору на
пере-ратификацию диффом — сам канон не правь.
## Скоуп S3 — слой данных, и ни шагом дальше
1. **`src/api/` становится асинхронным**: MSW как сетевой мок + серверное состояние на пинах
из STACK_DECISIONS §2 (версии сверить live на дату сессии; `.npmrc` держит `save-exact`).
Каждый новый пин — строкой в таблицу `FRONTEND_PLAN.md` с датой релиза и «зачем нам».
2. **Фикстуры всех состояний, а не одного счастливого:** ожидание · ошибка · пусто ·
частично · длинный хвост · потеря соединения на стриме. Правило S1/S2, которое здесь
действует сильнее всего: **фикстура по умолчанию — трудный случай.** Наивный счётчик глав
должен на ней давать ноль (идёт черновая волна), иначе скриншот-цикл смотрит на удобное.
3. **Живой прогресс — `EventSource` за швом `src/api/`** (STACK_DECISIONS §5; гейт сети уже
запрещает его где-либо ещё). Докачка по `Last-Event-ID`/ревизии — часть контракта, не выдумка.
4. **Ф-15 закрывается здесь:** ветки ожидания/ошибки/пустоты появляются вместе с MSW, а не
после первого продуктового экрана.
5. **Типы `src/api/types.ts` приводятся к контракту.** Что в них сегодня заведомо временное:
булев `signed` вместо трёхзначного `auto|draft|approved` · ключ строки банка, собранный
из (`src`, `dst`, `type`), — у движка термин уникален по (`src`, `sense`, `since_ch`,
`until_ch`) · отсутствие ревизии для докачки. Всё это перечислено строкой Ф-14.
**Закрытые юнионы получают явную ветку неизвестного значения** (строка Ф-22) — сегодня её нет
ни у одного, и строгость тайпчека здесь НЕ страхует: `runStates[book.state]`
(`showcase/Library.tsx:103`) — обращение к `Record` по КОНЕЧНОМУ юниону, а
`noUncheckedIndexedAccess` добавляет `undefined` только индексным сигнатурам (проверено `tsc`
на пробе: обращение по юниону компилируется молча, ругается только `Record<string, …>`).
Значит состояние прогона из будущего контракта даёт `undefined.tone` — падение дерева
библиотеки, а не пустую метку; `noteTone` тем же классом тихо уводит незнакомую ступень
замечания в СПОКОЙНУЮ ветку. **Место ветки — шов `src/api/`, где значение входит**, а не
каждый компонент: перевод «вердикт → вид» уже расползался по экранам, и контрольный вопрос
владельца требует, чтобы новое значение правило один файл.
6. **Поля не выдумывать.** Нет в контракте — это вопрос владельцу/оркестратору в
«Открытые вопросы» журнала зоны, а не догадка в типе. Дефект «фикстура выдумала поле»
в этой зоне случался дважды и оба раза стоил экрана.
**Не в скоупе:** экраны S4S7 · редактор текста · светлая тема · мобильная раскладка ·
React Compiler (Ф-2) · Tauri (Ф-5).
## Если замок закрыт
Контингенция на случай, если проверка замка даст «закрыт» (на вечер 04.08 замок ОТКРЫТ); тогда правильный ход — не ждать молча и не строить экраны
на синхронных моках (порядок этапов Ф-1 стоит именно на слое данных).
- **Доведи Ф-14 до артефакта, который можно отдать автору контракта:** не список намерений,
а перечень с обоснованием на каждый пункт — язык кодами · состояние прогона отдельно от
выполнения главы · прогресс пофазно по ЮНИТАМ · ревизия/`Last-Event-ID` · трёхзначный статус
подписи · поля банка (`type`/`sense`/`since_ch`) и ключ строки · продуктовый словарь вердиктов
(ПТ-33; §4.1 запрещает протечку внутренностей конвейера на экран). Половина уже написана
в строке Ф-14 и в §6 плана — собери, а не сочиняй заново.
- Отдай его оркестратору пингом в `frontend/docs/frontend-PROGRESS.md` и **остановись**:
заводить контракт своим решением фронт не может (шапка `BACKLOG.md`).
**Испр. сессией S3 04.08 по слову владельца:** здесь стояло «пингом в `docs/PROGRESS.md`» —
это чужая зона, и шапка журнала фронта фиксирует решение владельца 02.08 «в `docs/PROGRESS.md`
оркестратора не пишут». Канал передачи — журнал своей зоны; оркестратор пишет туда же.
- Ф-16, Ф-17, Ф-18, Ф-20 — **не трогать**: у каждой в бэклоге стоит свой триггер, и ни один
из них не наступил.
## Ловушки, купленные S2 — не переоткрывать
- **`react-aria-components`:** `Tab` не принимает клавиатурных обработчиков (обработчик живёт
на ряду вкладок) · у роли `tab` дети презентационные, поэтому крестик закрытия — не кнопка
(axe роняет `nested-interactive`), закрытие с клавиатуры — `Delete`, объявить его нечем (Ф-17) ·
**невыбранная `TabPanel` не рендерится вовсе** (`dist/private/Tabs.mjs:276`), отсюда потеря
прокрутки при переключении вкладки (Ф-19, замерено дважды) · `Tree` — это `treegrid`/`row`,
а не `treeitem`; раскрытие — `<Button slot="chevron">` · `renderEmptyState` обёрнут
в `role="option"` (зонд S2 принял это за дефект кода).
- **`react-resizable-panels` v4:** `className`/`style` панели уезжают во ВЛОЖЕННЫЙ div, у него
всегда inline `overflow:auto` · `Separator` обязан быть прямым ребёнком `Group` · ключ
хранилища раскладки содержит состав видимых панелей, поэтому сворачивание удалением панели
меняет ключ (сделано осознанно: так поле оболочки остаётся ровно замеренным).
- **Скриншот-цикл:** `vite build` и `preview` в один момент дают пустой экран — это гонка,
а не регрессия; перезапусти прогон, прежде чем «чинить» рабочий код.
- **Зонды и живые нарушения:** файлы зондов удалять за собой (в S2 агенты ревью оставили свои
в чужом дереве), правленые файлы восстанавливать из памяти процесса, **а не `git checkout`**
в дереве могут лежать незакоммиченные правки параллельных сессий.
- **Первому красному результату зонда не верить:** три «находки» первого прогона S2 оказались
дефектами зонда (селектор бил по трём панелям сразу), и соблазн «починить» рабочий код был
вполне реальный.
- **esquery:** селектор вида `Property[key.value=/^--/] > Literal[…]` ловит собственный ключ
свойства — в TSX-гейте это записано комментарием, не убирай его.
## Технические рамки
- Новый маршрут → сразу в `KNOWN_ROUTES` (`scripts/shot.mjs`); тест сверяет списки и упадёт.
- Гейты не ослаблять. Точечное подавление — только именованное правило с причиной.
- Файл = компонент + модуль стилей рядом; >150 строк — делить. Комментарии — одна-две строки
«почему», не «что».
- Тексты фикстур — настоящие пропорции кириллицы и иероглифов, объём минимальный: вопрос
авторского права (В-2) у владельца, цитаты не расширять.
## Как работать
1. **Ревью исполнением — мандат проекта, не пожелание:** приложение поднимается, скриншоты
сняты и ПРОСМОТРЕНЫ, каждый гейт проверен живым нарушением с перечнем форм, `npm run check:full`
зелёный. «Должно работать» ревью не является.
2. **Скриншот-цикл — с первого изменения**, критерий сведения — не растровое совпадение,
а плотность и впечатление (стоящий промт §8).
3. **Адверсариальная самопроверка перед финишем** (author≠reviewer): пройди по своим правкам
с установкой опровергать. S1 так поймала пять дефектов в собственных гейтах, S2 — восемь.
4. **Спорное с каноном или новое продуктовое решение не принимай сам:** вопрос в «Открытые
вопросы к владельцу» журнала зоны, и продолжай то, что вопроса не требует.
## Готово — это когда
- Замок проверен и результат записан: либо S3 сделана, либо в журнале лежит, чем сессия
занималась вместо неё и почему.
- Если S3 сделана: `src/api/` асинхронен, MSW отдаёт все состояния, ветки ожидания/ошибки/пустоты
живые, Ф-15 закрыта, типы сведены с контрактом, а расхождения — не «поправим потом»,
а строки бэклога с триггером.
- `npm run check:full` зелёный; новые маршруты в `shot.mjs`; скриншоты просмотрены.
- `frontend/docs/frontend-PROGRESS.md`: обновлено «Текущее состояние», добавлена хроника сессии
(что построено · что видно на снимках · где отошёл от канона и почему · что осталось);
строки бэклога получили диспозиции.
- Ничего не закоммичено: дерево подготовлено и передано оркестратору.
## Что ждёт не тебя (не решай сам)
**В-1** данные привязаны к одной машине (вопрос на движок/платформу) · **В-2** копирайт фикстур ·
**В-3/Ф-21** каким словом называть ступень замечания: владелец 05.08 передал разметку оркестратору
(«пусть работает как работает, потом вернёмся») ⇒ карту «причина → фраза» ты НЕ сочиняешь; до её
выдачи держи сегодняшние формулировки и не расширяй словарь ·
**Ф-11** контраст палитры ниже WCAG на четырёх узлах — принято как есть до слова владельца.

View file

@ -0,0 +1,114 @@
> ⚠ **ПРОМТ ОТРАБОТАН — исторический, не задание.** По нему прошли ЧЕТЫРЕ сессии: P0 (скелет, принят
> D39.107), P1 (вход OIDC, кредитный леджер, админ-CLI, деплой-юнит), P2 (очередь приёмки P1 +
> два своих ревью) и P3 (фикс-лист приёмки P2 целиком, передан запиской D39.111).
> **P1+P2 приняты D39.109 (`fcdab81`), фикс-пак P3 — D39.114 (`99f049c`, девять строк закрыто).** Состояние зоны, решения
> и открытые дефекты: `platform-PROGRESS.md` (раздел «Ратификация приёмкой P2») + `DEFECT_REGISTER.md`
> ⚠ **Перечень живых строк здесь НЕ дублируется** (норма D39.112 «один носитель на факт»: рукописная
> копия перечня разошлась с реестром на первом же фиксе). Живые строки — `python3 docs/scripts/counts.py`
> плюс сам `DEFECT_REGISTER.md`. Следующий промт зоны
> (реконсилятор · тейлер журнала · транзиентные юниты прогона) выдаётся по слову владельца —
> D39.107 п.3(3). Ниже — текст, по которому работали; исполнять его заново не нужно.
# Промт: платформа-сессия P0 — стек, скелет, дизайн-ответы контракту
Ты — первая платформенная сессия TextMachine. **Зона записи — только `platform/`.** `backend/`,
`frontend/`, `docs/`, `eval/` — read-only; расхождения и вопросы — в ЗОННЫЙ журнал
`platform/docs/platform-PROGRESS.md` (решение владельца 04.08: весь прогресс зоны — там,
в `docs/PROGRESS.md` платформа не пишет). **Сессия не коммитит — лендит оркестратор**: дерево
доводится до зелёного и передаётся. Git-канон — `CLAUDE.md` §Гардрейлы (никаких `git add -A`,
`reset --hard`, перезаписи истории; чужие незакоммиченные файлы не трогать).
> Промт написан оркестратором №12 (D39.100). Ратифицирует правки — он же.
> Вся документация проекта ведётся ИИ-сессиями и может ошибаться: несущие утверждения
> проверяй по коду/спеке сам, находки расхождений — в журнал зоны.
## Что за продукт и где твоё место
TextMachine — SaaS издательского художественного перевода больших текстов (zh/ja/en→ru)
мультиагентным LLM-пайплайном. **Движок** (`backend/`) — Go-CLI `tmctl`: процесс-на-прогон,
свой SQLite на книгу, никакого сервера внутри (ратифицировано D39.81/D39.85 — HTTP в движок
не тащить). **Фронт** (`frontend/`) — SPA ридер-IDE, работает на моках, ждёт живой API.
**Ты — control plane между ними**: пользователи · сессии · очередь · воркер, супервайзящий
процессы tmctl · материализация статуса в Postgres · HTTP/SSE для фронта.
## Обязательное чтение ДО кода (порядок; жаргон — docs/glossary.md)
1. Корневой `CLAUDE.md` — канон целей и гардрейлы (⚠ `.env` не читать НИКОГДА).
2. `docs/research/23-engine-platform-seam.md` — ратифицированный шов движок↔платформа
(D39.85) — приоритетный канон зоны: NDJSON-поток событий движка → идемпотентный апсерт
`(run_id, seq)` в Postgres (Reporting Database) → SSE фронту из Postgres; ре-синк на
обрыве — `tmctl status --json`; **анти-паттерны запрещены**: живой SQLite движка не
читать · event-sourcing/реплей истории не строить · read-пакет из ядра не выносить.
3. `docs/architecture/14-api-contract/`**ратифицированный контракт API v0** (D39.99):
`openapi.yaml` — нормативная поверхность, которую ты обязан отдать; `README.md`
провенанс каждого решения и открытые К-вопросы. Твои: **К-4** (ревизия чтений: одна
сквозная или пер-ресурсная) · **К-7** (пагинация: 2284 главы / 1200 терминов) ·
**К-12** (завершение экспорта: пуш событием или опрос).
4. `platform/BACKLOG.md` — П-1..П-5: твой зонный трекер (аутентификация П-1 ратифицирована
D39.84 + `frontend/docs/STACK_DECISIONS.md` §5: ОДНА серверная сессия в Postgres,
`__Host`-кука браузеру · `Bearer` десктопу/CLI · principal создаётся ТОЛЬКО в middleware ·
CSRF только на cookie-пути).
5. `frontend/docs/STACK_DECISIONS.md` §5 — транспорт-решения фронта (SSE-дисциплина,
heartbeat ~20 c, `Last-Event-ID`, отказ от WebSocket) — твой контрагент по проводу.
6. Grep по D-номерам в `docs/architecture/05-decisions-log.md`: D39.81 · D39.84 · D39.85 ·
D39.99 · D39.100 (целиком файл НЕ читать).
## Скоуп P0 — фундамент, и ни шагом дальше
1. **Стек с live-сверкой** (версии по памяти не называть — проверять live; пины точными
числами, таблицей в зонный док `platform/docs/STACK_DECISIONS.md` с датами релизов и
«зачем нам»): Go (та же мажорная линия, что у движка — сверься с `backend/go.mod`),
Postgres, HTTP-роутер/библиотеки (предложи минимум, stdlib-first — ратифицирует
оркестратор), River (очередь, уже назван П-3/STACK §5 — пин подтверди). Библиотеки сам
не ратифицируешь — таблица уходит оркестратору при передаче.
2. **Layout модуля.** ⚠ Ревью-гард D39.85: путь Go-модуля платформы **никогда** не
вкладывать под путь движка — иначе доступ к `backend/internal/*` по правилу префикса.
Отдельный `platform/go.mod` уже заведён — наполни. ⚠ Корневой `go.work` (мандат D39.85)
НЕ создавай — корень вне твоей зоны, его заведёт оркестратор при лендинге.
3. **Скелет, который компилируется и поднимается**: HTTP-сервер + `/healthz` · каркас
session-auth по П-1 (схема Postgres + middleware, без UI регистрации) · драфт схемы
read-model под контракт (books/runs/chapters/units/bank/notes/events + ревизии) ·
интерфейс NDJSON-ингест воркера (супервизия процесса tmctl, апсерт `(run_id, seq)`,
ре-синк `status --json`) — интерфейс и типы, живой прогон НЕ нужен: **NDJSON-эмиттер
в движке ещё НЕ построен** (строка 103 единого бэклога) — формы событий проектируй по
словарю research/23 §7 и контракту §6, из tmctl потока сегодня не получить.
4. **Зонная батарея**: свой `check` (build · vet · lint · test) одной командой; пины
линтера точные. Образец дисциплины — `backend/Makefile` (агрегатная цель там зовётся `battery`) и фронтовый `npm run check`.
5. **Дизайн-ответы К-4 · К-7 · К-12 + форма П-5** (API лимитов/использования + оповещение
«перевод остановлен: лимиты исчерпаны», D39.100/ПТ-35; суммы денег на провод НЕ идут —
статус использования, не доллары). Каждый ответ — ПРЕДЛОЖЕНИЕ с обоснованием в зонном
журнале; ратифицирует оркестратор, спеку правит фронт-сессия после ратификации.
**Не в скоупе:** П-2 (брокер рейт-лимитов — гейт «до второго пользователя») · стройка
очереди П-3 целиком (дизайн-заметки можно) · деплой/TLS/домены · UI чего угодно ·
любые вызовы LLM-провайдеров. Бюджет сессии $0.
## Жёсткие ограничения
- Движок не править и не форкать; `tmctl` дёргать можно только read-only командами и только
в интеграционных пробах ($0); живой SQLite движка не открывать.
- Деньги: суммы/цены не попадают в API-ответы (канон D39.84); в логи уровня INFO — тоже
(норма ЭТОГО промта, не D-лога); лимиты-СТАТУС — П-5, отдельная поверхность.
- ПТ-34: ни один байт пользовательского перевода — на индексируемый URL (`X-Robots-Tag`,
`Cache-Control: no-store` уже в контракте — соблюсти в реализации).
- Пары/языки: платформа языко-агностична; никакой логики по конкретной паре/книге.
## Как работать
1. **Ревью исполнением — мандат проекта (решение владельца 12.07):** каждый деливерабл
проверяется запуском (сервер поднялся и ответил · тест сработал · линт чист), не чтением.
2. **Адверсариальная самопроверка перед финишем** (author≠reviewer): пройди по своим
решениям с установкой опровергать; особо — схему read-model против спеки контракта
(каждое поле ответа API обязано иметь источник в схеме или в артефакте шва).
3. Спорное с каноном / новое продуктовое — НЕ решать: вопрос в зонный журнал, работу
продолжать там, где вопроса не требуется.
4. Комментарии в коде — «почему», не «что»; файлы малые; stdlib-first.
## Готово — это когда
- Дерево компилируется, зонная батарея зелёная, `/healthz` отвечает живым запуском.
- `platform/docs/STACK_DECISIONS.md` — пины live-сверены, таблица полная.
- Дизайн-ответы К-4/К-7/К-12/П-5 лежат в `platform/docs/platform-PROGRESS.md` с обоснованиями.
- Журнал зоны обновлён: что построено · что предложено · что спрошено; BACKLOG-строки
получили диспозиции.
- Ничего не закоммичено — дерево передано оркестратору.