From 6ac26f38ae4aa304886003b2345452e9917ea9ef Mon Sep 17 00:00:00 2001 From: heaven Date: Wed, 5 Aug 2026 05:25:40 +0300 Subject: [PATCH] Correct three defects in the S3 prompt: wrong pause reason value, schema pointer into a live foreign document, and the sign-in surface built after the prompt was written --- frontend/docs/S3_SESSION_PROMPT.md | 55 ++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/frontend/docs/S3_SESSION_PROMPT.md b/frontend/docs/S3_SESSION_PROMPT.md index 17bdf7e3..b6aa3b6e 100644 --- a/frontend/docs/S3_SESSION_PROMPT.md +++ b/frontend/docs/S3_SESSION_PROMPT.md @@ -73,8 +73,14 @@ 4. **К-3:** метка главы — ИЗ ДАННЫХ книги; зашитых форм «Глава N» не существует, легальна книга без номеров и глав вовсе. Проверь спеку И фикстуры на зашитую форму. -**Б. Ратифицированные ответы платформы (приёмка P0, `platform/docs/platform-PROGRESS.md` -§«Ратификация приёмкой»). Это уже НЕ вопросы — это форма, которую спека обязана выразить.** +**Б. Ратифицированные ответы платформы. Это уже НЕ вопросы — это форма, которую спека обязана +выразить.** + +> ⚠ Ссылки на `platform/docs/*` ниже и в разделе Г — **происхождение, а не задание.** Всё, что тебе +> нужно, приведено в этом промте целиком. В зону платформы ходить НЕ надо: там прямо сейчас живая +> сессия, её документы движутся, и промт, который зависит от чужого живого файла, ломается ровно в +> тот момент, когда сосед его правит. Если всё же полезешь — только читать, и знай, что читаешь +> черновик. 5. **К-4 (ревизия):** счётчик пер-КНИЖНЫЙ, одно и то же число несут все книго-скоупные чтения и `id` кадра потока. Прозой в спеку: ревизия монотонна В ПРЕДЕЛАХ скоупа и между скоупами не сравнивается · отбрасывание устаревшего чтения — обязанность клиента · докачка по @@ -95,16 +101,53 @@ 8. **CSRF:** браузерный клиент обязан слать заголовок **`X-TM-Client`** на небезопасных запросах cookie-пути. Место — описание `sessionCookie`. Несущим является ПРИСУТСТВИЕ заголовка, значение любое: не выдумывай токенную семантику. -9. **`Run.paused_reason`** (машинная причина паузы, напр. `limits_exhausted`, либо `null`) — - фразу рисует клиент, API несёт состояние. +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`), и её надо выразить — но БЕЗ полей окон. - Точную схему возьми из `platform/docs/PLATFORM_DIRECTION.md` §2, а не из головы. + ОТМЕНЕНА: форма ответила (`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; для тебя это правила, а не предложения):