133 lines
10 KiB
Markdown
133 lines
10 KiB
Markdown
# Требования к модулю: m05-progression-rules
|
||
|
||
> Модуль — сервисы `ProgressionRules` и `BreakEngine` в
|
||
> `Server.WatchBody.Core`: детерминированные правила прогрессии и
|
||
> делоада (Ф-12.2–12.4, правила 3–5 и 10 документа метрик), перерывы
|
||
> и возврат (Ф-14, правила 12–17 документа перерывов). Результат
|
||
> работы — предложение draft-версии программы (`author=rules`) через
|
||
> ProgramStore (m03). Самодостаточная копия требований (d-dev-6).
|
||
|
||
## 1. Назначение и границы
|
||
|
||
**В границах модуля:**
|
||
|
||
- класс `ProgressionRules` (`Server.WatchBody.Core`, каталог
|
||
`Programs\`): микроправка весов на следующее занятие после каждой
|
||
синхронизированной тренировки (Ф-12.2) и делоад (Ф-12.4) —
|
||
предложение draft-версии (`author=rules`, `rationale`);
|
||
- класс `BreakEngine` (тот же каталог): авто-детект перерыва по
|
||
пропускам (Ф-14.1, `break_insert` source=auto), закрытие break
|
||
первой сессией (`ended_on`), формула возврата (Ф-14.3, документ
|
||
перерывов разд. 3.2) → draft-версия с `session_kind=return`
|
||
(Ф-14.4–14.5), учёт правила 17 (break ≥ 14 дней → `session_kind=test`);
|
||
- вызов из m02: после пересчёта метрик (m04) sync вызывает правила;
|
||
сбой расчёта не откатывает sync (как у метрик);
|
||
- пороги — из конфигурации сервера `Progression.*`/`Deload.*`
|
||
(умолчания — requirements разд. 3); коэффициенты возврата —
|
||
документ перерывов разд. 3.2;
|
||
- тесты сервисов (интеграционные, docker `watchbody-pg`).
|
||
|
||
**Вне границ модуля:** показ диффа и подтверждение предложения
|
||
(телефон m09/m10, веб-консоль m08 — Ф-12.3); активация draft-версии
|
||
(только явным действием атлета/владельца, 🛡 vision 2.4); пометка
|
||
следующей тренировки лёгкой — телефон по Ф-13.2 (обнаружение —
|
||
`red_flags` m04); правила координации 7–9 (вес тела/дефицит) и
|
||
11 (VO2max) — v2/v3 (документ метрик п. 5); правила 13/14 (средняя
|
||
тренировка при аврале, домашний комплекс) — телефон; правило 15
|
||
(ужесточение порогов АД после break ≥ 14 дней) — кандидат v2 (меняет
|
||
пороги m04, отдельное решение); свободный текст ограничений
|
||
(`body.profile.limitations`) правила не интерпретируют — учёт
|
||
ограничений детерминированный, через персональную библиотеку атлета
|
||
(см. разд. 2.4); интерпретация текста — LLM-контур A (v2).
|
||
|
||
## 2.4. Учёт индивидуальных ограничений атлета (решение гейта 1.3)
|
||
|
||
Ограничения атлета (травмы, недоступные тренажёры, противопоказания)
|
||
влияют на набор упражнений в предложениях правил детерминированно,
|
||
через персональную библиотеку (🛡 библиотека принадлежит атлету,
|
||
Ф-4.4; ведут атлет/владелец по своим ограничениям):
|
||
|
||
1. `src.exercise.is_active=false` — «противопоказано/исключено»:
|
||
упражнение не попадает в draft-версию; микроправка для него
|
||
решений не генерирует; сессия только из неактивных упражнений
|
||
исключается из плана целиком.
|
||
2. Исключаемое упражнение с парой-заменой в `src.exercise_replacement`
|
||
(замена активна, та же группа) → в draft подставляется замена
|
||
(веса исходного плана; пометка в `rationale`).
|
||
3. Сопоставление плана и факта: `body.exercises[].exercise_id`
|
||
== `src.exercise.name` (так создаёт импорт пакета, m06);
|
||
упражнение библиотеки не найдено → решение не генерируется,
|
||
пометка в `rationale`.
|
||
4. Свободный текст `body.profile.limitations` переносится между
|
||
версиями без изменений (не интерпретируется).
|
||
|
||
## 2. Правила (v1 — детерминированные)
|
||
|
||
### 2.1. Микроправка весов (Ф-12.2, документ метрик правила 3–5)
|
||
|
||
По каждому упражнению тренировки, по факту `workout_set`:
|
||
|
||
| # | Условие | Действие |
|
||
|---|---|---|
|
||
| 1 | все плановые подходы закрыты «по плану» при RPE ≤ 7 в 2 тренировках подряд | вес + `Progression.BaseStepKg` (базовые) / + `Progression.IsoStepKg` (изоляция) |
|
||
| 2 | RPE ≥ 9 в 2+ сетах | вес − `Progression.BackoffPercent` % |
|
||
| 3 | повторения достигли верхней границы диапазона (15–20) | вес ↑ (шаг прогрессии), повторения к 12 |
|
||
| 4 | ≥ 2 подходов не дотянуты по повторениям | вес − `Progression.BackoffPercent` % |
|
||
| 5 | иначе (частичное выполнение) | вес без изменения |
|
||
|
||
Правила проверяются по порядку, срабатывает первое; решения по всем
|
||
упражнениям собираются в одну draft-версию.
|
||
|
||
### 2.2. Делоад (Ф-12.4, правило 10)
|
||
|
||
`Deload.MaxWeeks` недель подряд без делоада → draft-версия с объёмом
|
||
−40–50 % (веса × 0.6, подходы −1), `session_kind=deload`.
|
||
|
||
### 2.3. Перерывы и возврат (Ф-14, документ перерывов разд. 3.2)
|
||
|
||
- авто-детект: все запланированные сессии за 4 дня подряд пропущены →
|
||
`break_insert` (source=auto); break закрывается первой сессией
|
||
(`ended_on`);
|
||
- формула возврата по длительности простоя: 4–6 дней → 100 % (первая
|
||
сессия −1 подход, RPE 5–6); 7–13 → −10 %; 14–27 → −15 % (1 вводная
|
||
неделя); 28–59 → −25 % (2 вводные); 60+ / болезнь с температурой →
|
||
−30…−40 % (перезапуск). Кардио возвращается со 100 % сразу;
|
||
- первая сессия после break → draft-версия с формульными весами,
|
||
`session_kind=return` (после break ≥ 14 дней — `test`), rationale —
|
||
причина снижения. Применение — подтверждением атлета/владельца
|
||
(Ф-12.3), 🛡 автоматической смены активной версии нет.
|
||
|
||
## 3. Инварианты (🛡 — нарушать запрещено)
|
||
|
||
1. **Изоляция атлета** — все выборки и записи по одному `athleteId`.
|
||
2. **Только предложение, не смена** — правила создают draft-версии
|
||
(`author=rules`); активация — только человеком (Ф-12.3, vision 2.4).
|
||
3. **Неизменяемость версий** — правила ничего не переписывают в
|
||
существующих версиях; новая версия — через ProgramStore.CreateDraft
|
||
(m03); ссылки тренировок на версии не трогаются.
|
||
4. **Без записи в факт** — правила ничего не пишут в
|
||
`workout`/`workout_set`/`workout_metrics`/`daily_log`; запись
|
||
разрешена только в `breaks` (детект/закрытие перерыва).
|
||
5. **Сбой правил не ломает sync** — исключение логируется, пакет
|
||
остаётся принятым (как у метрик m04).
|
||
6. **Детерминированность** — тот же вход → тот же выход; никакого LLM.
|
||
7. **Пороги — только из конфига** (`Progression.*`, `Deload.*`;
|
||
коэффициенты возврата — константы документа перерывов).
|
||
|
||
## 4. Критерии приёмки модуля
|
||
|
||
1. Микроправка: сценарии правил 1–4 из разд. 2.1 дают ожидаемые
|
||
решения; правило 5 — вес не меняется.
|
||
2. Draft-версия создаётся через ProgramStore (`author=rules`,
|
||
`based_on_version` = активная, `rationale` заполнен), активная
|
||
версия не меняется; повторный вызов до подтверждения не плодит
|
||
черновики (одна rules-черновая на активную версию).
|
||
3. Делоад: `Deload.MaxWeeks` без делоада → draft с `session_kind=deload`.
|
||
4. Перерыв: пропуски 4 дней → строка `breaks` (source=auto); первая
|
||
сессия закрывает break (`ended_on`); draft возврата с
|
||
`session_kind=return|test` и коэффициентом по таблице.
|
||
5. Изоляция: данные атлета Б не влияют на решения атлета А.
|
||
6. Сбой правил не мешает принятию пакета sync.
|
||
7. Тесты интеграционные против docker `watchbody-pg` — зелёные;
|
||
сборка решения без ошибок.
|