# Журнал ревью — срез 11 Сводка: [`../reviewed.md`](../reviewed.md). Индекс среза: [`README.md`](README.md). ## Срез 11. Этап A — только Krea 2 - **Фазы:** 63 - **Проверен на:** `1002aeb`, 2026-08-21 - **Пути:** `src/HSchool.Server/swarmui.json`, `src/HSchool.Server/Game/SwarmUiSettingsStore.cs`, `tests/HSchool.Server.Tests/SwarmUiSettingsStoreTests.cs`, `tests/HSchool.AppHost.Tests/PortraitApiTests.cs` - **Итог:** обещания фазы 63 совпадают с кодом. Сокет в коммите фазы не бампили. Живые сейвы с SDXL в `models` не лифтятся; пустой `models` поднимает id с пресетов, а не подменяет каталог Krea. Дописаны границы возраста 6–11, сверка shotType `child` с файлом и отказ лифтить сейв без списка моделей. Хостовые `PortraitApiTests` в этом проходе не гонялись (общий AppHost / живой сервер). Этапы B–D (64–67) в этот проход не входили. ### 63. Каталог Krea 2 `Catalog()` — только `museByStableYogi_v30TurboGguf.gguf` и `realismByStableYogi_v25INT8Turbo.safetensors` (8 / CFG 1 / euler / simple). `swarmui.json` совпадает после `NormalizeAfterLoad`. Пресеты `default` и `child` — Realism v2.5; стиль, negative и shotType `child` — проза без `(low quality` и `:1.4)`. `ageRules` 6–11 → `child`. Константы babes / DreamShaper / epicrealism / lustify остались для живых копий, в ванильный список не входят. v2.0 GGUF нет. `NormalizeAfterLoad` не переписывает непустой SDXL-каталог; `Clone` не подмешивает Muse/v2.5. Если `models` пуст, `LiftModelsFromPresets` копирует id с пресетов **до** подстановки `Catalog()` — иначе DreamShaper в пресете резолвился бы в Muse. HTTP: `GET /api/settings/swarmui` и create копируют два Krea-id (тесты в `PortraitApiTests` на месте; здесь не прогонялись). Пикер — Swarm ∩ каталог (`AllowedModelIds` / `allowedSwarmModels`). Сокет: коммит `6fb6efb` не трогал `ProtocolConstants.Version` / `PROTOCOL_VERSION`; текущая 10 — от фазы 64. Абзац каталога в `protocol.md` описывает Krea 2 без четырёх SDXL. `dotnet test tests/HSchool.Server.Tests --filter FullyQualifiedName~SwarmUiSettingsStoreTests`: 20 зелёных. Дописано: - `Resolve_AgeRuleCoversSixThroughElevenInclusive` — 6 и 11 → child, 5 и 12 → default, модель v2.5 - `CreateDefault_SeedsCatalogModels` — `ageRules` ровно 6–11 / `child` - `SwarmUiJson_MatchesCatalogAndDefaultPresets` — shotType avatar/fullBody у `child` - `NormalizeAfterLoad_EmptyModelsKeepSdxlPresetIdsInsteadOfKreaCatalog` — пустой `models` не становится Krea Код фазы не чинился. ### Открытое - Пример JSON у `GET .../portrait/prompt` в `protocol.md` всё ещё с `cinematic photo`, `age 12` и `(low quality, worst quality:1.4)` — это HTTP промпта/сцены (этапы C–D), не каталог. Здесь не правился: соседний проход трогает `protocol.md`. - Хостовый GET/create на Krea-id не перегонялся в этом worktree. - Этапы B–D (тосты, пауза, сборщик сцены, `generateImage`) — не этот проход. ## Срез 11. Этапы B–D — лента, сцена и кнопка - **Фазы:** 64–67 - **Проверен на:** `a544d34`, 2026-08-21 - **Пути:** `src/HSchool.Content/EventDefs.cs`, `src/HSchool.Content/EventDefValidator.cs`, `src/HSchool.Content/PromptContribution.cs`, `src/HSchool.Content/PromptContributionValidator.cs`, `src/HSchool.Simulation/EventSystem.cs`, `src/HSchool.Simulation/WorldEvent.cs`, `src/HSchool.Protocol/ProtocolCodec.cs`, `src/HSchool.Client/src/net/protocol.ts`, `docs/protocol.md`, `src/HSchool.Server/Game/NoticeBoard.cs`, `src/HSchool.Server/Game/PortraitSceneCollector.cs`, `src/HSchool.Server/Game/PortraitPromptBuilder.cs`, `src/HSchool.Server/Game/GenerationFailedPoster.cs`, `src/HSchool.Client/src/ui/noticeToasts.ts`, `src/HSchool.Client/src/ui/noticeModals.ts`, `src/HSchool.Client/src/ui/gameScreen.ts` - **Итог:** обещания 64–67 совпадают с кодом и тестами. Сокет v10 (`0x87` / `0x08`), info не в сейве, sticky паузит и переживает Open, сцена после одежды с бюджетом 6/2/2, кнопка `generateImage` — хозяин, успех не снимает паузу. Дописаны тесты на Play lock, неизвестный `action` и сборку «доска после одежды». Пример JSON у `GET .../portrait/prompt` приведён к прозе и сцене (замечание этапа A). Каталог Krea / состав моделей не ревьюился. Хостовые `GameSocketTests` / `NoticeImageApiTests` в этом проходе не гонялись (общий AppHost / живой сервер). ### 64. События и info-тост `EventDef`: severity / pause / ttlMs / trigger / action, локаль как у других def. Ваниль `DayStarted` / `LessonStarted` — info, TTL 8000, `none`. `EventSystem` на крае рабочего утра и на смене периода урока — один факт на школу, не по классам; повторный тик в ту же минуту пуст. Работник сопоставляет def и шлёт `0x87`. Клиент — тост, `t(defName)`, клик → `0x08`, TTL гасит локально, колонки нет. Info не в сейве и не на Open. Круглый трип и байтовая раскладка на C# и TS, `PROTOCOL_VERSION` = 10. `dotnet test tests/HSchool.Content.Tests --filter FullyQualifiedName~EventDefTests`: 3 зелёных (включая неизвестный action). `HSchool.Simulation.Tests` `WorldEventTests` и `HSchool.Protocol.Tests` `Notice_*` на месте, в этом проходе не перегонялись. ### 65. Варнинг и пауза `Notice` с `pause` ставит `running=false`; `SetRunning(true)` игнор, пока sticky не пуст. Dismiss последнего не Play. Потолок 8, девятый не эмитится. Sticky в сейве, info нет. Dismiss pausing — хозяин (сокет `CanManage`, HTTP `403` `not-owner`). Модал без TTL, очередь из одного. Play серый, пока модал открыт. ### 66. Сцена в промпте Блок `prompt` на Thing / Room / Territory / осадках; 121 символ и вес < 0 — ошибка загрузки. Ваниль: доска и снег непустые, `Chair` молчит. Сборщик на работнике: узел + fill + worn/held + погода только на улице, после одежды, вес ↓ затем `defName`. Бюджет в `SimulationOptions` (6 / 2 / 2). LoRA в `loras`, embed как ``. Сокет не бампили. `GET .../portrait/prompt` и Generate делят `PortraitPromptBuilder.Build` + `LookupBuildInput`. ### 67. Картинка с уведомления `GenerationFailed` — error, pause, `generateImage`. Эмит из `PortraitService` при Unavailable/TimedOut, не при успехе и не при пустом personId. HTTP `POST .../notices/{id}/generate` — хозяин, тот же сборщик, kind с доски или `full`. Без personId — `400` `notice-cannot-generate`, Swarm не зовётся. Успех паузу не снимает. Кнопка только при action и personId ≠ 0; тост дня без кнопки. Дописано: - `UnknownAction_FailsTheCatalog` — `action: teleport` валит загрузку - `CollectThenBuild_PutsBlackboardAfterClothing_ChairRoomDoesNot` — фрагмент доски после одежды; стул не попадает - `disables Play while a pausing notice is open` — Play `disabled`, title `noticePauseLocked` Код фаз не чинился, кроме примера JSON в `protocol.md` (устаревшие `age 12` / cinematic / `(word:1.4)`). Абзац каталога Krea не трогался. ### Открытое - `generateImage` на info-тосте (не sticky): кнопка на клиенте есть, HTTP ищет только sticky → `404` `unknown-notice`. Ваниль так не делает (кнопка на `GenerationFailed`). Валидатор не требует `pause` у `generateImage`. - Хостовые `GameSocketTests` (утро, пауза, гость, F5) и `NoticeImageApiTests` в этом worktree не гонялись: живой сервер пользователя, общий AppHost. - Локаль тоста при смене языка: `NoticeToasts.localize` обновляет текст, не подпись кнопки «создать картинку» (тост живёт 8 с).