Files
h-school/docs/phases/reviewed.md
T
Leonid Pershin 5cd5a6d258
ci / server (push) Failing after 3m40s
ci / client (push) Successful in 14s
Update decision-making phase and enhance localization for presence tracking
- Marked tasks as complete in the decision-making phase documentation, indicating readiness for implementation.
- Updated the README to reflect the completion status of the decision-making phase.
- Enhanced localization strings to include new presence tracking features, improving user experience.
- Revised the game screen logic to display real-time presence status, including walking states for individuals.
- Added tests to validate the new localization strings and presence functionalities, ensuring robust performance.
2026-08-19 21:00:12 +03:00

9.6 KiB
Raw Blame History

Проверенные срезы

Журнал ревью. Фаза с в README.md — заявка автора; строка здесь — проверенный факт: каждое обещание фазы сверено с кодом и тестом, найденное дописано или исправлено.

Коммит в «Проверен на» делает журнал самопроверяющимся. Срез перестаёт считаться проверенным, как только git log <коммит>..HEAD -- <пути> перестаёт быть пустым — поэтому «Пути» обязательны.

Срез 1. Оболочка и карта

  • Фазы: 04
  • Проверен на: b135a9c, 2026-08-19
  • Пути: src/HSchool.Client, src/HSchool.Protocol, src/HSchool.Content, src/HSchool.Server/Game, src/HSchool.Server/Api/ModEndpoints.cs, src/HSchool.Server/Api/SchoolEndpoints.cs, src/HSchool.Server/Net, tests/HSchool.Content.Tests, tests/HSchool.Protocol.Tests, tests/HSchool.AppHost.Tests/SchoolApiTests.cs, tests/HSchool.AppHost.Tests/GameSocketTests.cs
  • Итог: дописано 2 теста (оба прогнаны на чистом b135a9c), расхождений кода с дизайном не найдено кроме одного — панель «Общие события» из фазы 1 снята с экрана в фазе 8 и решение нигде не записано (оставлено открытым, см. ниже)

Что подтверждено:

  • Фаза 0. pixi.js нет ни в package.json, ни в lockfile, ни в импортах; npm run build проходит.
  • Фаза 1. Дерево карты, панель локации со всеми пятью секциями и пустыми состояниями, клик по дереву фильтрует на клиенте, localize() перекрашивает подписи. Панели «Общие события» на экране нет — единственное расхождение среза.
  • Фаза 2. SchoolWorkerLongRunning-поток, свой PeriodicTimer, свой World, аккумулятор с потолком в 5 шагов. Супервизор держит таблицу и не трогает World (инвариант 3). Сейв пишется на create, на shutdown и по SaveIntervalSeconds; настройки коалесцируются. Требуемый фазой тест «create → reload → та же школа с тем же временем» — это GameSocketTests.ReloadFromDisk_RestoresAPausedClock (точное равенство времени, паузы и скорости), плюс SchoolApiTests.ReloadFromDisk_RestoresCreatedSchools. Независимость школ — GameSocketTests.PausingOneSchool_DoesNotStopAnother.
  • Фаза 3. Все восемь тестов из списка фазы на месте в HSchool.Content.Tests (JSONC-фикстуры, last-wins по defName и по ключу локали, parent/abstract и цикл, патч add в actions, связность, пустая комната, одна комната без двора). Ванильная раскладка валидируется (VanillaCoreTests.CoreDefaultMap_PassesValidation). Пропавшая папка мода не стартует школу и не трогает файл: исключение летит до создания School, поэтому finally с Persist() недостижим, а супервизор только снимает школу с таблицы.
  • Фаза 4. GET /api/mods, GET /api/catalog?lang=, POST /api/schools с картой и модами, снимок карты при OpenSchool в языке Hello — всё покрыто тестами (OpeningASchool_SendsAMapSnapshot, LabelsTheSnapshotInTheHelloLocale, WithACustomMap_ReturnsThatLayout, ReloadFromDisk_RestoresACustomMap). Кодек, protocol.ts и docs/protocol.md описывают один и тот же MapSnapshot, байтовые смещения проверены с обеих сторон; версия 7 совпадает в ProtocolConstants и PROTOCOL_VERSION.
  • Инварианты. Content/People/Schedule/Ai не ссылаются на Arch и ASP.NET, Simulation — только на Arch; DateTime.Now/UtcNow в этих проектах нет.
  • «Things that will bite you». Ни одна из относящихся к срезу регрессий не вернулась: modal.ts резолвит промис явно, .dialog--screen держит height: fit-content, DefaultStartDate форсирует UTC-kind, аккумулятор работника на месте, MapSnapshotSize считается от сообщения, GameClient переносит оба WaitToReadAsync между итерациями, outbox роняет старейший кадр, меню патчит карточки через card.update.

Дописано:

  • SchoolApiTests.Catalog_WithAnUnknownMod_IsRejectedGET /api/catalog?mods= с неизвестной пачкой описан в docs/protocol.md как 400 unknown-mod, но не проверялся.
  • SchoolApiTests.ModId_ThatEscapesTheModsFolder_IsRejectedOnBothEndpoints — инвариант 6: id пачки приходит из браузера и подставляется в путь. ModContent.IsSafePackId его чистит на обоих входах (каталог и создание школы), тестом это закреплено не было.

Открыто:

  • Панель «Общие события» пропала. Фаза 1 требует три области, design/near-term.md держит их в «Что уже зафиксировано», а design/people.md описывает список людей как панель «рядом с картой и событиями». Коммит d8f8db6 (фаза 8) заменил панель вкладками Карта/Люди, не сказав об этом; ключи eventsTitle/eventsEmpty остались в i18n/strings.ts мёртвыми. Решать надо одно из двух: вернуть пустую панель (или третью вкладку) — или записать отказ от неё в дизайн и убрать ключи. Молча менять экран ревью не стало.

Замечено рядом (за границами среза):

  • SchoolRegistry после фазы 2 в бою не используется: сервер тикает школы работниками, а из класса вызывается только TryNormalizeName. SchoolRegistryTests.Tick_AdvancesOnlyRunningSchools проверяет путь, которым сервер больше не ходит.
  • PeopleApiTests.Card_IncludesFamilyAndLiveNeeds зависит от порядка тестов (фаза 8, срез 2). Проверено на чистом checkout b135a9c в отдельном worktree: в одиночку класс проходит (8/8), в полном прогоне класса падает на Assert.Equal(2, card.Family.Parents.Count) — ожидалось 2, пришёл 1. Причина: тест берёт People[0] и требует у него двух родителей, а состав семьи зависит от сида, сид — от id школы, id — от того, сколько школ создали тесты до него (и от saves/index.json на машине). На машине с накопленными сейвами тест зелёный, на чистом клоне — красный. Чинить надо тест: брать ученика, у которого два родителя, а не первого попавшегося. Неполные семьи — сознательное решение design/people.md, не баг генерации.
  • GameSocketTests.OpeningASchoolDuringAMathLesson_... не выдерживает полный прогон (срез 4). В одиночку проходит за 1 с, в полном прогоне падает с «No presence frame matched within 40 frames» через 22 с. Похоже на нехватку кадров под нагрузкой, а не на ошибку присутствия.
  • Полный dotnet test один раз упал: процесс HSchool.Simulation.Tests умер с 0xC0000005, успев отчитаться о 44 тестах из 63, и два ActivityTests (фаза 20) не прошли. Повторить не удалось. Скорее всего дерево правилось прямо во время прогона (см. ниже).
  • На момент проверки в рабочем дереве шла правка фазы 21 (Decision.cs, LessonLearning.cs, LessonLearningSystem.cs, PresenceSystem.cs, gameScreen.ts), и какое-то время решение не компилировалось. Выводам по срезу 1 это не мешает: его файлы правка не трогает, а дописанные тесты прогнаны и на чистом b135a9c, и на дереве после починки сборки.