10 KiB
Требования к модулю: 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_insertsource=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; ведут атлет/владелец по своим ограничениям):
src.exercise.is_active=false— «противопоказано/исключено»: упражнение не попадает в draft-версию; микроправка для него решений не генерирует; сессия только из неактивных упражнений исключается из плана целиком.- Исключаемое упражнение с парой-заменой в
src.exercise_replacement(замена активна, та же группа) → в draft подставляется замена (веса исходного плана; пометка вrationale). - Сопоставление плана и факта:
body.exercises[].exercise_id==src.exercise.name(так создаёт импорт пакета, m06); упражнение библиотеки не найдено → решение не генерируется, пометка вrationale. - Свободный текст
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. Инварианты (🛡 — нарушать запрещено)
- Изоляция атлета — все выборки и записи по одному
athleteId. - Только предложение, не смена — правила создают draft-версии
(
author=rules); активация — только человеком (Ф-12.3, vision 2.4). - Неизменяемость версий — правила ничего не переписывают в существующих версиях; новая версия — через ProgramStore.CreateDraft (m03); ссылки тренировок на версии не трогаются.
- Без записи в факт — правила ничего не пишут в
workout/workout_set/workout_metrics/daily_log; запись разрешена только вbreaks(детект/закрытие перерыва). - Сбой правил не ломает sync — исключение логируется, пакет остаётся принятым (как у метрик m04).
- Детерминированность — тот же вход → тот же выход; никакого LLM.
- Пороги — только из конфига (
Progression.*,Deload.*; коэффициенты возврата — константы документа перерывов).
4. Критерии приёмки модуля
- Микроправка: сценарии правил 1–4 из разд. 2.1 дают ожидаемые решения; правило 5 — вес не меняется.
- Draft-версия создаётся через ProgramStore (
author=rules,based_on_version= активная,rationaleзаполнен), активная версия не меняется; повторный вызов до подтверждения не плодит черновики (одна rules-черновая на активную версию). - Делоад:
Deload.MaxWeeksбез делоада → draft сsession_kind=deload. - Перерыв: пропуски 4 дней → строка
breaks(source=auto); первая сессия закрывает break (ended_on); draft возврата сsession_kind=return|testи коэффициентом по таблице. - Изоляция: данные атлета Б не влияют на решения атлета А.
- Сбой правил не мешает принятию пакета sync.
- Тесты интеграционные против docker
watchbody-pg— зелёные; сборка решения без ошибок.