Remove off-queue.md and add new design documentation files including README.md, defs.md, near-term.md, projects.md, runtime.md, people.md, staffing.md, and schedule.md to outline the structure and agreements for the game's design phases.

This commit is contained in:
Leonid Pershin
2026-08-20 12:26:13 +03:00
parent 12cc36b4dd
commit a37a5eb82d
101 changed files with 1015 additions and 921 deletions
+131
View File
@@ -0,0 +1,131 @@
# Ремесло: слои, страховка тестов, горячие точки
Договорённость на срез после одежды, сессии и склейки урока, не текущий код.
Фундамент: [`foundation.md`](../06-foundation/foundation.md). Проекты: [`projects.md`](../01-shell/projects.md).
Вне очереди: [`off-queue.md`](../off-queue/README.md). Общение (не ждём 44/46): [`social.md`](../09-social/social.md).
Игра уже живая: люди ходят, одеваются, учатся, болтают. Рядом лежат четыре копии одного
запрета на ссылки, `npm test` зелёный при красном `tsc`, работник школы на тысячу строк и
дамп, который не проверяет явку. Срез это **подметает**. Новой кнопки нет.
Срез отвечает на вопросы «сломал ли я слой», «прошёл ли клиентский tsc» и «можно ли разрезать
работника, не трогая поток». Оценок, протокола +1 и охоты на всё SOLID нет.
## Что увидит игрок
Ничего обязательного на экране. Школа после каждой фазы та же, что вчера. Игрок может заметить
только то, что агент и CI ловят дубликат ключа и чужой `using` до мержа, а не после.
## На какие вопросы отвечает
- Слои из [`projects.md`](../01-shell/projects.md) и инвариант 4 — тест в одном месте, не четыре копипасты.
- `npm test` клиента = typecheck + vitest; дубликат в `strings.ts` красный без `npm run build`.
- `SchoolWorker` и сборка карточки режутся по швам, поведение то же.
## Чего нет
- Новых экранов, полей сейва, байтов сокета.
- Фаз 44 и 46, портретов/SwarmUI как фичи, `GET /api/catalog.lunchBreaks`.
- Багов сессии (второе имя при живой куке, ключи DataProtection) — [`../bugs/README.md`](../../bugs/README.md).
- Инверсии Game → Api DTO и «пройти SOLID по всему дереву».
## Что меняется в уже принятом
| Было | Стало | Почему |
| --- | --- | --- |
| Запрет Arch/ASP.NET/`DateTime.Now` скопирован в People, Ai, Schedule, Simulation | Один проект `HSchool.Architecture.Tests`; Content и Protocol в том же списке | Четыре теста расходятся; Content и Protocol молчат |
| `npm test` = только vitest | `npm test` = `tsc -b` и vitest | Журнал трижды ловил дубликат ключа, зелёный в vitest |
| `SchoolWorker` и `PersonCardReader` — по одному файлу на всё | `partial` / файлы по шву; один тип, один поток, один `Read` | SRP без нового инварианта |
| Дамп «люди с узлом **или** нуждами» | После найма и хода часов — кто-то с `NodeId` | Нужды есть у всех; явка не проверялась |
Протокол, HTTP меню и формат сейва не меняются. Версию сокета не бампить.
## Этап A — страховка
Слои и клиентский tsc. После этапа школа целая, даже если работник ещё тысяча строк.
### Слои одной пачкой
Новый тестовый проект ссылается на библиотеки, не на AppHost. Пакета NetArchTest нет: как сейчас,
`GetReferencedAssemblies` и чтение `*.cs`. Копии `Assembly_DoesNotReference*` и `Sources_DoNotUseWallClock`
из People/Ai/Schedule/Simulation уезжают сюда.
Список (как [`projects.md`](../01-shell/projects.md)):
| Сборка | Не ссылается | Не содержит в исходниках |
| --- | --- | --- |
| Protocol | Arch, ASP.NET, Sockets, игровые проекты | `DateTime.Now` / `UtcNow` |
| Content | Arch, ASP.NET, Sockets, Protocol, Simulation | то же |
| People, Schedule, Ai | Arch, ASP.NET, Sockets | то же |
| Simulation | ASP.NET, Sockets | то же; Arch — да |
`HSchool.Server` в этот список не входит: он и есть хост.
### tsc в `npm test`
Скрипт `test` гоняет `typecheck` (`tsc -b`), потом vitest. Петля `"hschool-client": "file:"`
в `package.json` уходит, если без неё `npm test` и `npm run build` зелёные.
## Этап B — горячие точки
Именованный рефактор, не аудит всего дерева. После этапа поведение то же: карточка, пауза,
снимок, дамп.
1. **`SchoolWorker`** (~1200 строк) — `partial`: почта, тик, запись. Один тип, тот же
`LongRunning`-поток, без замка вокруг `School`/`World`.
2. **`PersonCardReader`** (~600) — сборка по вкладкам в том же классе или соседних
`internal` helper; публичный вход по-прежнему `Read(School, personId, locale)`.
3. **`personCard.ts`** (~850) — модули по вкладкам; `personCardHost.ts` по-прежнему
ходит в HTTP.
Game-слой по-прежнему может зависеть от DTO в `Api` — инверсия не этот срез.
## Этап C — дамп не врёт
`Dump_ReturnsPeopleNodesAndTimetable` после найма **запускает** часы и ждёт человека с
`NodeId`, не `Needs.Count > 0`. На паузе не ждать людей (кадры присутствия всё равно идут).
## Где живёт код
Новой игровой библиотеки нет.
| Что | Куда |
| --- | --- |
| Запреты слоёв и wall-clock | `tests/HSchool.Architecture.Tests` |
| Скрипт `npm test` | `src/HSchool.Client/package.json` |
| Работник | `src/HSchool.Server/Game/SchoolWorker*.cs` |
| Карточка HTTP | `PersonCardReader` + клиент `ui/personCard*.ts` |
| Дамп | уже `DevEndpoints` / `SchoolDumpReader`; меняется тест |
## Советы, которые стоит принять сразу
- Не тащить NetArchTest ради четырёх `Assert.DoesNotContain`.
- Не резать `SchoolWorker` на несколько типов с разными потоками.
- Не инвертировать Game → Api «заодно»: это другой срез или вне очереди.
- Не бампить протокол и не расширять catalog, чтобы «заодно» отдать `lunchBreaks`.
- Фаза 55 занята веткой `phase/55-view-state` — номера среза с 56.
## Заведомо не сейчас
- Срез 9: ссора/драка, политика речи и дом.
- Баги сессии и DataProtection.
- `GET /api/catalog` + `lunchBreaks`.
- Портреты как контент; SwarmUI не выкидывать.
- README «школа ещё пустая» как отдельная кампания — одна строка в фазе 56, не рерайт.
- Новый именованный кусок игры (оценки, приказы, магазины).
## Зафиксировано этим разговором
| Тема | Решение |
| --- | --- |
| Куда | Срез 10, не «Вне очереди» |
| SOLID | Arch-тесты слоёв + три именованные точки, не всё дерево |
| Список | Журнал ревью + ложь AGENTS; без инвентаризации-фазы |
| Баги сессии | Не брать, `/bug-work` |
| Протокол | Не бампить |
| HTTP | Не расширять catalog |
| Сейв | Не трогать |
| Срез 9 | Не ждать 44/46, не писать в них |
| Стоп | После A школа целая; после B — тоже |
| Ваниль | Без пака |
| Номера | 56–59; 55 занята |