diff --git a/frontend/docs/S3_SESSION_PROMPT.md b/frontend/docs/S3_SESSION_PROMPT.md index c765af96..17bdf7e3 100644 --- a/frontend/docs/S3_SESSION_PROMPT.md +++ b/frontend/docs/S3_SESSION_PROMPT.md @@ -1,4 +1,4 @@ -# Промт: фронт-сессия S3 — слой данных (вход под замком) +# Промт: фронт-сессия S3 — слой данных Ты — фронтенд-сессия TextMachine, четвёртая по счёту. Зона записи — **только `frontend/`**; сессия не коммитит — лендит оркестратор (протокол — стоящий промт `FRONTEND_SESSION_PROMPT.md` @@ -24,23 +24,18 @@ во всех транспортах (`fetch`/`EventSource`/`WebSocket`/`XMLHttpRequest`, включая `window.*`) · тест общности: код языка не зашивается в разметку, стили не ветвятся по `:lang(…)` · контракт-тест токенов и структурные тесты CSS-модулей. -- ⚠ **На момент написания промта в дереве лежали незакоммиченные правки** по ревью оркестратора - (`frontend/src/{api/types.ts,generality.test.ts,mock/book.ts,mock/scale.ts,showcase/Context.tsx, - showcase/Reader.module.css,tokens/tokens.css,tokens/tokens.test.ts}`, `eslint.config.js`, - `frontend/docs/*`). Их лендит оркестратор. **Первым делом сверься с `git log` и `git status`:** - если правок в дереве нет — они уже уехали, ничего восстанавливать не нужно. +- Правки S2 и дофикс по ревью ЗАЛЕНДЕНЫ (`02872b6`) — восстанавливать нечего, дерево фронта чистое. + ⚠ В дереве могут лежать незакоммиченные файлы ДРУГИХ зон (параллельные сессии — норма): не трогать + и не «прибирать». -## Замок на входе — первое действие сессии +## Замок снят (оркестратор №14, 05.08) -**Проверь сам, промту не верь** (он написан 04.08 и мог устареть): - -1. Существует ли `docs/architecture/14-api-contract/` (спека + компаньон)? — **на 04.08 вечера: ДА, ратифицирован (D39.99), замок ОТКРЫТ**; -2. Строки 95 в таблице единого бэклога больше НЕТ — она ЗАКРЫТА (D39.99, закрытые строки уходят в D-лог); если видишь её живой — дерево старее канона, стоп и пинг. - -**Открыт** (контракт есть и ратифицирован) → скоуп S3 ниже. -**Закрыт** → раздел «Если замок закрыт» (контингенция; на вечер 04.08 замок ОТКРЫТ — D39.99). Не начинай S3 «пока -на своих типах, потом поправим»: моки, снятые не с того контракта, разойдутся с API — ровно -то, ради чего строка 95 заведена. +Контракт существует и ратифицирован (`docs/architecture/14-api-contract/`, D39.99), строка 95 +закрыта, вторая сторона контракта — платформа — уже написана и принята: её скелет живёт в +`platform/` и ратифицированные ответы платформы вошли в список правок спеки ниже. Раздел «Если +замок закрыт» оставлен как исторический — исполнять его НЕ надо. Один сохраняющийся запрет: +не начинать «пока на своих типах, потом поправим» — моки, снятые не с того контракта, разойдутся +с API, ровно ради чего строка 95 и заводилась. ## Обязательное чтение до кода (порядок) @@ -63,27 +58,67 @@ этой сессией), Ф-19, Ф-21. 7. `references/*.png` и `.shots/*.png` — открой и посмотри до первой правки. -## Решения владельца 04.08 вечер (D39.100) — правки спеки ПЕРВЫМ шагом S3 +## Правки спеки — ПЕРВЫЙ шаг S3 (список актуализирован оркестратором №14, 05.08) -Контракт ратифицирован, четыре К-вопроса закрыты владельцем; спеку правишь ты (минорный бамп -версии, регенерация типов, батарея), компаньон-К-таблицу — статусами «решено»: +Контракт ратифицирован. Спеку правишь ты: минорный бамп версии, регенерация типов, батарея, +компаньон-К-таблица получает статусы. **Ниже — ПОЛНЫЙ список; он вырос с 04.08**, потому что +платформа ответила на свои К-вопросы и владелец сменил модель лимитов. Порядок правок твой, +но ни одна не «на потом»: спека — нормативная поверхность, и на ней уже стоит код платформы. -1. **К-1 закрыт: десять статусов приняты.** -2. **К-8 закрыт механизмом «как Claude Code»** (ПТ-35, П-5): `BookStatus` получает - 11-е значение **`paused`** (стоп по потолку; резюмируемый; в `failed` не мапить — уже - запрещено спекой); пользователь видит оповещение «перевод остановлен: лимиты исчерпаны», - сами лимиты — страница в настройках (СТАТУС использования, не суммы: запрет денег на - проводе в силе). API лимитов проектирует платформа (П-5) — поле/эндпоинт в спеку НЕ - выдумывать, только статус и семантику оповещения. -3. **К-5 закрыт: ETA показывать** — `eta_seconds` в прогресс-модель (движок отдаёт, - `status.go:112`; поле опциональное — оценка бывает недоступна). -4. **К-3 закрыт с канон-уточнением: метка главы — ИЗ ДАННЫХ книги, зашитых форм нет.** - «Глава N» — это шаблон langpack-ДАННЫХ, не закон: легальна книга вовсе без номеров и - глав. Дерево рендерит label, который дал манифест (строка 100)/heading (К-2), внутренний - порядок — непрозрачный индекс. Проверь спеку и фикстуры на зашитую форму «Глава N». -5. После правок: байт-сверка зонной спеки с ратифицированной копией - (`docs/architecture/14-api-contract/openapi.yaml`) — расхождение отдай оркестратору - на пере-ратификацию диффом, сам канон не правь. +**А. Решения владельца 04.08 (D39.100).** +1. **К-1:** десять статусов приняты — статусов больше не трогать. +2. **К-8:** `BookStatus` получает 11-е значение **`paused`** (резюмируемый стоп; в `failed` не + мапить — спека это уже запрещает). Оповещение «перевод остановлен: лимиты исчерпаны». +3. **К-5:** `eta_seconds` в прогресс-модель (движок отдаёт, `status.go:112`; поле опциональное). +4. **К-3:** метка главы — ИЗ ДАННЫХ книги; зашитых форм «Глава N» не существует, легальна книга + без номеров и глав вовсе. Проверь спеку И фикстуры на зашитую форму. + +**Б. Ратифицированные ответы платформы (приёмка P0, `platform/docs/platform-PROGRESS.md` +§«Ратификация приёмкой»). Это уже НЕ вопросы — это форма, которую спека обязана выразить.** +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`** (машинная причина паузы, напр. `limits_exhausted`, либо `null`) — + фразу рисует клиент, API несёт состояние. + +**В. Решение владельца 05.08 — модель лимитов СМЕНИЛАСЬ.** Не подписка с окнами, а **БАЛАНС +кредитов** («покупка токенов как у OpenRouter»). Следствия для спеки: +10. Окон и `resets_at` НЕТ. Экран показывает ОСТАТОК, а не «сбросится через». Денежные СУММЫ + по-прежнему на провод не идут (D39.84) — процент остатка, не доллары. +11. Прежняя инструкция этого промта «API лимитов проектирует платформа, в спеку не выдумывать» + ОТМЕНЕНА: форма ответила (`GET /v0/usage`), и её надо выразить — но БЕЗ полей окон. + Точную схему возьми из `platform/docs/PLATFORM_DIRECTION.md` §2, а не из головы. + +**Г. Ограничения скорости, которые спека обязана удержать** (замер и разбор — +`platform/docs/PLATFORM_DIRECTION.md` §4; для тебя это правила, а не предложения): +12. **Юниты читаются только пер-главно.** Пер-книжной ручки юнитов не заводить никогда — + на этом стоит вся память клиента (рабочий набор 27 КБ против ~62 МБ). +13. **Экспорт — артефакт по ссылке;** сборка текста книги на клиенте запрещена явно. +14. **Сервер ВПРАВЕ склеивать события прогресса**, клиент обязан терпеть скачки счётчиков — + записать в описания событий (иначе прогон на 9500 юнитов = неограниченный источник рендера). +15. **Заголовок главы ограничен по длине на сервере** — единственная неограниченная строка в + списке из 5000 строк. + +**Д. После правок:** байт-сверка зонной спеки с ратифицированной копией +(`docs/architecture/14-api-contract/openapi.yaml`); расхождение отдай оркестратору на +пере-ратификацию диффом — сам канон не правь. ## Скоуп S3 — слой данных, и ни шагом дальше @@ -199,5 +234,7 @@ React Compiler (Ф-2) · Tauri (Ф-5). ## Что ждёт не тебя (не решай сам) **В-1** данные привязаны к одной машине (вопрос на движок/платформу) · **В-2** копирайт фикстур · -**В-3/Ф-21** каким словом называть ступень замечания (словарь продуктовый, ПТ-33) · +**В-3/Ф-21** каким словом называть ступень замечания: владелец 05.08 передал разметку оркестратору +(«пусть работает как работает, потом вернёмся») ⇒ карту «причина → фраза» ты НЕ сочиняешь; до её +выдачи держи сегодняшние формулировки и не расширяй словарь · **Ф-11** контраст палитры ниже WCAG на четырёх узлах — принято как есть до слова владельца.