From 02156e4491745eb0e797d426d03d8dd4fea8e4c9 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Fri, 21 Aug 2026 20:46:33 +0300 Subject: [PATCH] Register slice 16 sight: inspect images and a denser linked catalog. Co-authored-by: Cursor --- AGENTS.md | 1 + docs/design/16-sight/sight.md | 232 ++++++++++++++++++++ docs/phases/16-sight/85-wardrobe-prompts.md | 49 +++++ docs/phases/16-sight/86-rooms-rules.md | 53 +++++ docs/phases/16-sight/87-image-subject.md | 54 +++++ docs/phases/16-sight/88-inspect-button.md | 44 ++++ docs/phases/16-sight/README.md | 27 +++ docs/phases/README.md | 1 + 8 files changed, 461 insertions(+) create mode 100644 docs/design/16-sight/sight.md create mode 100644 docs/phases/16-sight/85-wardrobe-prompts.md create mode 100644 docs/phases/16-sight/86-rooms-rules.md create mode 100644 docs/phases/16-sight/87-image-subject.md create mode 100644 docs/phases/16-sight/88-inspect-button.md create mode 100644 docs/phases/16-sight/README.md diff --git a/AGENTS.md b/AGENTS.md index 2df68d1..3c9e9ea 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -31,6 +31,7 @@ way; this file is *how to work in them*. | marks 2–5, attendance journal | [`docs/design/13-grades/`](docs/design/13-grades/grades.md) — slice 13, phases 73–76 | | health conditions, diseases, contagion, nurse | [`docs/design/14-health/`](docs/design/14-health/health.md) — slice 14, phases 77–80 | | fight injuries, sick teachers, parent summons, wet/aftereffect | [`docs/design/15-fallout/`](docs/design/15-fallout/fallout.md) — slice 15, phases 81–84 | +| inspect images (room/thing), denser catalog, extra dress knobs | [`docs/design/16-sight/`](docs/design/16-sight/sight.md) — slice 16, phases 85–88 | | a bug in already-shipped behaviour | `.claude/skills/bug-work` — document in `docs/bugs/`, discuss only if the fix has a fork, then patch | | a task that is not in any slice | `.claude/skills/side-work` — discuss, document in [`docs/phases/off-queue/`](docs/phases/off-queue/README.md), then implement | | a new named slice of the game | `.claude/skills/slice-work` — discuss, write design and phases, then `/phase-orch` | diff --git a/docs/design/16-sight/sight.md b/docs/design/16-sight/sight.md new file mode 100644 index 0000000..dbb212b --- /dev/null +++ b/docs/design/16-sight/sight.md @@ -0,0 +1,232 @@ +# Вид и каталог + +Договорённость на срез после событий/сцены и одежды, не текущий код. +Сцена и тосты: [`events.md`](../11-events/events.md). Портреты: [`portrait-models.md`](../off-queue/portrait-models.md), +[`portrait-prompt-craft.md`](../off-queue/portrait-prompt-craft.md). Вещи и правила: [`inventory.md`](../07-inventory/inventory.md). +Экран: [`near-term.md`](../01-shell/near-term.md). Сессия (гость): [`session.md`](../08-session/session.md). +Протокол: [`protocol.md`](../../protocol.md). + +Игрок **смотрит** именованную сущность — и может попросить картинку. Каталог `core` перестаёт +быть «достаточным минимумом»: одежда, комнаты и правила связаны так, чтобы и генератор людей, +и генератор кадра видели одно и то же. Кадр локации больше не запрещён: это не портрет человека +без тела, а отдельный субъект. + +Срез отвечает на вопросы «что можно нарисовать», «почему в промпте худи, а не только рубашка» +и «какие ещё две ручки дресс-кода отбирают вещи». LLM, ControlNet и бумажной куклы нет. + +## Что увидит игрок + +На карточке человека кнопка портрета как сейчас. На панели выбранного узла карты — «создать +картинку» кабинета, двора, коридора, если у места или его fill есть что сказать генератору. +В списке одежды, ноши и предметов локации — то же у вещи с непустым `prompt`. Гость смотрящей +школы жмёт те же кнопки, что хозяин: как `POST .../portrait`, не как pausing-notice. + +В «Правилах» две новые оси на роль (ученики / сотрудники): аксессуары и обувь. Как форма и +цвет — с завтрашнего рабочего утра. + +Новая школа и новый набор одевают шире: худи, пиджак, кеды рядом со старой рубашкой. Живых +людей молча не переодеваем. + +## На какие вопросы отвечает + +- Какой HTTP-субъект кадра, если это не человек: узел карты и тип вещи. +- Как kind `scene` / `thing` стыкуется с уже собранным портретом, не ломая инварианты 1, 3, 4. +- Какие дефы ванили получают прозу и fill, чтобы кабинет не рисовался пустым стулом. +- Как две новые политики одежды фильтруют тот же `Appropriateness`, без нового вида поведения. + +## Чего нет + +- LLM-текста, ControlNet, позы в UI, автогенерации всем узлам утром. +- Спрайтов-слоёв и бумажной куклы: по-прежнему PNG по запросу, слои на карточке — текст и цвет. +- Картинок у часов, журнала, комбобоксов, тоста без сущности. +- Группового портрета класса с лицами конкретных учеников. +- Магазинов, одевания с карточки, новых стран, отдельного пака variety. +- Черт «любит худи» и экшена `Inspect`. +- Лифта живых `portraitSettings` и живого гардероба. + +## Что меняется в уже принятом + +| Было | Стало | Почему | +| --- | --- | --- | +| Kind `scene` запрещён ([`events.md`](../11-events/events.md)) | Узел карты — отдельный субъект кадра | «Просматриваемое» уже есть на панели локации | +| Картинка только у человека и notice с `personId` | Плюс узел и вещь с непустым вкладом | Иначе кабинет и куртка только текстом | +| Одежда в промпте из локали карточки | Слой одежды берёт английский `prompt` с ThingDef | RU UI не должен кормить Krea русским существительным | +| Ванильный гардероб — минимум для генератора | Закрытый расширенный список + цвета | Иначе новые правила не из чего выбирать | +| Стул и большинство комнат молчат в кадре | Ключевые Room/Thing говорят; `Chair` по-прежнему пустой | Бюджет сцены; не каждый fill | +| Правила: форма × цвет (и речь сбоку) | Плюс аксессуары и обувь | Две оси, которые уже есть слоями | +| «Портреты одежды не этот срез» ([`inventory.md`](../07-inventory/inventory.md)) | PNG вещи по кнопке, не спрайт на слое | Просмотр, не кукла | +| Гость генерирует портрет человека, не notice | Гость генерирует и локацию, и вещь | Смотреть чужую школу иначе слепое | + +Протокол: новые HTTP маршруты узла и вещи. Версию сокета **не** бампим. Сейв: PNG рядом с +портретами; у правил одежды два новых поля с подъёмом `free`. Живые `portraitSettings` не +переписываем: нет kind `scene`/`thing` — fallback из опций. + +## Этап A — каталог + +Школа целая без арта кабинета: люди разнообразнее, портрет человека уже видит худи и доску. + +### Гардероб + +Закрытый список **новых** `ThingDef` в `core` (слои как в срезе 7, не новые роли): + +| Def | Слой | Зачем | +| --- | --- | --- | +| `Hoodie` | OverTop | Неформальный верх | +| `Cardigan` | OverTop | Теплее свитера, спокойнее худи | +| `Vest` | OverTop | Жилет, формальность выше | +| `Blazer` | OverTop | Пиджак; снимается отдельно от брюк | +| `Polo` | Top | Между футболкой и рубашкой | +| `Blouse` | Top | Женский верх, формальность | +| `Turtleneck` | Top | Водолазка | +| `Tights` | Socks | Колготки, `sex: female` | +| `Leggings` | Bottom | Неформальный низ, женский | +| `Sweatpants` | Bottom | Спортивные штаны не-PE | +| `Sneakers` | Shoes | Кеды, низкая формальность | +| `SchoolShoes` | Shoes | Школьные туфли, тег school | +| `Cap` | Head | Кепка, не шапка от мороза | +| `Headband` | Head | Ободок | +| `Raincoat` | Outer | Плащ; не шуба | +| `PeTrackPants` | Bottom | PE-низ полной длины рядом с шортами | + +Новые `ColorDef`: `Navy` (`neutral`, `school`), `Brown` (`neutral`), `Burgundy` (`neutral`), +`Pink` (`bright`), `Yellow` (`bright`). Существующие вещи **могут** получить Navy/Brown в +`colors`, где это уместно (брюки, пиджак), без смены палитры на радугу. + +На **каждой** носимой вещи, включая уже существующие `TShirt` / `Shirt` / …, заполняется +английский блок `prompt` (тот же вид, что у доски). Пустой — вещь в портрете человека +по-прежнему собирается из подписи; цель ванили — непустой блок, чтобы locale карточки не +текла в Swarm. Длина фрагмента как у сцены: ≤ 120 символов, иначе ошибка загрузки. + +Генератор одежды включает новые def в те же броски слоёв (`optionalApparelChance` и выбор +низа/верха/обуви). Детерминизм: тот же сид + карта + страна → тот же ростер; состав одежды +на **новой** школе может отличаться от старого золотого отпечатка — фикстуру обновляет эта +фаза. Живой `people.json` не дополняем худи задним числом; новый набор (create / yearly +intake) — да. + +### Комнаты, fill, правила + +Непустой `prompt` у ванильных мест, которые игрок реально открывает: `Classroom` (уже есть), +`Library`, `ComputerLab`, `GymHall`, `Cafeteria`, `MedicalOffice`, `PrincipalsOffice`, +`TeachersRoom`, `SecretaryOffice`, `UtilityRoom`, меняльные, `SchoolYard`, `EntranceHall`, +`Corridor`. `Restroom` — короткая проза умывальной, не кабинки крупным планом. `Stairwell`, +этажи и корпуса без текста **молчат** (кнопки не будет). + +Новые fill-вещи (слоты на def комнаты и/или дефолтной карте, не свободная геометрия): + +| Def | Куда | +| --- | --- | +| `PottedPlant` | класс, библиотека, кабинет директора | +| `WallPoster` | класс | +| `NoticeBoard` | холл | +| `GymMat` | зал | + +`Chair`, `StudentDesk`, шкафчик без прозы — молчат, как сейчас. Связность: fill с текстом +попадает в сборщик сцены человека (фаза 66 уже спрашивает fill) и позже в кадр узла. + +Две оси на `DressRulePair`, те же роли ученики/сотрудники, вступление **с завтра**: + +| Ось | Значения | Смысл | +| --- | --- | --- | +| Аксессуары | `free` / `none` | `none` — слой `Accessory` в школе неуместен (ремень, шарф). Шапка от холода не аксессуар | +| Обувь | `free` / `uniform` | `uniform` — обувь с тегом цвета `school` и формальностью не ниже обычной; кеды не в школу (PE — свой режим) | + +Дефолт обеих — `free`, чтобы живая школа без полей вела себя как сегодня. Неизвестный код — +`400`, как у формы/цвета. Речь не трогаем. Новых `ApparelIssue` достаточно, чтобы утренний +dresser снял/заменил; ходьбу и магазины не открываем. + +После этапа портрет человека уже богаче; клик по кабинету ещё может не рисовать. + +## Этап B — кадр с панели + +Школа целая: кнопка на том, что уже открыто глазом. + +### Субъект + +Три субъекта, не четвёртый kind портрета человека в том же URL: + +| Субъект | Ключ | PNG | Сборка промпта | +| --- | --- | --- | --- | +| Человек | как сейчас | `saves/{id}.portraits/` | внешность + одежда + сцена узла | +| Узел карты | id узла | `saves/{id}.images/node.{safeId}.png` | место + fill + погода, если улица; **без** лиц карточки | +| Вещь | `defName` + цвет, если есть | `saves/{id}.images/thing.{def}.{color\|none}.png` | блок вещи + цвет + износ, если смотрим надетое; без человека | + +HTTP (имена уточнит фаза, смысл нет): + +- `GET`/`POST` `.../nodes/{nodeId}/image` и `.../image/prompt` +- `GET`/`POST` `.../things/{defName}/image?color=` и `.../image/prompt` + +Неизвестный узел / def — `404`. Пустой вклад (нет ни одного фрагмента) — `400` `cannot-generate`, +Swarm не зовём. Swarm как у портрета: `503` / `502` / `504`. Гость — `201`, не `403`. + +В шаблоне `swarmui.json` у пресетов появляются shot kind `scene` и `thing` (проза кадра без +человека). Живая копия без них **не лифтится**: сборщик подставляет fallback из +`SimulationOptions` (строки по умолчанию, не константы в билдере). + +Кадр локации не портретирует присутствующих поимённо. Если в узле кто-то есть, допустим **один** +общий фрагмент из опций («pupils at desks») — не список имён и не их одежда. + +Вещь на карте — тип fill, без нового instance id в сейве. Вещь на человеке в промпт кладёт +цвет и полосу износа; ключ кэша PNG — def+цвет, не personId (перегенерация обновляет файл). + +### Кнопка + +Панель локации, строка одежды/ноши, строка предмета в локации: кнопка только если GET prompt +(или эквивалентная проверка вклада) не пустой. «Показать промпт» — тот же текст, что уйдёт в +Swarm. Открытие панели не генерирует. Строки через `t(...)`. + +Notice `generateImage` не меняем: по-прежнему человек и хозяин. + +После этапа клик по кабинету или белой футболке даёт PNG. + +## Где живёт код + +Нового проекта нет. + +| Что | Куда | +| --- | --- | +| Новые Thing/Color, `prompt` на одежде и комнатах, слоты fill | `HSchool.Content` + JSONC `core` | +| Генератор гардероба, золотой ростер | `HSchool.People` | +| Уместность аксессуаров и обуви | `HSchool.Content.Appropriateness` + dresser в Simulation / People | +| HTTP картинки узла и вещи, PNG, fallback shot | `HSchool.Server` (сервис портретов / работник спрашивает карту) | +| Маршруты | `docs/protocol.md` (+ клиент `api.ts`); сокет не трогаем | +| Кнопки на панели и карточке | `src/HSchool.Client/src/ui` | +| Kind `scene`/`thing` в шаблоне | `swarmui.json` | + +Инвариант 4: Simulation по-прежнему не знает Swarm. Сборщик кадра узла — тот же работник, что +спрашивает комнату для портрета. + +## Советы, которые стоит принять сразу + +- Не вешать картинку локации на кадр присутствия 2 Гц: PNG по HTTP, как портрет. +- Не давать вещи instance id «чтобы кэш был уникальнее». Def+цвет дешевле смены `people.json`. +- Не лифтить живой гардероб «всем по худи». Разнообразие — create и набор. +- Не рисовать корпус без `prompt`: этаж в дереве остаётся навигацией. +- Не складывать `scene` в `PortraitKind` человека: иначе `kind=scene` на `/people/.../portrait`. +- Гость жжёт GPU на картинке кабинета — это уже так на лице; очередь Swarm общая. + +## Заведомо не сейчас + +- LLM, ControlNet, редактор позы, автоген утра. +- Бумажная кукла, иконки слоёв, арт на каждом ряду дерева сразу (только выбранный узел). +- Журнал оценок как картинка, погода у часов как PNG. +- Групповое фото класса, лица с карточек на кадре кабинета. +- Магазин, стирка, игрок одевает, новые `CountryDef`. +- Черты вкуса к одежде, `Inspect` как действие ИИ. +- Лифт `portraitSettings`, возврат SDXL. + +## Зафиксировано этим разговором + +| Тема | Решение | +| --- | --- | +| Форма | Один срез 16, не два и не side-work | +| Просматриваемое | Человек, узел карты, надетое/несомое, fill локации | +| Kind `scene` | Да, без человека в сборке | +| Каталог | Закрытый список в `core`, не пак | +| Связность | `prompt`, fill, теги, правила — без новых глаголов ИИ | +| Правила | Аксессуары `free`/`none`, обувь `free`/`uniform`, с завтра | +| Гость | Как портрет человека, не как notice | +| Живые школы | Без лифта лиц и гардероба; правила без полей → `free` | +| Кэш вещи | def + цвет, не экземпляр | +| Стоп | После A школа в разнообразии; после B — кнопка на панели | +| Протокол | HTTP в коммите 87; сокет не +1 | +| Ваниль/пак | `core` | diff --git a/docs/phases/16-sight/85-wardrobe-prompts.md b/docs/phases/16-sight/85-wardrobe-prompts.md new file mode 100644 index 0000000..1e9df3f --- /dev/null +++ b/docs/phases/16-sight/85-wardrobe-prompts.md @@ -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`. Не лифт живых лиц. diff --git a/docs/phases/16-sight/86-rooms-rules.md b/docs/phases/16-sight/86-rooms-rules.md new file mode 100644 index 0000000..ec7902e --- /dev/null +++ b/docs/phases/16-sight/86-rooms-rules.md @@ -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 картинки узла. Не кнопку на панели локации. Не групповое фото. Не лифт лиц. diff --git a/docs/phases/16-sight/87-image-subject.md b/docs/phases/16-sight/87-image-subject.md new file mode 100644 index 0000000..9d827c7 --- /dev/null +++ b/docs/phases/16-sight/87-image-subject.md @@ -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. Не бамп сокета. Не групповые лица. diff --git a/docs/phases/16-sight/88-inspect-button.md b/docs/phases/16-sight/88-inspect-button.md new file mode 100644 index 0000000..1ca36c1 --- /dev/null +++ b/docs/phases/16-sight/88-inspect-button.md @@ -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. Не бумажная кукла. Не картинка +журнала и часов. diff --git a/docs/phases/16-sight/README.md b/docs/phases/16-sight/README.md new file mode 100644 index 0000000..bb2f9d1 --- /dev/null +++ b/docs/phases/16-sight/README.md @@ -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. diff --git a/docs/phases/README.md b/docs/phases/README.md index ce5ce51..75c3ced 100644 --- a/docs/phases/README.md +++ b/docs/phases/README.md @@ -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/) |