Progression Engine v2
Why It Matters
- Unlocks tier-aware progression so powerlifters and tinkers can script complex programs (GZCLP, 5/3/1) without touching code.
- Preserves friendly authoring for existing playbooks by extending condition/action blocks rather than introducing a DSL.
- Lines up with monetisation strategy by gating set-level recommendations and premium playbooks behind role-based permissions.
- Strengthens observability and simulation tooling so coaches can validate changes before athletes touch the bar.
Headline Capabilities
Enhanced Playbook Authoring
- Tier & Stage Awareness: Rules can target tiers (
T1–T3) and stages (STAGE_1–3) to rotate templates automatically. - Richer Conditions: Support for weekly modifiers, program blocks, training-max thresholds, cross-exercise volume, and more.
- Action Toolkit: Adjust training max (absolute or percent), enforce pyramid templates, set/rep/rest targets, allocate assistance volume, and flag custom state.
- Metadata & Premium Flag:
isPremiumandmetadatafields unlock future pricing tiers without breaking legacy playbooks.
Runtime Execution
- Program Context Ingestion: Pulls weekly modifiers, coach overrides, and block metadata before evaluating rules.
- Workout Context Summary: Computes total and per-tier volume, set counts, and skipped set ratios for cross-exercise logic.
- Adaptive State Model: Stores tier stage history, training max, custom flags, and cycle week for each exercise snapshot.
- Dual Edition Output: Generates community-edition (uniform) or full-edition (set-specific) recommendations depending on permissions.
- Simulation Hooks:
simulatePlaybookaccepts overrides for state, modifiers, and tiers to test scenarios on demand.
Effective Workout Integration
- Suggestions propagate to Effective Workout targets: set templates, rep ranges, rest timers, tier stage, and assistance goals.
- Coach overrides still trump automation—the engine honours absolute targets and protective overrides before firing actions.
Feature Walkthrough
- Baseline Progression
- Deload Protection
- Failed Session
- Premium Coaching
Sam completes his heavy squat session with all reps ✔️
- Rule checks
TIER_EQUALST1 +TIER_STAGE_EQUALSStage 1 ADVANCE_TIER_STAGE→ Stage 2,ADJUST_TRAINING_MAX+5 kgSET_SET_TEMPLATEforces pyramid next week, rest of metadata stored- Effective Workout shows 4×3–5 pyramid for the next session
Sam enters deload week. Weekly modifier weight multiplier < 0.9
- Engine logs progression blocked, still updates streaks
- No suggestion is inserted, state moves to 3 consecutive successes
- Effective Workout keeps coach-programmed conservative targets
Stage 2 Sam misses AMRAP
- Failure rule resets tier stage to Stage 1 and drops TM -5 kg
- Consecutive fails increment, so next week restarts linear progression
- Effective Workout surfaces the lighter workload automatically
With advanced permissions, Sam sees set-level cues:
- Warm-up ladder, per-set weights, AMRAP callouts, assistance quotas
- Without the permission, engine falls back to uniform prescription
Deep Dive Examples
1. Sam & Coach Alex – Weekly Modifier Driven Deload
Scenario: Alex schedules a deload in Week 4 using the weekly modifier builder.
Weekly Modifier Snapshot
{
"weekNumber": 4,
"nameAtEnrollment": "Deload Week",
"descriptionAtEnrollment": "Reduce load and reps by 20%",
"weightMultiplierAtEnrollment": 0.8,
"repsMultiplierAtEnrollment": 0.8,
"rpeMultiplierAtEnrollment": 0.85
}
- Listener injects modifiers into
ProgramContext. - Engine sees
weightMultiplier < 0.9→_shouldBlockProgressionreturnstrue. ProgressionStatestill incrementsconsecutiveSuccessesso Sam’s streak is preserved.- Effective Workout pulls the scaled targets from the modifier rather than progression suggestions.
- When Sam starts Week 5, the modifier no longer applies, progression resumes.
2. Alex Adds a Peak-Block Rule for Stage 3
Playbook Rule Snippet
{
"order": 3,
"conditions": [
{ "type": "TIER_EQUALS", "value": "T1" },
{ "type": "TIER_STAGE_EQUALS", "value": "STAGE_3" },
{ "type": "TRAINING_BLOCK_EQUALS", "value": "PEAKING" },
{ "type": "TRAINING_MAX_PERCENT_REACHED", "operator": "GTE", "value": 0.95 }
],
"actions": [
{ "type": "SET_SET_TEMPLATE", "template": "PYRAMID_DESCENDING" },
{ "type": "SET_SET_COUNT", "value": 3 },
{ "type": "SET_REST_TARGET", "seconds": 240 },
{ "type": "FLAG_CUSTOM_STATE", "key": "tmRetestDue", "value": true }
],
"userMessage": "You're in peak mode: reverse pyramid with 4 min rest. TM retest next week."
}
- Once Alex switches Sam’s training block to “Peaking”, the rule fires only when Sam reaches Stage 3 and lifts ≥95 % of TM.
- Effective Workout now shows descending pyramid, longer rest, and surfaces the custom flag so Alex can retest Sam’s TM.
- If Sam fails a set, the Stage-Reset rule in the spec takes over and removes the retest flag automatically.
3. Tier-Stacked Volume Control for Accessories
Coach Alex notices Sam’s T2 posterior chain work is climbing too high. He adds a guard rule:
Cross-Tier Volume Guard
{
"conditions": [
{ "type": "TIER_EQUALS", "value": "T1" },
{ "type": "CROSS_EXERCISE_VOLUME", "targetTier": "T2", "operator": "GT", "value": 4000 }
],
"actions": [
{ "type": "SET_ASSISTANCE_VOLUME", "tier": "T3", "totalReps": 60 },
{ "type": "FLAG_CUSTOM_STATE", "key": "accessoryVolumeManaged", "value": true },
{ "type": "SET_REST_TARGET", "seconds": 120 }
]
}
- Sam’s RDL + glute bridge combo logs >4000 kg of Tier-2 volume → rule fires on the main squat exercise.
- Assistance block for T3 glute work is capped to 60 reps, rest shortened to keep the session under 75 minutes.
- The custom flag is stored in
ProgressionState.customFlagsso analytics dashboards can alert Alex when deloading is needed.
4. Coach Override vs. Automation
Alex prescribes an absolute bench single at 145 kg for Sam’s test week.
- Program override (
absoluteTargetWeight) is stored on the PWE snapshot. - During evaluation,
_shouldBlockProgressionsees the override and returns early. ProgressionStatestill tracks success/failure for future rules; suggestions are not created.- When Alex removes the override, the next automated workout picks up with the new stage and TM values.
5. Premium vs Community Editions
| User | Permission | Output |
|---|---|---|
| Sam (MemberPro) | can_use_advanced_progression_features ✅ | Receives set-specific weights, warmups, AMRAP cues, assistance quotas. |
| Chris (Member) | can_use_advanced_progression_features ❌ | Gets uniform working-set recommendations; warmups still generated; assistance stays generic. |
- Same playbook; edition is chosen at runtime.
- If Sam shares a workout screenshot, it’s obvious he’s on premium due to per-set instructions; Chris sees the simpler view.
6. Simulating Tweaks Before Deployment
Alex edits the Stage-2 rule and wants to verify if +2.5 kg absolute jump is too aggressive.
Simulator Example
await progressionPlaybookService.simulatePlaybook(playbook, {
sets: [
{ weight: 110, reps: 5, skipped: false },
{ weight: 112.5, reps: 5, skipped: false },
{ weight: 115, reps: 5, skipped: false }
],
targetReps: 5,
trainingMax: 125,
tierStage: 'STAGE_2',
currentWeekNumber: 9
}, trainingFocus);
- Output includes triggered rule, state diff, suggested TM, and warmup/working sets.
- Alex can iterate until the result fits his programming philosophy, then push the change live.
Permissions & Monetisation
| Capability | Permission | Roles (by seed) | Behaviour when missing |
|---|---|---|---|
| Assign premium playbooks | can_assign_premium_playbooks | MemberPro, Coach, Admin | Playbook assignment denied |
| Use advanced (set-level) recommendations | can_use_advanced_progression_features | MemberPlus+, Coach, Admin | Engine emits community edition suggestions |
| View effective workout | can_view_effective_workouts | All seeded roles | Access denied; prompts upgrade |
- Role metadata service already surfaces upgrade prompts for UI.
- Premium gating happens both during assignment and at runtime to prevent orphaned suggestions.
Developer Workflow
Authoring & Schema
- Add or migrate Prisma models (
ProgressionPlaybook,UserProgramPWESnapshot,WorkoutExerciseProgressionSuggestion). - Seed new permissions via
prisma/mongo/seeds/core/00permissions.seeder.ts. - Extend playbook CRUD UI/API to expose new metadata, conditions, and actions.
Runtime Integration
- Ensure
ProgressionPlaybookService.processWorkoutreceives program context (listener and GraphQL paths updated). - Update Effective Workout service/GraphQL to consume expanded suggestion metadata.
- Pipe enhanced logs and metrics into observability dashboards (rule IDs, tiers, stage transitions).
Testing Strategy
| Layer | Coverage | Command |
|---|---|---|
| Unit | New condition/action handlers (TIER_EQUALS, SET_SET_TEMPLATE, etc.) | npm run test -- progressionPlaybook.engine |
| Integration | Program-aware scenarios (deload, failure reset, premium fallback, cross-volume) | npm run test -- progression-playbook-engine.integration |
| Simulation | Compare legacy vs v2 output for unchanged rules | Dedicated harness (simulatePlaybook) |
- Integration harness spins up an isolated Mongo replica + canonical seed; tests clean up automatically (see
tests/integration/progression-playbook-engine.integration.test.ts). - Before releasing, run the full suite (
npm run test && npm run coverage) and update docs/telemetry dashboards.
Rollout Checklist
- ✅ Ship schema migrations and seed permission changes.
- ✅ Deploy engine v2 behind feature flag, verify parity with existing playbooks.
- ✅ Run integration simulations for flagship programs (GZCLP, 5/3/1) with canned data.
- ✅ Enable premium gating and advanced edition for pilot roles.
- ✅ Monitor metrics (evaluation duration, rule hit rate, fallback counts) and business events.
- 🔁 Collect user feedback, iterate on additional actions/conditions as needed.
Quick Reference
- Source of truth:
src/services/progressionPlaybook/progressionPlaybook.service.ts - Listener context provider:
src/listeners/progression-playbook.listener.ts - Effective workout consumer:
src/services/effectiveWorkout/effectiveWorkout.service.ts - Spec & design artifacts:
specs/003-progression-engine-v2/spec.md(detailed requirements) - Sample integration scenarios:
tests/integration/progression-playbook-engine.integration.test.ts
Need more detail? We’ll publish a full specification and data model doc soon, with types and schema diffs.