Register slice 16 sight: inspect images and a denser linked catalog.
ci / server (push) Failing after 3m43s
ci / client (push) Successful in 22s

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-21 20:46:33 +03:00
co-authored by Cursor
parent bcc3f1333c
commit 02156e4491
8 changed files with 461 additions and 0 deletions
@@ -0,0 +1,49 @@
# Фаза 85. Гардероб и промпт одежды
## Зависимости
- [Фаза 30](../07-inventory/30-apparel-defs.md)
- [Фаза 31](../07-inventory/31-dress-generator.md)
- [Фаза 62](../off-queue/62-portrait-prompt-craft.md)
## Зачем
Ванильная одежда перестаёт быть минимумом «чтобы генератор было чем кормить». Портрет человека
берёт английскую прозу с def, а не подпись карточки.
## Задачи
- [ ] Новые `ThingDef` из закрытого списка в [`sight.md`](../../design/16-sight/sight.md): худи,
кардиган, жилет, пиджак, поло, блузка, водолазка, колготки, леггинсы, спортивные штаны,
кеды, школьные туфли, кепка, ободок, плащ, PE-штаны. Слои существующие, не новые роли
- [ ] Новые `ColorDef`: Navy (school+neutral), Brown, Burgundy, Pink (bright), Yellow (bright).
Уместные старые вещи могут добавить Navy/Brown в `colors`
- [ ] На **каждой** носимой ванильной вещи, включая TShirt/Shirt/…, непустой английский
`prompt.positive` (≤ 120 символов). Негатив/LoRA не обязательны. Длиннее — ошибка загрузки
- [ ] Сборщик одежды портрета предпочитает `prompt` def, подставляя цвет и износ; при RU-локали
карточки в Swarm не уходит русское «футболка»
- [ ] Генератор гардероба бросает новые def на тех же слоях, что свитер/обувь/верх. Живой
`people.json` не дополнять. Create и набор — да
- [ ] Локали RU/EN на новые def. Сокет не бампить. `portraitSettings` не лифтить
## Тесты, без которых фаза не закрыта
- [ ] Каталог `core` грузится; неизвестный цвет на новой вещи — ошибка загрузки
- [ ] `prompt.positive` длиннее 120 на одежде — ошибка загрузки
- [ ] Тот же сид+карта+страна → тот же состав людей; золотой гардероб обновлён, если бросок
изменился (свойство «кто-то в OversTop из расширенного множества», не «первый ученик в худи»)
- [ ] Новая школа: среди одетых есть хотя бы один новый def из списка (не обязательно худи у id 1)
- [ ] Сборка промпта портрета при locale `ru`: слой одежды содержит английский фрагмент TShirt,
не слово из `ru.jsonc`
- [ ] Живая карточка без новых вещей по-прежнему одета; загрузка сейва не выдаёт худи задним числом
## Критерий готовности
- Create школы → в гардеробе видны новые фасоны, портрет «показать промпт» говорит hoodie/blazer
по-английски
- Отфильтрованные тесты по Testing policy проходят (`HSchool.Content`, `HSchool.People`,
сборщик на сервере — не весь раствор)
## Стоп
Не кнопки на кабинете. Не оси аксессуаров/обуви. Не kind `scene`. Не лифт живых лиц.
+53
View File
@@ -0,0 +1,53 @@
# Фаза 86. Комнаты, вещи, правила
## Зависимости
- [Фаза 85](85-wardrobe-prompts.md)
- [Фаза 37](../07-inventory/37-school-rules.md)
- [Фаза 66](../11-events/66-scene-prompt.md) (сборщик fill уже есть; не блокер прозы на RoomDef)
## Зачем
Место и fill умеют сказать кадру то же, что игрок видит в панели. Две ручки правил отбирают
новые слои, без магазинов и без «надеть с карточки».
## Задачи
- [ ] Непустой английский `prompt` у ванильных мест из [`sight.md`](../../design/16-sight/sight.md)
(библиотека, комп. класс, зал, столовая, медкабинет, кабинет директора, учительская,
секретарь, техник, меняльные, двор, холл, коридор, туалет — умывальная). `Stairwell` /
этажи / корпуса без текста молчат. `Chair` молчит
- [ ] Fill-вещи `PottedPlant`, `WallPoster`, `NoticeBoard`, `GymMat` с прозой; слоты на
соответствующих RoomDef и/или дефолтной карте
- [ ] Портрет человека в классе после 66 включает растение/плакат, если они в fill и вес прошёл
бюджет
- [ ] `DressRulePair`: поля аксессуаров (`free`/`none`) и обуви (`free`/`uniform`). Дефолт `free`.
Сейв без полей поднимается в `free`, файл сам не переписываем до записи правил
- [ ] Уместность: `none` → слой Accessory в школе — issue; `uniform` → кеды/не-school цвет обуви
в everyday — issue. PE не требует туфли. Утро/pending как у формы: с завтра
- [ ] HTTP GET/POST `dress-rules` отдаёт и принимает новые поля; неизвестный код — `400`. Вкладка
«Правила»: два комбобокса на роль рядом с формой/цветом. Речь не трогать. Строки `t(...)`
- [ ] Сокет не бампить
## Тесты, без которых фаза не закрыта
- [ ] Каталог: у `Library` и `GymHall` непустой prompt; у `Chair` пустой
- [ ] Дефолтная карта/слоты: в зале есть `GymMat` или эквивалентный слот; в классе — растение или
плакат
- [ ] GET правил новой школы — accessories/shoes `free` на обе роли
- [ ] POST `none` сегодня не снимает ремень до следующего рабочего утра; после утра на учениках
в школе нет слоя Accessory
- [ ] POST `uniform` → после утра на учениках в everyday нет `Sneakers`
- [ ] Неизвестный код оси — `400`
- [ ] Vitest: смена нового комбобокса не зовёт API до «Применить»
- [ ] Сборка сцены человека (как 66): fill с прозой попадает в prompt, молчаливый стул — нет
## Критерий готовности
- Выставить «без аксессуаров» и «форма обуви», промотать на утро — шарфов нет, туфли школьные
- «Показать промпт» ученика в классе может содержать растение или плакат
- Отфильтрованные тесты: Content, Simulation/Appropriateness, AppHost dress-rules, Vitest панели
## Стоп
Не HTTP картинки узла. Не кнопку на панели локации. Не групповое фото. Не лифт лиц.
+54
View File
@@ -0,0 +1,54 @@
# Фаза 87. Субъект кадра
## Зависимости
- [Фаза 66](../11-events/66-scene-prompt.md)
- [Фаза 60](../off-queue/60-portrait-models.md) (пресеты и shot kind)
- [Фаза 39](../08-session/39-school-owners.md) (гость уже генерирует портрет человека)
## Зачем
Кабинет и футболка — не человек в URL портрета. Появляется HTTP субъекта «узел» и «вещь»,
PNG на диске, kind `scene`/`thing` без лифта живых пресетов.
## Задачи
- [ ] `GET`/`POST` `.../schools/{id}/nodes/{nodeId}/image` и `.../image/prompt`. Ключ узла —
id карты. PNG: `saves/{id}.images/node.{safeId}.png`
- [ ] `GET`/`POST` `.../schools/{id}/things/{defName}/image` (query `color`) и `.../image/prompt`.
PNG: `saves/{id}.images/thing.{def}.{color\|none}.png`. Нет instance id
- [ ] Сборка узла: Room/Territory prompt + fill с текстом + погода, если улица. Без внешности и
одежды человека. При ненулевой занятости узла — не больше одного общего фрагмента из
`SimulationOptions`, не имена
- [ ] Сборка вещи: `prompt` def + цвет + износ, если смотрим надетое (износ в промпте; ключ файла
без износа). Молчаливый def — не Swarm
- [ ] Пустой вклад — `400` `cannot-generate`. Нет узла/def — `404`. Swarm как портрет (`503`/`502`/`504`)
- [ ] Гость: тот же успех, что `POST .../people/.../portrait`, не `403`
- [ ] В шаблоне `swarmui.json` у пресетов shot kind `scene` и `thing`. Живая школа без них не
переписывается; fallback строки в `SimulationOptions`
- [ ] [`protocol.md`](../../protocol.md) — маршруты и коды, тем же коммитом. Сокет не бампить.
`PortraitKind` человека не расширять значением `scene`
## Тесты, без которых фаза не закрыта
- [ ] GET картинки узла до POST — `404` `image-missing` (или согласованный код в protocol.md)
- [ ] POST класса: prompt содержит место/fill, не «teenage girl» / возраст карточки
- [ ] POST узла без вклада (этаж/лестница без prompt) — `400`, Swarm не звали
- [ ] POST `Chair``400` `cannot-generate`
- [ ] POST `TShirt?color=White` — prompt английский про футболку, без субъекта-человека
- [ ] Гость POST узла — не `403` (тот же класс исхода, что портрет; хост с фикстурой Swarm или
тот же skip-контракт, что у портрета)
- [ ] Живой `portraitSettings` без kind `scene` генерирует узел через fallback и не перезаписывает
сейв пресета
- [ ] Occupancy > 0 добавляет не больше одного общего фрагмента; имён людей в prompt нет
- [ ] Сокет Version не меняется
## Критерий готовности
- curl/хостовый тест: POST кабинета → PNG на диске; GET отдаёт image/png
- «Показать промпт» узла доступен HTTP, даже если кнопки в UI ещё нет
- Отфильтрованные тесты: AppHost (маршруты), сборщик на сервере; не весь раствор
## Стоп
Не кнопки в DOM. Не автоген всем узлам. Не ControlNet. Не бамп сокета. Не групповые лица.
+44
View File
@@ -0,0 +1,44 @@
# Фаза 88. Кнопка на панели
## Зависимости
- [Фаза 87](87-image-subject.md)
- [Фаза 86](86-rooms-rules.md)
## Зачем
То, что уже открыто глазом, получает ту же кнопку, что портрет: узел, одежда, fill. Гость
смотрит и рисует.
## Задачи
- [ ] Панель выбранной локации: «создать картинку» и «показать промпт», если узел может дать
непустой вклад (как 87). Нет вклада — кнопок нет. Открытие дерева не генерирует
- [ ] Строка одежды и ноши на карточке: кнопка, если у def есть `prompt`. Цвет из строки уходит
query. Износ в промпт кладёт сервер
- [ ] Строка предмета в секции «предметы» локации: то же для fill с прозой; молчаливый стул —
без кнопки
- [ ] Успех показывает PNG (как карточка человека). Ошибки Swarm — тот же текст, что портрет
- [ ] Гость видит и жмёт. Notice `generateImage` не менять (хозяин, человек)
- [ ] Строки через `t(...)`, обе локали. Сокет не бампить
## Тесты, без которых фаза не закрыта
- [ ] Vitest: у узла Classroom кнопка есть; у узла без prompt (лестница/этаж) — нет
- [ ] Vitest: у строки TShirt кнопка есть; у Chair в предметах — нет
- [ ] Vitest: гость не лишает кнопку disabled так, как notice
- [ ] Клиент зовёт POST узла/вещи, не `.../people/.../portrait?kind=scene`
- [ ] «Показать промпт» показывает тело GET `.../prompt`, не выдуманную строку на клиенте
- [ ] Открытие панели / вкладки одежды не вызывает POST
## Критерий готовности
- Клик по кабинету на дереве → панель → картинка класса
- Клик по белой футболке на карточке → PNG вещи
- Гость на чужой школе может то же
- `npm test` по затронутым `ui/*.test.ts` (tsc+vitest клиента, не весь раствор)
## Стоп
Не автоген утра. Не иконка на каждом ряду дерева. Не LLM. Не бумажная кукла. Не картинка
журнала и часов.
+27
View File
@@ -0,0 +1,27 @@
Индекс срезов: [`../README.md`](../README.md).
## Срез 16. Вид и каталог
Дизайн: [`sight.md`](../../design/16-sight/sight.md).
Игрок смотрит сущность и может попросить картинку. Ванильный каталог гуще и связан с кадром
и правилами. Срез можно остановить после этапа A — школа одета разнообразнее, даже если
кабинет ещё без PNG.
**Этап A — каталог.** Одежда, промпт, комнаты, две ручки правил.
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [85. Гардероб и промпт одежды](85-wardrobe-prompts.md) | ⬜ | Новые вещи и цвета; английский `prompt` на слоях |
| [86. Комнаты, вещи, правила](86-rooms-rules.md) | ⬜ | Промпт мест, fill, аксессуары и обувь с завтра |
85 независима от 87. 86 стоит на 85 и на 37.
**Этап B — кадр с панели.** Узел и вещь.
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [87. Субъект кадра](87-image-subject.md) | ⬜ | HTTP узла и вещи, PNG, kind `scene`/`thing` |
| [88. Кнопка на панели](88-inspect-button.md) | ⬜ | Локация, одежда, fill; гость как портрет |
87 стоит на 66; можно параллельно с 85. 88 стоит на 86 и 87.
+1
View File
@@ -26,4 +26,5 @@
| 13. Учёба и журнал | 73–76 | [13-grades](13-grades/README.md) | [grades](../design/13-grades/grades.md) |
| 14. Здоровье и болезни | 77–80 | [14-health](14-health/README.md) | [health](../design/14-health/health.md) |
| 15. Последствия | 81–84 | [15-fallout](15-fallout/README.md) | [fallout](../design/15-fallout/fallout.md) |
| 16. Вид и каталог | 85–88 | [16-sight](16-sight/README.md) | [sight](../design/16-sight/sight.md) |
| Вне очереди | 48–55 | [off-queue](off-queue/README.md) | [off-queue](../design/off-queue/) |