From e2e7d30701add03a9f6682c1976f4ec32326c77c Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Thu, 20 Aug 2026 14:04:35 +0300 Subject: [PATCH 1/2] Tighten layer graph tests and document npm test typecheck. Content and People/Schedule/Ai now fail the same way if they grow a game-layer edge the projects.md graph forbids; README matches the tsc-then-vitest script from phase 57. --- README.md | 3 ++- src/HSchool.Client/scripts/npm-test.test.ts | 4 ++++ .../LayerBoundaryTests.cs | 20 +++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cc46fbe..2ac1521 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,8 @@ dotnet test npm --prefix src/HSchool.Client test ``` -Vitest covers the client codec, the calendar formatting and the RU/EN dictionaries. +`npm test` runs `tsc -b` then Vitest (codec, calendar formatting, RU/EN dictionaries). A duplicate +key in `strings.ts` fails typecheck without `npm run build`. `test:watch` is Vitest only. ## Layout diff --git a/src/HSchool.Client/scripts/npm-test.test.ts b/src/HSchool.Client/scripts/npm-test.test.ts index 15fd606..53a39c0 100644 --- a/src/HSchool.Client/scripts/npm-test.test.ts +++ b/src/HSchool.Client/scripts/npm-test.test.ts @@ -33,6 +33,10 @@ describe('npm test script', () => { it('does not depend on the hschool-client file: loop', () => { expect(pkg.dependencies?.['hschool-client']).toBeUndefined(); }); + + it('keeps build as typecheck then vite, without the file: loop', () => { + expect(pkg.scripts.build).toBe('tsc -b && vite build'); + }); }); describe('duplicate dictionary keys', () => { diff --git a/tests/HSchool.Architecture.Tests/LayerBoundaryTests.cs b/tests/HSchool.Architecture.Tests/LayerBoundaryTests.cs index 4bb4e6d..f7b1ba9 100644 --- a/tests/HSchool.Architecture.Tests/LayerBoundaryTests.cs +++ b/tests/HSchool.Architecture.Tests/LayerBoundaryTests.cs @@ -40,11 +40,14 @@ public class LayerBoundaryTests } [Fact] - public void Content_DoesNotReferenceArchAspNetSocketsProtocolOrSimulation() + public void Content_DoesNotReferenceArchAspNetSocketsProtocolPeopleScheduleAiOrSimulation() { var names = References(typeof(MapLayout)); AssertNoArchAspNetOrSockets(names); Assert.DoesNotContain("HSchool.Protocol", names, StringComparer.Ordinal); + Assert.DoesNotContain("HSchool.People", names, StringComparer.Ordinal); + Assert.DoesNotContain("HSchool.Schedule", names, StringComparer.Ordinal); + Assert.DoesNotContain("HSchool.Ai", names, StringComparer.Ordinal); Assert.DoesNotContain("HSchool.Simulation", names, StringComparer.Ordinal); } @@ -54,7 +57,10 @@ public class LayerBoundaryTests [InlineData(typeof(WalkGraph))] public void PeopleScheduleAi_DoNotReferenceArchAspNetOrSockets(Type marker) { - AssertNoArchAspNetOrSockets(References(marker)); + var names = References(marker); + AssertNoArchAspNetOrSockets(names); + Assert.DoesNotContain("HSchool.Protocol", names, StringComparer.Ordinal); + Assert.DoesNotContain("HSchool.Simulation", names, StringComparer.Ordinal); } [Fact] @@ -83,6 +89,16 @@ public class LayerBoundaryTests } } + [Fact] + public void ArchitectureTests_DoNotReferenceHostOrNetArchTest() + { + var csproj = File.ReadAllText( + Path.Combine(RepoRoot(), "tests", "HSchool.Architecture.Tests", "HSchool.Architecture.Tests.csproj")); + Assert.DoesNotContain("HSchool.Server", csproj, StringComparison.Ordinal); + Assert.DoesNotContain("HSchool.AppHost", csproj, StringComparison.Ordinal); + Assert.DoesNotContain("NetArchTest", csproj, StringComparison.OrdinalIgnoreCase); + } + [Fact] public void PeopleAiScheduleSimulationTests_NoLongerCarryLayerBans() { From a7e2820824bfdb9d509302e9bbbd6b5e176e45a6 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Thu, 20 Aug 2026 14:06:12 +0300 Subject: [PATCH 2/2] Record slice 10 A review. Phases 56-57 checked on e2e7d30. Phase 58 was in flight; 59 was out of this pass. --- docs/phases/10-craft/reviewed.md | 41 ++++++++++++++++++++++++++++++++ docs/phases/reviewed.md | 3 +-- 2 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 docs/phases/10-craft/reviewed.md diff --git a/docs/phases/10-craft/reviewed.md b/docs/phases/10-craft/reviewed.md new file mode 100644 index 0000000..33c1aa2 --- /dev/null +++ b/docs/phases/10-craft/reviewed.md @@ -0,0 +1,41 @@ +# Проверенные этапы среза 10 + +Журнал этого среза. Сводка ссылок — [`../reviewed.md`](../reviewed.md). + +## Срез 10. Этап A — страховка + +- **Фазы:** 56–57 +- **Проверен на:** `e2e7d30`, 2026-08-20 +- **Пути:** `tests/HSchool.Architecture.Tests`, `src/HSchool.Client/package.json`, `src/HSchool.Client/scripts`, `AGENTS.md`, `README.md` +- **Итог:** обещания 56–57 на месте; дописаны проверки графа из `projects.md` и запрет AppHost/NetArchTest в csproj; README приведён к `tsc`+vitest. Этап B (58) в работе на момент проверки; 59 в этот проход не входила. +- **В работе на момент проверки:** фаза 58 (этап B). + +### 56. Слои одной пачкой + +Все шесть пунктов «тестов, без которых фаза не закрыта» есть в `LayerBoundaryTests` и проходят (`dotnet test tests/HSchool.Architecture.Tests --filter FullyQualifiedName~LayerBoundaryTests`: 9 зелёных). Копипасты `Assembly_DoesNotReference*` / `Sources_DoNotUseWallClock` из People/Ai/Schedule/Simulation.Tests уехали. NetArchTest в solution нет; проект не ссылается на Server/AppHost. README больше не называет школу пустой, `MaxSchools` — слоты игрока. Testing policy в `AGENTS.md` указывает на `HSchool.Architecture.Tests`. + +Дописано: + +- Content не ссылается на People, Schedule, Ai (таблица `craft.md` их не требовала; граф `projects.md` — да) +- People/Schedule/Ai не ссылаются на Protocol и Simulation +- csproj Architecture.Tests не содержит Server, AppHost, NetArchTest + +Инвариант 4 (Simulation без ASP.NET/сокетов) и запрет `DateTime.Now` / `UtcNow` в шести библиотеках держатся; исходники дополнительно ловят неиспользованный `using System.Net.Http`. + +### 57. tsc в npm test + +`package.json` → `"test": "node ./scripts/run-test.mjs"` гоняет `tsc -b`, потом vitest, и не глотает код выхода typecheck на Windows. `"hschool-client": "file:"` в зависимостях нет. `test:watch` — только vitest. `AGENTS.md` это описывает. + +`npm --prefix src/HSchool.Client test -- scripts/npm-test.test.ts` на текущем дереве: tsc молча зелёный, 5 vitest зелёных (включая дубликат ключа в копии `strings.ts` → TS1117/TS2300 без `vite build`). + +Дописано: + +- скрипт `build` по-прежнему `tsc -b && vite build` (сам `vite build` не гонялся) + +README теперь говорит, что `npm test` = tsc + Vitest. Оговорка в сводке «vitest зелёный при красном tsc» снята: её закрыла эта фаза. + +### Открытое + +- `README.md` «What is deliberately missing» всё ещё пишет «No authentication» и что диалог создания не выбирает моды — ложь срезов 8 и 1, не этого этапа. +- Дубликат ключа проверяется изолированным `tsc -p`, не `tsc -b` живого клиента; проводка `run-test.mjs` покрыта отдельно. +- Фаза 58 (этап B) в работе — не проверялась. Фаза 59 (этап C) в этот проход не входила. diff --git a/docs/phases/reviewed.md b/docs/phases/reviewed.md index 2bc5d0e..639ec47 100644 --- a/docs/phases/reviewed.md +++ b/docs/phases/reviewed.md @@ -12,8 +12,6 @@ - Хостовый `OpeningASchoolDuringAMathLesson_...` после правки явки не гонялся: Aspire держал DLL (`MSB3021`). Симуляционные тесты явки зелёные. -- `npm test` в клиенте не гоняет `tsc`. Дубликат поля и любой TS2300 зелёный в vitest и красный - на `npm run build`. - `GET /api/catalog` отдаёт каркас дня без `lunchBreaks` (только `longBreakAfter`). Сетке смены не нужны; молча расширять HTTP ревью не стало. @@ -32,3 +30,4 @@ | Срез 7. Этап B–C — климат, жизнь одежды и правила | `5dcdee6` | [07-inventory](07-inventory/reviewed.md) | | Срез 8. Сессия и темп | `1c3ae9a` | [08-session](08-session/reviewed.md) | | Срез 9. Этапы A–B — мнения и разговоры | `b38d0bb` | [09-social](09-social/reviewed.md) | +| Срез 10. Этап A — страховка | `e2e7d30` | [10-craft](10-craft/reviewed.md) |