VEU.WathBody/1-docs/4-modules/m05-progression-rules/module_reqs.md

10 KiB
Raw Permalink Blame History

Требования к модулю: 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 — зелёные; сборка решения без ошибок.