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
@@ -0,0 +1,42 @@
# Фаза 56. Слои одной пачкой
## Зависимости
Нет. Запреты уже размазаны по четырём тестовым проектам.
## Зачем
Инвариант 4 и таблица в [`projects.md`](../../design/01-shell/projects.md) должны ломаться одним красным
тестом, а не «забыли дописать пятую копию». Content и Protocol сейчас молчат.
## Задачи
- [ ] Проект `tests/HSchool.Architecture.Tests` в solution, `IsTestProject`, без AppHost и без
нового NuGet. Ссылки на Protocol, Content, People, Schedule, Ai, Simulation
- [ ] Тесты ссылок: каждая библиотека из таблицы в [`craft.md`](../../design/10-craft/craft.md) — этап A
- [ ] Тесты исходников: в `src/HSchool.{Protocol,Content,People,Schedule,Ai,Simulation}` нет
`DateTime.Now` / `DateTime.UtcNow`
- [ ] Удалить копипасты `Assembly_DoesNotReference*` и `Sources_DoNotUseWallClock` из People,
Ai, Schedule, Simulation (остальные факты тех файлов не трогать)
- [ ] Testing policy в `AGENTS.md`: слои — `HSchool.Architecture.Tests`, не хост
- [ ] README: школа не «ещё пустая»; потолок create — слоты игрока, не «шесть»
## Тесты, без которых фаза не закрыта
- [ ] Protocol не ссылается на Arch, ASP.NET, Sockets, Content, Simulation
- [ ] Content не ссылается на Arch, ASP.NET, Sockets, Protocol, Simulation
- [ ] People, Schedule, Ai не ссылаются на Arch, ASP.NET, Sockets
- [ ] Simulation не ссылается на ASP.NET и Sockets (Arch — можно)
- [ ] Исходники шести библиотек выше не содержат `DateTime.Now` / `DateTime.UtcNow`
- [ ] В People/Ai/Schedule/Simulation.Tests больше нет этих двух фактов
## Критерий готовности
- `dotnet test tests/HSchool.Architecture.Tests` проходит
- Добавить `using System.Net.Http` в `HSchool.Content` — слой красный
- Старые проекты тестов без этих фактов по-прежнему собираются
## Стоп
Не подключать NetArchTest. Не гонять AppHost. Не резать `SchoolWorker`. Не ссылаться на
`HSchool.Server`. Не бампить протокол, не трогать сейв.
@@ -0,0 +1,37 @@
# Фаза 57. tsc в npm test
## Зависимости
Нет. Скрипт `typecheck` уже есть; `npm test` его не вызывает.
## Зачем
Журнал срезов 1 и 7: дубликат ключа в `strings.ts` / поле в клиенте зелёный в vitest и красный
на `npm run build`. Агент гоняет `npm test` и мержит дыру.
## Задачи
- [ ] `package.json``"test":` сначала `tsc -b` (`typecheck`), потом `vitest run`. Без
`&&` скрывать код выхода typecheck
- [ ] Убрать петлю `"hschool-client": "file:"` из `dependencies`; `npm test` и `npm run build`
без неё
- [ ] `AGENTS.md` Commands и Testing policy: клиентский `npm test` включает typecheck
- [ ] `test:watch` по-прежнему только vitest — typecheck на каждый файл в watch не нужен
## Тесты, без которых фаза не закрыта
- [ ] `npm --prefix src/HSchool.Client test` гоняет tsc и vitest и проходит на текущем дереве
- [ ] Дубликат ключа в одном объекте `strings.ts` (ru или en) делает `npm test` красным без
`npm run build`
- [ ] В `package.json` нет зависимости `hschool-client`
- [ ] `npm --prefix src/HSchool.Client run build` проходит
## Критерий готовности
- Обычный агентский `npm test` ловит TS2300/TS1117
- Watch-режим не стал вдвое медленнее из-за полного `tsc -b` на каждый файл
## Стоп
Не тащить eslint ради одного дубликата. Не включать клиентский TS в stamp AppHost (фаза 49).
Не бампить протокол. Не трогать сейв и HTTP.
@@ -0,0 +1,41 @@
# Фаза 58. SchoolWorker и карточка
## Зависимости
Нет. Поведение уже покрыто хостом и клиентскими тестами карточки. Этап A (56, 57) не обязан
быть зелёным, но резать удобнее после tsc в `npm test`.
## Зачем
Три файла держат слишком много швов: почта работника, тик, запись; сборка карточки; вкладки
DOM. Разрезать по существующим границам, не меняя поток и JSON.
## Задачи
- [ ] `SchoolWorker``partial` (почта / тик / запись или эквивалент по швам). Один тип,
тот же `LongRunning`-поток, тот же mailbox. Без `lock` вокруг `School`/`World`
- [ ] `PersonCardReader`: публичный вход по-прежнему `Read(School, personId, locale)`;
сборка вкладок — соседние `internal` helper или `partial`, не второй публичный API
- [ ] `personCard.ts`: вкладки в отдельных модулях; `personCardHost.ts` по-прежнему fetch
- [ ] Инверсия Game → типы из `HSchool.Server.Api` **не** входит: `using` можно оставить
## Тесты, без которых фаза не закрыта
- [ ] Карточка: нужды, одежда/ноша, связи — как сейчас (`PeopleApiTests`,
`InventoryApiTests`, `Card_ConnectionsCarryOnlyThisPersonsOpinions`)
- [ ] `personCard.test.ts` (вкладки, портрет-кнопки, связи) проходит
- [ ] Пауза одной школы не останавливает другую (существующий хостовый факт)
- [ ] Дамп школы по-прежнему 200 на известный id (`Dump_ReturnsPeopleNodesAndTimetable`
текущий оракул, ужесточение — фаза 59)
- [ ] `SchoolWorker` остаётся одним `internal sealed` типом (рефлексия или исходник: нет
второго worker-класса с mailbox)
## Критерий готовности
- Открыть школу, карточку, паузу — как вчера
- Нет нового публичного фасада карточки и нет второго потока на школу
## Стоп
Не менять инвариант 3. Не инвертировать DTO. Не трогать протокол, сейв, SwarmUI. Не резать
`GameLoopService` «заодно».
+34
View File
@@ -0,0 +1,34 @@
# Фаза 59. Дамп проверяет узлы
## Зависимости
Нет. Ручка дампа и тест уже есть (фаза 27). Журнал среза 6: оракул не проверяет явку.
## Зачем
`Needs.Count > 0` истинно у всех. Тест зелёный на пустом кампусе. После найма дамп должен
видеть человека в узле, как ревью и хотело замерить.
## Задачи
- [ ] `Dump_ReturnsPeopleNodesAndTimetable`: нанять, **включить** часы, дождаться человека с
`NodeId`, затем дамп. Не ждать людей на паузе
- [ ] Нужды по-прежнему не пустые у всех в выборке, но явка — отдельный assert
- [ ] Урок математики в дампе — как сейчас
## Тесты, без которых фаза не закрыта
- [ ] После найма математика и хода часов дамп содержит человека с непустым `NodeId`
- [ ] Все люди в дампе с id, именем и непустым `Needs`
- [ ] В `dump.Lessons` есть Mathematics
- [ ] Неизвестный id — по-прежнему 404 `unknown-school`
## Критерий готовности
- Сломать публикацию `NodeId` в дампе — этот тест красный, а не только глаз ревью
- На паузе тест не висит на пустой явке
## Стоп
Не расширять JSON дампа. Не включать ручку по умолчанию. Не ходить в `World` мимо работника.
Не бампить протокол. Не трогать сейв.
+31
View File
@@ -0,0 +1,31 @@
Индекс срезов: [`../README.md`](../README.md).
## Срез 10. Ремесло
Дизайн: [`../design/craft.md`](../../design/10-craft/craft.md).
Срез без новой кнопки. Слои ловятся одним тестовым проектом, клиентский `npm test` гоняет tsc,
работник и карточка режутся по швам, дамп проверяет явку. После этапа A школа целая, даже если
файлы ещё толстые. Не ждёт фазы 44 и 46.
Порядок свободный: 56, 57 и 59 ни от чего не зависят, 58 удобнее после 57. Начинать разумно с
56 или 57.
**Этап A — страховка.** Слои и tsc.
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [56. Слои одной пачкой](56-architecture-tests.md) | ⬜ | Один проект вместо четырёх копипаст |
| [57. tsc в npm test](57-client-typecheck.md) | ⬜ | Дубликат ключа красный без `npm run build` |
**Этап B — горячие точки.** Поведение то же.
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [58. SchoolWorker и карточка](58-worker-card-split.md) | ⬜ | partial / модули по швам, один поток |
**Этап C — дамп.**
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [59. Дамп проверяет узлы](59-dump-nodes.md) | ⬜ | После найма в дампе есть `NodeId` |