Merge branch 'phase/49-skip-stale-build'

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-20 08:51:57 +03:00
co-authored by Cursor
9 changed files with 497 additions and 16 deletions
+31 -1
View File
@@ -1,7 +1,7 @@
# Вне очереди
Задачи, которых нет в нумерованных срезах. Сюда не дописывают срез 9 и не заводят срез 10:
это склейка уже живых систем, после любой фазы школа целая.
склейка уже живых систем и мелкий DX. После любой фазы школа целая.
Люди: [`people.md`](people.md). Штат: [`staffing.md`](staffing.md). Расписание:
[`schedule.md`](schedule.md). Присутствие: [`ai.md`](ai.md). Одежда и климат:
@@ -88,3 +88,33 @@
| Тепло | Рядом с голодом, произведение двух `NeedFactor` |
| Учебник | Только сумка, не шкафчик и не дом; ваниль ×0.5 |
| Погода на дорогу | Минуты в `BehaviorDef`; лога нет |
## Пропуск сборки при запуске
### Зачем
`run-aspire.cmd` каждый раз вызывает `dotnet run`, а тот — MSBuild графа Aspire, даже когда
исходники не менялись. Повторный запуск после Ctrl+C стоит десятки секунд впустую: SDK
пересчитывает хост, хотя dll на месте.
### Было / Стало / Почему
**Было.** Скрипт всегда `dotnet run --project src/HSchool.AppHost`. Аргументы проходили насквозь.
**Стало.** Если `HSchool.AppHost.dll` и `HSchool.Server.dll` новее входов (C#, csproj, props,
`global.json`), скрипт делает `dotnet run --no-build`. Иначе — `dotnet build`, потом `--no-build`.
`--rebuild` собирает всегда. Конфигурация (`-c` / `--configuration`) выбирает, какие dll сравнивать;
по умолчанию Debug, как у `dotnet run`.
**Почему.** Инкрементальный MSBuild всё равно оценивает Aspire SDK. `--no-build` это пропускает.
Клиентский TypeScript и JSONC модов не входы: Vite и каталог читают диск (`ContentRoot`), а не
`bin`. Тестовые проекты AppHost не ссылается — их правки запуск не пересобирают.
Правила «устарел ли билд» живут в `tools/apphost-uptodate.ps1` (то, что вызывает `.cmd`) и в
`LaunchBuildStamp` (то, что проверяют тесты). Менять надо оба.
### Что не входит
Голый `dotnet run --project src/HSchool.AppHost` по-прежнему собирает — так удобнее агентам с
грязным деревом. Linux-обёртки нет: точка входа Windows — `.cmd`. Протокол, HTTP и сейв не
трогаем.
+45
View File
@@ -0,0 +1,45 @@
# Фаза 49. Пропуск сборки при запуске
## Зависимости
Нет. Скрипт запуска уже есть.
## Зачем
Повторный `run-aspire.cmd` без правок в C# не должен ждать MSBuild графа Aspire. Сборка нужна
только когда входы новее dll или когда просили `--rebuild`.
## Задачи
- [x] `tools/apphost-uptodate.ps1`: выход 0, если AppHost и Server dll новее входов; 1 — если
нет dll или вход новее. Входы: `*.cs` / `*.csproj` / `*.props` под `src/` без `bin` /
`obj` / `node_modules`, плюс `global.json`, `Directory.Build.props`, `Directory.Packages.props`.
TypeScript и JSONC не входы
- [x] `run-aspire.cmd` вызывает проверку; при 0 — `dotnet run --no-build` и пишет, что сборка
пропущена; иначе `dotnet build`, затем `--no-build`. `--rebuild` всегда собирает и не
уходит в AppHost. `-c` / `--configuration` выбирают папку `bin`
- [x] `LaunchBuildStamp` с теми же правилами, тесты на временных папках без `AppHostFixture`
- [x] `AGENTS.md` и `README.md`: повторный запуск без правок — `run-aspire.cmd`; голый
`dotnet run` по-прежнему собирает. `--rebuild` упомянут
## Тесты, без которых фаза не закрыта
- [x] Нет dll — нужно собирать
- [x] Dll новее всех входов — пропускать
- [x] `.cs` новее dll — собирать
- [x] `.ts` или `.jsonc` новее dll — пропускать
- [x] Файл в `bin` / `obj` / `node_modules` не считается входом
- [x] `Directory.Packages.props` новее dll — собирать
- [x] `-c Release` смотрит `bin/Release`, а не Debug
## Критерий готовности
- Два запуска `run-aspire.cmd` подряд без правок: второй пишет, что сборка пропущена, и
стартует AppHost
- `run-aspire.cmd --rebuild` собирает даже со свежими dll
- `dotnet test` проходит; тесты штампа не поднимают хост
## Стоп
Не менять Aspire-граф, протокол, сейвы. Не вшивать `--no-build` в голый `dotnet run`. Не
сканировать `tests/` и не считать клиентский TS поводом пересобрать сервер.
+4 -2
View File
@@ -227,12 +227,14 @@
Дизайн: [`../design/off-queue.md`](../design/off-queue.md).
Склейка уже живых систем, не новый кусок игры. Номера не спорят со срезом 10. После каждой
фазы школа целая. 50–52 стоят на 48; 53 — на 18 и 32, можно параллельно с 48.
Склейка уже живых систем и мелкий DX, не новый кусок игры. Номера не спорят со срезом 10.
После каждой игровой фазы школа целая. 50–52 стоят на 48; 53 — на 18 и 32, можно параллельно
с 48. 49 от них не зависит.
| Фаза | Статус | Зачем |
| --- | --- | --- |
| [48. Учитель в кабинете](48-lesson-teacher-present.md) | ✅ | Нет учителя на месте — нет роста навыка |
| [49. Пропуск сборки при запуске](49-skip-stale-build.md) | ✅ | `run-aspire.cmd` не гоняет MSBuild, если dll свежие |
| [50. Навык учителя](50-teacher-skill-gain.md) | 🔄 | Соискатель 78 учит лучше, чем 41 |
| [51. Тепло на уроке](51-warmth-lesson.md) | ⬜ | Замёрзший учится хуже, как голодный |
| [52. Учебник на уроке](52-textbook-lesson.md) | ⬜ | Нет в сумке — половинный рост |