From 4c8d91c6f3eb546dea16052ff9d94014461a96a5 Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Fri, 21 Aug 2026 11:30:32 +0300 Subject: [PATCH] Mark phase 73 in progress; register slice 13. Co-authored-by: Cursor --- AGENTS.md | 1 + docs/design/13-grades/grades.md | 141 ++++++++++++++++++++ docs/design/README.md | 1 + docs/phases/13-grades/73-lesson-marks.md | 38 ++++++ docs/phases/13-grades/74-attendance.md | 36 +++++ docs/phases/13-grades/75-gradebook-ui.md | 35 +++++ docs/phases/13-grades/76-grades-coupling.md | 37 +++++ docs/phases/13-grades/README.md | 35 +++++ docs/phases/README.md | 1 + 9 files changed, 325 insertions(+) create mode 100644 docs/design/13-grades/grades.md create mode 100644 docs/phases/13-grades/73-lesson-marks.md create mode 100644 docs/phases/13-grades/74-attendance.md create mode 100644 docs/phases/13-grades/75-gradebook-ui.md create mode 100644 docs/phases/13-grades/76-grades-coupling.md create mode 100644 docs/phases/13-grades/README.md diff --git a/AGENTS.md b/AGENTS.md index dcf0354..c433cb4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,6 +28,7 @@ way; this file is *how to work in them*. | layer tests, client tsc-in-test, worker/card splits, dump nodes | [`docs/design/10-craft/`](docs/design/10-craft/craft.md) — slice 10, phases 56–59 | | notices, toasts, scene prompt contributions, Krea-only catalog | [`docs/design/11-events/`](docs/design/11-events/events.md) — slice 11, phases 63–67 | | class teachers, director summons queue, parent meetings | [`docs/design/12-office/`](docs/design/12-office/office.md) — slice 12, phases 68–72 | +| marks 2–5, attendance journal | [`docs/design/13-grades/`](docs/design/13-grades/grades.md) — slice 13, phases 73–76 | | a bug in already-shipped behaviour | `.claude/skills/bug-work` — document in `docs/bugs/`, discuss only if the fix has a fork, then patch | | a task that is not in any slice | `.claude/skills/side-work` — discuss, document in [`docs/phases/off-queue/`](docs/phases/off-queue/README.md), then implement | | a new named slice of the game | `.claude/skills/slice-work` — discuss, write design and phases, then `/phase-orch` | diff --git a/docs/design/13-grades/grades.md b/docs/design/13-grades/grades.md new file mode 100644 index 0000000..c368a26 --- /dev/null +++ b/docs/design/13-grades/grades.md @@ -0,0 +1,141 @@ +# Учёба и журнал + +Договорённость на срез после кабинета и классного, не текущий код. +Урок: [`lesson-consequences.md`](../off-queue/lesson-consequences.md). Расписание: [`schedule.md`](../04-schedule/schedule.md). +ИИ: [`ai.md`](../05-ai/ai.md). Кабинет: [`office.md`](../12-office/office.md). Общение: [`social.md`](../09-social/social.md). +Одежда: [`inventory.md`](../07-inventory/inventory.md). Здоровье (следующий): [`health.md`](../14-health/health.md). + +Урок перестаёт быть только ростом навыка: появляется **оценка 2–5** и **посещаемость**. Игрок +их **не ставит** — считает мир. Карточка и класс показывают журнал. Плохой след сам тянет +внимание классного / авто-вызов из среза 12. + +## Роль игрока: менеджер / симулятор бога + +Тот же жест, что в [`office.md`](../12-office/office.md): рамка школы (учителя, расписание, +классный, правила), не ручной журнал и не «поставь пятёрку». Оценок от игрока нет. + +## Что увидит игрок + +- На карточке ученика — журнал: недавние оценки по предметам (2–5) и отметки явки. +- У класса — сводка (средний след / кто часто отсутствует), без таблицы на весь год в одной + простыне. +- Тост или авто-следствие, когда след совсем плохой (данные `BehaviorDef`), без кнопки «поставить + двойку». + +## На какие вопросы отвечает + +- Как из уже живого роста навыка на уроке получить школьную оценку 2–5. +- Как посещаемость берётся из присутствия (узел = кабинет урока), а не из отдельного чекбокса. +- Как журнал пишется в сейв и отдаётся по HTTP, не по сокету 20 Гц. +- Какие уже существующие множители (учитель, тепло, учебник, шёпот, голод) входят в оценку. +- Как плохой журнал стыкуется с классным и кабинетом директора **без** приказов игрока. + +## Чего нет + +- Ручных оценок и правок журнала игроком. +- Приказов «вызови Иванова» / «исправь оценку». +- Электронного дневника родителя и облачной выгрузки. +- Четвертных/годовых аттестаций как отдельной кампании (можно средний след, не «аттестация»). +- Болезней — срез 14; здесь только шов «отсутствие → прогул», который 14 заполнит причиной. + +## Что меняется в уже принятом + +| Было | Стало | Почему | +| --- | --- | --- | +| Урок пишет рост навыка и лог | Плюс оценка 2–5 по правилам | Иначе учёба не видна как школа | +| «Кто в кабинете» видно | Плюс явка/прогул/опоздание в журнале | Присутствие уже есть | +| Оценок нет ([`lesson-consequences`](../off-queue/lesson-consequences.md)) | Журнал есть | Этот срез | +| Классный только для собраний (12) | Плюс реакция на плохой след (авто) | Связность систем | +| Уместность одежды → тема разговора (9) | Может слегка двигать оценку / лог, если урок «на виду» — по данным | Связность без отдельного среза weave | + +## Этап A — оценка с урока + +После осмысленного куска урока (не каждый тик): из тех же входов, что `LessonLearning.Gain`, +мир пишет **одну** оценку 2–5 за урок (или за день-предмет — правило в `BehaviorDef`, ваниль: +за слот урока, если ученик хотя бы частично присутствовал и рост мог бы идти). + +Шкала классическая: 2, 3, 4, 5. Пороги от нормализованного «качества урока» — данные, не UI. +Нет учителя в кабинете / множитель 0 → не пятёрка «за воздух»: либо пропуск оценки, либо 2 по +правилу в данных (явно в фазе). + +Сейв — на ученике, разреженно (последние N по предмету / общий потолок). + +После этапа школа целая: оценки пишутся, журнала на карточке может ещё не быть. + +## Этап B — посещаемость + +На каждый слот урока класса: **присутствовал** (в узле кабинета, не идёт), **опоздал** +(пришёл после начала — порог минут в данных), **отсутствовал**. Источник — присутствие и +обязанность, не чекбокс. + +Пишется рядом с журналом оценок. Прогул без уважительной причины (здоровье — срез 14) может +добавлять проступок / вес к авто-вызову, если 12 уже в мире — пороги в данных. + +После этапа явка есть даже без красивой сводки класса. + +## Этап C — экран журнала + +Вкладка или блок на карточке: оценки и явка. Сводка класса в Управлении или у классного — +коротко. HTTP через мейлбокс. Список людей журнал не раздувает. + +Локали RU/EN. + +## Этап D — связность и реакция + +Явно в этом срезе, не «потом»: + +| Уже есть | Влияние на журнал | +| --- | --- | +| Учитель в кабинете, навык, тепло, учебник, голод, шёпот | Качество → оценка | +| Уместность формы (7/9) | Лёгкий модификатор или только лог — число в `BehaviorDef` | +| Плохие оценки / прогулы | Info-тост; вес к авто-вызову (12); классный «замечает» в логе | + +Игрок по-прежнему не ставит отметок. + +После этапа срез 13 закрыт; болезни подключат причину отсутствия в 14. + +## Поток данных + +Оценки и явка — состояние человека / класса, считает симуляция + `HSchool.Ai` (качество урока). +Карточка — HTTP. Тосты — `EventDef` (срез 11). Сокет присутствия не несёт весь журнал. + +Инварианты 1, 3, 4, 7: клиент не считает пятёрки; воркер пишет; симуляция без ASP.NET. + +## Где живёт код + +Нового проекта нет. + +| Что | Куда | +| --- | --- | +| Пороги 2–5, потолки журнала | `BehaviorDef` / JSONC `core` | +| Качество урока → оценка | `HSchool.Ai` (+ уже существующий `LessonLearning`) | +| Явка из присутствия | `HSchool.Simulation` адаптер | +| Сейв журнала | ростер / people рядом с человеком | +| Карточка, сводка | Server + Client | +| Тосты / стык с вызовом | EventDef + хуки среза 12 | + +## Советы, которые стоит принять сразу + +- Не давать игроку редактировать оценку. +- Не слать журнал по WS 20 Гц. +- Одна оценка за урок (или явное правило), не спам каждую минуту. +- Связность — таблица в этапе D, не размазанные «заодно» по фазам без тестов. +- Уважительный пропуск (болезнь) — контракт для 14: вид явки или флаг причины. + +## Заведомо не сейчас + +- Приказы игрока, ручной журнал. +- ЕГЭ, олимпиады, переводные экзамены, родительский дневник онлайн. +- Больной учитель как дыра в дне, точечный вызов родителя — [`fallout.md`](../15-fallout/fallout.md). +- Болезни как система — [`health.md`](../14-health/health.md) (уже соседний срез). + +## Зафиксировано этим разговором + +| Тема | Решение | +| --- | --- | +| Шкала | Классические **2–5** | +| Приказы | Нет; менеджер / симулятор бога | +| Weave | Отдельного среза нет; этап D внутри 13 | +| Болезнь | Срез 14 | +| Стоп | После A/B/C школа целая | +| Ваниль | `core` | diff --git a/docs/design/README.md b/docs/design/README.md index aea4962..d78aaef 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -16,4 +16,5 @@ | 10. Ремесло | [10-craft](10-craft/craft.md) | | 11. События и сцена | [11-events](11-events/events.md) | | 12. Кабинет и классный | [12-office](12-office/office.md) | +| 13. Учёба и журнал | [13-grades](13-grades/grades.md) | | Вне очереди | [off-queue](off-queue/) | diff --git a/docs/phases/13-grades/73-lesson-marks.md b/docs/phases/13-grades/73-lesson-marks.md new file mode 100644 index 0000000..5b21114 --- /dev/null +++ b/docs/phases/13-grades/73-lesson-marks.md @@ -0,0 +1,38 @@ +# Фаза 73. Оценка с урока + +## Зависимости + +- [Фаза 48](../off-queue/48-lesson-teacher-present.md) +- [Фаза 50](../off-queue/50-teacher-skill-gain.md) +- [Фаза 51](../off-queue/51-warmth-lesson.md) +- [Фаза 52](../off-queue/52-textbook-lesson.md) + +## Зачем + +Рост навыка получает школьный смысл: оценка 2–5 за урок. + +## Задачи + +- [ ] Из качества урока (те же входы, что `LessonLearning.Gain`) писать оценку **2, 3, 4 или 5** +- [ ] Пороги и «когда писать» (раз за слот урока) — в `BehaviorDef` / данных `core` +- [ ] Нет учителя / множитель 0 — явное правило (нет оценки или 2), зафиксировать в данных и тесте +- [ ] Хранение на ученике, потолок недавних; сейв +- [ ] Детерминизм: тот же сид и те же входы → та же оценка +- [ ] Игрок оценку не ставит и не правит (нет API правки) + +## Тесты, без которых фаза не закрыта + +- [ ] Урок с сильным учителем и полными множителями даёт не ниже урока с пустым кабинетом учителя + при тех же прочих +- [ ] За один слот не пишется пачка оценок каждую минуту +- [ ] Сейв сохраняет последние оценки +- [ ] HTTP/сокет не принимает «поставить оценку» + +## Критерий готовности + +- После урока у ученика в данных есть 2–5; перезагрузка школы не стирает +- Отфильтрованные тесты по Testing policy проходят + +## Стоп + +Не явка. Не UI журнала. Не тосты. Не болезни. diff --git a/docs/phases/13-grades/74-attendance.md b/docs/phases/13-grades/74-attendance.md new file mode 100644 index 0000000..d1dcc0a --- /dev/null +++ b/docs/phases/13-grades/74-attendance.md @@ -0,0 +1,36 @@ +# Фаза 74. Посещаемость + +## Зависимости + +- [Фаза 18](../05-ai/18-presence-walking.md) +- [Фаза 73](73-lesson-marks.md) + +## Зачем + +Журнал знает, был ли ученик на уроке, без ручной галочки. + +## Задачи + +- [ ] На слот урока класса: присутствовал (узел = кабинет, не идёт), опоздал (порог минут в + данных), отсутствовал +- [ ] Писать в сейв рядом с журналом оценок +- [ ] Источник — присутствие и расписание, не клиент +- [ ] Заготовка причины отсутствия (прогул по умолчанию); «болезнь» заполнит срез 14 +- [ ] Опоздание не отменяет оценку целиком, если правило этапа A иначе — согласовать с 73 в данных + +## Тесты, без которых фаза не закрыта + +- [ ] Ученик в кабинете к началу → присутствовал +- [ ] Пришёл после порога → опоздал +- [ ] Вне школы / другой узел весь слот → отсутствовал +- [ ] Тот же день и сид → та же явка +- [ ] Сейв переживает reload + +## Критерий готовности + +- Прогульщик и сидящий на уроке отличаются в данных явки после одного и того же слота +- Отфильтрованные тесты по Testing policy проходят + +## Стоп + +Не UI. Не уважительная болезнь (14). Не авто-вызов за прогул (76). diff --git a/docs/phases/13-grades/75-gradebook-ui.md b/docs/phases/13-grades/75-gradebook-ui.md new file mode 100644 index 0000000..c8d5035 --- /dev/null +++ b/docs/phases/13-grades/75-gradebook-ui.md @@ -0,0 +1,35 @@ +# Фаза 75. Журнал на карточке + +## Зависимости + +- [Фаза 73](73-lesson-marks.md) +- [Фаза 74](74-attendance.md) +- [Фаза 8](../02-people/08-people-browser.md) + +## Зачем + +Игрок видит оценки и явку, не открывая сейв. + +## Задачи + +- [ ] Блок/вкладка на карточке ученика: недавние оценки по предметам и явка +- [ ] Короткая сводка класса (средний след / частые отсутствия) в Управлении или у класса — + без простыни на год +- [ ] HTTP через мейлбокс; гость читает, не пишет +- [ ] Строки `t(...)`, обе локали +- [ ] Список людей в панели журнал не раздувает + +## Тесты, без которых фаза не закрыта + +- [ ] Карточка отдаёт те же оценки/явку, что в мире +- [ ] Нет права править оценку через API +- [ ] Клиентский тест панели/вкладки (vitest) на пустое и заполненное состояние + +## Критерий готовности + +- Открыть ученика после урока — видны 2–5 и явка; F5 не чинит данные с клиента +- Отфильтрованные тесты по Testing policy проходят + +## Стоп + +Не тосты и авто-вызов (76). Не болезни. diff --git a/docs/phases/13-grades/76-grades-coupling.md b/docs/phases/13-grades/76-grades-coupling.md new file mode 100644 index 0000000..bdfb390 --- /dev/null +++ b/docs/phases/13-grades/76-grades-coupling.md @@ -0,0 +1,37 @@ +# Фаза 76. След и реакция + +## Зависимости + +- [Фаза 75](75-gradebook-ui.md) +- [Фаза 43](../09-social/43-whisper.md) +- [Фаза 35](../07-inventory/35-appropriateness.md) + +## Зачем + +Журнал стыкуется с уже живыми системами и сам поднимает шум — без приказов игрока. + +## Задачи + +- [ ] Явно учесть в качестве/оценке уже существующие множители (учитель, тепло, учебник, голод, + шёпот) — тесты на каждый вклад +- [ ] Уместность формы: лёгкий модификатор оценки или только лог — число в `BehaviorDef` +- [ ] Плохой средний след / прогулы → `EventDef` info; веса к авто-вызову (12), если срез 12 в мире +- [ ] Классный (если назначен) пишет заметку в лог / учитывается в пороге — без кнопки игрока +- [ ] Контракт для 14: причина явки «болезнь» не зовёт вызов как прогул + +## Тесты, без которых фаза не закрыта + +- [ ] Шёпот на уроке ухудшает оценку относительно контроля при тех же прочих +- [ ] Нет учебника ухудшает относительно контроля +- [ ] Порог плохого следа эмитит notice +- [ ] Прогул с причиной «болезнь» (заглушка/флаг) не добавляет проступок вызова +- [ ] Нет API «вызови за двойку» от игрока + +## Критерий готовности + +- Слабый урок и прогулы видны в журнале и дают тост/вес к системе 12 без клика игрока +- Отфильтрованные тесты по Testing policy проходят + +## Стоп + +Не болезни и заражение. Не ручной журнал. Не отдельный срез weave. diff --git a/docs/phases/13-grades/README.md b/docs/phases/13-grades/README.md new file mode 100644 index 0000000..7f5ac4c --- /dev/null +++ b/docs/phases/13-grades/README.md @@ -0,0 +1,35 @@ +Индекс срезов: [`../README.md`](../README.md). + +## Срез 13. Учёба и журнал + +Дизайн: [`grades.md`](../../design/13-grades/grades.md). + +Оценка 2–5 и явка из живого урока и присутствия. Игрок журнал не правит (менеджер / симулятор +бога). Срез можно остановить после этапа A — оценки пишутся, даже если сводки класса ещё нет. + +**Этап A — оценка.** + +| Фаза | Статус | Зачем | +| --- | --- | --- | +| [73. Оценка с урока](73-lesson-marks.md) | 🔄 | 2–5 из качества урока, сейв | + +**Этап B — явка.** + +| Фаза | Статус | Зачем | +| --- | --- | --- | +| [74. Посещаемость](74-attendance.md) | ⬜ | Присутствовал / опоздал / отсутствовал | + +**Этап C — экран.** + +| Фаза | Статус | Зачем | +| --- | --- | --- | +| [75. Журнал на карточке](75-gradebook-ui.md) | ⬜ | HTTP, сводка класса | + +**Этап D — связность.** + +| Фаза | Статус | Зачем | +| --- | --- | --- | +| [76. След и реакция](76-grades-coupling.md) | ⬜ | Множители, тост, стык с вызовом/классным | + +73 независима от 12 по записи оценок; 76 стыкуется с 12, если тот уже в мире. 74 стоит на 18; +75 — на 73 и 74; 76 — на 75. diff --git a/docs/phases/README.md b/docs/phases/README.md index 1339f87..e172688 100644 --- a/docs/phases/README.md +++ b/docs/phases/README.md @@ -23,4 +23,5 @@ | 10. Ремесло | 56–59 | [10-craft](10-craft/README.md) | [craft](../design/10-craft/craft.md) | | 11. События и сцена | 63–67 | [11-events](11-events/README.md) | [events](../design/11-events/events.md) | | 12. Кабинет и классный | 68–72 | [12-office](12-office/README.md) | [office](../design/12-office/office.md) | +| 13. Учёба и журнал | 73–76 | [13-grades](13-grades/README.md) | [grades](../design/13-grades/grades.md) | | Вне очереди | 48–55 | [off-queue](off-queue/README.md) | [off-queue](../design/off-queue/) |