Document slice 11: notices, scene prompt contributions, and a Krea-only catalog.
ci / server (push) Failing after 3m53s
ci / client (push) Successful in 35s

Agents can implement toasts, pausing warnings, and bounded object prompts without bringing SDXL back into new schools.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-20 20:13:23 +03:00
co-authored by Cursor
parent 0428852388
commit ea3f5c7bf1
10 changed files with 472 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
# Фаза 63. Каталог Krea 2
## Зависимости
- [Фаза 62](../off-queue/62-portrait-prompt-craft.md)
## Зачем
Новая школа больше не предлагает SDXL. Дети рисуются тем же Krea 2, что и остальные, а не
DreamShaper.
## Задачи
- [ ] В `swarmui.json` только Muse GGUF и Realism v2.5 INT8 (8 / CFG 1 / euler / simple).
babes, epicrealism, lustify и DreamShaper убрать. `Catalog()` совпадает с файлом
- [ ] Пресеты `default` и `child` — Realism v2.5. Стиль и shotType `child` — проза без
`(word:1.4)` и SD-весов
- [ ] `ageRules` 6–11 по-прежнему ведут на `child`, но модель у child — v2.5
- [ ] Живые школы не лифтить. Сокет не бампить. PNG не перегенерировать
- [ ] [`protocol.md`](../../protocol.md) — описание каталога без четырёх SDXL, тем же коммитом
(версия сокета не меняется)
## Тесты, без которых фаза не закрыта
- [ ] `CreateDefault` содержит ровно два id: Muse и Realism v2.5; нет DreamShaper и babes
- [ ] Resolve взрослого и ребёнка (6–11) берут Realism v2.5
- [ ] Стиль/негатив child без `(low quality` и без `:1.4)`
- [ ] `GET /api/settings/swarmui` отдаёт только Krea-id; create копирует их в сейв новой школы
- [ ] Нормализация загрузки не переписывает `models` уже лежащей школы с SDXL в каталоге
## Критерий готовности
- В диалоге создания школы в пикере только Muse и v2.5 (если Swarm их отдал)
- Новая школа без правок генерирует ребёнка и взрослого с Realism v2.5
- Уже созданная школа со старым каталогом открывается и рисует по своей копии
## Стоп
Не бампить сокет. Не лифтить живые сейвы. Не тащить Realism v2.0. Не писать позу в UI.
Не перегенерировать PNG. Не подключать вклад сцены и тосты.
+48
View File
@@ -0,0 +1,48 @@
# Фаза 64. События и info-тост
## Зависимости
- [Фаза 16](../04-schedule/16-timetable-in-school.md) (звонок на урок)
- [Фаза 34](../07-inventory/34-wear-home.md) (рабочее утро как край)
- [Фаза 39](../08-session/39-school-owners.md) (гость уже есть; dismiss pausing — фаза 65)
## Зачем
Игрок видит, что начался день или урок. Это тост, не колонка и не пауза.
## Задачи
- [ ] `EventDef`: id, `severity` (`info` / `warning` / `error`), `pause`, `ttlMs` (0 = не гаснуть),
`trigger` (`dayStart` / `lessonStart` / `generationFailed`), `action` (`none` в этой фазе).
Локаль как у других def. Валидатор каталога
- [ ] Ваниль `DayStarted` и `LessonStarted`: info, без паузы, TTL 8000, `action` none
- [ ] Симуляция на крае рабочего утра и на звонке (смена периода урока, один факт на школу)
отдаёт факт, без UI. Работник сопоставляет def и кладёт info-`Notice`
- [ ] Новый кадр S→C (уведомление: id, defName, severity, pause, ttlMs, optional personId = 0).
Новый кадр C→S dismiss по id. `ProtocolCodec.cs`, `protocol.ts`, [`protocol.md`](../../protocol.md)
в одном коммите. Версия протокола +1
- [ ] Клиент: тост поверх школы, текст из каталога/`t` по defName, клик шлёт dismiss, TTL
гасит локально. Строки через `t(...)`. Не колонка «События»
- [ ] Info не писать в сейв. Открытие школы info не повторяет. Гость тост видит
- [ ] `generationFailed` в каталоге можно завести, но не эмитить — фаза 67 / 65
## Тесты, без которых фаза не закрыта
- [ ] Каталог грузит `DayStarted` / `LessonStarted`; неизвестный trigger — ошибка загрузки
- [ ] Переход через край рабочего утра даёт один факт `dayStart`; повторный тик в ту же минуту — нет
- [ ] Смена периода на урок даёт один `lessonStart` на школу, не по числу классов
- [ ] Круглый трип и байтовая раскладка кадра уведомления и dismiss — на обеих сторонах
- [ ] Клиентский тест: тост показывает локализованный текст, клик вызывает dismiss, без монтирования колонки
- [ ] Хостовый: открытая школа после утра получает кадр; после Close/Open info-тост не висит из сейва
## Критерий готовности
- Запустить часы до начала уроков: тост «начало дня», затем «начало урока», оба сами гаснут
- Клик по тосту убирает его сразу
- Гость той же школы тост видит
- Старый клиент отваливается Hello из‑за версии
## Стоп
Не паузить. Не писать sticky в сейв. Не вклад сцены. Не кнопку картинки. Не колонку событий.
Не эмитить по классу. Не бампить протокол отдельно от трёх файлов.
+42
View File
@@ -0,0 +1,42 @@
# Фаза 65. Варнинг и пауза
## Зависимости
- [Фаза 64](64-event-defs.md)
- [Фаза 39](../08-session/39-school-owners.md)
## Зачем
Ошибка и варнинг останавливают школу, пока хозяин не закроет карточку. F5 не проглатывает их.
## Задачи
- [ ] `Notice` с `pause`: работник ставит `running=false`. `SetRunning(true)` игнор, пока есть
хотя бы одно такое уведомление (как нелегальный skip — не fatal)
- [ ] Модал (не тост): висит, очередь если несколько, на экране один. Закрытие — dismiss
- [ ] Sticky в сейве школы; после загрузки и Open — снова кадры. Info по-прежнему не сохранять
- [ ] Dismiss pausing — только хозяин; гость кадр видит, dismiss игнор / HTTP `403` `not-owner`
- [ ] Потолок 8 sticky; девятый не эмитить. После последнего dismiss часы сами не запускать
- [ ] Ванильный `GenerationFailed` (error, pause) можно положить в каталог; эмит с портрета —
фаза 67, здесь достаточно тестового/внутреннего поста на доску
- [ ] [`protocol.md`](../../protocol.md) — поведение паузы и прав, без лишнего бампа версии
(версия уже +1 в 64)
## Тесты, без которых фаза не закрыта
- [ ] Пост pausing-notice: `running` становится false; последующий SetRunning(true) оставляет паузу
- [ ] Dismiss последнего pausing: SetRunning(true) снова включает часы; без Play сами не идут
- [ ] Сейв/загрузка: sticky на месте, info нет
- [ ] Гость не снимает паузу dismiss-ом; хозяин снимает
- [ ] Клиентский: модал не гаснет по TTL; очередь показывает следующий после закрытия
- [ ] Хостовый: Open после рестарта работника отдаёт sticky, часы на паузе
## Критерий готовности
- Варнинг встаёт на паузу; Play серый/бесполезный, пока модал открыт
- Закрыли — можно нажать Play. F5: модал снова, пауза держится
- Гость модал видит и не закрывает школу
## Стоп
Не авто-Play. Не колонку. Не вклад сцены. Не кнопку «создать картинку». Не эмит Swarm в этой фазе.
+48
View File
@@ -0,0 +1,48 @@
# Фаза 66. Сцена в промпте
## Зависимости
- [Фаза 62](../off-queue/62-portrait-prompt-craft.md)
- [Фаза 32](../07-inventory/32-weather-warmth.md) (улица vs здание)
- [Фаза 18](../05-ai/18-presence-walking.md) (узел человека)
Не стоит на 64/65 — можно параллельно с лентой.
## Зачем
Почти любой объект может добавить короткий позитив/негатив (и редко LoRA/embed), если он в
кадре этого человека. Стул без текста молчит. Промпт не раздувается.
## Задачи
- [ ] Блок `prompt` на `ThingDef`, `RoomDef` (и территории, если двор — тот же блок) и на осадках
климата (ясно / дождь / снег). Пустой = нет вклада. Валидация: строка ≤ 120 символов,
вес конечный ≥ 0
- [ ] Ваниль: непустой вклад у доски и у снега; обычный `Chair` без блока или с пустым
- [ ] Сборщик (на работнике, не в Simulation): узел человека → комната/двор + fill + worn/held
с блоком + погода только на улице. После слоя одежды. Порядок: вес ↓, затем `defName`
- [ ] Бюджет с дефолтом в опциях/профиле: 6 фрагментов, 2 LoRA сцены, 2 embeddings сцены.
LoRA — параметры Swarm; embeddings — `<embed:…>` как в фазе 61
- [ ] `GET .../portrait/prompt` включает сцену. Сокет не бампить
- [ ] Живые школы: пустой блок на старых вещах — поведение как вчера
## Тесты, без которых фаза не закрыта
- [ ] Каталог: доска даёт positive; Chair не попадает в сборку; строка 121 символ — ошибка загрузки
- [ ] Человек в кабинете с доской: промпт содержит фрагмент доски после одежды; без доски на карте — нет
- [ ] На улице в снег — фрагмент снега; в кабинете в снег — снега нет
- [ ] Больше 6 кандидатов — в тексте только топ-6 по весу; детерминированный тай-брейк по имени
- [ ] LoRA сцены в `loras`, не в тексте; embedding сцены в positive как `<embed:…>`
- [ ] «Показать промпт» / `GET prompt` совпадает со сборкой Generate (без вызова Swarm)
## Критерий готовности
- Карточка ученика в классе с доской: «Показать промпт» содержит chalk/blackboard-фразу
- Во дворе в снег — зимняя фраза; в том же снег в кабинете — нет
- Стулья не засоряют промпт
- Старая школа без полей `prompt` генерирует как раньше
## Стоп
Не kind `scene`. Не ControlNet. Не бампить сокет. Не кнопку на тосте. Не лифт каталога моделей
(это 63). Не писать вклад в Simulation.
+46
View File
@@ -0,0 +1,46 @@
# Фаза 67. Картинка с уведомления
## Зависимости
- [Фаза 65](65-warning-pause.md)
- [Фаза 66](66-scene-prompt.md)
- [Фаза 63](63-krea-only.md) (ваниль уже на Krea; не блокер сборки кнопки, но дефолт генерации)
## Зачем
Событие может предложить нарисовать человека из факта. Кнопка использует тот же сборщик, что
карточка, включая сцену.
## Задачи
- [ ] `EventDef.action`: `none` | `generateImage`. `generateImage` без `personId` на `Notice`
не рисовать, не 500
- [ ] Ваниль `GenerationFailed`: error, pause, `generateImage`. Эмит из сервиса портретов при
неуспехе Swarm (тот же personId и kind). Утро и звонок остаются `none`
- [ ] UI: на модале/тосте с action — кнопка; вызов существующего портретного HTTP (или узкого
`POST .../notices/{id}/generate`, если так проще связать права). Kind по умолчанию `full`.
Строки через `t(...)`
- [ ] Хозяин только. Гость кнопку не активирует. Успех не снимает паузу сам — нужен dismiss
- [ ] [`protocol.md`](../../protocol.md) — HTTP действия, тем же коммитом. Сокет не бампить
повторно, если кадр 64 уже несёт action/personId; иначе добавить поля в том же смысле,
что 64, без лишнего +1 если укладка уже есть
## Тесты, без которых фаза не закрыта
- [ ] Каталог: `GenerationFailed` с `generateImage`; `DayStarted` без кнопки
- [ ] Неуспех генерации ставит pausing notice с personId; успех — не ставит
- [ ] Хостовый: хозяин с кнопки получает PNG (или тот же outcome, что карточка); гость 403
- [ ] Промпт этой генерации содержит сцену узла человека (как 66), не пустой коридор без людей
- [ ] Notice без personId и с `generateImage` не дергает Swarm
- [ ] Клиентский: кнопка есть только при action; info-тост дня кнопки не имеет
## Критерий готовности
- Сломать/отменить Swarm на портрете: ошибка паузит школу, кнопка перерисовывает того же
- Утро по-прежнему тост без кнопки
- Гость видит модал и не запускает GPU
## Стоп
Не автогенерация утром всем. Не арт локации без человека. Не LLM. Не снимать паузу успехом
картинки. Не третью колонку.
+40
View File
@@ -0,0 +1,40 @@
Индекс срезов: [`../README.md`](../README.md).
## Срез 11. События и сцена
Дизайн: [`events.md`](../../design/11-events/events.md).
Мир говорит игроку тостом или варнингом и генератору — коротким вкладом в промпт, если объект
в кадре. Новая школа рисует только Krea 2. Срез можно остановить после этапа B — тосты живые,
даже если стул в промпте ещё молчит.
**Этап A — только Krea 2.** Каталог без SDXL.
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [63. Каталог Krea 2](63-krea-only.md) | ⬜ | Muse + v2.5, child на v2.5, без лифта |
**Этап B — лента.** Факт, тост, пауза.
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [64. События и info-тост](64-event-defs.md) | ⬜ | `EventDef`, утро и звонок, кадр на сокете, тост |
| [65. Варнинг и пауза](65-warning-pause.md) | ⬜ | sticky, Play игнор, сейв, dismiss хозяина |
63 независима. 65 стоит на 64.
**Этап C — вклад в кадр.**
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [66. Сцена в промпте](66-scene-prompt.md) | ⬜ | Thing/Room/погода, бюджет, LoRA/embed сцены |
66 стоит на 62; можно параллельно с 64/65.
**Этап D — действие на событии.**
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [67. Картинка с уведомления](67-notice-image.md) | ⬜ | `generateImage`, кнопка, тот же сборщик |
67 стоит на 65 и 66.
+1
View File
@@ -21,4 +21,5 @@
| 8. Сессия и темп | 38–40 | [08-session](08-session/README.md) | [session](../design/08-session/session.md) |
| 9. Общение и романтический пак | 41–47 | [09-social](09-social/README.md) | [social](../design/09-social/social.md) |
| 10. Ремесло | 5659 | [10-craft](10-craft/README.md) | [craft](../design/10-craft/craft.md) |
| 11. События и сцена | 63–67 | [11-events](11-events/README.md) | [events](../design/11-events/events.md) |
| Вне очереди | 48–55 | [off-queue](off-queue/README.md) | [off-queue](../design/off-queue/) |