Skip to content

Workouts & Compliance Scoring ​

FitOps lets you define structured workouts in plain Markdown, link them to completed Strava activities, and score how well you executed each segment against your actual heart rate stream.


Workout Files ​

Workouts are .md files stored in ~/.fitops/workouts/. You write them by hand (or generate them via CLI) — they're just text.

markdown
---
name: Threshold Tuesday
sport: Run
target_duration_min: 60
tags: [threshold, quality]
---

## Warmup
10 min easy (Z1–Z2)

## Main Set
4 × 8 min @ Z4
2 min Z1 recovery jog between reps

## Cooldown
8 min easy Z1

Frontmatter (all optional) sets the display name, sport, target duration, and tags. If name is omitted, the filename stem is used.

Segments are defined by ## headings. Everything under a heading — duration, zone target, rep structure — is parsed automatically and becomes a scoreable unit when the workout is linked to an activity.


Segments ​

Each ## heading in the workout body is a segment. FitOps parses:

  • Duration — from patterns like 10 min, 4 × 8 min, 2 min
  • Zone target — from patterns like Z4, Zone 3, Z2–Z3
  • Rep structure — 4 × 8 min expands to 4 repetitions of 8 minutes each

Segments are used in two ways:

  1. Compliance scoring — each segment is mapped to a time slice of the activity's HR stream and scored against the target zone
  2. Workout simulation — each segment is projected onto a course with terrain and weather adjustments applied per-segment

Linking a Workout to an Activity ​

bash
fitops workouts link threshold-tuesday 12345678901

Linking stores:

  • The raw Markdown content of the workout file at link time
  • Parsed frontmatter metadata (name, sport, tags, target duration)
  • A physiology snapshot: CTL, ATL, TSB, VO2max, LT1/LT2, and the zone method/values active at that moment

The physiology snapshot lets you look back at any past workout and see exactly what your fitness and fatigue state was when you did it — even if your zones have since been updated.


Compliance Scoring ​

Compliance scoring answers: how well did you actually execute this workout?

How it works ​

FitOps maps each segment onto the activity's heart rate stream, proportional to duration. For example, a workout with a 10 min warmup + 32 min main set + 8 min cooldown (50 min total) is mapped onto the actual moving time of the activity. Each segment gets the corresponding slice of HR data.

For each segment, FitOps computes:

compliance_score = time_in_target_pct × 0.6 + (1 − |deviation| / 2) × 0.4

Where:

  • time_in_target_pct — fraction of segment time spent in the target HR zone (0.0–1.0)
  • deviation — how many zones above or below the target your average HR landed

Being below target is penalised equally to being above — the formula is symmetric. A score of ≥ 0.8 is generally a successful segment.

The overall_compliance_score is a duration-weighted average across all scored segments.


Contribution Analytics ​

Workout contribution analytics answer: how much has this specific workout contributed to my training load over time?

For each linked execution, FitOps reads stored activities.training_stress_score and attributes that load back to the workout definition. It then reports:

  • Total and period TSS from that workout
  • Share of the selected period's total training load
  • Compliance-weighted TSS (TSS × compliance_score)
  • Estimated current CTL and ATL contribution using the same EWMA decay constants as training load
  • True pace change across repeated executions when stored GAP and weather-adjusted pace data is available

The CTL/ATL contribution is attribution, not proof of causation. It means the workout's stored TSS mathematically contributes that much to the current EWMA load model. Execution quality and fitness improvement should be read alongside compliance, pace, HR, and fatigue state.

Contribution analytics are read from cached DB rows. The dashboard and fitops workouts analytics command do not fetch streams, compute true pace, rescore segments, or estimate missing TSS during the read. Linked activities without stored TSS are reported as missing coverage and excluded from load contribution totals; linked activities without stored true pace are omitted from the true pace trend.

Example output ​

Compliance  activity 12345678901  Threshold Tuesday

  Segment     Duration  Target  Avg HR  Time in Zone  Score
 ──────────────────────────────────────────────────────────
  Warmup      10 min    Z1–Z2   138     94%           0.96
  Main Set    32 min    Z4      162     78%           0.86
  Cooldown    8 min     Z1      141     62%           0.73

  Overall compliance  0.86  [Good]

Requirements ​

  1. A workout linked to the activity (fitops workouts link first)
  2. HR stream data for the activity (auto-fetched from Strava if not cached)
  3. Zone thresholds configured (fitops analytics zones --set-lthr 165 or --infer)

Workout Simulation ​

Before you do a workout, you can simulate how it will play out on a specific course — accounting for terrain and weather per segment.

bash
fitops workouts simulate threshold-tuesday --course 3
fitops workouts simulate tempo-run --activity 12345678901 --base-pace 5:10
fitops workouts simulate long-run --course 1 --date 2026-04-20 --hour 8

For each segment, the simulation computes:

  • The terrain effect from the course's elevation profile at that segment's distance slice
  • The heat/humidity effect from the date/conditions provided
  • A GAP- and WAP-adjusted target pace for the segment

This gives you a realistic per-segment pace plan before race or workout day — not just a flat pace target, but one that accounts for the actual course and expected conditions.

See Weather & Pace for the GAP and WAP models behind the adjustment.


Commands ​

bash
fitops workouts list                              # list all workout files
fitops workouts show threshold-tuesday            # display parsed workout
fitops workouts create "Threshold Tuesday" def.json  # create from JSON
fitops workouts edit threshold-tuesday updated.json  # replace definition
fitops workouts delete threshold-tuesday --yes    # remove definition + cached links
fitops workouts link threshold-tuesday <id>       # link to an activity
fitops workouts get <activity_id>                 # retrieve linked workout
fitops workouts compliance <activity_id>          # score HR compliance
fitops workouts compliance <activity_id> --recalculate
fitops workouts analytics threshold-tuesday       # workout-specific contribution
fitops workouts simulate threshold-tuesday --course 3
fitops workouts history --limit 10                # recent linked workouts
fitops workouts unlink <activity_id>              # remove link

See Commands → workouts for the full reference.

← Concepts

FitOps CLI — terminal-first training analytics