6/8 - Public Beta (Discord)
|See Changelog
Skip to main content

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 (T1T3) 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: isPremium and metadata fields 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: simulatePlaybook accepts 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

Sam completes his heavy squat session with all reps ✔️

  • Rule checks TIER_EQUALS T1 + TIER_STAGE_EQUALS Stage 1
  • ADVANCE_TIER_STAGE → Stage 2, ADJUST_TRAINING_MAX +5 kg
  • SET_SET_TEMPLATE forces pyramid next week, rest of metadata stored
  • Effective Workout shows 4×3–5 pyramid for the next session

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_shouldBlockProgression returns true.
  • ProgressionState still increments consecutiveSuccesses so 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.customFlags so 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, _shouldBlockProgression sees the override and returns early.
  • ProgressionState still 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

UserPermissionOutput
Sam (MemberPro)can_use_advanced_progression_featuresReceives set-specific weights, warmups, AMRAP cues, assistance quotas.
Chris (Member)can_use_advanced_progression_featuresGets 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

CapabilityPermissionRoles (by seed)Behaviour when missing
Assign premium playbookscan_assign_premium_playbooksMemberPro, Coach, AdminPlaybook assignment denied
Use advanced (set-level) recommendationscan_use_advanced_progression_featuresMemberPlus+, Coach, AdminEngine emits community edition suggestions
View effective workoutcan_view_effective_workoutsAll seeded rolesAccess 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

  1. Add or migrate Prisma models (ProgressionPlaybook, UserProgramPWESnapshot, WorkoutExerciseProgressionSuggestion).
  2. Seed new permissions via prisma/mongo/seeds/core/00permissions.seeder.ts.
  3. Extend playbook CRUD UI/API to expose new metadata, conditions, and actions.

Runtime Integration

  1. Ensure ProgressionPlaybookService.processWorkout receives program context (listener and GraphQL paths updated).
  2. Update Effective Workout service/GraphQL to consume expanded suggestion metadata.
  3. Pipe enhanced logs and metrics into observability dashboards (rule IDs, tiers, stage transitions).

Testing Strategy

LayerCoverageCommand
UnitNew condition/action handlers (TIER_EQUALS, SET_SET_TEMPLATE, etc.)npm run test -- progressionPlaybook.engine
IntegrationProgram-aware scenarios (deload, failure reset, premium fallback, cross-volume)npm run test -- progression-playbook-engine.integration
SimulationCompare legacy vs v2 output for unchanged rulesDedicated 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

  1. ✅ Ship schema migrations and seed permission changes.
  2. ✅ Deploy engine v2 behind feature flag, verify parity with existing playbooks.
  3. ✅ Run integration simulations for flagship programs (GZCLP, 5/3/1) with canned data.
  4. ✅ Enable premium gating and advanced edition for pilot roles.
  5. ✅ Monitor metrics (evaluation duration, rule hit rate, fallback counts) and business events.
  6. 🔁 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.